Architecture
ProChart
A solution-architecture summary — how the system is designed, and why. Verified from the source code.
- Type of system
- Multi-tenant SaaS (AI process mapping)
- Users
- Business analysts and consultants
- Hosting
- United Kingdom
- Main stack
- React + TypeScript, Django REST, PostgreSQL
- Status
- Live
- Built for
- Client — built by Moanv
The problem
After a discovery workshop, a business analyst reads the transcript line by line and maps it into Visio — days of work nobody sees. The hard part isn't drawing boxes; it's spotting what wasn't said: the rejected path nobody mentioned, the approval authority left undefined, the step only half the room agreed on.
How it fits together
Users
Business analysts & consultants
Front end
React 18 + TypeScript (Vite)
Tenant boundary
Backend / API
Django + DRF (Gunicorn, nginx)
Database
PostgreSQL
One shared database; access scoped by an ownership chain (user → workspace → project), enforced on every endpoint.
External services
- Anthropic Claude — extraction (Grok optional)
- Stripe — billing
- Mailjet — email
- Google Analytics — consent-gated
Tech stack
Front end
- React 18, TypeScript, Vite
- jsPDF for client-side PDF/PNG export
Backend
- Python, Django 5, Django REST Framework
- Gunicorn behind nginx
- python-docx for Word export (server-side)
Database
- PostgreSQL (psycopg 3)
Hosting
- United Kingdom
- Self-hosted Ubuntu, deployed via Azure DevOps over SSH
Third-party
- Anthropic Claude (default), operator-switchable to xAI Grok
- Stripe (billing)
- Mailjet (email)
- Google Analytics (consent-gated)
Key design decisions
A review loop, not an auto-answer
Why: Every node carries a confidence level and every gap becomes an open question; a Draft-vs-Confirmed gate is derived live from the model, so nothing is ‘Confirmed’ until a human resolves it.
Trade-off: The analyst still has to close the loop — the tool won't pretend it's done.
Never store the transcript
Why: The sensitive input is held only in memory for the request and discarded; only the resulting structured model is saved.
Trade-off: No re-processing an old transcript server-side; the user re-supplies it.
Strict schema on AI output
Why: LLM output is validated against a JSON schema and a canonical model before it's trusted — malformed output is rejected.
Trade-off: Stricter prompting and the occasional re-ask.
Ownership-based tenancy
Why: Simple, auditable isolation: you can only reach processes in a workspace you own.
Trade-off: No in-workspace sharing or seats yet.
Security & data protection
- Hosted in the United Kingdom, over TLS (Let's Encrypt) with HTTP redirected to HTTPS.
- Session authentication with Django's password hashing; email verification and password reset.
- Every process endpoint is gated so you can only access workspaces you own.
- Strong input validation: DRF serializers, Pydantic, a strict JSON-schema on AI output, and email MX + disposable-domain checks at signup.
- Rate limiting on signup and the contact form.
- Analytics are consent-gated (loaded only after ‘accept’); fonts are self-hosted.
- Transcripts are never stored or used to train models; secrets are server-side only.
Built to hold up
- Performance
- A React single-page app with a Django API; PDFs render in the browser.
- Availability
- A single UK host, Gunicorn behind nginx.
- Scalability
- Ownership-scoped tenancy on one shared PostgreSQL; plan limits (3 / 30 extractions per month) enforced server-side.
What we'd do next
- Add HSTS and a strict Content-Security-Policy.
- Extend rate limiting to the login and extraction endpoints.
- Add in-workspace collaboration — shared seats within a workspace.