Architecture Overview
Proxima Invoice is a web application with a Go backend, React frontend, and dual-database architecture. It replaces three n8n workflows (~1500 lines of JavaScript) that previously handled invoice generation, approval, and delivery.
System Diagram
Technology Stack
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | React 18, TypeScript 5, Tailwind CSS, shadcn/ui | UI components and pages |
| State Management | TanStack React Query | Server state, caching, mutations |
| Build Tool | Vite | Fast dev server and production builds |
| Backend | Go + Gin | HTTP server, business logic |
| Write Database | PostgreSQL (pgx/v5) | Invoice CRUD, state machine, events |
| Read Database | ClickHouse (clickhouse-go/v2) | Worklogs, CDM data, analytics |
| PDF Generation | Gotenberg (convert.prxm.uz) | HTML to PDF conversion |
| Authentication | JWT (Bearer tokens) | Stateless API authentication |
Key Design Principles
1. Dual-Database Separation
PostgreSQL handles all writes (invoice CRUD, events, edit history). ClickHouse is read-only and provides analytics data (worklogs, client info, Jira data). See Dual Database for details.
2. Pre-fill, Don't Pre-determine
Jira/Tempo data pre-fills invoices, but users have full editing control. The system never assumes automated data is final — human review and editing is a first-class workflow.
3. State Machine Enforcement
Invoice status transitions are enforced at the service layer. Invalid transitions return 409 Conflict. Every transition is logged as an event for audit purposes.
4. PDF on Finalize Only
PDFs are generated only when an invoice is finalized (draft → needs_review), not during pre-fill or editing. This avoids unnecessary PDF generation for work-in-progress invoices.
5. Financial Precision
All monetary calculations use shopspring/decimal (Go) — never float64. Database columns use DECIMAL(15,2). This prevents rounding errors in financial computations.
Request Flow
A typical request flows through these layers:
Middleware Stack
- Recovery — Panic recovery, returns 500
- Security Headers — CSP, X-Frame-Options, etc.
- CORS — Configurable allowed origins
- Request ID — UUID per request, propagated via context
- Logging — Structured JSON logging with slog
- JWT Auth — Token validation on protected routes
Ports and Services
| Service | Port | Notes |
|---|---|---|
| Backend (Go) | 8081 | Avoids conflict with existing proxima-backend on 8080 |
| Frontend (Vite) | 5173 | Dev server |
| PostgreSQL | 5433 | Docker Compose, mapped from 5432 |
| ClickHouse | 443 | External HTTPS at clickhouse-api.prxm.uz |
| Gotenberg | 443 | External HTTPS at convert.prxm.uz |