SOFTWARE ARCHITECTURE DOCUMENT
VietGara — Based on the C4 Model
Version 1.3 — October 9, 2026 · Cloud: Google Cloud Platform (GCP) · Backend: Go
Naming. The garage web console is the Owner Web (
vietgara-owner-web, for owners and staff); the platform web console is the Admin Web (vietgara-admin-web, platform admins and admin staff only). All documents use these names.
1. Introduction
1.1. Purpose
This document describes the software architecture of the VietGara platform using the C4 Model (Context, Container, Component, Code) by Simon Brown — a visualization method with 4 increasingly detailed layers, allowing different audiences (business stakeholders, architects, developers) to understand the system at the level of detail relevant to them.
1.2. Reference Documents
- Vision & Scope Document — VietGara
- Functional Requirements Document (FRD) — VietGara
- Architecture Decision Records (ADR) — VietGara
- High-Level Design (HLD), Low-Level Design (LLD) — VietGara
1.3. The 4 Layers of the C4 Model
| Layer | Answers the Question | Primary Audience |
|---|---|---|
| Level 1 — System Context | Where does the system sit in the bigger picture, and who/what does it interact with? | All stakeholders, including non-technical |
| Level 2 — Container | What independently deployable building blocks make up the system (applications, services, databases)? | Architects, DevOps, tech leads |
| Level 3 — Component | What logical components exist inside a container, and how do they interact? | Developers on the team owning that container |
| Level 4 — Code | Class/module/function-level detail — see Low-Level Design (LLD) | Developers writing the code directly |
2. Level 1 — System Context Diagram
The context diagram depicts VietGara as a black box, along with the human actors and external systems that interact with it.
flowchart TB staff["Garage owner & staff<br/>(owner, manager, accountant,<br/>advisor, technician, stock)"] customer["Customer (car owner)"] admin["Platform Admin"] supplier["Supplier<br/>(parts supplier; portal in Phase 17)"] vg[["VIETGARA SYSTEM<br/>Multi-tenant SaaS"]] einv["E-invoice provider<br/>(VNPT / Viettel)"] pay["Payment gateway<br/>(VNPay / Momo / ZaloPay)"] ins["Insurance company<br/>(PVI / PTI / ...)"] mail["E-mail delivery<br/>(Mailjet)"] google["Google (OAuth sign-in)"] staff -->|uses Owner Web / Owner App / Technician App| vg customer -->|uses Customer App| vg admin -->|uses Admin Web / Admin App| vg supplier -->|"receives purchase orders; uses the Supplier Portal (Phase 17)"| vg vg -->|issues invoices via API| einv vg -->|payments, webhooks| pay vg -->|sends claims| ins vg -->|sends OTP & notification e-mail| mail vg -->|verifies sign-in| google
2.1. Actors & External Systems
| Name | Type | Interaction Description |
|---|---|---|
| Garage owner / staff | Human actor | Uses the Owner Web console (and, for owners, the Owner App) to run daily operations |
| Customer (car owner) | Human actor | Uses the Customer App to approve quotes, track progress, and pay |
| Technician | Human actor | Uses the Technician App to receive and update repair orders |
| Supplier | Human actor | A business that sells parts to the garage. Receives the garage’s purchase orders by print or e-mail; from Phase 17, as a linked supplier user, uses the Supplier Portal to confirm orders and attach delivery notes. Never uses the Owner Web, the Admin Web or the Customer App |
| Platform Admin | Human actor | Operates the platform through the Admin Web: subscription plans, subscriptions, monitoring |
| E-invoice provider | External system | VNPT/Viettel — receives invoice issuance requests via API |
| Payment gateway | External system | VNPay/Momo/ZaloPay — processes payments, sends confirmation webhooks |
| Insurance company | External system | PVI/PTI/Bao Viet — receives claim records (via API or manually) |
| E-mail delivery | External system | Mailjet — delivers OTP, invitation and notification e-mails (ADR-011) |
| External system | OAuth 2.0 sign-in with a Google account |
3. Level 2 — Container Diagram
The container diagram shows the independently deployable building blocks (runnable applications/databases) that make up VietGara, and the communication protocols between them.
flowchart TB
web["Owner Web<br/>React/TS"] & padm["Admin Web<br/>React/TS"] & oapp["Owner App<br/>Flutter"] & aapp["Admin App<br/>Flutter"] & capp["Customer App<br/>Flutter"] & tapp["Technician App<br/>Flutter, offline-first"] & sportal["Supplier Portal<br/>planned, Phase 17"] -->|HTTPS REST/JSON| gw["API Gateway<br/>Kong on GKE<br/>TLS, routing, rate limiting"]
gw -->|REST| svc
subgraph svc["Business services (Go) — one modular monolith in Phase 1"]
direction LR
idn[Identity] --- ten[Tenant/Garage] --- lic[License] --- cus[Customer & Vehicle]
quo[Quote] --- rep[Repair Order] --- inv[Inventory] --- bil[Billing & Settlement]
rec[Receivables] --- insr[Insurance, Phase 17] --- payad[Payment Adapter] --- einv[E-Invoice]
cat[Catalogue] --- bkg[Booking] --- fil[Files]
doc[Document] --- noti[Notification] --- rpt[Reporting] --- bff[BFFs: Customer / Technician]
end
svc -->|outbox relay| kafka[("Kafka<br/>event bus")]
kafka -->|consumer groups| svc
svc --> sql[("Cloud SQL PostgreSQL<br/>RLS by garage_id")]
svc --> redis[("Memorystore Redis<br/>sessions, OTP, entitlement cache")]
svc --> gcs[("Cloud Storage<br/>logos, PDFs, photos")]
Release 1.1 as deployed. The first four modules run in one Go process. REST requests are translated by grpc-gateway inside the process and pass through the same gRPC interceptor chain as gRPC calls:
flowchart LR web[Owner Web] -->|/api/v1| kong[Kong] padm[Admin Web] -->|/api/v1| kong kong --> http["HTTP :8080<br/>grpc-gateway"] http -->|in-memory gRPC| chain["Auth → EmailVerified →<br/>PlatformAdmin → Garage<br/>(tx + RLS scope + access + license)"] grpc["gRPC :50051"] --> chain chain --> mods["identity · tenant · license · customer"] mods --> pg[(PostgreSQL)] mods --> rd[(Redis)] mods -->|outbox| kf[(Kafka)] mods --> mj[Mailjet / Mailpit] mods --> st[GCS / local disk]
3.1. Container List
| Container | Technology | Responsibility |
|---|---|---|
Owner Web (vietgara-owner-web) | React + TypeScript | Web console of the garage for its owners and staff (owner, manager, accountant, advisor, stock staff); not for platform admins |
Admin Web (vietgara-admin-web) | React + TypeScript | Web console for VietGara’s platform admins and admin staff: plans and subscriptions (FR-LIC-05). Separate deployable, separate host; calls the same API under /api/v1/admin/* |
Web UI kit (vietgara-web-ui) | React + TypeScript, Tailwind v4, Radix UI | Library, not a deployable: design tokens (light/dark), components and shell shared by the Owner Web and the Admin Web; compiled into each app’s static bundle |
Owner App (vietgara-owner-app) | Flutter (iOS/Android) | Mobile app for garage owners on the same REST API as the Owner Web: dashboard, quotes, repair orders, receivables (Phase 2, Release 2.0) |
Admin App (vietgara-admin-app) | Flutter (iOS/Android) | Mobile app for VietGara operators on the /api/v1/admin/* API: plans, subscriptions (Phase 2, Release 2.1), platform dashboards (Phase 12) |
| Supplier Portal (planned, Phase 17) | Web, a separate surface and host | For the Supplier actor: the purchase orders addressed to a linked supplier user, confirm or decline lines, attach delivery notes and invoices (FR-SUP-02/03). Uses the same API under /api/v1/me/supplier-links/* and sees only documents addressed to its supplier; not part of the Customer App |
Customer App (vietgara-customer-app) | Flutter (iOS/Android) | Approve quotes, track progress (Phase 11); book appointments (Phase 12); pay and receive invoices (Phase 16) |
Technician App (vietgara-technician-app) | Flutter, offline-first | Receive/update repair orders, take photos, sync when online |
| API Gateway | Kong on GKE | Single entry point: TLS termination, routing, request-size limits, rate limiting (Release 8.0). Token validation and authorization happen in the backend interceptors |
| 21 business modules | Go, containerized, running on GKE Autopilot — one modular-monolith deployment in Phase 1 (ADR-001) | See the detailed list in HLD, Section 3. gRPC and REST (grpc-gateway, ADR-010) from the vietgara-proto contracts |
| Event Bus | Apache Kafka (managed) | Asynchronous inter-module communication through the transactional outbox (see Event Design, ADR-004) |
| Cloud SQL (PostgreSQL) | Managed database; one database for the modular monolith, one per service once split (ADR-008) | Business data storage, RLS by garage_id through a non-bypass application role |
| Memorystore | Managed Redis | Refresh-token sessions, OTPs, entitlement cache, daily transaction counters |
| Cloud Storage | Object storage | Garage logos, part images, PDFs, e-invoices, repair photos, claim documents. Keys garages/{garageId}/{kind}/{entityId}/{uuid}.{ext}, registered in the files table; private kinds only through signed URLs |
4. Level 3 — Component Diagram (Illustrative Example)
The C4 Model recommends drawing a Component Diagram for the most important/complex container rather than the entire system. Below is an example for the Billing & Settlement service — the service with the most complex business flow (a Saga spanning multiple services).
flowchart TB
subgraph c["Container: Billing & Settlement Service (Go)"]
h[gRPC handler] --> uc[Settlement use case]
uc --> ae["Payment and voucher rules<br/>(single payer; insurer split in Phase 17)"]
uc --> repo[Settlement repository]
uc --> ow["Outbox writer<br/>(same transaction)"]
relay["Outbox relay<br/>(background worker)"]
end
repo --> db[("Cloud SQL<br/>settlements, settlement_lines")]
ow --> ob[("outbox_events")]
ob --> relay --> k[(Kafka)]
The detailed logic inside each component (algorithms, internal data structures) is presented in the Low-Level Design (LLD), Section 2 — Billing & Settlement Service.
5. Level 4 — Code
The Code layer (class diagrams, specific function signatures) is not repeated in the SAD to avoid duplication and rapid staleness as the code changes — see the Low-Level Design (LLD) for the core services, and the source code/gRPC reflection as the ultimate source of truth.
6. Mapping to Architecture Decision Records
The decisions underlying the architecture described above are recorded in detail in a dedicated ADR document, and the analysis is not repeated here:
| Architectural Aspect | Related ADR |
|---|---|
| Overall architecture style (Modular Monolith → Microservices) | ADR-001 |
| Cloud provider (GCP) | ADR-002 |
| Backend language (Go) | ADR-003 |
| Message broker (Kafka) | ADR-004 |
| Multi-tenancy model (Hybrid, tenant = garage_id) | ADR-005 |
| Internal communication (gRPC/Protobuf) | ADR-006 |
| REST generated from gRPC contracts (grpc-gateway) | ADR-010 |
| Transactional e-mail (Mailjet) | ADR-011 |
| Identity provider (in-house Identity module) | ADR-007 |
| Primary database (Cloud SQL for PostgreSQL) | ADR-008 |
| Container orchestration (GKE Autopilot) | ADR-009 |