How it's built
A site audit that used to take a day
now runs in four minutes.
Stewards.Digital rebuilds websites for 501(c)(3) organizations as fixed-price, quick-turnaround projects — and this is the pipeline that makes that economical. A nonprofit asks for a review; an automated crawler and a language model produce a structured audit of their site; that audit becomes a private URL they can open the same afternoon. No engineer is copying findings into a slide deck.
The sample above is a complete, real portal rendered from a fictional organization's audit record — the same code path a client sees.
The pipeline
From a form submission to a live portal.
Five stages. Four of them run without anyone watching.
Request arrives
HumanA nonprofit submits the audit form. The browser posts to a server route rather than a third-party endpoint, so the form target is not a string in the client bundle.
Next.js route handler
The site gets crawled
AutomatedHeadless Chromium loads the organization's real site and captures what a visitor actually sees — rendered DOM, computed styles, contrast ratios, mobile layout, and console errors.
Python · Playwright
Findings get classified
AutomatedClaude reads that capture and returns structured findings — each one a severity, a plain-language title, and an explanation written for a board member rather than a developer.
Claude API
The audit is stored
AutomatedAn import script validates the required fields, writes the document to MongoDB, and mints a portal ID from 12 random bytes so the URL cannot be guessed or walked.
MongoDB Atlas
The portal goes live
AutomatedA server component reads the audit and renders it on request — no build, no deploy. Contact details are projected out of the query, so they never reach the page.
React Server Component
- ~4 minper audit, start to finish
- $0.03–0.08model cost per audit
- 0deploys required to publish one
Engineering decisions
Every choice cost something.
The tradeoffs are the interesting part, so they are written down rather than smoothed over.
Two rendering strategies in one app
The marketing site is prerendered and served from the CDN. Each client portal is a server component that queries MongoDB per request and is never prerendered, never cached, never indexed.
What it costThe portal pays a database round trip on every request and cannot be served from an edge cache. Accepted, because prerendering a portal would write a named organization's audit into the build output and push it to every CDN node.
Contact details are excluded by the type system
Audits carry contact information, but the portal renders a PublicAudit — a type with the contact field removed — and the database query projects it away before it is read.
What it costTwo places to widen instead of one whenever the portal legitimately needs a new field. That friction is the point: a UI change cannot start leaking a phone number by accident.
Accessibility is a build gate, not a checklist
axe-core runs against the landing page and a portal on every push, on desktop and mobile viewports, and fails the build on serious or critical violations.
What it costAutomated tooling catches roughly a third of real accessibility defects and skips aria-hidden subtrees entirely — a contrast bug in a decorative mock survived a green build here and had to be caught by eye. The gate raises the floor; it does not certify compliance.
Audits are data, not deploys
Audit results are documents in MongoDB, keyed by an unguessable portal ID. Running an audit for a new organization mints a live URL immediately.
What it costA hard dependency on the database: if it is unreachable, portals fail while the marketing site stays up. And with no schema, a malformed write is only caught when someone opens the page — so the import script validates what the database will not.
Quality gates
The site has to pass what it sells.
This business sells WCAG 2.1 AA compliance, so its own site failing that standard is not an option. It did, before this was enforced — grey-on-red navigation text at 1.69:1, form errors signalled by colour alone, no keyboard focus indicator, and no navigation at all below 900 pixels.
13 specs, 25 runs
Every spec runs against a production build on both desktop and mobile viewports, covering the real journeys — lead capture success and failure, portal rendering, unknown portal codes, mobile navigation.
Accessibility assertions
axe-core scans gate the build, alongside explicit checks that form errors are announced to assistive technology, that focus moves to the first invalid field, and that a skip link is the first thing a keyboard user reaches.
Typecheck, lint, build, test
Every push, with no escape hatches — TypeScript and lint errors fail the build rather than being suppressed. Tests run against fixtures, so continuous integration never touches real client data.
Stack
What it runs on.
- Application
- Next.js 15 App Router · React 19 · TypeScript (strict)
- Audit engine
- Python · Playwright · Claude API
- Data
- MongoDB Atlas
- Testing
- Playwright · axe-core · Cucumber/BDD
- Delivery
- GitHub Actions · Vercel
Built and maintained by Andre Spencer. The application repository is private — it holds real client audit data — so the architecture and decisions are documented here instead.
Want this run against your site?
The audit is free, and you get the same portal the sample links to.
Get my free audit