How akncodes/ai-spend-audit works
1. This is a Next.js 15 App Router application organized around a single business flow: collect AI tool/spend data, analyze it, persist the audit, and expose a shareable result link. The codebase is split cleanly into route handlers, domain logic, service wrappers, and reusable UI.
2. The main user-facing surfaces are:
• / for the landing page
• /scan for entering team spend/tool usage
• /audit/results/[slug] for the authenticated/internal results view
• /audit/share/[slug] for a public share page
The app/(audit) route group keeps the audit experience together without changing URLs.
3. Input collection is handled by components/forms/SpendForm.tsx and ToolSelector.tsx, with form-schemas.ts providing validation rules. The repo uses Zod + React Hook Form, so validation happens before the request reaches the API layer.
4. The server API surface is small and purpose-built:
• POST/GET /api/audit for creating an audit
• GET /api/audit/[slug] for retrieving an existing audit by share slug
• /api/tools for the supported tool catalog
• /api/leads for capturing interested users
• /api/health for deployment/liveness checks
These route handlers are the boundary between the browser and the server-side domain logic.
5. lib/audit-engine.ts is the core business logic. It appears to be the deterministic scoring layer that decides whether a team is overpaying, calculates savings opportunities, and produces the audit findings. The presence of a dedicated unit test file for it suggests this logic is meant to stay pure and well-covered.
6. lib/audit-service.ts likely orchestrates the full audit lifecycle: accept normalized form data, invoke the audit engine, store the audit result, and return the slug used for sharing. This is the main application service that connects business rules to persistence and external services.
7. lib/ai-service.ts is the content-generation boundary. Per the README, Anthropic is used for summaries, so the audit likely combines deterministic savings analysis with an AI-written explanation or executive summary. This keeps the model-driven text separate from the scoring logic.
8. Persistence and integration are centralized:
• lib/supabase.ts encapsulates Supabase access
• Supabase provides the backing data store for audits and related records
• lib/email-service.ts handles outbound email, using Gmail/Nodemailer per the README
• lib/tools-config.ts provides the supported AI tools and their pricing/plan metadata
This makes the repo easy to diagram as “app → service layer → external providers.”
9. The results flow is slug-based. After an audit is created, the user is routed to a results page keyed by slug. The client component at app/(audit)/results/[slug]/AuditResultsClient.tsx suggests the page may fetch or hydrate data client-side after the initial server render. The public share page reuses the same underlying audit record but presents it without the internal scan workflow.
10. lib/types.ts and lib/utils.ts provide shared contracts and helpers used across UI, API, and services. The components/ui folder is a reusable primitive layer for the form and page UI, not a domain subsystem.
11. Quality gates are lightweight but focused: __tests__/audit-engine.test.ts validates the scoring logic, and __tests__/form-validation.test.ts validates the input schema behavior. CI is wired through GitHub Actions, so the main architectural risk areas are the business rules and form validation rather than infrastructure complexity.
12. Operationally, this is a serverless-style web app: all important work happens in request/response handlers or shared server modules, with no separate worker queue or background job system visible in the tree. The key external dependencies that matter architecturally are Supabase for data storage, Anthropic for summaries, and Gmail/Nodemailer for outbound email.
Main entry points: audit-service.ts Audit service · SpendForm.tsx Spend form · route.ts Audit by slug · form-schemas.ts Form schemas
Components 23
App routes
Next.js App Router pages and route handlers that expose the product and API.
- Landing · Top-level marketing or entry page.
app/page.tsx - Scan page · Entry point for collecting spend and tool usage.
app/scan/page.tsx - Results page · Authenticated/internal audit results route.
app/(audit)/results/[slug]/page.tsx - Results client · Client-side wrapper for the results view and hydration.
app/(audit)/results/[slug]/AuditResultsClient.tsx - Share page · Public shareable audit view keyed by slug.
app/(audit)/share/[slug]/page.tsx - Audit API · Create and retrieve audits through the server boundary.
app/api/audit/route.ts - Audit by slug · Fetch an existing audit record by share slug.
app/api/audit/[slug]/route.ts - Tools API · Serves the supported tool catalog and metadata.
app/api/tools/route.ts - Leads API · Captures interested users and inbound lead data.
app/api/leads/route.ts - Health API · Deployment and liveness probe endpoint.
app/api/health/route.ts
UI layer
Reusable form and UI components used by the scan and results flows.
- Spend form · Primary input form for team spend and usage data.
components/forms/SpendForm.tsx - Tool selector · Selectable tool input used by the audit form.
components/forms/ToolSelector.tsx - Form schemas · Zod rules and shared form validation contracts.
components/forms/form-schemas.ts
Core logic
Domain services, persistence adapters, and shared utilities.
- Audit engine · Deterministic scoring and savings opportunity logic.
lib/audit-engine.ts - Audit service · Orchestrates normalization, scoring, persistence, and slug creation.
lib/audit-service.ts - AI service · Produces AI-written audit summaries and explanations.
lib/ai-service.ts - Supabase · Database access wrapper for audits and related records.
lib/supabase.ts - Email service · Outbound email integration for notifications or lead follow-up.
lib/email-service.ts - Tools config · Supported tools, pricing, and plan metadata.
lib/tools-config.ts - Shared types · Common types and helpers used across the app.
lib/types.ts
Tests
Focused validation of the scoring and form schema behavior.
- Engine test · Validates the deterministic scoring rules.
__tests__/audit-engine.test.ts - Schema test · Validates the input schema behavior.
__tests__/form-validation.test.ts
CI
Repository automation for continuous integration.
- CI workflow · GitHub Actions configuration for repository checks.
.github/workflows/ci.yml
Connections 24
- Landing → Scan page: start audit · Users move from the landing page into the scan flow.
- Scan page → Spend form: renders · The scan page composes the main audit form.
- Spend form → Tool selector: uses · The form includes a reusable tool selection control.
- Spend form → Form schemas: validates · Client-side validation is driven by shared schemas.
- Tool selector → Tools config: populates · Tool options come from the supported catalog.
- Form schemas → Audit API: guards · Validated form data is sent to the audit API.
- Audit API → Audit service: delegates · The route handler forwards normalized requests to the application service.
- Audit by slug → Supabase: reads · Slug lookups fetch stored audit records.
- Audit service → Audit engine: scores · The service invokes the deterministic scoring core.
- Audit service → AI service: summarizes · The service requests generated explanatory copy.
- Audit service → Supabase: persists · Audit results are stored for later retrieval and sharing.
- Audit service → Email service: notifies · Outbound email can be triggered as part of the audit lifecycle.
- Audit service → Tools config: uses · Supported tool metadata informs audit normalization and scoring.
- Audit service → Shared types: shares contracts · Shared types and helpers keep service boundaries consistent.
- Tools API → Tools config: serves · The tools API exposes the catalog to the UI.
- Leads API → Email service: triggers · Lead capture can hand off to email notification logic.
- Health API → Supabase: checks · Health checks may verify downstream connectivity.
- Results page → Results client: hydrates · The server page delegates interactive rendering to the client component.
- Results page → Audit by slug: loads · The results view fetches the underlying audit by slug.
- Share page → Audit by slug: loads · The public share view reuses the same slug-based audit fetch.
- Engine test → Audit engine: verifies · Unit coverage protects the scoring rules.
- Schema test → Form schemas: verifies · Unit coverage protects schema behavior.
- CI workflow → Engine test: runs · CI executes the scoring logic tests.
- CI workflow → Schema test: runs · CI executes the form validation tests.