# Data Model Canonical persistence model for the as4-411 directory. Aligned with [OpenAPI schemas](../api/openapi.yaml) and the [resolution algorithm](resolution-algorithm.md). ## Tables (relational baseline) ### tenants Multi-tenant isolation. All participant data is scoped by tenant. | Column | Type | Description | | ---------- | --------- | ----------------- | | id | PK | Tenant identifier | | name | string | Display name | | created_at | timestamp | | | updated_at | timestamp | | ### participants Logical entity capable of sending/receiving messages (organization, node, service). | Column | Type | Description | | ---------- | --------- | ---------------------- | | id | PK | Participant identifier | | tenant_id | FK | References tenants | | name | string | Display name | | created_at | timestamp | | | updated_at | timestamp | | ### identifiers Typed identifier bound to a participant. Used for resolution lookup and cross-mapping. | Column | Type | Description | | --------------- | --------- | --------------------------------------------- | | id | PK | | | participant_id | FK | References participants | | identifier_type | string | See [Identifier types](#identifier-types) | | value | string | Identifier value | | scope | string | Optional scope (e.g. scheme) | | priority | integer | Resolution priority (higher = preferred) | | verified_at | timestamp | When value was last verified (e.g. SMP fetch) | ### endpoints Routable address for a protocol domain (HTTPS URL, MLLP, MQ queue, SS7 point code, etc.). | Column | Type | Description | | -------------- | ------- | --------------------------------------------------- | | id | PK | | | participant_id | FK | References participants | | protocol | string | as4, ss7, smp, http, mq, etc. | | address | string | Protocol-specific address (URL, PC/SSN, queue name) | | profile | string | Transport profile (e.g. AS4 profile name) | | priority | integer | Ranking for resolution | | status | string | active, inactive, draining | ### capabilities Supported services/actions/processes/document types and constraints. | Column | Type | Description | | ---------------- | ------ | ----------------------- | | id | PK | | | participant_id | FK | References participants | | service | string | e.g. AS4 service value | | action | string | e.g. AS4 action | | process | string | e.g. PEPPOL process ID | | document_type | string | e.g. document type ID | | constraints_json | JSON | Additional constraints | ### credentials References to key material in vault/KMS. No private keys stored in DB. | Column | Type | Description | | --------------- | --------- | --------------------------- | | id | PK | | | participant_id | FK | References participants | | credential_type | string | tls, sign, encrypt | | vault_ref | string | URI to vault/KMS | | fingerprint | string | Certificate/key fingerprint | | valid_from | timestamp | | | valid_to | timestamp | | ### policies Rules controlling resolution (tenant scope, trust domains, allow/deny, priority). | Column | Type | Description | | --------- | ------- | -------------------- | | id | PK | | | tenant_id | FK | References tenants | | rule_json | JSON | ABAC rule definition | | effect | string | allow, deny | | priority | integer | Evaluation order | ### audit_log Append-only audit trail for all modifications. Optional hash-chain for tamper-evidence. | Column | Type | Description | | ----------- | --------- | ------------------------------------- | | id | PK | | | at | timestamp | | | actor | string | Who made the change | | action | string | create, update, delete | | resource | string | tenants, participants, etc. | | resource_id | string | | | payload | JSON | Before/after or diff | | hash_prev | string | Optional: previous row hash for chain | ## Relationships ```mermaid erDiagram tenants ||--o{ participants : "has" participants ||--o{ identifiers : "has" participants ||--o{ endpoints : "has" participants ||--o{ capabilities : "has" participants ||--o{ credentials : "has" tenants ||--o{ policies : "has" participants { string id PK string tenant_id FK string name } identifiers { string id PK string participant_id FK string identifier_type string value int priority } endpoints { string id PK string participant_id FK string protocol string address string status } ``` - **Tenant** scopes all participants and policies. - **Participant** has many identifiers, endpoints, capabilities, and credential refs. - Resolution uses identifiers to find participants, then endpoints + capabilities + policies to produce directives. ## Graph layer (edges) Cross-mapping and provenance are modeled as an explicit graph. An **edges** table (or equivalent) represents relationships with provenance and validity. ### edges | Column | Type | Description | | ----------- | --------- | ------------------------------------------ | | id | PK | | | from_type | string | Entity type (identifier, participant, etc.) | | from_id | string | Source entity id | | to_type | string | Target entity type | | to_id | string | Target entity id | | relation | string | Relation kind (e.g. resolves_to, has_endpoint) | | confidence | number | 0–1 confidence score | | source | string | Provenance (internal, smp, gtt_feed, etc.) | | valid_from | timestamp | | | valid_to | timestamp | Optional | Relationship types: identifier → participant (resolves_to), participant → endpoint (has_endpoint), participant → capability (has_capability). When two sources give different data for the same logical edge, conflict resolution applies. ### Conflict resolution (deterministic) When multiple candidates or edges exist, apply in order: 1. **Explicit priority** (from endpoint/identifier priority column) 2. **Policy** (allow/deny and policy priority) 3. **Freshness** (updated_at / verified_at / valid_from) 4. **Confidence** (edge or evidence confidence score) 5. **Lexical** (stable sort by id) Documented in [resolution-algorithm.md](resolution-algorithm.md). ## RouteDirective (output schema) Normalized object returned by the resolver. Must match [OpenAPI RouteDirective](../api/openapi.yaml#components/schemas/RouteDirective). | Field | Type | Description | | ----------------- | ------ | -------------------------------------------------- | | target_protocol | string | e.g. as4, ss7 | | target_address | string | Endpoint address (URL, PC/SSN, etc.) | | transport_profile | string | Profile name | | security | object | signRequired, encryptRequired, keyRefs, algorithms | | service_context | object | service, action, or SS7 service indicator | | qos | object | retries, receiptsRequired, ordering | | ttl_seconds | int | Cache TTL for this directive | | evidence | object | source, lastVerified, confidenceScore | ## Identifier types Reference values for `identifier_type` and resolution input. See protocol domains in the master plan. ### AS4 domain - `as4.partyId` (with optional partyIdType in scope) - `as4.role` (initiator/responder) - `as4.service`, `as4.action`, `as4.mpc` For FI-to-FI, PartyId type is often BIC or LEI (see [iso20022-over-as4](../protocols/iso20022-over-as4.md)). ### PEPPOL / SMP - `peppol.participantId` - `peppol.documentTypeId` - `peppol.processId` ### SS7 domain - `e164` (MSISDN, E.164 format) - `gt` (Global Title) - `pc` (Point Code) - `ssn` (Subsystem Number) - `mccmnc` (mobile network identifiers where relevant) Cross-mapping examples: `as4.partyId: "0088:123456789"` ↔ `peppol.participantId: "0088:123456789"`; `e164` ↔ `gt` ↔ `pc/ssn` via GTT.