# Canonical Example This example demonstrates how the ABC Pattern structures a real application using only: * Constructs (ABC‑C0) * Application Stack (ABC‑C1) * Logical Units (ABC‑C2) * Resource Groups (ABC‑C3) * Input/Output Contracts (ABC‑C4, ABC‑C5) * Instantiation Interface (ABC‑C6) * Capturing Down (ABC‑C7) * Bubbling Up (ABC‑C8) Every interaction is explicit. Every dependency is visible. Nothing leaks sideways. ## Overview We model a classic 3‑tier architecture: * Data Tier - database + storage * Logic Tier - compute + messaging * Presentation Tier - CDN + web frontend Each tier is a Logical Unit (ABC‑C2). Each component inside a tier is a Resource Group (ABC‑C3). The Application Stack (ABC‑C1) composes them, wires them, and exposes the final outputs. ## Conceptual Diagram ```default ┌──────────────────────────────┐ │ Application Stack │ │ (ABC‑C1) │ └─────────────┬────────────────┘ │ ┌──────────────────────┼────────────────────────┐ │ │ │ ┌───────▼────────┐ ┌───────▼────────┐ ┌─────────▼────────┐ │ DataUnit │ │ LogicUnit │ │ PresentationUnit │ │ (C2) │ │ (C2) │ │ (C2) │ └───────┬────────┘ └───────┬────────┘ └────────┬─────────┘ │ │ │ │ │ ┌────────│──────┐ ┌────▼─────┐ ┌────▼─────┐ ┌────▼──────┐ ┌──────▼─────┐ │StorageGrp│ │ComputeGrp│ │WebAppGrp │ │ CDNGrp │ │ (C3) │ │ (C3) │ │ (C3) │ │ (C3) │ └──────────┘ └──────────┘ └───────────┘ └────────────┘ ``` ## Application Stack (ABC‑C1) The Application Stack is the root construct. It has no parent and defines the deployment boundary. ### Responsibilities * Instantiate each Logical Unit (ABC‑R1). * Provide downward inputs (ABC‑F1). * Receive upward outputs (ABC‑F2). * Route outputs between Logical Units (ABC‑R44). * Expose a final Output Contract representing the whole system. ### Input Contract (ABC‑C4) The Application Stack receives only global configuration: ```default AppStackInputs: environment: string region: string global_tags: map ``` ### Output Contract (ABC‑C5) The Application Stack exposes: ```default AppStackOutputs: frontend_url: string api_endpoint: string ``` These values originate from the Presentation and Logic tiers, respectively. ## Logical Units (ABC‑C2) Each Logical Unit encapsulates a functional domain. They do not know about each other. They communicate only through the Application Stack. We define three: * DataUnit * LogicUnit * PresentationUnit Each has its own Input/Output Contracts and internal Resource Groups. ### Data Logical Unit (ABC‑C2) #### Purpose Provide persistent storage and database capabilities. #### Resource Groups (ABC‑C3) * StorageGroup - object storage * DatabaseGroup - relational database #### Input Contract ```default DataUnitInputs: environment: string region: string storage_class: string db_engine: string db_instance_size: string ``` #### Output Contract ```default DataUnitOutputs: storage_bucket_name: string database_endpoint: string ``` #### Internal Wiring * StorageGroup produces `storage_bucket_name`. * DatabaseGroup produces `database_endpoint`. * DataUnit aggregates both and bubbles them up (ABC‑F2). #### NOTE * StorageGroup and DatabaseGroup do not know about each other (ABC‑R10). * All configuration flows downward from DataUnit (ABC‑F1). ### Logic Logical Unit (ABC‑C2) #### Purpose Provide compute and messaging capabilities for the application backend. #### Resource Groups * ComputeGroup - application compute (e.g., functions, containers) * MessagingGroup - queue or pub/sub system #### Input Contract ```default LogicUnitInputs: environment: string region: string compute_size: string message_retention: number database_endpoint: string # Provided by DataUnit via AppStack ``` #### Output Contract ```default LogicUnitOutputs: api_endpoint: string message_queue_url: string ``` #### Internal Wiring * ComputeGroup receives `database_endpoint` via Capturing Down (ABC‑F1). * MessagingGroup is independent. * LogicUnit aggregates outputs and bubbles them up. #### NOTE * LogicUnit does not know where the database came from. * It only knows it received a database_endpoint in its Input Contract (ABC‑R22). ### Presentation Logical Unit (ABC‑C2) #### Purpose Serve the frontend and expose the public entry point. #### Resource Groups * CDNGroup - global content distribution * WebAppGroup - static or dynamic frontend #### Input Contract ```default PresentationUnitInputs: environment: string region: string frontend_assets_bucket: string api_endpoint: string # Provided by LogicUnit via AppStack ``` #### Output Contract ```default PresentationUnitOutputs: frontend_url: string ``` #### Internal Wiring * WebAppGroup receives `api_endpoint` via Capturing Down. * CDNGroup receives the output of WebAppGroup. * PresentationUnit bubbles up the final `frontend_url`. ## Resource Groups (ABC‑C3) Each Resource Group is a small, focused construct with: * A minimal Input Contract * A minimal Output Contract * No knowledge of siblings * No access to parent state except via inputs * No side effects during instantiation (ABC‑R33) ### Example: Database Group #### Input Contract ```default DatabaseGroupInputs: db_engine: string db_instance_size: string environment: string ``` #### Output Contract ```default DatabaseGroupOutputs: database_endpoint: string ``` #### Instantiation Interface ```default new DatabaseGroup(DatabaseGroupInputs) -> DatabaseGroupOutputs ``` This pattern repeats for all Resource Groups. ## Full Data Flow (ABC‑F1 and ABC‑F2) The complete data flow includes: * AppStack → Logical Units * Logical Units → Resource Groups * Resource Groups → Logical Units * Logical Units → AppStack This is the full vertical chain required by the ABC Pattern. ### Downward Flow (Capturing Down — ABC‑F1) 1. AppStack → DataUnit : * `environment` * `region` * `storage_class` * `db_engine` * `db_instance_size` 2. DataUnit → StorageGroup : * `environment` * `region` * `storage_class` 3. DataUnit → DatabaseGroup : * `environment` * `db_engine` * `db_instance_size` 4. AppStack → LogicUnit > * `environment` > * `region` > * `compute_size` > * `message_retention` > * `database_endpoint` (bubbled up from DataUnit) 5. LogicUnit → ComputeGroup : * `environment` * `compute_size` * `database_endpoint` 6. LogicUnit → MessagingGroup : * `environment` * `message_retention` 7. AppStack → PresentationUnit : * `environment` * `region` * `frontend_assets_bucket` * `api_endpoint` (bubbled up from LogicUnit) 8. PresentationUnit → WebAppGroup : * `environment` * `frontend_assets_bucket` * `api_endpoint` 9. PresentationUnit → CDNGroup : * `environment` * `webapp_origin_url` (bubbled up from WebAppGroup) ### Upward Flow (Bubbling Up — ABC‑F2) 1. StorageGroup → DataUnit : * `storage_bucket_name` 2. DatabaseGroup → DataUnit : * `database_endpoint` 3. DataUnit → AppStack : * `storage_bucket_name` * `database_endpoint` 4. ComputeGroup → LogicUnit : * `api_endpoint` 5. MessagingGroup → LogicUnit : * `message_queue_url` 6. LogicUnit → AppStack : * `api_endpoint` * `message_queue_url` 7. WebAppGroup → PresentationUnit : * `webapp_origin_url` 8. CDNGroup → PresentationUnit : * `frontend_url` 9. PresentationUnit → AppStack : * `frontend_url` ## Rationale This example demonstrates: * Strict encapsulation * Explicit dependencies * No lateral references * Deterministic wiring * Testability at every level * Predictable evolution * Agent‑friendly structure It is the canonical reference for all profiles (CDK, Terraform, etc.).