Advanced System Design Tutorial 0/70 lessons ~6 min read Lesson 1

    Introduction to Software Architecture

    TechLearningPro's marketplace and its video classroom once shared a single deployable called "the platform." During the 2025 enrollment week the checkout path stayed up, the progre

    Course progress0%
    Focus
    15 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction to Software Architecture

    Advanced System Design & Software Architecture · Lesson 01 · Software Architecture Foundations

    Lesson Overview

    TechLearningPro's marketplace and its video classroom once shared a single deployable called "the platform." During the 2025 enrollment week the checkout path stayed up, the progress API timed out, and the incident channel filled with a question nobody could answer from the diagram on the wiki: which structure was supposed to protect progress writes when the catalog was under a flash sale. The diagram showed boxes. It did not show an owner, a constraint, or a quality attribute anyone could measure after launch.

    That gap is the subject of this lesson, and of the course it opens. Software architecture is the set of structures you need in order to reason about a system: the elements, the relations among them, and the properties of both. The definition comes from Bass, Clements, and Kazman, and it matches the obligation in ISO/IEC/IEEE 42010: architecture is the fundamental concepts or properties of a system in its environment, embodied in elements, relationships, and the principles of its design and evolution. A framework choice, a repository layout, and a slide with six hexagons can each be a view of those structures. None of them is the architecture by itself.

    This lesson is the home for Advanced System Design & Software Architecture. You will leave with a working vocabulary for stakeholders, concerns, constraints, and the lifecycle that keeps quality attributes alive after the first release. You will also see how this track differs from the sibling courses already on TechLearningPro. /learn/design-principles builds the vocabulary of design principles. /learn/design-patterns teaches local object structure, including a SOLID overview aimed at pattern selection. /learn/enterprise-architecture introduces enterprise quality language such as scalability and availability. This course assumes you can read that language and spends its time on decision quality: a named stakeholder, a C4 view at the right altitude, a measurable quality attribute, an explicit trade-off, and a record the next team can reverse.

    The running system for the track is the TechLearningPro Learning Platform: catalog, enrollment, progress, instructor studio, and payouts. Later lessons will open that platform at the seams that matter. Module case studies (a bank, a commerce checkout, a multi-tenant academy, a payment authorization) are staff-training designs with stated assumptions. They are not disguised product claims.

    Six modules, seventy lessons:

    ModuleLessonsYou will be able to
    Software Architecture Foundations1–10Name drivers, quality scenarios, and a structure (clean, hexagonal, modular monolith, events) and record the decision
    Low-Level Design and Design Patterns11–22Shape objects, UML, and patterns inside a boundary the architecture already chose
    High-Level Design and Distributed Systems23–37Estimate capacity and design data, delivery, and failure across processes
    Microservices and Enterprise Architecture38–48Split or keep a boundary, integrate, observe, and migrate with operational cost in view
    Real-World System Design Case Studies49–60Carry one problem from drivers to a design you can defend
    Architecture Practice, Interviews and Capstone61–70Review someone else's architecture, including your own, against evidence

    Lesson 10 is the documentation and ADR lesson. This lesson only shows the minimum record a brief must carry so that later decisions have somewhere to live. Lesson 2 turns quality adjectives into scenarios. Lesson 3 decides which of those scenarios are architecturally significant.

    Learning Objectives

    By the end of this lesson you will be able to:

    1. State what software architecture is for, using structures, relations, and properties a reviewer can check.
    2. List the stakeholders of a learning platform and attach each one to a concern that can change a design.
    3. Separate constraints from preferences and from functional requirements in a one-page brief.
    4. Describe the architecture lifecycle from discovery through operation, including what a missed quality measure forces you to reopen.
    5. Draw a C4 context diagram that shows people, the system, and external systems, and refuse detail that belongs in a container view.
    6. Explain why module structures, component-and-connector structures, and allocation structures can all be true of one system.
    7. Review an architecture brief in Java and reject a brief whose quality intents have no measure.
    8. Place this course relative to design principles, design patterns, and the enterprise-architecture primer so you know which questions belong here.

    Prerequisites

    • You can read Java 21, including records and compact constructors. The brief reviewer in this lesson uses the JDK and Spring Boot 3. You do not need to have operated a Spring estate.
    • You have shipped or maintained a backend that talks to a database and an identity provider. The examples assume HTTP, JSON, and a relational store exist. They do not assume a particular cloud.
    • You can read a component diagram. C4 notation is introduced here; you do not need to have drawn one before.
    • Design-principle and pattern vocabulary helps and is not required. Where this lesson uses a principle, it says what decision the principle is protecting.

    If you want the shorter primers first, start at /learn/design-principles/home and /learn/enterprise-architecture/what-makes-good-architecture, then return. This lesson will still be the one that asks for a stakeholder, a constraint source, and a measure.

    Detailed Core Concepts

    Purpose

    Architecture exists so that a group of people can make a change, survive a failure, pass an audit, or meet a latency budget without rediscovering the system from the source tree. Code already contains every behavior the system has. It does not, by itself, tell a new engineer which behaviors are load-bearing. The architect's job is to make the load-bearing choices visible, to attach them to the people who will suffer if they are wrong, and to leave a path to reverse them when evidence arrives.

    Three purposes show up in every TechLearningPro design review:

    1. Coordination. Teams can work in parallel only when they know which elements they own and which relations they must not break. A progress service that writes through the catalog's tables has no parallel development story, regardless of how clean the classes look.
    2. Prediction. Stakeholders need to predict qualities the code does not shout: will a sale Saturday keep enrollment writes inside five hundred milliseconds at the ninety-fifth percentile; will a lost availability zone drop in-flight card captures; will a new tax rule touch one module or thirty.
    3. Governance. Some choices are expensive to undo. Data ownership, trust boundaries, and consistency scopes are in that set. Architecture is how the organization notices those choices before they calcify.

    A purpose that does not serve one of those three is a preference. Preferences can still be followed. They should not be allowed to impersonate architecture.

    Structures, not a single picture

    Bass, Clements, and Kazman group architectural structures into three families. You will use the names for the rest of the course.

    • Module structures describe how the system is partitioned for construction: packages, layers, build modules, and who is allowed to depend on whom. They are the structures you reason about at compile time and in code review.
    • Component-and-connector structures describe runtime elements and their interaction: processes, data stores, queues, and the protocols among them. They are the structures you reason about when a request is in flight.
    • Allocation structures describe the mapping of software onto environments: which process runs in which zone, which team owns which code, which repository produces which deployable.

    A team can draw a beautiful module diagram and still have no idea which process owns the enrollment transaction. A team can draw containers and still let every module depend on every other module. Both drawings are architecture. Each one answers a different question. ISO/IEC/IEEE 42010 calls the questions concerns, the people who hold them stakeholders, and a representation of the system organized around a set of concerns an architecture view. The conventions for constructing that view are a viewpoint. C4 is a set of viewpoints (context, container, component, code), not a methodology that replaces drivers.

    Stakeholders and concerns

    A stakeholder is any person or group with a concern the architecture can satisfy or violate. For the TechLearningPro Learning Platform the minimum set is larger than "product and engineering."

    StakeholderConcern the architecture can violateWhat they will ask in review
    LearnerProgress is durable and the player starts quickly"If I refresh, is my place in the lesson still there?"
    InstructorUploads complete, payouts match the contract"Who can change the revenue split after a course is sold?"
    Support leadA single enrollment id explains a ticket"Which log carries the enrollment id, and who may read it?"
    Security and privacyIdentity, consent, and retention are enforceable"Where does a learner email sit at rest, and for how long?"
    FinanceRevenue and refunds reconcile to the ledger"Is the charge captured in the same transaction as the entitlement?"
    Platform operationsDeploys, saturation, and restore have an owner"What is the restore point for progress, and how long does it take?"
    Course authoring (internal)A lesson can ship without a platform rewrite"Can we add a practice type without touching checkout?"
    Enterprise buyer (Academies)Their employees' data stays inside their tenant"Can another customer's admin see our roster?"

    Collapsing this table into "the business wants scalability" produces designs that optimize a word. The learner's latency concern and finance's consistency concern pull in different directions during a card payment. Both are business concerns. Architecture names the tension. It does not pretend one stakeholder's adjective covers the others.

    External actors are stakeholders when they can force a change: an identity provider's outage behavior, a card network's capture rules, an auditor's retention period. They do not attend your stand-up. Their constraints still bind the design.

    Constraints

    A constraint is a design decision that has already been made, or a condition the environment imposes, that the current effort may not overturn without an explicit escalation. A constraint has a source. "We prefer Kotlin" has no source that binds the program. "Cardholder data must stay inside the existing PCI segment operated by the payments vendor, because the 2024 assessment scoped our network that way" has a source.

    Useful constraint classes for this course:

    • Technical. The progress store is PostgreSQL 16. The identity protocol is OpenID Connect against the company issuer. Video bytes already live in an S3-compatible bucket. These are reversible in principle and expensive in practice. Write the cost of reversal next to the constraint so a future team knows what "expensive" meant.
    • Organizational. Two squads, one shared on-call rotation, no dedicated database administrator. An architecture that needs a per-service datastore and a twenty-person platform group is in conflict with this constraint even when the diagrams are fashionable.
    • Regulatory and contractual. Retention of learner assessment records for the period named in the enterprise contract. No storage of full card numbers. These are not quality-attribute goals you tune. They are conditions of operating.
    • Schedule. An enrollment-week date. Schedule does not delete quality attributes. It changes which attributes you will meet by degrading scope, adding people, or accepting a time-bounded risk that is written down.

    A preference that survived a meeting is still a preference until someone with authority records it as a constraint. Lesson 3 uses this distinction as a sorting rule for architecture drivers. Here, the rule is simpler: if the brief cannot name the source, the item does not yet constrain the design.

    Functional requirements and quality attributes

    A functional requirement states what the system does: enroll a learner, record a lesson checkpoint, refund a purchase inside the published window. A quality attribute states how well a function must be carried out under stated conditions: the checkpoint write completes within a measured time while the catalog is under a stated load; a single unavailable zone does not lose a committed checkpoint.

    Quality attributes are not a separate backlog that architects own and product managers ignore. Every functional requirement is delivered at some level of each relevant quality, including the level "we have not decided." An undecided level is a risk, not a neutral default. The lifecycle in the next section exists because the level drifts: traffic grows, a new stakeholder appears, a dependency changes its failure mode.

    This course uses five attributes as the default lens, mapped onto the ISO/IEC 25010 product-quality model so the names stay honest:

    Lens in this courseISO/IEC 25010 homeWhat a brief must eventually measure
    LatencyPerformance efficiency, time behaviourA percentile, a path, a load
    AvailabilityReliability, availabilityA period, an error budget or downtime allowance, a user-visible definition of "down"
    ScalabilityPerformance efficiency, capacity (scalability is the tactic and the growth story, not a separate 25010 characteristic)A workload multiplier the design must absorb and what you will add to absorb it
    SecuritySecurity (confidentiality, integrity, non-repudiation, accountability, authenticity)A threat the structure closes, and the control's location
    ModifiabilityMaintainability, modifiabilityA class of change, the modules it may touch, and a cost bound

    Lesson 2 writes these as six-part scenarios. Lesson 1 only requires that a brief refuse naked adjectives. "The system shall be secure" cannot be reviewed. "Support staff can see an enrollment id and cannot see a card number" can.

    Other 25010 characteristics (usability, compatibility, portability) matter. They become architectural when a structure has to change to satisfy them. A theme switch inside one stylesheet usually does not. A requirement that every enterprise tenant bring its own identity provider does.

    The lifecycle

    Architecture is not a phase that ends when coding starts. The lifecycle this course will keep reopening has seven moves. They are sequential only on a new system. On a living system they run as a loop.

    1. Discover. Name the system boundary, the stakeholders, and the concerns. If two stakeholders use the same noun for different data ("account" as a learner versus "account" as a payout recipient), stop and split the noun before drawing containers.
    2. Drive. Turn concerns into architecture drivers: business goals, architecturally significant requirements, and constraints. This is lesson 3. Most functional requirements are not drivers. The ones that force a structure are.
    3. Shape. Choose structures and tactics that satisfy the highest-priority drivers, and write down what those structures make worse. Attribute-driven design, in lesson 2, is the method. Pattern selection from /learn/design-patterns happens inside this move, after a driver exists.
    4. Record. Capture the decision, the context, and the consequences in a form a stranger can read. Lesson 10 standardizes Architecture Decision Records. Until then, a brief with a decision paragraph is enough.
    5. Realize. Implement the structures in code and in deployment. Lessons 4 through 9 are realization choices: SOLID inside a module, a dependency rule, ports, a modular monolith, domain boundaries, events.
    6. Evaluate. Compare the running system to the measures. A design review before launch can check reasoning. Only production, or a test that reproduces production's shape, can check the measure.
    7. Revise. When the measure misses, or a constraint appears, reopen the decision. Revision is success of the lifecycle. Silent drift is failure.

    The loop is how quality attributes stay attached to the system after the launch slide is archived. A team that evaluates availability with a load-balancer health check, while learners experience progress loss, is measuring a different system than the one the stakeholder named.

    What a brief is for

    Before a container diagram, the TechLearningPro architecture guild asks for a one-page architecture brief:

    • System name and the purpose, in one sentence a learner or buyer would recognize.
    • Stakeholders and the concern each can veto.
    • Constraints with sources.
    • Functional scope in and out, so the diagram does not absorb the entire company.
    • Quality intents written as stimulus and measure, even if the numbers are still assumptions. Label assumptions.
    • One to three decisions already taken, each with a consequence.
    • The view you will draw next, and the question that view answers.

    The brief is a filter. If it cannot be written, the diagram will invent a system. The Java reviewer later in this lesson encodes the filter that can be checked mechanically: every quality intent has a measure, every constraint has a source, and a compliance constraint requires a stakeholder whose concern is security or compliance. Judgment stays with people. The machine only rejects briefs that are not yet reviewable.

    Decision quality

    A good decision, at this stage of the course, has five visible parts.

    1. The driver it serves.
    2. The alternatives that were real for this team, not a survey of the industry.
    3. The consequence for at least one other quality attribute.
    4. The constraint that made an alternative illegal or merely expensive.
    5. The evidence that would cause the team to reopen it, and where that evidence will be read.

    "We chose microservices because modern systems are microservices" has none of the five. "We kept enrollment and progress in one deployable because one squad owns both, the consistency of 'paid therefore entitled' is a finance concern, and a second datastore has no operator. We will split progress out if p95 checkpoint latency stays above 400 ms for two enrollment weeks while enrollment CPU is idle." That sentence can be wrong and still be architecture. The course will spend later lessons making such sentences harder to get wrong.

    Architecture and Design Diagrams

    The first diagram of the Learning Platform is a system context. People and external systems sit outside the boundary. Inside the boundary, this view has exactly one system. Containers, databases, and class names are a different viewpoint. Putting them here feels thorough and makes the context diagram useless: every reviewer stares at the box they already understand and misses the trust boundary.

    mermaid
    C4Context
    title TechLearningPro Learning Platform — system context
    Person(learner, "Learner", "Enrolls, watches, and expects durable progress")
    Person(instructor, "Instructor", "Publishes courses and receives payouts")
    Person(support, "Support lead", "Traces one enrollment across tickets")
    System(platform, "Learning Platform", "Catalog, enrollment, progress, studio, and payouts")
    System_Ext(idp, "Company IdP", "OpenID Connect issuer")
    System_Ext(objectstore, "Object storage", "Video and lesson media already in production")
    System_Ext(payvendor, "Payments vendor", "Card capture inside the vendor PCI segment")
    System_Ext(mail, "Email provider", "Receipts and operational mail")
    Rel(learner, platform, "Uses", "HTTPS")
    Rel(instructor, platform, "Publishes and reads payouts", "HTTPS")
    Rel(support, platform, "Looks up an enrollment", "HTTPS")
    Rel(platform, idp, "Authenticates principals", "OIDC")
    Rel(platform, objectstore, "Reads and writes media", "HTTPS")
    Rel(platform, payvendor, "Authorizes and captures course purchases", "HTTPS")
    Rel(platform, mail, "Sends receipts", "HTTPS")

    Read the arrows as obligations. The platform authenticates with the company issuer; it does not invent a second user directory. Card data stops at the payments vendor. Media bytes stop at object storage. Support reaches the platform, not the vendor and not the bucket. Those three sentences are architectural. They will be tested by any design that proposes storing card numbers "just for refunds," or letting the player talk to the bucket with a long-lived public URL.

    The lifecycle sits next to the context diagram. Evaluation feeds revision. Revision may change a stakeholder list when a new buyer appears, which is why discovery is in the loop and not only at the start.

    mermaid
    flowchart TD
    discover[Discover stakeholders and boundary]
    drive[Name drivers and constraints]
    shape[Choose structures and trade-offs]
    record[Record decisions]
    realize[Realize in code and deployment]
    evaluate[Measure the quality intents]
    revise[Reopen the decision]
    discover --> drive --> shape --> record --> realize --> evaluate
    evaluate -->|measure missed or constraint changed| revise
    revise --> drive

    A module structure for the same platform answers a different question: who may depend on the enrollment model. This is not a C4 container view. No process is implied.

    mermaid
    flowchart LR
    subgraph modules [Module structure — construction time]
    catalog[catalog]
    enrollment[enrollment]
    progress[progress]
    payouts[payouts]
    sharedkernel[shared kernel: ids and money]
    end
    catalog --> sharedkernel
    enrollment --> sharedkernel
    enrollment --> catalog
    progress --> sharedkernel
    payouts --> sharedkernel
    payouts --> enrollment

    The arrow from payouts to enrollment is a decision: payout calculation may read an enrollment fact. The absence of an arrow from catalog to payouts is also a decision. A context diagram cannot say this. A module diagram cannot say which database process runs in which zone. Teams that publish one picture and call it "the architecture" have chosen a single stakeholder and left the others unserved.

    Allocation, the third family, is the one incident response actually uses. During enrollment week the question is which deployable is saturated, who is on call, and which store holds the system of record for progress.

    mermaid
    flowchart TB
    subgraph zone [One region, two availability zones]
    app[platform deployable]
    pg[(PostgreSQL progress and enrollment)]
    end
    squad[One squad, shared on-call]
    bucket[Object storage outside the PCI segment]
    squad --- app
    app --> pg
    app --> bucket

    If a proposal adds a second deployable, this diagram must gain an owner and a datastore story in the same review. Otherwise the proposal has changed a component-and-connector fantasy and left the allocation structure untouched.

    Technical Explanation

    Views answer questions

    Simon Brown's C4 model stacks four viewpoints. You owe the audience only the views whose questions are in play.

    ViewpointQuestion it answersIt should refuse to show
    ContextWho uses the system, and which external systems are trusted for what?Classes, frameworks, topics, internal databases
    ContainerWhat are the runnable units and data stores, and how do they communicate?Method names, package layout
    ComponentInside one container, what are the major structural parts and their interfaces?Every class
    CodeHow is a specific component implemented?The entire system

    A context diagram that includes a Kafka topic has slipped into the container viewpoint and usually into an undebated technology choice. Technology belongs in a container or allocation view, next to the driver that forced it. Lesson 9 introduces events because a driver called for them, not because the context diagram had a spare arrow.

    UML remains useful and is not replaced by C4. A sequence diagram shows a single runtime scenario: login, then enroll, then the failure when the payments vendor times out. A component diagram in UML can be the C4 component view. Lesson 12 and lesson 13 teach UML in the low-level design module. Use a sequence diagram when the order of calls and the failure branch are the decision. Use C4 when the question is scope and responsibility.

    Architecturally significant means "forces a structure"

    Most requirements are implemented inside a structure that already exists. Adding a field to a lesson summary does not move a database or a trust boundary. Those requirements need design. They do not need an architecture change.

    A requirement or constraint is architecturally significant when meeting it forces you to choose, split, or protect a structure. Examples from the Learning Platform:

    • "A committed purchase must create an entitlement even if the receipt email fails." That forces a consistency boundary: the entitlement write and the card capture acknowledgment have a defined relationship, and email is outside it.
    • "Checkpoint p95 stays under 400 ms during a ten-times catalog read spike." That forces a runtime structure: progress writes cannot sit behind the catalog's cache stampede.
    • "Enterprise tenants authenticate with their own IdP." That forces an allocation and a trust boundary around tokens.
    • "We will ship a new practice widget next month." That does not, by itself, force a structure, unless the current module dependencies mean every widget change recompiles checkout.

    The phrase "significant" is a claim about impact, not about the speaker's seniority. Lesson 3 builds a utility tree so the claim is prioritized instead of shouted.

    Trade-offs are the content of the decision

    Every structure that improves one property taxes another. Keeping enrollment and progress in one PostgreSQL database improves the chance that "paid" and "entitled to lesson one" agree, and it couples their failure domain and their schema calendar. Splitting them improves independent scaling and creates a new failure: the card is captured, the entitlement row is not, and support has no single transaction to read.

    You record the tax at decision time. You do not discover it by being clever in the incident. A useful consequence names the stakeholder who pays. "More complexity" is not a consequence. "Support must reconcile two stores during a partial failure, and we have no reconciler" is a consequence.

    Reversibility belongs in the same paragraph. A decision is cheap to reverse when the data model, the external contract, and the operating skill can move with it. Picking a JSON library is usually cheap. Promising learners that progress is stored in a form you cannot migrate is not. The brief should say which kind you think you are making, and what evidence would change your mind.

    Architecture and organizational shape

    Conway's observation still holds: the system will resemble the communication structure that builds it, because interfaces form where conversation is expensive. For a single TechLearningPro squad, a single deployable with a strict module structure is often the design that matches the allocation constraint. Drawing eight services does not create eight teams. It creates one team operating eight failure domains.

    This is not an argument against splitting. It is an argument for splitting when a driver, usually a quality attribute or a genuine ownership boundary, exceeds what one module structure can protect. Module 4 of this course takes that argument apart with operational detail. Module 1 only forbids the split as a default.

    Evaluation before and after launch

    Before launch you can evaluate reasoning: missing stakeholders, measures with no stimulus, decisions with no alternative, diagrams that disagree. Methods such as ATAM (Architecture Tradeoff Analysis Method) exist to structure that conversation around scenarios and risks. The capstone review checklist in lesson 69 is this course's operational version. You do not need the full method to refuse a brief that says "highly available."

    After launch you evaluate with the measure the brief named. If the brief named none, the dashboard you build will measure what was easy to instrument. Teams then "meet SLO" on a health endpoint while the learner-facing checkpoint fails. The fix is not a better dashboard. The fix is to write the scenario, then instrument that path. Lesson 2 puts a Micrometer timer on the path the scenario names. Lesson 43 covers a full observability design. Do not wait for lesson 43 to name the path.

    Security and operations are architectural from the first brief

    Security in this lesson is a placement decision. Secrets live with the process that must use them. Card data stays in the vendor segment named by the constraint. Support tokens do not grant bucket administration. A context diagram that draws support "to the platform" is incomplete until the brief says what the platform will not return.

    Operations is a placement decision too. A restore point that exists only in a vendor console nobody can access is not a restore point for the stakeholder who asked. The allocation diagram should make the operator visible. If the operator is "a squad that also ships features," the architecture's operational burden has to fit that squad. Complexity the squad cannot carry will be carried by the incident, which is the most expensive design review available.

    Practical Implementation or Design Walkthrough

    Problem

    The architecture guild will not review a container diagram for a new initiative until a brief passes a mechanical check and a human check. The initiative used here is the staff-training case Harborline, a retail bank's "open an account and transfer between own accounts" slice. It is a teaching boundary, small enough to finish, sharp enough to expose stakeholders. The same reviewer runs on TechLearningPro briefs. The rules are domain-neutral on purpose.

    Requirements the brief must carry

    Functional slice, in scope: a customer opens a checking account after identity proofing; a customer transfers an amount between two accounts they own; the transfer is rejected when it would overdraw; every accepted transfer is durable.

    Out of scope for this brief: mortgages, card issuing, teller cash, international wires. Writing the out-of-scope list is what stops the context diagram from becoming a core-banking replacement.

    Assumptions, labeled as assumptions: one region; peak of 30 transfers per second; customers authenticate through the bank's existing OIDC issuer; the ledger is a relational database the bank already operates; the team is one squad of six with no separate platform group.

    Constraints

    IdStatementSource
    C1Customer identity comes from the existing issuer. A second password store is prohibited.Bank IAM standard, current assessment
    C2The squad will operate the system. A design that needs a dedicated network team to ship is out of bounds.Staffing plan for the training case
    C3Overdraft is not offered on this product. A transfer that would make available balance negative is rejected.Product rule signed by retail banking
    C4Transfer records are retained for seven years.Records schedule named by compliance

    C3 is easy to misfile as a functional requirement. It is both a function ("reject") and a constraint ("this product will not grow an overdraft feature inside the slice"). The brief records it as a constraint so a later "small" overdraft story cannot land inside the same consistency design without reopening the decision.

    Quality intents

    These are intents, not yet the six-part scenarios of lesson 2. They already have a measure.

    AttributeStimulusMeasure
    LatencyCustomer submits an own-account transfer under the assumed peakp95 under 300 ms, excluding the customer's network, measured at the API
    IntegrityTwo transfers race on the same accountAvailable balance never goes negative; one transfer commits, the other is rejected
    AvailabilityThe API process restartsNo committed transfer is lost; recovery uses the database, not the process heap
    AuditCompliance asks for a transferThe record shows who, what amount, which accounts, and when, for seven years

    "Fast" and "safe" do not appear. Integrity and latency are in tension if every transfer takes a table lock coarser than the account. The decision paragraph has to say which locking scope was chosen and what it costs.

    Decisions the brief records

    Decision H1. One relational database is the system of record for accounts and transfers. The API process holds no durable state.

    • Driver: integrity of the balance, and the operational constraint of one squad.
    • Alternative considered: a cache of balances in the API process. Rejected because a restart would either lose updates or serve stale balances that allow an overdraft.
    • Consequence: horizontal scaling of the API is allowed; scaling of writes depends on the database. At 30 transfers per second this is an accepted limit. The evidence that reopens H1 is a sustained write saturation of the database at peak, with API CPU idle.
    • Stakeholder who pays if we are wrong: the customer, by a rejected transfer, or compliance, by a missing record. Both are preferable to a silent negative balance.

    Decision H2. Identity proofing stays outside this system. The transfer API trusts a token from the existing issuer and authorizes "owns both accounts" locally.

    • Driver: constraint C1.
    • Consequence: issuer downtime means no transfers. The brief does not invent a break-glass password. Availability of transfers is bounded by the issuer, and that bound is written down so the availability intent is not read as "the API process is up."

    The reviewer

    The following types are the ones the guild actually compiles. They use Java 21 records. Validation that protects an invariant lives in the compact constructor. Review findings are a list. An empty list means "mechanically reviewable," not "approved."

    java
    package com.techlearningpro.architecture.brief;
    import java.util.List;
    import java.util.Objects;
    public enum Concern {
    AVAILABILITY,
    LATENCY,
    INTEGRITY,
    SECURITY,
    COMPLIANCE,
    COST,
    OPERABILITY,
    MODIFIABILITY
    }
    public record Stakeholder(String name, String role, List<Concern> concerns) {
    public Stakeholder {
    Objects.requireNonNull(name, "name");
    Objects.requireNonNull(role, "role");
    Objects.requireNonNull(concerns, "concerns");
    concerns = List.copyOf(concerns);
    if (name.isBlank() || role.isBlank() || concerns.isEmpty()) {
    throw new IllegalArgumentException(
    "A stakeholder needs a name, a role, and at least one concern");
    }
    }
    }
    public record Constraint(String id, String statement, String source) {
    public Constraint {
    requireText(id, "id");
    requireText(statement, "statement");
    requireText(source, "source");
    }
    private static void requireText(String value, String field) {
    if (value == null || value.isBlank()) {
    throw new IllegalArgumentException(field + " is required");
    }
    }
    }
    public record QualityIntent(String attribute, String stimulus, String measure) {
    public QualityIntent {
    if (attribute == null || attribute.isBlank()
    || stimulus == null || stimulus.isBlank()
    || measure == null || measure.isBlank()) {
    throw new IllegalArgumentException(
    "A quality intent needs an attribute, a stimulus, and a measure");
    }
    }
    }
    public record ArchitectureBrief(
    String systemName,
    String purpose,
    List<Stakeholder> stakeholders,
    List<Constraint> constraints,
    List<QualityIntent> qualities,
    List<String> outOfScope) {
    public ArchitectureBrief {
    if (systemName == null || systemName.isBlank()) {
    throw new IllegalArgumentException("systemName is required");
    }
    if (purpose == null || purpose.isBlank()) {
    throw new IllegalArgumentException("purpose is required");
    }
    stakeholders = List.copyOf(Objects.requireNonNull(stakeholders));
    constraints = List.copyOf(Objects.requireNonNull(constraints));
    qualities = List.copyOf(Objects.requireNonNull(qualities));
    outOfScope = List.copyOf(Objects.requireNonNull(outOfScope, "outOfScope"));
    if (stakeholders.isEmpty() || constraints.isEmpty() || qualities.isEmpty()) {
    throw new IllegalArgumentException(
    "Name at least one stakeholder, one constraint, and one quality intent");
    }
    }
    }

    BriefReviewer applies the rules that constructors cannot see, because they compare fields to each other.

    java
    package com.techlearningpro.architecture.brief;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Locale;
    import java.util.regex.Pattern;
    public record ReviewFinding(String code, String message) {}
    public final class BriefReviewer {
    private static final Pattern HAS_DIGIT = Pattern.compile(".*\\d.*");
    public List<ReviewFinding> review(ArchitectureBrief brief) {
    var findings = new ArrayList<ReviewFinding>();
    for (var quality : brief.qualities()) {
    if (!HAS_DIGIT.matcher(quality.measure()).matches()) {
    findings.add(new ReviewFinding(
    "MEASURE_WITHOUT_NUMBER",
    quality.attribute() + " has a measure with no number"));
    }
    }
    boolean complianceConstraint = brief.constraints().stream()
    .anyMatch(c -> c.statement().toLowerCase(Locale.ROOT).contains("retain")
    || c.id().toLowerCase(Locale.ROOT).contains("audit"));
    boolean complianceStakeholder = brief.stakeholders().stream()
    .flatMap(s -> s.concerns().stream())
    .anyMatch(concern -> concern == Concern.COMPLIANCE || concern == Concern.SECURITY);
    if (complianceConstraint && !complianceStakeholder) {
    findings.add(new ReviewFinding(
    "COMPLIANCE_WITHOUT_STAKEHOLDER",
    "A retention or audit constraint is present and no stakeholder owns security or compliance"));
    }
    if (brief.outOfScope().isEmpty()) {
    findings.add(new ReviewFinding(
    "UNBOUNDED_SCOPE",
    "State what this brief refuses to design"));
    }
    return List.copyOf(findings);
    }
    }

    The digit check is deliberately blunt. "Seven years" passes. "Highly available" fails. A measure can contain a number and still be a bad measure ("1 microservice"). Human review stays mandatory. The mechanical check only clears the adjectives.

    Spring Boot 3 boundary

    The guild exposes the reviewer on an internal endpoint. It is not a public product API. Spring Security 6 restricts it to a token that carries SCOPE_architecture.read, issued by the company IdP. The resource-server starter is spring-boot-starter-oauth2-resource-server. The issuer URI comes from configuration (spring.security.oauth2.resourceserver.jwt.issuer-uri). No issuer is hardcoded.

    java
    package com.techlearningpro.architecture.brief;
    import jakarta.validation.Valid;
    import jakarta.validation.constraints.NotBlank;
    import jakarta.validation.constraints.NotEmpty;
    import java.util.List;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.security.config.Customizer;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.web.SecurityFilterChain;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.bind.annotation.RestController;
    record StakeholderRequest(@NotBlank String name, @NotBlank String role, @NotEmpty List<Concern> concerns) {
    Stakeholder toStakeholder() {
    return new Stakeholder(name, role, concerns);
    }
    }
    record ConstraintRequest(@NotBlank String id, @NotBlank String statement, @NotBlank String source) {
    Constraint toConstraint() {
    return new Constraint(id, statement, source);
    }
    }
    record QualityIntentRequest(
    @NotBlank String attribute,
    @NotBlank String stimulus,
    @NotBlank String measure) {
    QualityIntent toIntent() {
    return new QualityIntent(attribute, stimulus, measure);
    }
    }
    record ReviewRequest(
    @NotBlank String systemName,
    @NotBlank String purpose,
    @NotEmpty List<@Valid StakeholderRequest> stakeholders,
    @NotEmpty List<@Valid ConstraintRequest> constraints,
    @NotEmpty List<@Valid QualityIntentRequest> qualities,
    @NotEmpty List<@NotBlank String> outOfScope) {
    ArchitectureBrief toBrief() {
    return new ArchitectureBrief(
    systemName,
    purpose,
    stakeholders.stream().map(StakeholderRequest::toStakeholder).toList(),
    constraints.stream().map(ConstraintRequest::toConstraint).toList(),
    qualities.stream().map(QualityIntentRequest::toIntent).toList(),
    outOfScope);
    }
    }
    record ReviewResponse(List<ReviewFinding> findings, boolean reviewable) {}
    @RestController
    @RequestMapping("/internal/architecture-briefs")
    class ArchitectureBriefController {
    private final BriefReviewer reviewer;
    ArchitectureBriefController(BriefReviewer reviewer) {
    this.reviewer = reviewer;
    }
    @PostMapping("/review")
    ResponseEntity<ReviewResponse> review(@Valid @RequestBody ReviewRequest request) {
    var findings = reviewer.review(request.toBrief());
    var status = findings.isEmpty() ? HttpStatus.OK : HttpStatus.UNPROCESSABLE_ENTITY;
    return ResponseEntity.status(status)
    .body(new ReviewResponse(findings, findings.isEmpty()));
    }
    }
    @Configuration
    class InternalBriefSecurity {
    @Bean
    SecurityFilterChain internalBriefs(HttpSecurity http) throws Exception {
    return http
    .securityMatcher("/internal/**")
    .authorizeHttpRequests(auth -> auth.anyRequest().hasAuthority("SCOPE_architecture.read"))
    .oauth2ResourceServer(oauth -> oauth.jwt(Customizer.withDefaults()))
    .build();
    }
    }

    ReviewRequest.toBrief() maps validated request records onto Stakeholder, Constraint, and ArchitectureBrief. The mapping is ordinary Java. HTTP 422 means the brief is well-formed JSON and still not reviewable. HTTP 200 means a person may now spend review time on the decisions. It does not mean Harborline should be built.

    Bean validation (@NotBlank, @Valid) is Jakarta Validation, shipped with spring-boot-starter-validation. Constructor checks remain, because the domain types are also built from tests that never touch HTTP.

    Test

    A JUnit 5 test locks the rule that "fast" is not a measure. The test does not boot Spring. The domain rule does not need a container.

    java
    import static org.junit.jupiter.api.Assertions.assertTrue;
    import java.util.List;
    import org.junit.jupiter.api.Test;
    class BriefReviewerTest {
    @Test
    void rejectsMeasureThatHasNoNumber() {
    var brief = new ArchitectureBrief(
    "Harborline transfers",
    "Move money between a customer's own accounts without overdraft",
    List.of(new Stakeholder("Retail customer", "account holder", List.of(Concern.INTEGRITY))),
    List.of(new Constraint("C4", "Retain transfer records for seven years", "Records schedule")),
    List.of(new QualityIntent("Latency", "Submit a transfer at peak", "fast")),
    List.of("Mortgages", "Card issuing"));
    var codes = new BriefReviewer().review(brief).stream().map(ReviewFinding::code).toList();
    assertTrue(codes.contains("MEASURE_WITHOUT_NUMBER"));
    assertTrue(codes.contains("COMPLIANCE_WITHOUT_STAKEHOLDER"));
    }
    }

    The second assertion is the lifecycle in miniature. A retention constraint without a compliance stakeholder will be "handled later," which means the seven-year store will be designed by whoever picks a database default.

    What this walkthrough deliberately does not do

    It does not draw Harborline's containers. The context is "customer, bank system, existing issuer, existing database." Containers come after the brief is reviewable. It does not pick a framework beyond the reviewer itself. It does not claim 30 transfers per second is a researched capacity model. Lesson 24 is the capacity lesson. The number is an assumption with a name, which is the only honest way to write it in week one.

    Enterprise Real-World Scenarios

    Enrollment week at TechLearningPro

    Planning assumptions the squad wrote down before the 2025 enrollment week: catalog reads could jump by about ten times for two days; checkpoint writes had to stay under 400 ms at p95 for learners already in a lesson; a failed receipt email must not roll back an entitlement. The architecture they had was one deployable and one database, which matched the staffing constraint. The failure was not the single deployable. The failure was a quality intent nobody had separated by path.

    Catalog traffic and checkpoint traffic shared a connection pool. When the sale hit, catalog queries occupied the pool, checkpoint writes waited, and the status page stayed green because the load balancer could open a TCP connection. Learners saw a spinner on "continue." Support saw tickets with no common id, because the player retried without the original checkpoint key.

    The revision, after the week, was an architecture change of the small kind that briefs exist to catch:

    • A stakeholder who had been missing: the learner in the middle of a lesson, distinct from the buyer at checkout.
    • A constraint that had been treated as a preference: one squad, one on-call, so a new service was not the first move.
    • A decision: separate pool and statement timeout for checkpoint writes, and an idempotency key on the checkpoint so a retry does not double-write progress. The catalog remained in-process.
    • Evidence that would force a larger split: checkpoint p95 above 400 ms for a second enrollment week while the checkpoint pool is the saturated resource and catalog CPU is not.

    The post-incident diagram that helped was the allocation view plus a sentence about pools. A new microservices poster would have added operators the squad did not have. Lesson 2 will turn the 400 ms sentence into a full scenario. Lesson 37 covers idempotency keys as a distributed-systems topic. The architectural act in this story is naming the stakeholder and the measure before choosing a mechanism.

    Instructor payouts and the learner refund

    A second tension sits in the same platform and is easy to miss because both sides use the word "money." Instructors are paid from a revenue share on a course purchase. Learners can request a refund inside a published window. Finance needs the share and the refund to reconcile to a ledger. Instructors need to know, before they spend the payout, whether a refund can still claw it back. Support needs one explanation when a learner says they were charged and an instructor says they were not paid.

    The first design computed the share inside the request that captured the card, and credited an instructor balance immediately. It was simple, and it made refunds a special case that edited history. Two stakeholders were harmed in opposite ways: instructors saw balances that finance would later reverse, and finance could not explain a clawback without a manual journal.

    The brief that replaced it recorded:

    • Stakeholders who can veto: finance (reconciliation), instructor (predictable payout), learner (refund inside the window), support (one id).
    • Constraint: card capture stays at the payments vendor. The platform stores an entitlement and a payout obligation, not a card number.
    • Decision: a purchase writes an entitlement and a payout obligation in the same database transaction after the vendor acknowledges capture. The obligation has a state, ACCRUED, until the refund window closes, then PAYABLE. A refund inside the window voids the obligation. It does not edit a payout that has already been sent.
    • Trade-off: instructors wait until the window closes before the balance is spendable. That is a product consequence, agreed with the instructor stakeholder, not an accidental delay.
    • Modifiability consequence: a new revenue-share rule changes the obligation calculator. It does not change the vendor adapter. That sentence is the bridge to lessons 4 and 5.

    Both stories are the same lesson. The system already had code. It did not have a structure anyone could reason about when two stakeholders pulled apart. The repair was a brief, a decision with a named tax, and a measure that told the team when the repair was no longer enough.

    Best Practices

    • Write the brief before the container diagram. If the purpose sentence is controversial, the diagram is fiction.
    • Give every constraint a source and a reversal cost. A constraint nobody can trace will be ignored under schedule pressure, and you will not know whether ignoring it was a decision.
    • Attach every quality adjective to a stakeholder, a stimulus, and a measure. Keep the measure coarse until lesson 2, and keep it numeric.
    • Draw at least two structures when the review is real: one construction-time (modules) and one runtime or allocation. Publish the question each drawing answers.
    • Name the out-of-scope list in public. Scope creep in a diagram is how a training-case transfer system becomes a core-banking program.
    • Record the alternative you rejected and the evidence that would resurrect it. Future you will face the rejected idea again, brought by someone who did not attend the meeting.
    • Put internal design tools behind the same identity boundary as the rest of the company. An architecture-brief endpoint that anyone on the network can post to will be filled with unowned documents.
    • When the squad is the operator, prefer structures that squad can restore. Heroic designs are a staffing assumption you did not write down.
    • Revisit the brief at the end of the first real peak. A lifecycle that stops at launch has no evaluation move.
    • Use this course's later lessons for mechanisms. Use this lesson to decide whether you are allowed to reach for one.

    Common Mistakes and Anti-Patterns

    The framework is the architecture. A team announces "we are a Spring Boot shop" and believes the architecture question is closed. Spring Boot is a construction constraint and a set of libraries. It does not decide data ownership, consistency, or which stakeholder is protected when email fails. The repair is to write the brief in language that would still make sense if the next service were written in something else. Then, and only then, map the realization onto Spring, as lessons 4 and 5 do.

    One diagram, called final. Usually it is a container picture copied from a blog, with every database the author has heard of. Reviewers argue about the message bus because it is drawn, not because a driver required it. The repair is the three-family rule: module, component-and-connector, allocation. If a box appears in only one of them, ask which question it answers.

    The stakeholder list is the meeting invite. Product, the tech lead, and sometimes security if the calendar allowed. Learners, instructors, the on-call engineer, and the auditor are absent, so their concerns arrive as incidents and findings. The repair is the table in this lesson, edited until someone in the room can speak for each row or the row is explicitly deferred with a risk.

    Adjectives as requirements. "Scalable, secure, and easy to maintain" survives template reviews and constrains nothing. Two reasonable engineers will draw opposite systems and both will claim compliance. The repair is a number, a condition, and a path. Lesson 2 shows the full six-part form. Do not wait for perfection of the number; label it as an assumption and give it an owner.

    Constraints discovered during implementation. The team designs a second user store, then learns the company assessment forbids it. Weeks of model work are discarded, and the architecture earns a reputation for delay that actually belongs to an unstated constraint. The repair is a constraint section with sources before the decision section. Empty is acceptable. Invented is not. Unknown is a risk, written as a risk.

    Architecture as a gate at the start. The brief is approved, filed, and never compared to the running system. Pools get shared, idempotency keys get dropped, a "temporary" balance cache ships. The document still says the right things, so audits pass and learners do not. The repair is the evaluation move: the measure from the brief is a dashboard with an owner, and a miss reopens the decision.

    Premature distribution. Eight services are drawn because a conference talk did it for a company with a platform organization. The local constraint is one squad. The result is distributed transactions nobody staffed, and a modular structure that would have isolated the same changes inside one process. The repair is to write the allocation constraint next to the proposal and to demand the driver the process boundary serves. Module 4 exists for the cases where the driver is real.

    Troubleshooting and Design Review

    Symptom: Every design review re-argues whether to add a queue.

    Likely cause: the decision was never recorded with a driver and a reopening condition, so each newcomer treats the question as fresh. The diagram shows a queue icon someone sketched once.

    Investigation: find the brief or ADR. If the driver is missing, stop debating the icon.

    Corrective action: write the decision in the form used for H1. If nobody can name a driver, remove the queue from the diagram until lesson 9's criteria are met.

    Symptom: The status page is green and the learner-facing path is not.

    Likely cause: evaluation measures a different structure than the one the stakeholder cares about. Health checks prove the process accepts TCP. The stakeholder named checkpoint durability and latency.

    Investigation: read the quality intent. Identify the path and the store. Compare the dashboard.

    Corrective action: instrument the path named in the intent. Change the status definition, or stop calling the health check a measure of that intent.

    Symptom: Two squads produce container diagrams that disagree about who owns enrollment.

    Likely cause: no context boundary and no module ownership. Both diagrams can be internally pretty.

    Investigation: ask which system of record holds an enrollment row, and which team can migrate it.

    Corrective action: one owner for the data, recorded on the allocation structure. The other diagram becomes a client, not a second writer.

    Symptom: Security findings arrive the week of launch and require a different trust boundary.

    Likely cause: security was a stakeholder on the slide and not in the constraint list. Card data, tokens, or tenant isolation were drawn as arrows without a "does not store" sentence.

    Investigation: walk the context diagram and ask, for each external system, what data must not cross back.

    Corrective action: add the constraint with its source, move the data, and treat the schedule slip as the cost of a skipped lifecycle move. Then add the compliance stakeholder to the reviewer rule so the next brief fails in CI instead of in the last week.

    Symptom: The brief is approved and the code's package dependencies form a complete mesh.

    Likely cause: only a runtime picture was reviewed. Module structure was left to habit.

    Investigation: generate a dependency graph of build modules or packages and compare it to the allowed arrows.

    Corrective action: make the allowed arrows a review rule. Lessons 4 and 5 give you the language for those arrows inside a process. The fix starts by agreeing the arrows are architectural.

    A design review for this lesson is short on purpose. The reviewer asks six questions, in order: Who can veto, and are they named? Which constraints have sources? Which quality intents have a stimulus and a number? What is out of scope? Which decision records an alternative and a reopening condition? Which drawing answers which question? A review that starts with "why not Kubernetes" has skipped the brief.

    Interview Questions and Answers

    Q1. What is software architecture, in a definition you would defend in a design review?

    Architecture is the set of structures needed to reason about the system: elements, the relations among them, and the properties of both. That is the Bass, Clements, and Kazman definition, and it lines up with ISO/IEC/IEEE 42010's emphasis on fundamental properties in an environment. In a review I would immediately name which structures: module (who may depend on whom), component-and-connector (what talks to what at runtime), and allocation (what runs where, owned by whom). A diagram is a view of one of those structures. A framework is a constraint on how we realize them. If the candidate can only name a vendor stack, they have described an implementation preference.

    Q2. Which stakeholders must be named for a learning platform, beyond the product manager?

    At minimum: the learner whose progress must survive a refresh, the instructor whose payout must match the contract, support who needs one correlation id, security and privacy for identity and retention, finance for revenue and refunds, and the on-call engineer who will restore the system. Enterprise buyers appear as soon as tenant isolation is in scope. Each stakeholder is tied to a concern the architecture can violate. A list of job titles with no concern does not change a design. I would also include external systems that impose constraints, such as the identity provider and the payments vendor, because their failure and data rules bound our quality attributes.

    Q3. How do you tell a constraint from a preference?

    A constraint has a source and a consequence for violating it: an assessment, a contract, a staffing plan, a records schedule, an existing system of record the company has already committed to. A preference has enthusiasm and no source. "We like event-driven" is a preference. "Cardholder data remains inside the vendor's PCI segment named in the current assessment" is a constraint. I write the reversal cost next to real constraints so a later team can escalate honestly. I refuse to let preferences into the constraint section, because once they are there they shut down alternatives without authority.

    Q4. What does the architecture lifecycle look like after the first release?

    The same loop as before release: drivers, shape, record, realize, evaluate, revise. After release, evaluation uses the measure the brief named, taken on the path the stakeholder named, under a load that resembles production. A miss, or a new constraint, reopens the decision. The failure mode is a brief that is never read again while connection pools, caches, and retries drift. I treat a missed measure as a successful lifecycle, because it produced a revision. I treat a green dashboard on the wrong path as a failed one.

    Q5. What is a C4 context diagram responsible for, and what should it leave out?

    It shows people and roles, the system as one box, and the external systems the system trusts, with the purpose of each relationship. It answers "what is inside the boundary, and what is outside." It should leave out databases, frameworks, topics, classes, and protocol trivia beyond what the trust relationship needs (HTTPS, OIDC). Those belong to container, component, or code viewpoints. A context diagram that includes a message bus has already chosen a mechanism without a driver.

    Q6. Why can two structures of the same system both be correct and still be insufficient alone?

    Because they answer different questions. A module diagram can correctly forbid catalog from depending on payouts and say nothing about which process will be on call Saturday. An allocation diagram can correctly place one deployable in two zones and say nothing about whether every package may call every other package. Reviewers who bless a single picture have checked one family of concerns. Production incidents tend to land in the family nobody drew.

    Q7. What belongs in a one-page architecture brief before any container diagram?

    Purpose, stakeholders with concerns, constraints with sources, functional scope and an explicit out-of-scope list, quality intents with a stimulus and a measure, and one to three decisions that name an alternative, a consequence, and the evidence that reopens them. The brief should say which view will be drawn next and which question it answers. If the purpose sentence is still disputed, containers are premature. I would rather review a brief with an assumption labeled "assumption" than a precise diagram of the wrong system.

    Q8. A director asks for microservices on the first day of a new product with one squad. How do you answer?

    I separate the preference from the driver. I ask which quality attribute a process boundary serves that a module boundary does not, and who will operate the extra failure domains. If the answer is staffing we do not have, I recommend one deployable, a strict module structure, and a written condition under which we split (for example a saturated resource that is not the one we need to scale, sustained across a named peak). I do not argue from fashion in either direction. Module 4 of this course is where a real driver for distribution gets a full design. Day one with one squad rarely presents that driver.

    Q9. How do functional requirements and quality attributes interact on a funds transfer?

    The function is "move an amount between two accounts the customer owns, and reject an overdraft." The qualities state the conditions: p95 latency at a named peak, no committed transfer lost across a process restart, no negative balance under concurrency, retention for the scheduled years. The function can be implemented with a coarse lock that meets integrity and misses latency, or with a balance cached in memory that meets latency and misses integrity on restart. The architecture decision is which structure buys the quality the stakeholder prioritized, and which quality pays for it. Leaving the qualities implicit means the first implementation that works on a laptop becomes the architecture.

    Q10. What evidence, six months after launch, would convince you the architecture is fit for purpose?

    The measures in the brief, on the paths they named, during a real peak, inside the error budget or latency bound the stakeholder accepted. Plus the absence of a second, shadow architecture: no manual reconciliation that the decision claimed would not be needed, no card data where the constraint forbade it, no module dependency the diagram forbade. A quiet on-call shift helps only if the stakeholder-facing path was actually used. I would also check that reopening conditions were monitored. An architecture that cannot be shown to be wrong cannot be shown to be fit.

    Q11. How should a candidate talk about design patterns in an architecture interview for this kind of system?

    Patterns are local solutions once a structure and a variation are known. Naming "repository" or "outbox" without a driver is pattern tourism. I would point the interviewer at the decision: we needed durable progress without coupling to catalog reads, so we isolated a write path and an idempotency key. If a pattern then reduces the chance we get that wrong, we use it, and we can point to /learn/design-patterns for the mechanics. The architecture interview is about the driver, the trade-off, and the evidence. The pattern interview is a different module of this course.

    Q12. Where do you record a decision so the next team can reverse it?

    In a place the next team will find when they are about to redo the work: next to the brief, and later in an Architecture Decision Record as lesson 10 specifies. The record holds context, the decision, the alternatives, the consequences, and the reopening condition. A wiki page that only has the final picture forces the next team to reverse the decision by accident, in production. Reversibility is part of decision quality. A record that omits the rejected alternative will not survive contact with a new hire who has a blog post.

    Hands-On Exercises

    Exercise: Architecture brief for an online banking slice

    Problem statement. Produce an architecture brief for a retail bank slice: customers open a checking account after identity proofing, and transfer money between accounts they own. Use your own assumptions. Do not copy the Harborline numbers from the walkthrough. The point is the reasoning, not the prose.

    Tasks.

    1. Write the purpose in one sentence and list at least six stakeholders with a concern each. Include an operator and a compliance role.
    2. Separate functional scope from an out-of-scope list of at least four items the diagram must not absorb.
    3. Record at least four constraints. Each needs a source. Mark any item you are tempted to call a constraint and reclassify it as a preference.
    4. Write four quality intents (latency, integrity, availability, auditability). Each needs a stimulus and a numeric measure. Label planning assumptions.
    5. Draw a C4 context diagram and one other structure (module or allocation). State the question each drawing answers.
    6. Record two decisions in the H1 form: driver, alternative rejected, consequence with the stakeholder who pays, evidence that reopens the decision.
    7. Identify two failure modes and one security boundary ("this data does not land here").
    8. Define how you would evaluate the brief before code and six months after launch.

    Expected deliverables. The brief (two pages at most), the two diagrams, the decision records, a short failure and security note, and the evaluation plan.

    Evaluation rubric.

    Assessment areaWeightWhat "good" looks like
    Stakeholders, scope, assumptions15%Concerns can change a design; assumptions are labeled; scope has a boundary
    Structures and diagrams25%Context stays at context altitude; the second diagram answers a different question
    Constraints and intents20%Sources and numbers are present; preferences are not disguised
    Decisions and trade-offs20%Each decision can be wrong on the page and still be reviewable
    Evaluation and failure behavior10%A missed measure has an owner and a path
    Communication10%A stranger can find the reopening condition in under two minutes

    You pass the mechanical bar when BriefReviewer would return an empty list for your intents, constraints, stakeholders, and out-of-scope section. You pass the architecture bar when a reviewer can point to a stakeholder who would be harmed by each decision and you have already named that harm.

    Lesson Summary

    Software architecture is how a team reasons about structures, relations, and properties in front of the stakeholders who will live with them. The purpose is coordination, prediction, and governance of choices that are expensive to undo. A brief that names stakeholders, sourced constraints, and measured quality intents is the artifact this course will keep demanding before any mechanism, pattern, or deployment topology.

    Module, component-and-connector, and allocation structures answer different questions and are allowed to look unlike each other. C4 context is the first view, and it stays coarse. The lifecycle does not end at approval: evaluation of the measure, on the path the stakeholder named, is what makes the brief true or forces a revision.

    You now have the map of the seventy lessons and the difference between this track and the design-principle, design-pattern, and enterprise-architecture primers. Lesson 2 takes the quality intents you wrote here and turns them into scenarios precise enough to drive a design, then shows how those scenarios compete.

    Further Reading

    Ready to mark this lesson complete?Track your journey across the entire course.