KgwariC4 Architecture

Architecture Portfolio · C4 Model

Kgwari — a multi-repo TypeScript product

Context, container and component diagrams for the repositories that compose one cross-platform wine-discovery product: a universal client, a serverless API, and the versioned contract surface between them.

AUTHOR   Edward Seshoka
NOTATION   C4-PlantUML
SCOPE   3 repos · 10 diagrams
REVISED   July 2026

A note on names. The product is Kgwari; the repositories, CDK stacks and AWS resources still carry the earlier morara- prefix. The rename is deliberate and in flight, so this document uses the product name in prose and the literal repository and resource names everywhere they are the thing you would actually type.

00

The Platformfive repositories · one product · one AWS region

TypeScript AWS af-south-1 dev · beta · production GitHub Actions OIDC

0 — OverviewRepositories and the runtime they produce

Two repositories are deployed and run; one publishes the contract surface they both compile against; two carry the written record and this document. Only the first two exist at runtime.

pf-platform diagram
PlantUML source
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml

LAYOUT_WITH_LEGEND()
HIDE_STEREOTYPE()
skinparam backgroundColor #FFFFFF
skinparam defaultFontName "Inter"
skinparam shadowing false

title Kgwari — Platform Overview (five repositories, one product)

Person(member, "Member", "Enthusiast or collector.\nDiscovers, cellars, records verdicts.")
Person_Ext(verified, "Verified Account", "Professional · producer · distributor.\nEarns a trust mark; carries the byline.")
Person_Ext(maintainer, "Maintainer", "Authors changesets · merges Version Packages · deploys per-env")

System_Boundary(runtime, "Kgwari runtime (AWS af-south-1 · dev · beta · production)") {
  System(frontend, "Kgwari Client", "morara-frontend-app\nUniversal Expo app — web today, iOS/Android prepared")
  System(backend, "Kgwari API", "morara-backend-app\nServerless TypeScript · 12 Lambdas · 7 DynamoDB tables")
}

System_Ext(cognito, "Amazon Cognito", "User pool · passkeys + OTP · JWT issuer")

System(shared, "morara-shared", "Six published packages under @edwardseshoka\ncontracts · foundation · samples · capabilities · adapters")
System_Ext(ghpkg, "GitHub Packages", "Private npm registry (@edwardseshoka scope)")

System_Ext(docs, "kwari-docs", "Single source of truth for design & architecture.\nApp repos keep pointer stubs only.")
System(portfolio, "morara-portfolio", "This document.\nStatic S3 + CloudFront one-pager.")

Rel(member, frontend, "Uses", "HTTPS")
Rel(verified, frontend, "Publishes provenance & editorial", "HTTPS")
Rel(frontend, backend, "Calls REST API", "HTTPS / JSON · Bearer JWT")
Rel(frontend, cognito, "Passkey / OTP sign-in", "SRP · JWT")
Rel(backend, cognito, "Verifies JWTs · admin OTP broker", "JWKS · cognito-idp")

Rel(shared, ghpkg, "Publishes changed packages only", "Changesets")
Rel_Back(ghpkg, frontend, "Installs contracts / samples / capabilities", "build-time")
Rel_Back(ghpkg, backend, "Installs contracts / samples / adapters", "build-time")

Rel(maintainer, shared, "Versions & releases")
Rel(maintainer, docs, "Writes the design record")
Rel_U(docs, runtime, "Governs the layering both repos follow", "review-time")
Rel(maintainer, portfolio, "Publishes")

@enduml
Why five

The split is drawn along release cadence, not along technology. morara-frontend-app and morara-backend-app deploy on their own schedules into the same three AWS environments; morara-shared is the only thing both compile against, so it is published rather than vendored, and a breaking change there has to announce itself as a semver major before either consumer can pick it up.

The two non-runtime repositories exist to stop duplication. kwari-docs is the single source of truth for design and architecture — the app repos keep pointer stubs at docs/<name>.md naming the canonical location, so a developer still finds their way without a second copy that can drift. morara-portfolio is this site: a private S3 bucket behind CloudFront with Origin Access Control, deployed by the same OIDC-assumed-role pattern as everything else.