Skip to content

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

LayerAnswers the QuestionPrimary Audience
Level 1 — System ContextWhere does the system sit in the bigger picture, and who/what does it interact with?All stakeholders, including non-technical
Level 2 — ContainerWhat independently deployable building blocks make up the system (applications, services, databases)?Architects, DevOps, tech leads
Level 3 — ComponentWhat logical components exist inside a container, and how do they interact?Developers on the team owning that container
Level 4 — CodeClass/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

NameTypeInteraction Description
Garage owner / staffHuman actorUses the Owner Web console (and, for owners, the Owner App) to run daily operations
Customer (car owner)Human actorUses the Customer App to approve quotes, track progress, and pay
TechnicianHuman actorUses the Technician App to receive and update repair orders
SupplierHuman actorA 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 AdminHuman actorOperates the platform through the Admin Web: subscription plans, subscriptions, monitoring
E-invoice providerExternal systemVNPT/Viettel — receives invoice issuance requests via API
Payment gatewayExternal systemVNPay/Momo/ZaloPay — processes payments, sends confirmation webhooks
Insurance companyExternal systemPVI/PTI/Bao Viet — receives claim records (via API or manually)
E-mail deliveryExternal systemMailjet — delivers OTP, invitation and notification e-mails (ADR-011)
GoogleExternal systemOAuth 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

ContainerTechnologyResponsibility
Owner Web (vietgara-owner-web)React + TypeScriptWeb 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 + TypeScriptWeb 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 UILibrary, 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 hostFor 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-firstReceive/update repair orders, take photos, sync when online
API GatewayKong on GKESingle entry point: TLS termination, routing, request-size limits, rate limiting (Release 8.0). Token validation and authorization happen in the backend interceptors
21 business modulesGo, 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 BusApache 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
MemorystoreManaged RedisRefresh-token sessions, OTPs, entitlement cache, daily transaction counters
Cloud StorageObject storageGarage 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 AspectRelated 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