Intelligent Payment Verification
Universidad Nacional de Colombia · 2026 - At present
A contractor at the National University of Colombia has to prove, every month, that their social security contributions are in order before they can be paid. This app takes that whole procedure — reading the contract, the ARL certificate and the PILA form, checking the figures against Colombian regulation, and filling the institutional templates — and turns it into a four-step wizard for the university office that handles those payments.
Architecture and Tech Stack
Core Architecture
- Framework: Next.js 16 (App Router), TypeScript, deployed on Vercel
- AI extraction: Vercel AI SDK over a Mistral + OpenAI model chain with automatic fallback
- Document reading: native text extraction for born-digital PDFs, OCR for scans and screenshots
- Business rules: a pure calculation engine, parameterized per fiscal year
- Validation: Zod schemas per document type (contract, ARL, payment sheet, activity report)
- PDF generation: the official templates are filled and merged with their annexes
- State: Zustand store across the wizard steps
- UI: shadcn/ui + Tailwind CSS 4
- Analytics: PostHog behind a typed event whitelist
Layered Architecture
The browser never talks to a model directly: every extraction goes through a route handler that streams NDJSON back, so the wizard can render fields as they are recognized instead of waiting for the whole document.
Request Flow
Key Features
Features at a Glance
Multi-document upload
Contract, ARL certificate, paid PILA form and — when the contract requires it — the activity report, all dropped at once. Each file is profiled and validated before extraction, so a wrong document is caught at the door rather than halfway through the flow.
Extraction with per-field confidence
The model returns every field tagged with how confident it is. Step 2 renders those tags, so review effort concentrates on what is actually uncertain instead of re-reading everything. The user edits inline and the corrected values feed the rest of the flow.
Regulation validation
Contributions, ARL validity and coverage, PILA deadlines, activity report percentages and the tax certification are each checked by an independent validator. Every finding cites the specific rule it comes from — and only rules whose text was verified directly.
Form 069 calculation engine
A pure, side-effect-free engine computes the contribution base and deductions. Fiscal parameters live in their own files per year, so rolling the app into a new year is a parameter change, not a rewrite.
Signature-ready output
The two official institutional formats are filled and merged with their annexes into a single downloadable PDF.
Technical Highlights
Nothing is cited that has not been read
The regulation catalog only holds rules whose text was verified first-hand, and that rule extends to every sentence quoted inside a validation message. When a source cannot be opened, the app says so instead of reconstructing it — a plausible-sounding citation is worse than no citation in a procedure that ends in a signature.
Analytics that cannot leak a person
The analytics layer accepts only enums, counts, booleans and field keys — never values, names, ID numbers, amounts or document content. The whitelist is a type, so TypeScript enforces it at compile time. Rule identifiers are never renamed either: they identify the situation, not the wording, so the historical series in PostHog stays comparable.
The official spreadsheet wins
When normative research and the official .xlsx contradict each other, the spreadsheet wins — the app has to reproduce the format the university actually receives, not the one the regulation implies.
Never silently overwrite a declaration
These formats are signed statements, so the app never normalizes what the person declared. When it detects an inconsistency it raises a warning and lets the person decide, instead of quietly correcting a field that someone is about to put their signature under.
Dates that often are not there
About a quarter of contracts express their term only in days ("doscientos sesenta y ocho (268) días calendario"), so no start or end date can be read at all — only a duration. The app infers the dates from the ARL certificate when the match is unambiguous; otherwise the user types the start date and the end is derived from it, never overwriting an end date already present.
A case corpus as the test harness
A fixture corpus pairs representative documents with their expected output — different operators, insurers and contract shapes, plus the awkward ones: scans, screenshots, rotated pages, expired coverage, incomplete contributions, several payment sheets. Obvious heuristics have failed against it more than once, which is exactly why every rule or extractor change is replayed over the corpus before it ships. "It works on my document" is not evidence.
Impact and Scalability
- Replaces a fully manual procedure: reading each document by hand, cross-checking figures and typing the templates.
- Review time concentrates on low-confidence fields instead of every field.
- Rolling to a new fiscal year is one parameter file.
- The case corpus makes every rule change verifiable before it ships.
- Usage is measured in PostHog without storing a single personal value.
Notes
Built with Next.js 16, the Vercel AI SDK over Mistral and OpenAI, @pdfme, Zod and shadcn/ui. The repository is private — it belongs to the Centro de Prototipado at the National University of Colombia.