Architecture overview¶
The FSH stack is a codegen pipeline. Declarative Jsonnet configs (Pydantic-validated) compile through a target-agnostic engine into a FastAPI backend, a typed React frontend, an OPA/Rego policy service, and a render sidecar. Generated apps pull shared logic from runtime libraries at load time; infra provisions the AWS/GitHub substrate.
See getting started to stand a project up.
How it fits together¶
The codegen engine holds no framework knowledge: it discovers scopes, orders operations,
walks the config tree, and renders Jinja templates, then hands off to target plugins
(in codegen-targets) that emit the be/fe/opa/render source. Generated code never
re-templates shared logic — the backend calls into fsh-lib, the frontend consumes
@fsh/components-library, the render sidecar consumes @fsh/codegen-render. infra deploys
the result.
jsonnet config
│ codegen (engine) + codegen-targets (be/fe/opa/render plugins)
▼
generated app: be/ fe/ opa/ render/
│ at runtime: fsh-lib (BE) · @fsh/components-library (FE) · @fsh/codegen-render (render)
▼
deployed by infra (OpenTofu + Terragrunt) → AWS ECS/Aurora/ALB + static FE
Who owns what¶
The same split holds for every feature; each guide’s How it works only notes its feature-specific exceptions.
You write:
SQLAlchemy models (and their migrations).
The jsonnet config (
be/config/*.jsonnet,fe/config/fe.jsonnet) — the declarative source of truth.Python glue the config references by dotted path: pre/post hooks,
canguards, action handlers, serializers, comms transports/renderers/resolvers, OPA loaders, auth domain types.The Rego rules, and the safe-to-edit FE scaffolds — field catalogs, enum displays, action modules, pages.
Codegen generates — never edit:
The BE routes/handlers, pydantic request/response schemas, serializers, and the OpenAPI spec.
The OPA baseline (RBAC + schemas) and each resource’s
_generated/{module}/….The whole TypeScript client —
types,sdk,queries,tables, action catalogs, the auth bridge — underfe/src/_generated/.
Two write modes: everything under _generated/ is overwritten every run;
scaffolds (if_exists=skip) are written once, then yours. Each guide’s code
labels — Generated (do not edit), Scaffolded, safe to edit, You
write — mark which is which.
The repositories¶
Repo |
Kind |
Deployed by infra? |
What it does |
|---|---|---|---|
|
tool |
no (published lib/CLI) |
Target-agnostic generation engine (pkg |
|
tool |
no (published libs) |
uv workspace of target plugins under |
|
tool |
no (published lib/CLI) |
Dimension configs → SQLAlchemy models + Alembic migrations (pkg |
|
runtime lib |
no (published to CodeArtifact) |
Publishes |
|
design system |
no (published to CodeArtifact) |
|
|
generated app |
yes — |
Kitchen-sink reference app (be/opa/render ECS + static FE); round-trip validation harness. |
|
generated app |
yes — |
Deployed sales-domain app: FastAPI + pgqueuer worker ( |
|
generated app |
no (source/CI only) |
Clone-and-fork starting point; |
|
tool |
no (published |
|
|
tool |
no (published |
Package manager for |
|
tool |
no (source/CI only) |
Shared |
|
tool (docs) |
yes — |
This Sphinx/MyST docs hub; cross-cutting stack concepts. |
|
infra service |
yes — scheduled runner |
Self-hosted Renovate config + cron; opens dependency-bump PRs org-wide. |
|
infra |
self |
OpenTofu + Terragrunt IaC; the control plane for everything below. |
codegen— the engine; depends only on generic tooling (typer,pydantic,jsonnet,jinja2). Every target repo depends on it via thecodegen.targetsentry-point group.codegen-targets— the six plugins holding all framework knowledge (FastAPI/SQLAlchemy, openapi-ts + react-query, Rego RBAC, render service,*-rootbootstraps).python-lib/fsh-lib— the BE “libc”: byte-identical across generated apps; its public signatures are an ABI version-coupled to thebetemplates.components-library— the FE analog: design system plus the render library whose openapi-ts plugin turns the BErender-contract.openapi.jsoninto per-template types.infra— Terragrunt + OpenTofu; deploy target and control plane for all siblings (it even declares the GitHub repos themselves).
What infra tracks¶
infra is a Terragrunt + OpenTofu (Terragrunt Stacks) monorepo. Each environment is its
own vended AWS account under a management account that owns the AWS Org. It enumerates
every org repo in live/source-code (teams, branch protection, CI deploy keys), wires
per-repo CodeArtifact publish/read roles in live/package-registry, deploys
codegen-example-app and sales-pipeline as full per-tier stacks
(VPC/Aurora/ECS/ALB/ECR/S3) under live/internal, and publishes Cloudflare Pages docs
sites via live/docs. See infrastructure for detail.