Skip to main content
chaptertechnical-review

Architecture judgment under changing constraints

Learning outcome and why the problem is difficult​

An enrollment team asks for “a fast, reusable flow.” This does not select a framework. First discover who submits, whether submissions have legal or financial consequences, which partners embed the flow, how identities cross origins, and what must survive a failed connection. The outcome is a decision that another engineer can falsify, rather than an architecture diagram that merely looks plausible.

Mental model: invariants before boundaries​

Separate six boundaries: business capability, UI ownership, network, process lifetime, trust, and deployment. A React folder can enforce none of the last three by itself. A BFF may consolidate several network calls while still depending on a remote authority for identity. A reusable component can move to a package without granting its host permission to perform an operation.

For our synthetic enrollment scenario, preserve these invariants: only an authorized operator submits; accepted work has one stable receipt; retrying an unchanged operation does not create another record; changing an operation's payload cannot reuse its receipt. “Disable the button” improves UX but does not establish any of these server properties.

Worked decision and constraint change​

OptionUseful propertyCost or disqualifier
React app calling partner APIsFew infrastructure piecesBrowser receives partner-specific contracts; credential handling may disqualify it
React plus BFFCentral authorization, validation and receiptsAdds service ownership and availability requirements
Hosted enrollment redirectCentral release and security boundaryNavigation and partner branding constraints

Choose a BFF for the fixture because its operation ledger must be authoritative. Start with a modular monolith: a module and a database transaction are enough. Do not add a message broker until work must outlive the request or cross transaction boundaries.

Now change the requirement: the partner permits only an iframe and blocks third-party cookies. The original same-origin cookie design no longer transfers. Evaluate a top-level redirect handshake or explicitly scoped short-lived integration credentials; do not weaken cookie policy as an architectural shortcut. Record the changed assumption and rerun the identity journey. This is an example decision, not an OAuth implementation in the lab.

Failure investigation and verification​

Enable “Lose the response” in the account portal. The server commits and the browser sees a network error. Diagnose from the persisted receipt and request key, not the text of the error toast. A second POST with the same key must recover the receipt. The HTTP integration test actually drops the response after committing.

Estimate load before distributing the service. If a hypothetical campaign has 12,000 visitors per minute and 4% submit, average writes are eight per second. Neither average traffic nor SQLite's local test throughput is evidence about peak production capacity. Measure burst factor, payload size, contention and partner latency before selecting infrastructure.

Exercise, expected answer and rollout​

Write a one-page ADR with three options, two hard constraints, a reversible slice, and a kill condition. Inject the response loss and attach the assertion for one persisted write. Then change the partner constraint above. A strong answer revises identity delivery, preserves server idempotency, and distinguishes local evidence from production capacity. Roll out to one partner with a receipt lookup fallback; roll back the UI without deleting accepted operations.

Executable reference and sources​

Implementation · Behavioral evidence · Primary source.

Run the projects and assessment. Human review is pending.