← All work
ComplianceBot AI - Multi-Tenant SaaS - cover
02 / 04
AI SaaS
Case study

AI SaaS · Armadillo Safety Solutions

Role: Architected the full-stack applicationLive ↗
Next.js 15React 19TypeScriptSupabaseGoogle GeminiVercel AI SDKZodReact Hook FormZustand

Problem

Construction and infrastructure projects need Method Statements and compliance documents - formal descriptions of work procedures, safety measures, and risk assessments. Drafting them by hand is slow, inconsistent, and error-prone. The brief: build a SaaS that conducts an adaptive AI interview with the site engineer and assembles the document from structured answers.

Your scope

End-to-end architecture: multi-tenant data model on Supabase, the section-by-section interview engine, schema-driven AI integration, the document assembly pipeline, auth, and the entire frontend.

System architecture

Next.js 15 full-stack with Supabase for multi-tenant persistence and Google Gemini (via Vercel AI SDK) for structured LLM output. Each document section (PCI extraction, impact assessment, method statement, risk assessment) has its own API route with a section-specific system prompt and an output schema. Conversation history is windowed and summarised to stay inside model token budgets across long interviews.

Fig. 2 - Schema-driven AI pipeline with tenant isolation via Supabase RLS.

Key decisions

  • Zod schemas double as runtime validators and TypeScript types for AI outputs. Considered hand-written types + ad-hoc JSON checks; rejected - drift between types and validation is a category of bug we wanted to eliminate.
  • One API route per document section, not one giant prompt. Considered a single monolithic agent; rejected - each section has different evidence requirements, different schemas, and different prompts. Splitting makes prompts maintainable and outputs predictable.
  • Conversation history windowing + summarisation, not a sliding raw window. Construction interviews can run to dozens of turns; raw history burns tokens. Periodic summarisation keeps context dense and cheap.

Engineering challenges

  • Ensuring LLM outputs conform to strict document schemas required by industry standards.
  • Maintaining conversational context across multi-section interviews without exceeding token limits.
  • Validating and transforming unstructured AI output into typed, composable document sections that the renderer can assemble.

Solutions

  • Zod schemas for each section: used both for runtime validation of AI output and for TypeScript type inference at call sites. One source of truth.
  • Conversation history windowing with periodic summarisation to control token budgets across multi-section interviews.
  • Dedicated API routes (/api/ms/chat, /api/ms/generate-section, /api/ms/extract-pci, /api/ms/evaluate-impact) each with section-specific system prompts and output schemas.
  • Multi-tenant isolation through Supabase row-level security, enforced at the database layer.

What I'd change

Stack

  • Frontend - Next.js 15 (App Router), React 19, TypeScript, Tailwind, Zustand, React Hook Form
  • Data & Auth - Supabase (Postgres + RLS + Auth)
  • AI - Google Gemini via Vercel AI SDK, Zod-validated structured output
  • Deploy - Vercel