# Integration Architecture

## Inter-Service Channels

Only these channels are allowed ([ADR-001](adr/ADR-001.md)):

1. Versioned REST API
2. Webhook
3. Async Event (message bus / outbox worker)
4. Outbox/Inbox pattern

## Internal Auth

Services authenticate with **Internal Service Tokens** (hashed in `internal_service_tokens`, scoped).

## External Providers

External systems (SMS, payment, storage, tax) integrate through provider adapters registered in [provider-registry.md](../provider-registry.md). Modules must not hardcode vendor SDKs into domain services without a provider boundary.

### Current known providers

| Provider | Use |
| --- | --- |
| Payamak | SMS OTP |
| Keycloak | IdP / SSO |
| Let's Encrypt + Certbot | TLS certificates |
| S3-compatible (planned) | File storage |

## BFF Pattern

Identity & Access acts as BFF for OIDC token exchange and Keycloak theme handoff so browser secrets stay constrained.

## Frontend Integration

Frontend uses typed API clients (`lib/api.ts` primary; `lib/api-client.ts` may exist for narrower helpers). Never call databases from the browser.

## Published Resources (`publish_id`)

Every public surface that Payment, Communication, Short Link, QR, Analytics, CRM, or verticals may attach to is a **Published Resource** identified by `publish_id` ([ADR-022](adr/ADR-022.md)).

| Rule | Detail |
| --- | --- |
| Registry | Logical Publish Target Registry (`publish_id`, `tenant_id`, `resource_type`, `resource_id`, `canonical_url`, `publish_status`, `visibility`, `owner_service`) |
| Consumer key | Integrations reference **`publish_id` only** — never Experience/vertical internal tables |
| Open types | `resource_type` is an open string registry (unlimited future types) |
| Reserved URLs | `/s/`, `/p/`, `/f/`, `/survey/`, `/book/`, `/menu/`, `/card/`, `/event/` (routing not implemented by this architecture alone) |
| Published Actions | Open Action Registry — Experience binds `action_key` to `publish_id`; owning services execute |
| Public Access | Open access strategies; Experience stores policy metadata; Identity/Payment/Loyalty/Communication own auth/pay/membership/OTP |
| Universal Embed | Open embed types (iframe, SDK, widget, …); Experience owns embed metadata |

Normative docs: [published-resource-architecture.md](published-resource-architecture.md), [published-resource-contracts.md](../reference/published-resource-contracts.md), [published-action-registry.md](../reference/published-action-registry.md), [public-access-contract.md](../reference/public-access-contract.md), [embed-contract.md](../reference/embed-contract.md).

## Related Documents

- [Event-Driven Architecture](event-driven-architecture.md)
- [Published Resource Architecture](published-resource-architecture.md)
- [Provider Registry](../provider-registry.md)
- [Provider Reference](../reference/provider-reference.md)
- [Services Contracts](../reference/services-contracts.md)
- [Published Resource Contracts](../reference/published-resource-contracts.md)
