Frozen document. Dates and status refer to its original source. Private resources and unreviewed images are unavailable.
Fastify, TypeBox and private gRPC adapters
Accepted architecture amendment, September 30, 2026. The owner confirmed TypeBox and retained HTTPS/REST for browser traffic, with gRPC for suitable internal adapters. ADR 0011 records schema ownership; ADR 0012 records transport boundaries. The later ADR 0013 selects tRPC over HTTPS for React-to-SDUI BFF experience calls and amends the earlier REST clause. This is a design and migration plan, not evidence that every element is deployed.
flowchart LR
UI[React and Vite SPA] -->|HTTPS tRPC JSON| HTTP[Fastify experience API]
TB[Reviewed TypeBox schemas] -->|Types and JSON Schema| HTTP
HTTP --> SESSION[Keycloak session and CSRF checks]
HTTP --> SDUI[Authorized screen assembler]
CMS[Contentful bilingual definitions] --> COMP[Allowlisted release compiler]
COMP --> PIN[Pinned immutable release]
PIN --> SDUI
HTTP --> OWNER[Business-owner services and durable lifecycle]
OWNER --> DB[(PostgreSQL records and outbox)]
OWNER --> ADAPTER[Private workflow adapter]
ADAPTER -->|Supported commands and jobs via gRPC: planned| ZE[Camunda Zeebe]
ADAPTER -->|REST search and user-task APIs: present| REST[Camunda Orchestration Cluster API]
REST --> SDUI
OWNER --> SIM[In-process synthetic system adapters]
Boundary contracts
| Boundary | Selected pattern | Current implementation and required change |
| Browser to BFF | Same-origin HTTPS tRPC experience procedures, opaque cookie and CSRF; retained REST compatibility/protocol endpoints | Fastify 5.12.5 is installed. tRPC adoption follows ADR 0013 and its rollout. Preserve existing REST contracts during migration; OpenAPI does not describe the tRPC client contract. |
| HTTP structural validation | Reviewed TypeBox schemas, inferred TypeScript types, Fastify validator/serializer | TypeBox and its provider are not installed yet. Pin a compatible pair and migrate route envelopes incrementally. |
| CMS publication | Structured Contentful definition checked against a reviewed schema and component/rule vocabulary | The current release compiler validates and pins content. TypeBox may describe that vocabulary; CMS still defines form fields and constraints. |
| Runtime form answers | Pinned CMS rules plus owner validation | Keep the current constrained validation behavior and bilingual errors. Do not send arbitrary CMS schemas into a runtime code compiler. |
| Camunda commands/jobs | Private gRPC adapter where supported by the deployed engine version | Current adapter uses REST. First migrate one supported operation with engine and recovery proof. |
| Camunda search/user tasks | Orchestration Cluster REST API where gRPC does not supply the required operation | Retain existing REST operations and map results behind the same workflow interface. |
| Contentful and Keycloak | Their supported HTTPS APIs | No gRPC wrapper required. Credentials remain server-side. |
| Business owners in the BFF | In-process module interfaces with persistent owner records | No new network hop or service split. |
| Future independent system services | gRPC when a suitable versioned protobuf API exists; supported HTTPS otherwise | Add an adapter per actual destination, not a speculative service mesh. |
Schema and SDUI flow
- Reviewed TypeBox definitions describe request envelopes, authorized responses and the supported CMS definition vocabulary. Infer TypeScript types instead of maintaining a separate handwritten copy.
- Publication validates Contentful's component definitions, field identifiers, constraints, bindings and both locales. Retain the immutable release and compatibility references.
- The screen assembler resolves the authorized journey or Camunda task, the pinned release, permitted data, owner revision and allowed actions. React renders that model.
- A command supplies its transport envelope, release identity, answers, revision and retry identity. Structural validation rejects malformed or oversized input without mutating command answers. Existing authentication and error non-disclosure behavior remain required.
- The owner rechecks the pinned CMS rules, field applicability, identity/context, current membership, fresh MFA where needed, task assignment, business invariants and revision. Success at JSON or protobuf decoding establishes none of those permissions.
- Durable acceptance returns the existing operation. The outbox invokes a private adapter; results or uncertainty update the same lifecycle. A transport deadline does not erase an accepted command or justify a second effect.
Fastify's default coercion/default/removal settings must be reviewed explicitly. Command schemas must reject unexpected fields, and validation must not silently alter the captured command used for idempotency comparisons. Preserve permitted query coercion separately. Normalize errors into the existing Atlas codes and canonical field keys. Response serializers must exclude unapproved fields, with independent authorization/conformance tests.
gRPC adapter design
The workflow owner consumes a domain interface, not protobuf request/response types. A gRPC implementation maps supported Camunda operations into that interface. Search, task correlation and operations without an appropriate gRPC endpoint remain REST implementations in the same adapter module.
For vendor RPCs, use the deployed version's supported SDK/protobuf contracts. For future Atlas-owned RPCs, retain versioned .proto sources and reproducible generated code, reserve removed field numbers/names, and test compatible evolution. TypeBox is not the .proto authoring system. Decode 64-bit identifiers losslessly and explicitly map absent/default values to existing JSON contracts.
Use bounded deadlines and cancellation where the client supports it, bounded concurrency and messages, managed channel shutdown, service authentication, certificate validation across hosts and redacted tracing. Document any plaintext local channel on the private Compose network and verify it has no host/public ingress. Browser tokens and cookies are never service credentials. Service identity does not grant the acting customer authority over another customer's record.
Read retries may use bounded backoff. Effectful calls require owner-controlled delivery and reviewed SDK retry behavior. Response loss, unavailable service, deadline expiry and ambiguous results must retain pending/uncertain state as appropriate. Automatic REST fallback after a gRPC write timeout is forbidden. Reconciliation must use durable correlation and recorded receipts; protobuf alone does not guarantee unique delivery.
Incremental build gates
| Slice | Dependencies and scope | Required evidence |
| TypeBox adoption | Select compatible provider/library versions and validator settings. Convert one existing command envelope and response behind unchanged HTTP paths. | TDD for malformed/extra fields, payload bounds, unchanged error/auth behavior, non-mutated retry payloads and sensitive-field exclusion; focused Fastify injection and owner integration tests. |
| CMS vocabulary integration | First schema slice plus existing release compiler tests. Describe supported content structure while retaining CMS-authored field rules. | Published bilingual content succeeds; unsupported/deep/oversized definitions fail; pinned draft still uses its old release after content changes. |
| First Camunda gRPC operation | Existing durable lifecycle is stable, installed engine capability and SDK/proto compatibility verified. Replace one supported command behind the workflow interface. | Real engine receipt, same operation/revision behavior, response loss/deadline/duplicate prevention, exact 64-bit key mapping, no public RPC ingress and public HTTPS journey smoke. |
| Further routes and adapters | Accept preceding interfaces and review findings first. Migrate one bounded tracer bullet at a time. | Existing contract/recovery tests plus slice-specific system evidence; final local certification before cloud promotion. |
Use the test-first orchestration contract and audit cadence. Record red/green runs, system versus E2E evidence, exact runtime/tool versions and review mitigations. Classify each element as planned, implemented or qualified. Existing payment and case work must not be reported as gRPC-qualified until the real adapter gate passes.
ADR impact
ADRs 0003 through 0005 retain content/workflow/record ownership and durable command semantics. ADR 0008 gains schema and adapter-transport amendments. ADR 0009 retains browser sessions and MFA. ADR 0010 retains local certification before hosted UI and VPS deployment. No change to product scope, hosting provider, MuleSoft deferral or the public API is implied.
Sources checked September 30, 2026: Fastify TypeBox provider, Fastify validation and serialization, TypeBox, Camunda API catalog, Zeebe gRPC API, gRPC Node, deadlines and retry.