API Reference
Cpnucleo exposes three API services: the WebApi (REST), the IdentityApi (authentication), and the GrpcServer (gRPC command handling).
WebApi – REST Endpoints
The WebApi uses FastEndpoints to define REST endpoints with Swagger/OpenAPI documentation. Each entity has 5 standard CRUD endpoints.
Base URL
- Direct:
http://localhost:5100 - Via NGINX load balancer:
http://localhost:9999
Swagger
Available in Development mode at /swagger.
Endpoint Pattern
Every entity follows this consistent pattern:
| Method | Route | Description |
|---|---|---|
POST |
/api/{entity} |
Create a new record |
GET |
/api/{entity}/{id} |
Get a single record by ID |
GET |
/api/{entities} |
List records (paginated; plural route such as /api/projects) |
PUT |
/api/{entity}/{id} |
Update an existing record |
DELETE |
/api/{entity}/{id} |
Remove a record (soft delete) |
Available Entities
| Entity | Route Prefix | Tag |
|---|---|---|
| Appointment | /api/appointment / /api/appointments |
Appointments |
| Assignment | /api/assignment / /api/assignments |
Assignments |
| AssignmentImpediment | /api/assignmentImpediment / /api/assignmentImpediments |
AssignmentImpediments |
| AssignmentType | /api/assignmentType / /api/assignmentTypes |
AssignmentTypes |
| Impediment | /api/impediment / /api/impediments |
Impediments |
| Organization | /api/organization / /api/organizations |
Organizations |
| Project | /api/project / /api/projects |
Projects |
| User | /api/user / /api/users |
Users |
| UserAssignment | /api/userAssignment / /api/userAssignments |
UserAssignments |
| UserProject | /api/userProject / /api/userProjects |
UserProjects |
| Workflow | /api/workflow / /api/workflows |
Workflows |
Example: Create Appointment
Request:
POST /api/appointment
Content-Type: application/json
{
"id": "00000000-0000-0000-0000-000000000000",
"description": "Sprint planning meeting",
"keepDate": "2025-03-01T10:00:00Z",
"amountHours": 2,
"assignmentId": "...",
"userId": "..."
}
Response (200 OK):
{
"appointment": {
"id": "...",
"description": "Sprint planning meeting",
"keepDate": "2025-03-01T10:00:00Z",
"amountHours": 2,
"assignmentId": "...",
"userId": "...",
"createdAt": "...",
"active": true
}
}
Data Access
All WebApi endpoints use EF Core via IApplicationDbContext for database operations. Endpoints inject the context directly:
public class Endpoint(IApplicationDbContext dbContext) : Endpoint<Request, Response>
WebClient response expectations
The WebClient CRUD screens consume the REST endpoints through src/WebClient/src/lib/api/webapi-client.ts and normalize the response shapes used by the API:
- list arrays, paginated objects, and
{ result: ... }list envelopes - raw singular items with an
id { result: item }singular envelopes- resource-key singular envelopes such as
{ organization: { ... } }
Relation lookups rely on that singular normalization before resolving table labels. When a visible row references a related record outside the first prefetched relation page, the client fetches the specific related item and merges it into the relation cache instead of overwriting previously fetched labels.
Rate Limiting
- 50 requests per minute per IP address
- Fixed-window partitioning
- Queue limit: 10 additional requests
- Returns
429 Too Many RequestswithRetry-After: 60header when exceeded
IdentityApi – Authentication
Base URL
http://localhost:5200
Swagger
Available in Development mode at /swagger.
Login Endpoint
| Method | Route | Description |
|---|---|---|
POST |
/api/login |
Authenticate and receive JWT token |
Request:
POST /api/login
Content-Type: application/json
{
"login": "user@example.com",
"password": "password123"
}
Response (200 OK):
{
"token": "eyJhbGciOiJIUzI1NiIs..."
}
Response (404 Not Found):
Returned when credentials are invalid.
JWT Configuration
| Parameter | Value |
|---|---|
| Issuer | https://identity-cpnucleo.jonathanperis.tech |
| Audience | https://api-cpnucleo.jonathanperis.tech |
| Expiration | 1 day |
| Algorithm | HMAC-SHA (via FastEndpoints.Security) |
Rate Limiting
- 10 requests per minute per IP address
- Queue limit: 3 additional requests
- Stricter than WebApi to protect against brute-force attacks
Output Caching
- Base policy: 10-second cache expiration
- All responses are cached by default
GrpcServer – Remote Command Handling
The GrpcServer uses FastEndpoints.Messaging.Remote to handle commands over HTTP/2 gRPC transport.
Ports
- gRPC transport:
http://localhost:5300(HTTP/2) - Health check:
http://localhost:5301/healthz(HTTP/1.1)
Command Pattern
Each operation is a command/result pair defined in GrpcServer.Contracts:
Command -> Handler -> Result
Available Commands (per entity)
Each of the 11 entities has these 5 commands:
| Command | Description |
|---|---|
Create{Entity}Command |
Create a new record |
Get{Entity}ByIdCommand |
Retrieve by ID |
List{Entity}sCommand |
List with pagination |
Remove{Entity}Command |
Soft delete |
Update{Entity}Command |
Update fields |
Total: 55 registered command handlers.
Data Access
All gRPC handlers use Dapper via IUnitOfWork for database operations, providing transactional support with explicit BeginTransactionAsync, CommitAsync, and RollbackAsync.
Handler Registration
Handlers are registered in Program.cs:
app.MapHandlers(h =>
{
h.Register<CreateAppointmentCommand, CreateAppointmentHandler, CreateAppointmentResult>();
h.Register<GetAppointmentByIdCommand, GetAppointmentByIdHandler, GetAppointmentByIdResult>();
// ... 53 more handlers
});
Health Checks
All three APIs expose health check endpoints:
| Service | URL | Protocol |
|---|---|---|
| WebApi | /healthz |
HTTP |
| IdentityApi | /healthz |
HTTP |
| GrpcServer | /healthz |
HTTP |
Root Endpoint
All services also respond to GET / with "Hello World!".
Authentication Flow
JWT authentication is configured but currently commented out in WebApi and GrpcServer. The IdentityApi is fully functional for token generation. When enabled:
- Client authenticates via
POST /api/loginon IdentityApi - Receives JWT token
- Includes token in
Authorization: Bearer {token}header for WebApi/GrpcServer requests - Token validation checks issuer, audience, signing key, and expiration