Skip to content

API Contract Baseline

Neemias

OpenAPI 3.1 spec disponível em: /reference/api/openapi.json

Gere ou atualize com: pnpm docs:openapi

O 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 v2 or equivalent compatibility mechanism.

4. Authentication Model

Headers:

  • Authorization: Bearer <token> for protected endpoints
  • X-Device-Id: <uuid> for sync observability and replay analysis
  • X-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 409 with explicit error code.

6. Core Endpoints

6.1 Auth Login

  • Method: POST
  • Path: /api/v1/auth/login
  • Auth: not required

Request:

json
{
  "email": "admin@neemias.local",
  "password": "senha123"
}

Response 200:

json
{
  "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 refreshToken in 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:

json
{
  "sessionId": "5f2bc645-5f8f-4e4f-a7cb-f1ca01cc91e9",
  "clientTime": "2026-04-10T12:00:00Z"
}

Response 200:

json
{
  "status": "ACTIVE",
  "expiresAt": "2026-04-12T12:00:00Z",
  "serverTime": "2026-04-10T12:00:01Z"
}

Response 401:

json
{
  "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:

  • conflicts must include policy identifier.
  • failed entries must include machine-readable reason code.
  • synced entries must include authoritative serverTimestamp.

6.6 Student Query

  • Method: GET

  • Path: /api/v1/students

  • Auth: required

  • Query params:

  • q (optional search string)

  • status (ACTIVE or DELETED, default ACTIVE)

  • limit and cursor for pagination

Response 200:

json
{
  "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:

json
{
  "justification": "Text between 10 and 500 characters"
}

Delete constraints:

  • Non-admin attempts return 403.
  • Empty or short justification returns 422.
  • Delete creates immutable StudentEvent entry.

6.8 Attendance Marking

  • Method: POST
  • Path: /api/v1/attendance/events
  • Auth: role-gated and required
  • Idempotency: required

Request:

json
{
  "studentId": "a1cc3a6a-8501-4fa8-9ea4-0afc7bb8d2f1",
  "actionType": "MARK_PRESENT",
  "timestamp": "2026-04-10T12:00:00Z"
}

6.9 User Management (Phase 2 extension)

  • Method: GET

  • Path: /api/v1/users

  • Auth: admin role required

  • Method: POST

  • Path: /api/v1/users

  • Auth: admin role required

  • Method: PATCH

  • Path: /api/v1/users/{userId}

  • Auth: admin role required

  • Method: POST

  • Path: /api/v1/users/{userId}/reset-password

  • Auth: admin role required

  • Method: POST

  • Path: /api/v1/users/{userId}/deactivate

  • Auth: admin role required

Rules:

  • Preserve last-active-admin safeguards.
  • User changes append immutable userEvents records.
  • Deactivation is soft status transition; no hard delete.

Response 202:

json
{
  "eventId": "3d9d2f89-8429-4f95-b0ad-6b849bb7e2e0",
  "accepted": true,
  "serverTime": "2026-04-10T12:00:01Z"
}

7. Error Model

All non-2xx responses should use:

json
{
  "error": {
    "code": "MACHINE_READABLE_CODE",
    "message": "Human readable message",
    "correlationId": "uuid",
    "details": {}
  }
}

Core codes:

  • UNAUTHORIZED
  • FORBIDDEN_ROLE
  • SESSION_EXPIRED
  • VALIDATION_FAILED
  • CONFLICT_SUPERSEDED
  • IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_PAYLOAD
  • RATE_LIMITED
  • INTERNAL_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:

text
Contact: mailto:advisory@barateza.org
Contact: mailto:dpo@barateza.org
Expires: <1 year from issuance>
Preferred-Languages: pt-BR, en

Distribuído sob licença MIT.