Files
smoa/docs/database/DATABASE_SCHEMA.md
T
defiQUG a2dc194a49 Monorepo: Gitea CI, docs, auth/sync, backend APIs, gitignore
- 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
2026-03-23 20:19:24 -07:00

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
email VARCHAR(255) Email
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?
email 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_timestamp on sync_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