Files
smoa/backend/docs/BACKEND-GAPS-AND-ROADMAP.md
defiQUG 5a8c26cf5d Backend, sync, infra, docs: ETag, API versioning, k8s, web scaffold, Android 16, domain stubs
- Backend: ShallowEtagHeaderFilter for /api/v1/*, API-VERSIONING.md, README (tenant, CORS, Flyway, ETag)
- k8s: backend-deployment.yaml (Deployment, Service, Secret/ConfigMap)
- Web: scaffold with directory pull, 304 handling, touch-friendly UI
- Android 16: ANDROID-16-TARGET.md; BuildConfig STUN/signaling, SMOAApplication configures InfrastructureManager
- Domain: CertificateManager revocation stub, ReportService signReports, ZeroTrust/ThreatDetection minimal docs
- TODO.md and IMPLEMENTATION_STATUS.md updated; communications README for endpoint config

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 20:37:01 -08:00

6.0 KiB
Raw Permalink Blame History

SMOA Backend Gap Analysis and Roadmap

Review summary

The backend implements the sync contract expected by the mobile app (POST sync endpoints, SyncResponse with conflict/remoteData), with validation, optional API key auth, OpenAPI, conflict detection, and H2 persistence. Below are covered areas, gaps, and recommendations.


What's in place

Area Status
Sync API contract All five sync endpoints (directory, order, evidence, credential, report); request DTOs aligned with app; SyncResponse with success, itemId, serverTimestamp, conflict, remoteData, message.
Conflict detection Directory uses lastUpdated; others use clientUpdatedAt; server returns conflict + remoteData when server has newer version.
Validation @Valid on all sync bodies; NotBlank/NotNull on required fields.
Auth Optional API key via X-API-Key or api_key query; when key is set, all /api/v1/* require it.
Security Stateless; CSRF disabled for API; health/info/docs/h2-console permitted without auth.
Persistence JPA entities and repositories for all five resource types; H2 file DB; ddl-auto: update.
OpenAPI springdoc; /v3/api-docs, /swagger-ui.html; ApiKey scheme documented.
Health GET /health with status, application, timestamp, and DB check (up/down).
CORS Configurable via smoa.cors.allowed-origins (default *).
Error handling Global exception handler: 400 for validation/type errors with JSON body; 500 for other errors.

Gaps and recommendations

1. Delete / SyncOperation.Delete Done

  • Gap: App has SyncOperation.Create, Update, Delete. Backend only does upsert (create/update).
  • Done: DELETE endpoints added: /api/v1/sync/directory/{id}, /order/{orderId}, /evidence/{evidenceId}, /credential/{credentialId}, /report/{reportId}; each returns SyncResponse; audit logged.

2. Pull / GET (initial load or refresh) Done

  • Gap: No GET endpoints. App today only pushes from a queue; for "refresh after coming online" or initial load, pull is often needed.
  • Done: GET list endpoints: /api/v1/directory (optional unit, X-Unit), /api/v1/orders (since, limit, jurisdiction / X-Unit), /api/v1/evidence, /api/v1/credentials, /api/v1/reports (since, limit, optional filters). See PullController and api/dto/PullResponse.kt.

3. Enum validation Done

  • Gap: orderType, status (orders), evidenceType, reportType are free strings. App uses enums.
  • Done: @Pattern added for orderType (AUTHORIZATION|…|ADMINISTRATIVE), status (DRAFT|…|REVOKED), evidenceType (PHYSICAL|…|DOCUMENT), reportType (OPERATIONAL|…|REGULATORY), report format (PDF|XML|JSON|CSV|EXCEL).

4. SyncResponse.remoteData format Done

  • Gap: Backend returns remoteData as base64; client must decode.
  • Done: Documented in OpenAPI description that remoteData is base64-encoded JSON when conflict=true.

5. Production and ops

  • Gap: H2 console enabled in all profiles; no explicit prod profile with console off and stricter settings.
  • Recommendation: Add application-prod.yml: disable H2 console, set logging, optionally require API key. Document PostgreSQL (or other DB) and env vars.

6. Rate limiting Done

  • Gap: No rate limiting on sync or auth.
  • Done: RateLimitFilter on /api/v1/*; per API key or IP; configurable smoa.rate-limit.requests-per-minute (default 120); 429 when exceeded; disabled in test profile.

7. Audit / logging Done

  • Gap: No structured audit log for "who synced what when".
  • Done: SyncAuditLog entity and SyncAuditService; sync and delete operations logged (resourceType, resourceId, operation, success). SyncController calls audit after each sync/delete.

8. Tests Done

  • Gap: No backend unit or integration tests.
  • Done: DirectorySyncServiceTest (create, conflict/remoteData, delete); GlobalExceptionHandlerTest (500); SyncControllerIntegrationTest (POST valid/invalid, health); application-test.yml (H2 in-memory, rate limit off); mockk for unit tests.

9. Ids and authorization

  • Gap: No tenant/org/unit scoping; any client with a valid API key can read/write any resource.
  • Recommendation: If the app is multi-tenant or unit-scoped, add unit/tenant to API key or token and filter queries (e.g. directory by unit, orders by unit).

10. Infrastructure Done (Dockerfile)

  • Gap: No Dockerfile or k8s manifests; no migration strategy beyond ddl-auto.
  • Done: backend/Dockerfile (multi-stage); build from repo root: docker build -f backend/Dockerfile .. Optional: Flyway/Liquibase and ddl-auto: validate in prod.

Optional improvements

  • Pagination: For any future GET list endpoints, use page/size or limit/offset and document in OpenAPI.
  • ETag / If-None-Match: For GET-by-id or list endpoints, support caching with ETag.
  • Request ID: Add a filter to assign and log a request ID for tracing.
  • API versioning: Keep /api/v1; when introducing breaking changes, add /api/v2 and document deprecation.

Quick reference: config

Property Default Purpose
smoa.api.key (empty) API key; empty = no auth
smoa.api.key-header X-API-Key Header name
smoa.cors.allowed-origins * CORS origins (comma-separated)
smoa.rate-limit.enabled true Enable rate limit on /api/v1/*
smoa.rate-limit.requests-per-minute 120 Max requests per key/IP per minute
server.port 8080 Port
spring.datasource.url H2 file DB URL (use PostgreSQL in prod)

Summary

The backend is ready for mobile sync with: push and delete sync, pull/GET endpoints, conflict handling, enum validation, rate limiting, audit logging, tests, and a Dockerfile. Remaining optional work: prod profile and DB (PostgreSQL, H2 console off), unit/tenant scoping (filter by unit from API key or header), and migrations (Flyway/Liquibase with ddl-auto: validate).