Connect the business model to the code, the screens and the cloud. Follow ClearLend from a borrower’s first request to an auditable, deployable application.
12 focused chapters5 architecture diagrams8 role experiences
Explore the chapters. Select a topic on the left, then use Previous and Next to continue. Each chapter has a shareable link.
Design proposal · Synthetic data · Simulated payments
Chapter 01 / 124 min read
Start with the promises the system must keep
Phase 0 explains the product. Phase 1 explains the value exchange. Phase 2 assesses the engineering work. Phase 3 connects those decisions to a buildable application.
ClearLend should make one promise understandable: a borrower, lender or employee can complete an authorized action, the system preserves the relevant business rules, and someone can trace what happened afterward. This is a proposed solution architecture, not a claim that the application or its quality controls have already been implemented.
What we carry forward
ClearLend operates a managed lending marketplace. It is not assumed to lend its own capital.
Borrowers, lenders and operational teams have different permissions and information needs.
Borrower interest, lender returns and ClearLend fees remain distinguishable.
Offers preserve the exact terms shown when issued. Financial corrections create new records.
A request sent to a payment provider is not proof that money moved.
The educational build uses synthetic users, documents and simulated payments.
The first vertical slice is a vetted borrower creating and submitting an application.
Working assumptions — decisions still requiring agreement
Decision
Educational assumption
Owner / consequence
Funding model
One lender funds each loan.
Product owner: pooled funding needs allocation and partial-funding rules.
Currency
One currency per loan; sample data uses GBP.
Product and finance: no currency conversion in the first release.
Organization access
Lender employees act through organization membership.
Architect and product: every ownership policy must include organization scope.
Identity
External, standards-based identity provider; select before implementation.
Security lead: registration, recovery, MFA and session policies.
Credit decisions
Human-reviewed synthetic cases.
Product and risk: automated scoring is outside the first build.
Retention
Configurable categories, with no invented live retention period.
Privacy and compliance: approve retention and legal-hold rules.
Hosting
Agree region, budget and supported service tiers before provisioning.
Platform and business owner: cost, residency and resilience.
Quality targets
Proposals, not measured results.
Engineering and operations: agree workload and acceptance evidence.
How to use this guide
Start with the system map for the big picture, then follow submission through the layers. Frontend and role chapters connect the code to real work. Azure, quality and testing show how we will prove the design. Select a chapter from the contents menu or use Previous and Next at the end of each chapter.
Take this into implementation
Agree the boundaries first. The design becomes implementable when every important assumption has an owner and a visible consequence.
Chapter 02 / 125 min read
One application, deliberate business boundaries
Start with Angular, an ASP.NET Core modular monolith, SQL Server with EF Core, private document storage and durable background processing.
The system context: people, application responsibilities and external dependencies.Open full size ↗
Angular presents role-specific experiences. It calls the API and never connects directly to SQL. The API maps requests to use cases. Those use cases authorize the action, invoke business rules and persist the outcome. Background processing handles work that must survive an HTTP request ending: notification delivery, reminders, reconciliation and integration retries.
Business ownership map
Module
Owns
Access
User-to-party mapping, organization membership and application permissions.
Onboarding
Profiles, vetting cases, credit assessments and credit limits.
Products
Lender products, published versions and eligibility requirements.
Applications
Drafts, submissions, evidence links, review assignments and decisions.
Offers & funding
Offer versions, acceptance, commitments and funding coordination.
Finance
Payment attempts, reconciliation, fees, financial entries and adjustments.
Servicing
Loans, repayment schedules, arrangements and closure.
Support
Cases, messages, assignments and escalations.
Compliance
Compliance cases, restrictions and inspection workflows.
Documents
File metadata, versions, security status and controlled retrieval.
Notifications
Templates, delivery requests and delivery outcomes.
Reporting
Authorized read models and operational summaries.
A module owns its writes
Support may request a finance investigation through a defined application contract. It cannot change a payment table. Reporting consumes deliberate projections and never becomes a second route for changing business state. Modules can share a deployable host without sharing every implementation detail.
Why a modular monolith?
One initial application makes transactions, debugging, local development and releases easier to understand. The trade-off is coordinated deployment and shared runtime capacity. Boundaries require enforcement: folder names alone cannot prevent a tightly coupled application.
Extract a capability when its scaling needs are measurably different.
Separate a process when its failures must be isolated from interactive requests.
Consider independent services when team ownership or security requirements justify the operational cost.
Document processing and notifications are plausible candidates, but extraction still requires versioned contracts, data ownership and failure handling.
Take this into implementation
Keep deployment simple and business ownership explicit. Split a component when evidence supports the added operational complexity.
Chapter 03 / 126 min read
Give every piece of code a clear responsibility
Modules describe the business capability. Layers describe the kind of responsibility. Applications is a module; its submission feature crosses API, application, domain and infrastructure boundaries.
Clean Architecture: compile-time dependencies point toward the business core.Open full size ↗
Responsibilities and permitted dependencies
Layer
Responsibility / examples
Does not belong here
Domain
Invariants and transitions: LoanApplication, Money, OfferTerms. No outer-layer dependencies.
HTTP responses, EF queries, email or payment SDK calls.
Application
Use cases, authorization, transactions and ports: SubmitApplicationHandler, IApplicationRepository. Depends on Domain.
Provider-specific configuration and concrete database access.
Independent copies of eligibility or offer-acceptance rules.
API
HTTP contracts, authentication integration, mapping and ProblemDetails. Calls Application.
Credit decisions, balance calculations and direct table updates.
The arrows show source-code dependencies. At runtime a handler calls a repository interface and the infrastructure implementation executes SQL. The host composition root wires the implementations together. Dependency inversion lets business behavior remain testable without a database or web server.
Vertical slices group the command, validation, handler and result around one user action. Separate module assemblies can follow when stronger compile-time isolation becomes useful. Initially, architecture tests check allowed namespace dependencies, while review rejects cross-module table writes and EF entities leaking into API responses.
Put behavior behind meaningful methods
Submit checks the current state and required facts. The handler obtains authoritative eligibility and evidence information first. A browser-supplied IsEligible flag is never the authority. The domain owns the invariant; the application owns obtaining the facts and coordinating the work.
Review dependencies as carefully as class names. The domain should explain the lending rule without knowing how the request arrived or where the record is stored.
Chapter 04 / 126 min read
Follow a borrower submitting an application
A vetted borrower has a credit limit, a selected product and a completed draft. A successful submission must remain correct even when a response is lost or two requests arrive together.
One atomic business change, followed by durable asynchronous delivery.Open full size ↗
Angular validates fields and presents an accessible error summary.
The API establishes the caller’s identity; the use case verifies resource ownership and the permission to submit.
Check an idempotency key and request fingerprint within the authorized user and operation scope.
Load current vetting, credit limit, product version and evidence status.
Invoke the domain transition using authoritative facts and the expected application version.
Commit submitted state, audit entry, outbox item and replay result in one SQL transaction.
Return Submitted — awaiting review with a reference number.
A worker claims the durable outbox item and records the notification outcome.
Mutable facts require consistency too. A product pause or changed credit limit must not race unnoticed with submission. Use suitable transaction isolation or version checks for facts involved in the invariant. The product-pause policy must specify whether it blocks only new submissions or affects existing applications.
Failure cases are part of the API contract
Situation
Expected result
Invalid request shape
400 with field-level ProblemDetails.
Evidence absent or unapproved
422; application remains a draft.
Unauthenticated caller
401.
Wrong owner
Consistent non-disclosing 404 policy.
Same key and same request
Return the committed result; do not create another submission.
Same key, different request
409 conflict.
Stale version or competing submission
One valid transition commits; the other receives 409 and must reload.
Use SQL rowversion for optimistic concurrency and unique constraints for idempotency. Multiple instances must not rely on an in-memory lock. Claim outbox work using database leases and bounded batches so another worker can resume after a crash.
The business transaction succeeds independently of notification availability. Idempotency, concurrency and replay behavior are designed before the first endpoint is called complete.
Chapter 05 / 126 min read
Preserve ownership, history and uncertainty
A dashboard number must have a source. An offer must preserve its terms. A payment can remain unknown until reconciliation supplies evidence.
The record chain from product selection to a traceable loan and financial history.Open full size ↗
Core relationships and ownership
Owner
Entities and relationships
Onboarding
Borrower has credit assessments and an effective credit limit.
Application receives offer versions; an accepted version forms an agreement, with a commitment under the single-lender assumption.
Servicing
Agreement establishes a loan; loan owns versioned schedules and installments.
Finance
Loan links to payment attempts, reconciliation results and append-only financial entries.
Use schemas such as applications, products, finance and servicing to make ownership visible. Schemas alone do not enforce architecture. Repositories, permissions and boundary tests support that ownership. A shared database and controlled EF Core unit of work simplify initial transactions, with coordinated migrations as an accepted trade-off.
AwaitingFunding → Active → Closed; disputes, arrears and arrangements are separate explicit concepts.
Transaction boundaries and integrations
Application submission is a local transaction. A provider call happens outside it: first persist the intent, perform the external operation, then record the outcome. Authenticate callbacks, store a unique provider event ID, and update payment state, financial entries, audit and outgoing events atomically. Duplicate or out-of-order callbacks cannot regress a completed state.
Contracts define stable identifiers, money and currency, UTC timestamps, correlation IDs, idempotency, timeouts and error categories. Retry transient failures only when the operation is safe. Exhausted work enters an exception queue with an owner. Unknown payment outcomes initiate reconciliation rather than blind resubmission.
Store content in private Blob Storage. SQL stores ownership, an opaque storage key, version, checksum, content type, scan status, review status and retention category. Authorize the upload intent, enforce limits, quarantine the file, scan it and expose the exact accepted version. The educational build can simulate scanning but must label it. Failed or unfinished scans remain unavailable.
The baseline downloads documents through authorized application access. This avoids giving a browser access to private storage endpoints. Replaced evidence retains its history and reason; retention and deletion follow approved policy and legal holds rather than keeping everything forever.
Terms and financial history
An accepted offer references immutable principal, currency, rate, term, fees, repayment assumptions, disclosures and acceptance evidence. Product edits create future versions. Corrections reference original financial entries and preserve actor, reason and approval. Balances derive from authoritative entries, with projections for fast reads.
Take this into implementation
Own writes within modules, version what customers agreed to, and make unknown outcomes visible until there is evidence to resolve them.
Chapter 06 / 124 min read
Make the interface reflect the business state
Angular should help people understand what happened, who acts next and what they are allowed to do. A hidden button is not an authorization control.
Feature components own their forms and page-local state. Shared components provide accessible tables, pagination, status labels, money formatting, document summaries, timelines, confirmation dialogs and error summaries. Use reactive forms and typed API clients generated from a reviewed OpenAPI contract. Introduce a wider store only when state genuinely spans workflows.
Identity and the browser boundary
The proposed baseline serves Angular and the API from the same origin. ASP.NET Core handles external sign-in and issues a secure, HTTP-only session cookie. Mutating requests require antiforgery protection. Route guards improve navigation, while backend policies enforce access. Do not place sensitive responses in shared caches, and clear sensitive client state at logout.
Every screen has more than a happy path
Loading: show progress without implying that an action has completed.
Empty: explain whether there are no records or a filter has excluded them.
Validation: focus an error summary, identify fields and preserve the user’s input.
Conflict: explain stale state and offer a reload rather than overwriting someone else’s change.
Failure: show a safe message and a correlation reference; never expose internals.
Permission: do not reveal another customer’s record through error details.
Financial data: distinguish confirmed, pending and projected figures, with a refresh time.
Accessibility is part of workflow design
Use semantic headings and labels, keyboard-operable controls, visible focus, sufficient contrast and status descriptions that do not depend on colour. Announce meaningful asynchronous outcomes. Test complete journeys with keyboard and screen-reader review, not only an automated page scan.
Take this into implementation
Keep client state understandable and backend rules authoritative. The interface should explain uncertainty and next actions as carefully as it displays success.
Chapter 07 / 127 min read
Design the work, then design the screen
Explore two annotated screen examples for each established role. Each example connects visible actions to a use case, a permission boundary and an auditable result.
Choose a role below. The numbered rows highlight information that matters to that user. The action labels are illustrative wireframe controls, not a working lending application. In Read all mode every role is visible for comparison or printing.
Govern policy changes; aggregate access by default.
Business controls and aggregate results.
Borrower
Understand the cost, complete the application and know the next action.
ClearLend / Borrower
Illustrative screen
Application A-104
Draft · Home improvement · Product version 3
1Requested amount: £5,000 · Term: 24 months
2Identity evidence accepted; income evidence awaiting review
3Action needed: accepted income evidence before submission
Save draftSubmit: unavailable
How it works SaveDraft persists owned input. SubmitApplication rechecks eligibility and evidence on the server; the unavailable action includes a reason.
ClearLend / Borrower
Illustrative screen
My loan L-204
Confirmed figures show their last refresh time.
1Next payment: amount and due date
2Confirmed balance, separate from pending payments
3Agreement, schedule and payment history
View agreementAsk for help
How it works Read authorized servicing and finance projections. Ask for help creates a support case linked to this loan.
Lender
Manage products and understand confirmed portfolio outcomes.
ClearLend / Lender
Illustrative screen
My products
Only this lender organization’s records.
1Home improvement · Version 3 · Published
2Applications: 12 · Eligibility rules available
3Change preview: applies to new applications
Create productPause product
How it works Publish and pause commands check organization ownership and current state. Rate changes produce a new version.
ClearLend / Lender
Illustrative screen
Portfolio
Funding, interest and fees remain distinct.
1Commitments versus confirmed funding
2Interest received and platform fees shown separately
3Loan exceptions link to permitted summaries
View loan summaryView statement
How it works Figures derive from authoritative entries. Lenders cannot access another organization’s portfolio or internal compliance notes.
CRM reviewer
Review evidence consistently and preserve decision reasons.
ClearLend / CRM reviewer
Illustrative screen
Review queue
Assigned to me · Awaiting evidence · Unassigned
1R-108 · Borrower review · Age: 2 days
2Next action: review income evidence
3Assignment and due time are visible
Open caseClaim case
How it works Queue queries enforce assignment scope. Claiming uses concurrency control so two reviewers cannot silently take ownership.
ClearLend / CRM reviewer
Illustrative screen
Decision workspace
Evidence · Assessment · Previous decisions
1Policy version P-7 and evidence versions
2Approve, decline or request more information
3Reason required; second review where policy requires
Record decision
How it works RecordReviewDecision preserves actor, reason and policy version. A credit limit changes only through the authorized workflow.
Support
Resolve a customer’s question with enough context and limited authority.
ClearLend / Support
Illustrative screen
Support queue
Case references minimize personal information.
1S-302 · Customer C-180 · Payment question
2Due today · Assigned to support team
3Linked application or loan reference
AssignOpenEscalate
How it works Case assignment controls deeper access. Search results apply the same record policies as the case detail.
ClearLend / Support
Illustrative screen
Conversation S-302
Customer-visible conversation and internal notes are separate.
1Customer: payment has not arrived
2Linked payment: Unknown · Finance investigating
3Timeline preserves messages, handoffs and outcomes
Public replyInternal noteEscalate
How it works Public and internal messages use distinct visibility rules. Support can request an investigation but cannot change a balance.
Compliance
Investigate controls with scoped evidence and accountable exports.
ClearLend / Compliance
Illustrative screen
Control queue
Case C-440 · Evidence expired
1Trigger, owner and due date
2Evidence versions and review history
3Restriction scope and reason must be explicit
Request evidencePropose restriction
How it works Restrictions use controlled commands and configured second approval. Investigation access is limited to its purpose.
ClearLend / Compliance
Illustrative screen
Inspection pack
Read-only evidence for an authorized review.
1Evidence, decisions and policy references
2Audit and access history included by scope
3Export purpose and expiry are required
Generate export
How it works An asynchronous job creates a scoped, audited, expiring pack. Access does not grant permission to alter operations.
Finance
Reconcile outcomes and correct records without erasing history.
ClearLend / Finance
Illustrative screen
Reconciliation queue
Uncertainty remains visible until investigated.
1Payment P-601: internal state Unknown
2Provider reports Succeeded; difference flagged
3Agreement, attempt and provider references linked
InvestigateRefresh outcome
How it works Verified reconciliation records the resolution. There is no arbitrary mark-paid shortcut or blind second payment.
ClearLend / Finance
Illustrative screen
Adjustment request
Original entry F-701 is preserved.
1Type: reversal or correction · Amount
2Reason and supporting evidence required
3Requested by User A; independent approval required
Submit for approval
How it works Approval appends an adjustment linked to the original entry. The requester cannot approve their own controlled adjustment.
Servicing
Manage schedules and respectful, informed borrower contact.
ClearLend / Servicing
Illustrative screen
Due-payment queue
Loan L-204 · Overdue
1Due date, received amount and unresolved outcome
2Existing support case and contact restrictions
3Previous communications before the next contact
Review historyContact borrower
How it works Contact workflows consider disputes, preferences and existing cases. Staff can understand the history without asking the borrower to repeat it.
ClearLend / Servicing
Illustrative screen
Repayment arrangement
Current schedule beside the proposed schedule.
1Reason and effective date
2Borrower communication preview
3Approval and lender update requirements
Request approvalSchedule history
How it works Approval creates a new schedule version and follow-up notifications. It does not overwrite the previously agreed schedule.
Business owner
Understand outcomes and govern changes without unrestricted data access.
ClearLend / Business owner
Illustrative screen
Business overview
Commercial, operational and service indicators.
1Platform revenue and operating costs
2Review turnaround, complaints and exceptions
3Service health and metric source definitions
View trendSource definition
How it works Reports separate platform revenue, lender interest and funding volume. Aggregate access does not imply document access.
ClearLend / Business owner
Illustrative screen
Business controls
Versioned changes with visible impact.
1Fee policy version 4 · Change awaiting review
2Product intake: enabled
3Effective time, approvals and history
Propose changeView approvals
How it works Policy commands preserve approval and effective date. Business controls are separate from infrastructure administration.
These are annotated wireframes, not working finance controls. Values are illustrative. Risk/fraud, security/privacy and external-auditor roles remain later extensions.
Take this into implementation
A useful screen makes the correct action obvious and the permission boundary enforceable. Every consequential action has a use case, a reason and a traceable outcome.
Chapter 08 / 127 min read
Design the release as carefully as the request
Begin with a deployable educational host. Describe the production hardening explicitly, including its cost, networking, data and operational consequences.
Proposed hardened Azure topology. Smaller educational environments use synthetic data.Open full size ↗
The first App Service host serves Angular and ASP.NET Core. Hosted background handlers use SQL leases so scale-out does not duplicate ownership of jobs. ClearLend.Worker provides a separate host when background processing needs independent operation; only the intended processing host is enabled. For an App Service worker deployment, use a supported persistent hosting configuration and validate restart behavior.
Network and service access
The hardened design places a WAF-enabled Application Gateway in front of private App Service access. App Service private endpoints handle inbound connectivity; VNet integration handles outbound connections to private SQL, Blob Storage and Key Vault endpoints. Private DNS is part of the deployment. This is a production design option to price and validate, not a claim that the educational environment already has these controls.
Environment isolation versus deployment slots
Environment
Purpose and boundaries
Local
Local SQL, storage emulator or development adapter; simulated providers.
CI / test
Disposable databases, synthetic fixtures and repeatable automated checks.
Staging / UAT
Separate app resources, database, storage and identities for full journey rehearsal.
Production
Dedicated access boundaries, operational controls and monitored release.
Production candidate slot
Restricted next build within the production App Service plan; not the UAT environment.
Identity, secrets and infrastructure
Use managed identity for permitted Azure resource access and Key Vault for remaining secrets. API, worker, migration and pipeline identities have different privileges. Runtime identities cannot alter schemas. Staff privileged access requires MFA and controlled assignment. Use Bicep for resources, access, diagnostics, networking and environment parameters; use federated pipeline identity rather than committed credentials.
One artifact through the release pipeline
Compile, lint and run relevant tests; scan dependencies and secrets.
Build one versioned artifact and validate the infrastructure change.
Deploy to UAT and run the critical journeys.
Apply an approved backward-compatible production migration using a separate identity.
Deploy the same artifact to the candidate slot with controlled processing behavior.
Verify readiness and non-destructive smoke tests, then swap into production.
Observe error rates, latency, outbox age and failed jobs against release thresholds.
Database compatibility and rollback
Use expand, migrate, contract: add compatible structures, migrate usage and data, then remove obsolete structures in a later release. Do not run migrations on every application startup. A slot swap can restore application code, but does not reverse data writes. Rollback depends on schema compatibility; destructive changes require a separate, rehearsed recovery plan.
Health, workers and resilience
Liveness verifies the process; readiness checks essential dependencies without triggering business actions. An email outage should alert operators without necessarily blocking submissions. For separate workers, deploy disabled, validate, then transfer ownership through controlled configuration and expiring leases. Rehearse this rather than relying on a single slot setting.
Higher availability requires a supported zone-redundant plan, sufficient actual app instances and resilient dependencies. Zone redundancy is not regional disaster recovery. Select tiers and recovery arrangements only after the service target and budget are agreed.
A safe release includes code, compatible data, identities, worker ownership and a verified recovery path. Deployment slots are one tool within that process.
Chapter 09 / 126 min read
Replace “secure and scalable” with evidence
Each quality requirement needs a measurable target, a design response, a verification method and an accountable owner. All targets below are proposed until agreed.
Proposed non-functional requirements and evidence
Concern / owner
Target
Design and verification
Security / security lead
All protected operations tested; no unresolved critical/high release findings without explicit acceptance.
Resource policies, privileged MFA, least privilege and protected sessions. Verify authorization suite and security review.
Privacy / privacy owner
No document contents or credentials in ordinary logs; approved retention for every personal-data category before live use.
Minimization, redaction and controlled export. Inspect logs and exercise retention.
Performance / backend lead
Common reads p95 ≤500 ms; submission p95 ≤1 s at baseline load, excluding async delivery.
Pagination, indexes and bounded queries. Run representative load tests.
Scalability / platform lead
Meet latency targets at 3× baseline after approved scaling.
Stateless requests, leased jobs and measured database capacity. Rehearse scale-out.
Availability / operations lead
Initial monthly service objective: 99.9% for critical journeys.
Multiple instances, health routing and resilient dependencies. Synthetic checks and incident accounting.
Recovery / operations + data owners
Initial RPO ≤15 minutes; RTO ≤4 hours for the agreed regional recovery scenario.
Backups, infrastructure code and a documented restore sequence. Time a complete restore exercise.
Accessibility / frontend lead
WCAG 2.2 AA target for critical journeys.
Semantic controls, keyboard flow and meaningful errors. Automated checks plus screen-reader review.
Structured traces, metrics and alerts. Inject a failure and verify diagnosis and routing.
Maintainability / technical lead
No prohibited dependencies; executable tests for every state-transition rule.
Feature organization and architecture checks. Verify in CI and review.
Cost / business + platform owners
Stay within agreed monthly budget B; alerts at 80% and 100%.
Right-size resources, cap scaling and bound telemetry retention. Review actual spend.
Notification reliability / backend lead
99% delivered within 2 minutes while the provider is healthy.
Durable outbox, retries and exceptions. Monitor delivery age and test failures.
Financial integrity / finance + backend leads
Repeated callbacks create one financial effect; corrections preserve original entries.
Unique IDs, transactions and append-only adjustments. Replay callbacks and reconcile results.
Measure the whole system
RPO describes acceptable data loss; RTO describes acceptable time to restore service. State whether the scenario includes a region failure. Recovery must align SQL, documents, identity and pending provider operations. A successful SQL restore alone does not demonstrate application recovery.
A service objective is not a supplier SLA copied into a document. Measure the critical user journeys and their dependencies. When a target is missed, record whether the cause is code, query shape, capacity, provider behavior or an unrealistic assumption, then revise the appropriate part of the design.
Take this into implementation
Quality is reviewable when a target has an owner, a workload and a repeatable proof. Keep proposed objectives separate from measured results.
Chapter 10 / 124 min read
Test the promise and the ways it can fail
The most useful tests protect business behavior, access boundaries and operational recovery. They should explain why a change is safe to release.
Testing layers and ClearLend examples
Test type
Evidence
Unit
A draft without accepted required evidence cannot be submitted.
Application
A non-owner is rejected before any mutation.
Architecture
Domain cannot reference EF Core or ASP.NET Core; modules respect allowed contracts.
Integration
State, audit, outbox and replay result commit or roll back together against SQL Server.
API responses match OpenAPI; adapters handle all required provider outcomes.
End to end
Borrower saves and submits; an authorized reviewer sees the application.
Concurrency
Competing submissions produce one transition and a clear conflict.
Performance
Reviewer queue meets its latency target with representative data and load.
Resilience
Restart after delivery does not create a second business effect.
Recovery
Restore application and data, then reconcile pending external operations.
Accessibility
Complete submission with a keyboard and understand errors with a screen reader.
Use the right environment for the claim
Run SQL Server integration tests for transactions, unique constraints and rowversion concurrency. An in-memory substitute cannot establish those properties. Simulated providers make fault cases repeatable, but real adapters later need provider contract and sandbox verification.
Place checks where they help delivery
Every change: fast unit, application and architecture checks.
Before merge or release: relevant database integration, authorization, contract and browser journeys.
Before significant capacity changes: representative load and scale exercises.
Before claiming readiness: release, rollback, alerting and restore rehearsals.
Preserve results with the release so another engineer can inspect the evidence.
Take this into implementation
Choose a test because it protects a rule, a boundary or a recovery promise. Make the evidence understandable to the next engineer.
Chapter 11 / 124 min read
Record the reason, the cost and the revisit trigger
Architecture decision records let future developers understand the constraints behind a choice. They should be short enough to read and specific enough to challenge.
Initial architecture decision register — proposed
ADR / choice
Reason and trade-off
Revisit when
001 · Modular monolith
Simpler transactions and delivery; shared capacity and coordinated releases.
Independent scale, ownership or isolation is demonstrated.
002 · Vertical slices in clean layers
Feature cohesion and testability; boundary discipline is required.
Connects requests and jobs; requires redaction and retention control.
Operational evidence reveals gaps.
008 · Same-origin Angular and server-managed session
Simplifies browser integration; couples deployment and session configuration.
Independent clients or releases become necessary.
009 · App Service and compatible slot releases
Managed hosting and controlled rollout; data and workers need explicit transitions.
Hosting or isolation needs change.
A decision-record template
ADR-005: Reliable follow-up work
Status: Proposed
Context: A committed submission must not lose its notification.
Options: Synchronous call; fire-and-forget task; transactional outbox.
Decision: Commit an outbox record with the application transition.
Consequences: Add leases, retry policy, deduplication and monitoring.
Evidence: Crash after commit, restart worker, recover pending work.
Owner: Backend lead
Review trigger: Delivery volume or routing requires a message broker.
An ADR is not a permanent prohibition on change. Revisit it when its context changes, and preserve the old record so the decision history remains understandable. Changes in service shape, funding model or privacy requirements should update the relevant decisions before they spread through code.
Take this into implementation
A defensible architecture explains why a choice fits now and what evidence would make a different choice better.
Chapter 12 / 125 min read
Prove the blueprint with one deployable journey
The next implementation step is a deployed foundation followed by the application-submission slice. Expand the product after the important boundaries have been exercised.
Prioritized implementation roadmap
Order
Increment
Exit evidence
1
Resolve blocking decisions
Identity approach, submission rules, organization scope and hosting budget agreed.
2
Engineering foundation
Solution builds; boundaries tested; CI passes.
3
Deploy the skeleton
Bicep deployment, sign-in, health and telemetry work in non-production.
4
Draft application
Borrower creates, edits and reloads an owned draft.
5
Submission
Domain checks, concurrency, audit, outbox and idempotency work.
6
Reviewer visibility
Submitted application appears in the authorized review queue.
7
Delivery safety
Slot release, rollback and worker interruption rehearsed.
8
Expand workflows
Onboarding, products, decisions, offers, commitments and simulated finance.
The first slice uses declared fixtures
Seed a synthetic vetted borrower, approved credit limit, published product version and accepted synthetic evidence. These fixtures let the first journey prove its boundaries without implying that complete onboarding or malware scanning already exists.
Educational implementation versus live launch
The build demonstrates real engineering behavior with simulated decisions and money. A live launch additionally needs a confirmed operating model and jurisdiction, approved agreements and disclosures, provider onboarding, real identity and evidence verification, privacy and retention decisions, accounting validation, independent security assessment, support ownership and tested recovery. Architecture diagrams do not supply those capabilities.
Phase 3 completion criteria
Module ownership, layer dependencies and integration boundaries have been reviewed.
Every established role has a permission scope and representative screen journeys.
Submission specifies happy paths, failure paths, idempotency and concurrency.
Environment isolation, slots, worker processing, migrations and rollback form one consistent release story.
Quality targets have owners and are marked agreed or pending.
Architecture decisions include trade-offs and revisit conditions.
Blocking assumptions are resolved or explicitly constrain the implementation.
The first vertical slice can be estimated and has executable acceptance criteria.
Continue into implementation
Phase 4 can establish the engineering foundation and domain model. Phase 5 can deliver the first complete vertical slice. Security, testing and deployment begin with that work; later readiness exercises prove and strengthen those controls. This keeps the series connected from product vision to working software and operational evidence.
Take this into implementation
Another developer should now be able to explain ClearLend, locate each responsibility and begin the first deployable journey with clear acceptance criteria.