--- marp: true theme: gaia class: invert paginate: true title: How to implement a TAPPaaS module description: Walk-through of adding a new module to the TAPPaaS repository --- # How to implement a TAPPaaS module From empty directory to merged pull request --- ## Who this is for - You want to add an **app** or a **foundation** capability to TAPPaaS - You can read shell, JSON, and a little Nix - You have a TAPPaaS test environment you are allowed to break **Prerequisites** - A clone of `TAPPaaS/TAPPaaS`, branch `TODO: ADR007 or stable` - SSH access to a test site - `TODO: tooling list` --- ## Vocabulary in 60 seconds | Term | Means | | --- | --- | | **Module** | One installable unit under `src/apps/` or `src/foundation/` | | **Service** | A part of a module with its own lifecycle scripts | | **Manager** | Owns desired state for a domain | | **Controller** | Applies desired state to one concrete technology | `TODO: tighten against ADR-007 taxonomy; drop the terms that do not matter here` --- ## Anatomy of a module ```text src/apps// ├── README.md # what it is, why it exists ├── DESIGN.md # how it is put together ├── INSTALL.md # operator-facing install notes ├── UPGRADE.md # operator-facing upgrade notes ├── AUTHORS.md # who to ask ├── LICENSE ├── .json # declaration: the module's contract ├── .nix # runtime definition ├── install.sh # create it ├── update.sh # move it forward ├── test.sh # prove it works └── services// # per-service install/update/test/delete ``` --- ## The path from nothing to merged ```mermaid flowchart LR A[Scaffold from
00-Template] --> B[Declare
module.json] B --> C[Define runtime
module.nix] C --> D[install.sh] D --> E[services/] E --> F[update.sh] F --> G[test.sh] G --> H[Docs] H --> I[PR + CI] ``` --- ## Step 1 — Scaffold ```bash cp -r src/apps/00-Template src/apps/ ``` - Rename `template.json` → `.json`, `template.nix` → `.nix` - Read `README-template.md`, then delete it - `TODO: is there a scaffold script? if not, should there be?` --- ## Step 2 — Declare the module `.json` ```json { "TODO": "smallest working declaration" } ``` - What the module *is*, not how it is built - `TODO: required keys, optional keys, validation` --- ## Step 3 — Define the runtime `.nix` ```nix # TODO: minimal example ``` - `TODO: what belongs in nix vs. what belongs in install.sh` --- ## Step 4 — `install.sh` - Idempotent: safe to run twice - Fails loudly, never half-way - `pre-install.sh` when something must exist first ```bash # TODO: skeleton with the house conventions ``` --- ## Step 5 — Services ```text services//install-service.sh services//update-service.sh services//test-service.sh services//delete-service.sh ``` - One service = one thing with its own lifecycle - `TODO: when to split into services vs. keep it in the module` --- ## Step 6 — `update.sh` - Upgrade in place, no data loss - Version pinning: `TODO` - Rollback story: `TODO` --- ## Step 7 — `test.sh` - Runs against a real environment, not a mock - Exit non-zero on failure, quiet on success - `TODO: what CI runs, and what only a human can check` --- ## Step 8 — Documentation | File | Answers | | --- | --- | | `README.md` | What is this and why would I install it? | | `DESIGN.md` | How is it built, what were the trade-offs? | | `INSTALL.md` | How do I install it, step by step? | | `UPGRADE.md` | What breaks between versions? | Docs are synced to the docs site — a missing README is a missing page. --- ## Try it on a test site ```bash # TODO: the real loop ``` 1. Deploy to the test environment 2. Run `test.sh` 3. Break it on purpose, run it again --- ## Submit - Branch: `TODO: naming convention` - One module per pull request - CI must be green - Review checklist: - [ ] Idempotent install - [ ] `test.sh` passes on a clean site - [ ] Docs complete - [ ] `TODO` --- ## Pitfalls - `TODO: the three mistakes reviewers actually see` - `TODO` - `TODO` --- ## Where to go next - `src/apps/00-Template/` — the canonical starting point - `docs/ADR/ADR-007 - TAPPaaS Taxonomy.md` - `TODO: contribution guide link` **Questions?**