API Contract Baseline
Neemias
OpenAPI 3.1 spec disponível em: /reference/api/openapi.json
Gere ou atualize com:
pnpm docs:openapiO documento abaixo é o contrato textual de referência. A especificação OpenAPI é a fonte canônica para consumo programático (clients, testes, tooling).
1. Purpose
This document defines a baseline HTTP API contract for synchronization, auth/session checks, and operational data exchange.
It complements:
../data-dictionary.md../../architecture/srs.md../../architecture/sdd.md
2. Design Constraints
- Offline resilience via IndexedDB fallback is mandatory.
- Server endpoints must be idempotent for retry-safe sync.
- Admin precedence over lower-privilege conflicts is mandatory.
- Historical events are immutable and retained.
- Protected submissions require valid session.
3. Versioning and Transport
- Base path:
/api/v1 - Transport: HTTPS only
- Content type:
application/json - Time format: UTC ISO 8601
Versioning rule:
- Backward-compatible additions may remain in
v1. - Breaking changes require
v2or equivalent compatibility mechanism.
4. Authentication Model
Headers:
Authorization: Bearer <token>for protected endpointsX-Device-Id: <uuid>for sync observability and replay analysisX-CSRF-Token: <token>for mutating requests when cookie session mode is enabled
Session policy baseline:
- Session TTL defaults to 24 hours.
- Expired sessions cannot submit protected actions.
- Unsynced local actions must remain queued until re-authentication.
5. Idempotency and Retries
Protected mutation endpoints must support idempotency key handling.
Header:
Idempotency-Key: <uuid>
Rules:
- Same key plus same principal plus same payload returns same logical outcome.
- Key reuse with different payload returns
409with explicit error code.
6. Core Endpoints
6.1 Auth Login
- Method:
POST - Path:
/api/v1/auth/login - Auth: not required
Request:
{
"email": "admin@neemias.local",
"password": "senha123"
}Response 200:
{
"accessToken": "jwt",
"accessTokenExpiresAt": "2026-04-15T18:20:00Z",
"refreshToken": "only_when_bearer_mode",
"csrfToken": "uuid",
"user": {
"userId": "uuid",
"email": "admin@neemias.local",
"displayName": "Administrador",
"role": "ADMIN"
}
}6.2 Auth Refresh
- Method:
POST - Path:
/api/v1/auth/refresh - Auth: not required
Rules:
- Bearer mode sends
refreshTokenin body. - Cookie mode uses httpOnly refresh cookie and CSRF header for mutating calls.
- Successful refresh rotates and revokes prior refresh session.
6.3 Auth Revoke
- Method:
POST - Path:
/api/v1/auth/revoke - Auth: required
6.4 Session Validate
- Method:
POST - Path:
/api/v1/session/validate - Auth: required
Request:
{
"sessionId": "5f2bc645-5f8f-4e4f-a7cb-f1ca01cc91e9",
"clientTime": "2026-04-10T12:00:00Z"
}Response 200:
{
"status": "ACTIVE",
"expiresAt": "2026-04-12T12:00:00Z",
"serverTime": "2026-04-10T12:00:01Z"
}Response 401:
{
"error": {
"code": "SESSION_EXPIRED",
"message": "Re-authentication required",
"correlationId": "d70de4f2-f3f3-4219-b6f3-6bd5eb0185cf"
}
}6.5 Sync Events
- Method:
POST - Path:
/api/v1/sync/events - Auth: required
- Idempotency: required
Request shape aligns with ../data-dictionary.md section 7.1.
Response shape aligns with section 7.2 and 7.3.
Additional response constraints:
conflictsmust include policy identifier.failedentries must include machine-readable reason code.syncedentries must include authoritativeserverTimestamp.
6.6 Student Query
Method:
GETPath:
/api/v1/studentsAuth: required
Query params:
q(optional search string)status(ACTIVEorDELETED, defaultACTIVE)limitandcursorfor pagination
Response 200:
{
"items": [
{
"studentId": "a1cc3a6a-8501-4fa8-9ea4-0afc7bb8d2f1",
"displayName": "Joao Silva",
"photoRef": "photo:student:a1cc3a6a",
"status": "ACTIVE",
"updatedAt": "2026-04-10T12:00:00Z"
}
],
"nextCursor": null
}6.7 Student Mutations
- Create:
POST /api/v1/students - Update:
PATCH /api/v1/students/{studentId} - Delete (soft):
POST /api/v1/students/{studentId}/delete - Auth: role-gated and required
- Idempotency: required
Delete request requires:
{
"justification": "Text between 10 and 500 characters"
}Delete constraints:
- Non-admin attempts return
403. - Empty or short justification returns
422. - Delete creates immutable
StudentEvententry.
6.8 Attendance Marking
- Method:
POST - Path:
/api/v1/attendance/events - Auth: role-gated and required
- Idempotency: required
Request:
{
"studentId": "a1cc3a6a-8501-4fa8-9ea4-0afc7bb8d2f1",
"actionType": "MARK_PRESENT",
"timestamp": "2026-04-10T12:00:00Z"
}6.9 User Management (Phase 2 extension)
Method:
GETPath:
/api/v1/usersAuth: admin role required
Method:
POSTPath:
/api/v1/usersAuth: admin role required
Method:
PATCHPath:
/api/v1/users/{userId}Auth: admin role required
Method:
POSTPath:
/api/v1/users/{userId}/reset-passwordAuth: admin role required
Method:
POSTPath:
/api/v1/users/{userId}/deactivateAuth: admin role required
Rules:
- Preserve last-active-admin safeguards.
- User changes append immutable
userEventsrecords. - Deactivation is soft status transition; no hard delete.
Response 202:
{
"eventId": "3d9d2f89-8429-4f95-b0ad-6b849bb7e2e0",
"accepted": true,
"serverTime": "2026-04-10T12:00:01Z"
}7. Error Model
All non-2xx responses should use:
{
"error": {
"code": "MACHINE_READABLE_CODE",
"message": "Human readable message",
"correlationId": "uuid",
"details": {}
}
}Core codes:
UNAUTHORIZEDFORBIDDEN_ROLESESSION_EXPIREDVALIDATION_FAILEDCONFLICT_SUPERSEDEDIDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_PAYLOADRATE_LIMITEDINTERNAL_ERROR
8. Conflict Policy Representation
When conflicts occur:
- Include policy in response, such as
ADMIN_PRECEDENCE. - Include winner and loser event IDs.
- Preserve both events in history.
9. Observability Requirements
Server should log at minimum:
correlationId- principal user ID and role
- endpoint and outcome
- policy decision for conflicts
- idempotency decision path
Audit logs must support accountability requirements in SCR-006.
10. Open Items
Implementation can refine this contract, but changes should be tracked through ADR entries:
- token format and revocation strategy
- exact pagination style
- media photo retrieval endpoint and signed URL policy
- sync chunk limits and backoff strategy
- server-side ordering guarantees for same-timestamp events
11. Security.txt (RFC 9116)
- Method:
GET - Path:
/.well-known/security.txt - Auth: not required
Response 200:
Contact: mailto:advisory@barateza.org
Contact: mailto:dpo@barateza.org
Expires: <1 year from issuance>
Preferred-Languages: pt-BR, en