Overview
PolicyFlow is an AI-assisted contract review platform that helps organizations review contracts more consistently, transparently and efficiently. Users upload a contract, AI extracts and summarizes the relevant clauses, a deterministic rule engine evaluates the contract against organizational policies, and the platform generates a structured risk report before routing the document through an approval workflow.
I built PolicyFlow as a self-directed project to learn modern AI-native software engineering outside the Web3 ecosystem. The goal wasn't simply to integrate an LLM — it was to explore how AI fits into enterprise software while keeping auditability, security and deterministic business logic at the center of the architecture.
The project is intentionally scoped as an MVP. Features such as SSO, MFA and malware scanning have deliberately been left for future iterations to keep the focus on the core architecture.
Problem
Many organizations still review contracts through email chains, shared documents and manual checklists. The process is slow, difficult to audit and often inconsistent between reviewers.
I wanted to solve two problems.
The first is consistent policy evaluation. Every contract should be reviewed against the same organizational policies, regardless of who performs the review.
The second is policy evolution. A contract approved under yesterday's policies shouldn't suddenly appear "wrong" after the company updates its compliance rules. Historical decisions and current risk exposure answer different business questions and should therefore be stored separately.
Solution
Users upload a contract, AI extracts and summarizes the relevant clauses, and a deterministic rule engine evaluates the document against the organization's policies.
The LLM is responsible for understanding unstructured text. The platform is responsible for making compliance decisions.
Every policy evaluation is stored as an immutable historical record, while the same contract can later be re-evaluated against newer policy versions to identify newly introduced risks. Approval workflows are role-based and fully auditable, allowing reviewers, approvers and auditors to understand both what happened and why.
The core design principle is simple:
AI assists the user — it never becomes the decision maker.
Architecture
The architecture was designed around three principles:
- AI should improve productivity without reducing auditability.
- Security boundaries should be enforced structurally rather than relying on application logic.
- Future changes should require extending the system rather than rewriting it.
Backend
FastAPI with asynchronous SQLAlchemy 2.0 and Alembic migrations.
Multi-Tenancy
Organizations are isolated using PostgreSQL Row-Level Security (RLS). Every tenant-owned table contains an organization_id, with isolation enforced by the database rather than solely by application code.
AI & Retrieval
Retrieval-Augmented Generation (RAG) is implemented using PostgreSQL and pgvector. Retrieved context grounds AI responses and supports semantic search across contract clauses.
The AI provider is abstracted behind a provider interface, making it straightforward to switch between Gemini, Ollama or future providers without affecting the remainder of the application.
Background Processing
Redis and Arq handle asynchronous document processing, embeddings and long-running AI tasks.
Storage
Uploaded contracts are stored in MinIO using an S3-compatible object storage interface.
Frontend
The frontend is built with Next.js App Router acting as a Backend-for-Frontend (BFF). Authentication tokens remain inside httpOnly cookies and are never exposed to browser JavaScript.
Engineering Decisions
The most important architectural decision was making the audit log truly immutable.
Many applications describe an audit log as immutable simply because the application never issues an UPDATE statement. That still assumes the application itself is trusted.
In PolicyFlow, immutability is enforced by database permissions. The application simply does not have permission to modify historical audit records, meaning accidental bugs or compromised application credentials cannot rewrite history.
The second key decision was separating AI extraction from business decisions.
LLMs are very good at interpreting unstructured language but are not deterministic enough to decide whether a contract violates company policy.
Instead, AI extracts information. The rule engine evaluates compliance. This separation keeps policy decisions reproducible, explainable and auditable.
Technology Stack
- FastAPI
- SQLAlchemy 2.0
- Alembic
- PostgreSQL
- pgvector
- Redis
- Arq
- MinIO
- Next.js App Router
- Gemini
- Ollama
Trade-offs
Every architectural decision involved balancing flexibility against correctness.
Database-Level Isolation vs. Application-Level Filtering — PostgreSQL Row-Level Security requires additional setup but prevents accidental tenant data leaks even if an application query is written incorrectly.
Deterministic Rule Engine vs. AI Decision Making — Adding new policies requires implementing additional business rules rather than simply updating a prompt. The trade-off is slower feature development in exchange for consistent, reproducible and auditable compliance decisions.
MVP Scope — Security features such as SSO, MFA and malware scanning were intentionally excluded from the MVP. The goal was to demonstrate the architecture first rather than attempting to build every enterprise feature at once.
Lessons Learned
The biggest lesson from PolicyFlow is that AI should be introduced after the architecture is trustworthy.
Building multi-tenancy, auditability and authorization before adding AI made every later decision simpler.
It also reinforced my belief that AI should remain an assistant rather than becoming the source of truth. If a business decision has legal or financial consequences, the architecture — not the prompt — should define the final outcome.
I also gained a much deeper understanding of enterprise backend development, particularly around FastAPI, asynchronous applications, role-based authorization and designing systems that remain maintainable as requirements evolve.
What I'd Do Differently Today
If I started the project again today, I'd make several improvements.
- Introduce policy versioning and historical evaluations from the very beginning rather than adding them later.
- Invest earlier in automated evaluation datasets for measuring extraction quality.
- Separate the rule engine into independent policy modules to make adding new compliance domains easier.
- Add event-driven architecture for notifications and workflow updates instead of relying on direct service calls.
The overall architecture has held up well, but working through the project significantly changed how I think about enterprise AI applications and where deterministic systems should take precedence over generative AI.
Future Improvements
Before considering production use, I would prioritise:
- Single Sign-On (SSO)
- Multi-Factor Authentication (MFA)
- Malware scanning for uploaded files
- Automated evaluation pipelines for measuring AI extraction quality
- More sophisticated policy versioning and governance
- Configurable severity models for different compliance frameworks
- Additional AI providers and enterprise deployment options
Rather than expanding AI capabilities first, I'd continue investing in auditability, governance and operational tooling. For enterprise software, those capabilities ultimately create far more long-term value than adding another AI feature.