Skip to content
peterengineers.ai

Reference Project

The concepts behind a live SaaS product I built and run.

The Reference Project shows two systems whole: one production system, and the engineering system that builds it. That engineering system spans requirements, specification, implementation planning, implementation, tests, review, documentation, delivery and operations, and in every phase agents either do the work or assist with it, so a single engineer can hold every role. It took about six months to build.

The product is a live multi-tenant SaaS platform: several client brands served by three backend services and one frontend monorepo that holds the web app and the native mobile apps. The AI that builds the system and the AI inside the product are two different things, and the diagram keeps them apart. The repositories sit between the two because each one is an agent workspace and — bar the operations repository — a deployable module as well.

The rule

, with a hard line for where: a person approves every decision that cannot be taken back — a write to a production database, a destructive command, a release. The agents propose; the human decides.

Click a box for what it is and why it is set up that way; the sections beneath go deeper.

6 repositories28 agents64 skills10 workflows · own loop framework

Counted on 22 August 2026 across the six repositories and the global agent configuration, together with every count in the system landscape below. Archived agents excluded.

Diagram — Two planes joined by the repositories: the engineering system above, the product system below.
  1. Claude Code harness global agent configuration: agents · skills · commands · workflows · hooks · MCP servers. Claude Code is the engineering harness, and most of the agentic setup lives in one global configuration rather than in any single repository, so the same working method applies to all six: agents defined as roles, skills that carry a procedure, the standing rule that decides which tests get written at all, hooks that block destructive commands, and MCP servers that reach Jira, the IDE and production databases — the last of those read-only. Six of those agents are module experts, one per repository, and a session working in any other repository consults them for facts with file-and-line evidence instead of guessing at a neighbour's codebase. Orchestration runs on top of that: a loop framework that re-runs an unattended agent until a stated completion criterion is met, so a long mechanical pass finishes without a person watching it.
  2. Agent layer in every repository agent instructions · agent-facing docs · repo skills · pre-commit gates. Every repository carries its own agent instructions, and the larger ones carry an agent-facing documentation layer the agent routes through instead of re-deriving the codebase. Repository-local skills do the work only that repository can describe — bootstrapping a white-label brand, generating user documentation from the code, running a deployment — and pre-commit gates with project-specific checks make “correct” something the environment enforces, not something a reviewer remembers. Read on: CI and boundary enforcement
  3. Code hosting & delivery Bitbucket Pipelines · GitHub Actions · registries · image scanning. The backends and the identity server are hosted on Bitbucket and ship through Bitbucket Pipelines: test, build the image, push it to the registry, upgrade the demo release automatically on the main branch; production is a manual, tag-bound step. The frontend monorepo lives on GitHub and ships through GitHub Actions the same way, plus mobile builds and over-the-air updates. Every image goes through a security scan with Trivy, and each Helm chart lives beside the service it deploys. The line the pipelines draw is the one that decides how much can run unattended: everything reversible happens on its own — tests, images, the demo release — and every step that cannot be taken back waits for a person to start it. Read on: A Jira ticket resolved by an agent, with a human in the loop where it matters
  4. Issue tracking & knowledge base Jira epics, stories, tasks and bugs · Confluence processes, requirements and analysis. Jira is the backlog; Confluence holds the release record, the runbooks and the API-spec links. Both are reachable from the agent through an MCP server, so a ticket can be picked up, analysed, implemented and carried to review in one skill, and a production release is recorded by the skill that detected it. Read on: A Jira ticket resolved by an agent, with a human in the loop where it matters
  5. Core-data service Kotlin · Spring Boot · the platform's master data. A Kotlin and Spring Boot service owning the platform's master data: the accounts, the clubs, partners and supporter groups that offer through it, the separate tenants they are grouped into, loyalty, consent and verification, and every outbound notification channel. Its API is spec-first — seven OpenAPI documents are validated and code-generated before anything compiles — and one contract is checksummed against the sibling service that consumes it, so a drift fails the build rather than the integration. Read on: CI and boundary enforcement
  6. Domain service Kotlin · Spring Boot · Spring AI · the product's business logic. The service that carries the product's business logic: the offers a club or a partner puts up, the variants each one is sold as — fixed price, free sign-up, prize draw and, above all, auction — payments and invoicing through two payment providers, and gamification. The auction is the part that is not a generic checkout: a fan bids a maximum rather than a price and the system bids on their behalf up to it, a late bid extends the close so a contest cannot be sniped, and a win settles by card or, above a configured amount, by an invoice raised at close. Every rule that decides who wins and what they pay is enforced here; the apps render the result.
  7. File service Kotlin · Spring Boot · upload, validation, storage. A small service with one job: accept a file, prove it is what it claims to be — sniffing the real type, rejecting an SVG that carries a script and a document that tries to make the server fetch something on its behalf — store it, and link it to the record it belongs to. Files live as rows in the relational store rather than in a blob bucket, a simplicity the current scale allows.
  8. Identity provider Keycloak · open source · OAuth · social login · brand themes. Keycloak is the single identity provider for web, mobile and the backends, extended only where the multi-brand setup needs it: the login page works out which brand’s site the visitor arrived from and points its terms and privacy links there, and thirteen brand themes are colour-and-logo layers over one shared set of templates rather than thirteen sets. One further hook tells the platform’s own backend about a new sign-up. It deploys first and everything else validates its tokens; the admin console sits on a separate, IP-restricted host from the public login, so the surface that can change an identity is not the surface the internet reaches.
  9. Frontend monorepo Next.js web · React Native mobile apps (Expo) · embed SDK. One pnpm and Turborepo workspace holds the Next.js web app that serves every brand host, the mobile app in a platform build and a brand’s own, an Astro operator-documentation site written from the code, an embeddable SDK and the 23 shared packages under them. The cut is the point: a brand’s mobile app is a theme and a configuration entry rather than a new project, because the screens, the routes and the generated API clients are already shared — and those clients come from the backend specs in the sibling checkouts. This is where the agent-first setup is densest, and what it buys is that the expensive knowledge is not carried by anyone: 26 project-specific checks — route parity between the apps, locale parity, brand completeness, design-token use, the freshness of generated config — run before a commit exists, so a mistake surfaces in seconds rather than in a review comment, and a documentation layer for agents, itself validated in CI, means the next change starts from a route rather than a re-derivation. Read on: CI and boundary enforcement
  10. Ops & registry YAML registry · Azure CLI · kubectl · Helm · Expo EAS · GitHub CLI · Application Insights analytics. Not a service: a YAML registry that is the single source of truth for every service, environment and secret reference, the tools that read it, the runbooks, and the docker-compose stack for local development. Every secret is a named reference rather than a value — they reach the cluster as Kubernetes secrets and are held in a vault — so an environment can be wired without anyone reading one. Its skills do operational work: deploy the identity server, cut a mobile build and ship an over-the-air update, query the telemetry and triage what it shows. The same repository carries the security work that has to be answerable rather than remembered: a vulnerability register per repository, refreshed from container scans; an audit of the third-party actions the pipelines are pinned to; a register of who holds production admin access; and the PCI DSS responsibility matrix a card-payment audit asks for, kept honest by its own regression harness. And the erasure request that must remove exactly one person’s data and nothing else is generated by code from explicit inputs, never free-handed by a model.
  11. Managed cloud platform Microsoft Azure · Kubernetes · managed PostgreSQL · Container Registry · Application Insights. One Kubernetes cluster carries a demo and a production namespace: the three backends, the identity server and the web app, behind an nginx ingress with automatic certificates. Every database, identity's included, runs on a managed RDBMS, PostgreSQL. Images live in the Azure registry, telemetry in Application Insights with query-based alerts.
  12. AI inside the product Azure OpenAI · Azure AI Content Safety · Google Vertex AI. The AI the product itself calls — distinct from the AI that builds it. Text generation through Azure OpenAI, moderation through Azure AI Content Safety, and image generation and search-grounded research through Gemini models on Google Vertex AI. All of it is reached from the domain service; the frontends never call a model directly.
  13. Mobile distribution Expo EAS · EAS Update · App Store · Google Play · Firebase. Both mobile apps are built and submitted through Expo's EAS, reach users through the App Store and Google Play, and receive JavaScript updates over the air, which is what puts a fix on installed apps the same day instead of waiting on a store review — the production channel gated by an approval. Expo's push service delivers notifications through APNs and FCM, and a Firebase remote configuration tells an installed app when it must update.
  14. Third-party services Stripe · Payrexx · SendGrid · Google Places · Turnstile · Tag Manager. Payments through Stripe — Checkout, Connect, Tax — and Payrexx; transactional email through SendGrid; address capture through Google Places; bot protection on forms through Cloudflare Turnstile; consent-gated analytics through Google Tag Manager.

An Insight starts in the daily work of building — something met while doing it, and what answering it took. The sections beneath are the other half: the concepts that work produced, as this reference project applies them.

They carry the concept, not the source. An implementation belongs to its stack, and reading it teaches that codebase; the concept is the part that travels — so a skill appears as its own structure with its rules in pseudocode, and a pipeline as its stages. That is what an Insight points at: it argues its topic on its own terms, and where the argument is easier to take with a case in front of it, it links to the section holding one — the same idea, already applied on a real system.