- Add Gitea Actions workflow; point README to gitea.d-bis.org/Sankofa_Phoenix/SMOA - Expand .gitignore for Spring H2 data, secrets, Kotlin .kotlin/, tooling - Track docs/api/generated ReDoc bundle; refresh api docs README - Android: network/auth/sync, UI shell, tests; backend credentials/integrity APIs - Docs, scripts (generate-api-docs), modules and core updates Made-with: Cursor
6.8 KiB
SMOA database schema (server + device)
Version: 2.0
Last updated: 2026-03-23
This document aligns SMOA backend (Flyway V1__baseline.sql, H2 or PostgreSQL) with on-device Room entities in this repository. Older rows that described only a generic local credentials table without a matching entity are removed.
1. Server database (SMOA backend)
Source of truth: backend/src/main/resources/db/migration/V1__baseline.sql.
JPA entities: backend/src/main/kotlin/com/smoa/backend/domain/*.kt.
1.1 directory_entries
| Column | SQL type | Description |
|---|---|---|
| id | VARCHAR(255) PK | Directory entry id |
| name | VARCHAR(255) | Display name |
| title | VARCHAR(255) | Job title |
| unit | VARCHAR(255) | Unit / org |
| phone_number | VARCHAR(255) | Phone |
| extension | VARCHAR(255) | Extension |
| VARCHAR(255) | ||
| secure_routing_id | VARCHAR(255) | Secure routing |
| role | VARCHAR(255) | Role |
| clearance_level | VARCHAR(255) | Clearance |
| last_updated | BIGINT | Epoch ms |
1.2 orders
| Column | SQL type | Description |
|---|---|---|
| order_id | VARCHAR(255) PK | Order id |
| order_type | VARCHAR(255) | Enum string (see backend validation) |
| title | VARCHAR(255) | Title |
| content | CLOB | Body |
| issued_by | VARCHAR(255) | Issuer |
| issued_to | VARCHAR(255) | Recipient |
| issue_date | TIMESTAMP | Issued |
| effective_date | TIMESTAMP | Effective |
| expiration_date | TIMESTAMP | Expiry |
| status | VARCHAR(255) | Status enum |
| classification | VARCHAR(255) | Classification |
| jurisdiction | VARCHAR(255) | Jurisdiction |
| case_number | VARCHAR(255) | Case |
| updated_at | BIGINT | Epoch ms |
1.3 evidence
| Column | SQL type | Description |
|---|---|---|
| evidence_id | VARCHAR(255) PK | Evidence id |
| case_number | VARCHAR(255) | Case |
| description | CLOB | Description |
| evidence_type | VARCHAR(255) | Type enum |
| collection_date | TIMESTAMP | Collected |
| collection_location | VARCHAR(255) | Location |
| collection_method | VARCHAR(255) | Method |
| collected_by | VARCHAR(255) | Collector |
| current_custodian | VARCHAR(255) | Custodian |
| storage_location | VARCHAR(255) | Storage |
| updated_at | BIGINT | Epoch ms |
1.4 credentials (server)
| Column | SQL type | Description |
|---|---|---|
| credential_id | VARCHAR(255) PK | Credential id |
| holder_id | VARCHAR(255) | Subject / holder |
| credential_type | VARCHAR(255) | Canonical type (SmoaCredentialType + legacy; see docs/reference/IDENTITY-TEMPLATE-ALIGNMENT.md) |
| issuer | VARCHAR(255) | Issuing authority label |
| issued_at | BIGINT | Epoch ms (optional) |
| expires_at | BIGINT | Epoch ms (optional) |
| payload_json | CLOB | JSON object: format-specific fields, optional issuingAuthority, completeCredentialDomain, extensions |
| updated_at | BIGINT | Epoch ms |
Issuance validation: Parse payload_json as JSON, then validate with docs/schemas/credential-payload-*.schema.json for the given credential_type on the sync request body (not duplicated inside payload).
1.5 reports
| Column | SQL type | Description |
|---|---|---|
| report_id | VARCHAR(255) PK | Report id |
| report_type | VARCHAR(255) | Type enum |
| title | VARCHAR(255) | Title |
| format | VARCHAR(255) | PDF, XML, JSON, CSV, EXCEL |
| generated_date | BIGINT | Epoch ms |
| generated_by | VARCHAR(255) | Generator |
| content | BLOB | Optional binary |
| metadata_json | CLOB | Optional JSON |
| updated_at | BIGINT | Epoch ms |
1.6 sync_audit_log
| Column | SQL type | Description |
|---|---|---|
| id | BIGINT IDENTITY PK | Surrogate key |
| resource_type | VARCHAR(255) | Resource |
| resource_id | VARCHAR(255) | Id |
| operation | VARCHAR(255) | Operation |
| success | BOOLEAN | Outcome |
| principal | VARCHAR(255) | Optional actor |
| timestamp | TIMESTAMP | Event time |
2. On-device Room (implemented modules)
Room uses SQLite; module-specific databases. Below match Kotlin @Entity types.
2.1 Directory — directory_entries
modules/directory/.../DirectoryEntity.kt
| Column | Type | Notes |
|---|---|---|
| id | TEXT PK | |
| name | TEXT | |
| title | TEXT? | |
| unit | TEXT | |
| phoneNumber | TEXT? | camelCase in Kotlin → snake in DB per Room |
| extension | TEXT? | |
| TEXT? | ||
| secureRoutingId | TEXT? | |
| role | TEXT? | |
| clearanceLevel | TEXT? | |
| lastUpdated | INTEGER | Epoch ms |
2.2 Orders — orders
modules/orders/.../OrderEntity.kt
| Column | Type | Notes |
|---|---|---|
| orderId | TEXT PK | |
| orderType | TEXT | Enum persisted via converter |
| title | TEXT | |
| content | TEXT | |
| issuedBy | TEXT | |
| issuedTo | TEXT? | |
| issueDate | INTEGER / Date | Type converters |
| effectiveDate | ||
| expirationDate | ||
| status | Enum | |
| classification | TEXT? | |
| jurisdiction | TEXT | |
| caseNumber | TEXT? | |
| createdAt | ||
| updatedAt |
2.3 Evidence — evidence
modules/evidence/.../EvidenceEntity.kt
| Column | Type | Notes |
|---|---|---|
| evidenceId | TEXT PK | |
| caseNumber | TEXT | |
| description | TEXT | |
| evidenceType | Enum | |
| collectionDate | ||
| collectionLocation | TEXT | |
| collectionMethod | TEXT | |
| collectedBy | TEXT | |
| currentCustodian | TEXT | |
| storageLocation | TEXT? | |
| createdAt | ||
| updatedAt |
2.4 Custody — custody_transfers
modules/evidence/.../CustodyTransferEntity.kt
| Column | Type | Notes |
|---|---|---|
| transferId | TEXT PK | |
| evidenceId | TEXT FK → evidence | |
| timestamp | Date | |
| fromCustodian | TEXT | |
| toCustodian | TEXT | |
| reason | TEXT | |
| evidenceCondition | TEXT | |
| signatureData | BLOB? | |
| notes | TEXT? |
2.5 Credentials cache — credential_cache
modules/credentials/.../CredentialCacheEntity.kt (encrypted Room DB credential_cache_database)
| Column | Type | Notes |
|---|---|---|
| credentialId | TEXT PK | |
| holderId | TEXT | |
| credentialType | TEXT | |
| issuer | TEXT? | |
| issuedAt | INTEGER? | Epoch ms |
| expiresAt | INTEGER? | Epoch ms |
| payloadJson | TEXT? | JSON string |
| updatedAt | INTEGER | Epoch ms |
Populate from pull/sync merge logic in application code when wired; schema matches server credentials for offline display.
2.6 Reports (device)
No Room ReportEntity in this repo; reports remain server-backed unless a local entity is added later.
3. Indexes (server)
idx_sync_audit_timestamponsync_audit_log(timestamp)
4. References
- Backend Flyway:
backend/src/main/resources/db/migration/V1__baseline.sql - Identity / payload schemas:
docs/reference/IDENTITY-TEMPLATE-ALIGNMENT.md,docs/schemas/ - Tenant model:
docs/security/TENANT-THREAT-MODEL.md