SMOA requirements alignment – frontend and backend
This document maps requirements between the device application (Android; future iOS and Web) and the backend, and lists gaps with ownership (device vs backend).
1. Sync contract (frontend ↔ backend)
All clients (Android, iOS, Web) use the same REST contract.
| Requirement |
Backend |
Android app |
iOS (to build) |
Web Dapp (to build) |
| POST sync (directory, order, evidence, credential, report) |
✅ SyncController |
✅ SyncAPI + SyncService |
Same contract |
Same contract |
| SyncResponse (success, itemId, serverTimestamp, conflict, remoteData, message) |
✅ |
✅ core/common SyncResponse |
Same |
Same |
| Conflict (server returns conflict + base64 remoteData) |
✅ |
✅ SyncService handles ConflictException |
Same |
Same |
| DELETE (sync delete) |
✅ |
✅ SyncAPI.delete* + SyncService on SyncOperation.Delete |
Same |
Same |
| Pull GET (directory, orders, evidence, credentials, reports) |
✅ PullController |
✅ Use GET with since/limit |
Same |
Same |
| Auth (X-API-Key or api_key) |
✅ |
✅ Send header/query when configured |
Same |
Same |
| Rate limit (429, configurable RPM) |
✅ |
✅ Retry with backoff |
Same |
Same |
2. API surface (backend)
| Endpoint |
Method |
Purpose |
/health |
GET |
Liveness; db status. |
/api/v1/info |
GET |
Discovery: name, version, list of sync/pull/delete endpoints. |
/api/v1/sync/directory |
POST |
Sync directory entry. |
/api/v1/sync/order |
POST |
Sync order. |
/api/v1/sync/evidence |
POST |
Sync evidence. |
/api/v1/sync/credential |
POST |
Sync credential. |
/api/v1/sync/report |
POST |
Sync report. |
/api/v1/sync/directory/{id} |
DELETE |
Delete directory entry. |
/api/v1/sync/order/{orderId} |
DELETE |
Delete order. |
/api/v1/sync/evidence/{evidenceId} |
DELETE |
Delete evidence. |
/api/v1/sync/credential/{credentialId} |
DELETE |
Delete credential. |
/api/v1/sync/report/{reportId} |
DELETE |
Delete report. |
/api/v1/directory |
GET |
List directory (optional unit, X-Unit). |
/api/v1/orders |
GET |
List orders (since, limit, jurisdiction / X-Unit). |
/api/v1/evidence |
GET |
List evidence (since, limit, caseNumber). |
/api/v1/credentials |
GET |
List credentials (since, limit, holderId). |
/api/v1/reports |
GET |
List reports (since, limit). |
3. DTO alignment (device → backend)
Device sends JSON that matches backend request DTOs; backend returns JSON that matches device expectations.
| Resource |
Request (device → backend) |
Response (backend → device) |
| Directory |
DirectorySyncRequest (id, name, title, unit, …; lastUpdated) |
SyncResponse |
| Order |
OrderSyncRequest (orderId, orderType, title, content, …; clientUpdatedAt) |
SyncResponse |
| Evidence |
EvidenceSyncRequest (evidenceId, caseNumber, …; clientUpdatedAt) |
SyncResponse |
| Credential |
CredentialSyncRequest (credentialId, holderId, …; clientUpdatedAt) |
SyncResponse |
| Report |
ReportSyncRequest (reportId, reportType, title, format, …; clientUpdatedAt) |
SyncResponse |
Enums (validation): orderType, status, evidenceType, reportType, format — backend uses @Pattern; device must send allowed values (see backend SyncRequest.kt).
4. Gaps and ownership
4.1 Filled by device (Android)
| Gap |
Status |
Notes |
| Real SyncAPI implementation |
✅ Done |
BackendSyncAPI (app) calls backend when BuildConfig.SMOA_BACKEND_BASE_URL set; build with -Psmoa.backend.baseUrl=http://host:8080. |
| SyncService uses SyncAPI |
✅ Done |
CommonModule provides SyncService(syncAPI); AppModule provides SyncAPI (BackendSyncAPI or DefaultSyncAPI). |
| Delete operation |
✅ Done |
SyncService calls syncAPI.delete*(item.id) when item.operation == SyncOperation.Delete. |
| Pull on connect |
Optional |
On connectivity restored, call GET endpoints and merge into local DB. |
4.2 Filled by backend
| Gap |
Status |
Notes |
| CORS for Web |
✅ |
smoa.cors.allowed-origins; set to web app origin(s) for production. |
| Info endpoint |
✅ |
GET /api/v1/info lists all sync, delete, and pull endpoints for client discovery. |
| Auth for all clients |
✅ |
API key required when smoa.api.key set; same for Android, iOS, Web. |
4.3 Filled by iOS (when built)
| Gap |
Owner |
Notes |
| iOS app |
iOS |
Swift/SwiftUI or KMP; same REST contract; Keychain for API key. |
| Offline queue |
iOS |
Queue sync when offline; retry when online. |
4.4 Filled by Web Dapp (when built)
| Gap |
Owner |
Notes |
| Web app |
Web |
SPA (e.g. React/Vue); responsive + touch; same REST contract. |
| CORS origin |
Backend config |
Set smoa.cors.allowed-origins to web origin. |
| Secure storage |
Web |
sessionStorage or secure cookie for API key/session. |
5. References
- Backend API:
backend/README.md, OpenAPI /v3/api-docs, /swagger-ui.html
- Mobile contract:
core/common/SyncAPI.kt, SyncService.kt
- Platforms: PLATFORM-REQUIREMENTS.md