# 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](PLATFORM-REQUIREMENTS.md)