A government-grade workflow automation system for Food Safety Officer adjudication, inspection tracking, sample management, and legal document generation.
- Project Overview
- Architecture
- Technology Stack
- Current Status
- Roadmap
- Installation
- Development
- Testing
- Deployment
- API Reference
- Contribution
- Coding Standards
- Security
- Future Levels 1–10
- License
NSA Webservice digitizes and automates the complete lifecycle of food safety legal proceedings under the Food Safety and Standards Act, 2006 (FSS Act). It replaces paper-based workflows with a secure, auditable, and efficient digital platform used by Food Safety Officers (FSOs), adjudication officers, and administrators.
| Module | Purpose |
|---|---|
| Inspection Management | Record food business inspections, capture geo-tagged photo evidence, calculate compliance deadlines |
| Sample Management | Track food sample collection, lab submission, analyst reports with unique code generation |
| Case File Generation | Generate legal case files for sample-based violations (misbranded, substandard food) |
| Adjudication | Manage non-sample adjudication cases, section selection, legal document generation |
| FBO Issue Tracking | Unified state machine for Food Business Operator issues with audit trail |
| Billing | Summary dashboards and Excel export for sample billing |
| Document Generation | PDF generation for permission letters, petitions, and legal notices |
| Timeline & Case Visualization | Auto-generated milestone timelines + Gantt charts per case, with chronological-validity warnings; reachable from a global case picker and every case-linked page |
| Food Cell (DO Intimation) | Designated-Officer intimation forwarding for samples — PDF/HTML view, regenerate, sync to Sheets/Airtable/Excel (Phase 21) |
| Audit Trail | Tamper-evident hash-chained audit logging for all records and photo evidence |
| Google Sheets Sync | Optional data synchronization with Google Sheets for external reporting |
┌──────────────────────────────────────────────────────────────────┐
│ PRESENTATION LAYER │
│ Jinja2 Templates · CSS · JavaScript (Vanilla JS) │
└──────────────────────────┬───────────────────────────────────────┘
│
┌──────────────────────────▼───────────────────────────────────────┐
│ APPLICATION LAYER (Flask) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │
│ │Inspection│ │ Sample │ │Case File │ │Adjudicat.│ │ Billing│ │
│ │ Blueprint│ │ Blueprint│ │ Blueprint│ │ Blueprint│ │Blueprint│ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │
│ │FBO Issue │ │Settings │ │ Auth │ │ Audit (Hash-Chain) │ │
│ │ Blueprint│ │ Blueprint│ │ Blueprint│ │ Event Listeners │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────────────┘ │
└──────────────────────────┬───────────────────────────────────────┘
│
┌──────────────────────────▼───────────────────────────────────────┐
│ SERVICE LAYER │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────────────────┐ │
│ │ Shared Utils │ │ Google Sheets│ │ S3 Storage (R2/B2) │ │
│ │ (Keys/Models)│ │ Sync Service │ │ Photo Upload/Delete │ │
│ └──────────────┘ └──────────────┘ └───────────────────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────────────────┐ │
│ │ PDF Generator│ │ Verification│ │ Code Sequence Generator │ │
│ │ (WeasyPrint) │ │ Services │ │ (Atomic, Race-Safe) │ │
│ └──────────────┘ └──────────────┘ └───────────────────────────┘ │
└──────────────────────────┬───────────────────────────────────────┘
│
┌──────────────────────────▼───────────────────────────────────────┐
│ DATA LAYER │
│ ┌────────────────┐ ┌────────────────┐ ┌───────────────────────┐ │
│ │ PostgreSQL │ │ SQLAlchemy │ │ Redis (Celery │ │
│ │ (Primary) │ │ ORM + Alembic │ │ Message Broker) │ │
│ └────────────────┘ └────────────────┘ └───────────────────────┘ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ SQLite │ │ Local DB │ │
│ │ (Dev Fallback) │ │ (license.db) │ │
│ └────────────────┘ └────────────────┘ │
└───────────────────────────────────────────────────────────────────┘
| Decision | Rationale |
|---|---|
| Blueprint-per-domain | Separate Flask blueprints for each functional domain enable independent development, testing, and future migration to microservices |
| Canonical Key Contract | app/shared/case_keys.py defines uniform field names across modules, preventing field-name drift as the platform evolves |
| Hash-Chained Audit | Tamper-evident AuditLog using SHA-256 prevents retroactive modification of records |
| Race-Safe Sequences | CodeSequence table with atomic increments and PostgreSQL advisory locks ensures unique codes across concurrent workers |
| Optimistic Concurrency | version_id columns with StaleDataError handling prevent lost updates during concurrent edits |
| Storage Abstraction | S3-compatible interface (R2/B2) for photo evidence decouples storage from application logic |
| Layer | Technology | Version | Purpose |
|---|---|---|---|
| Runtime | Python | 3.12+ | Application runtime |
| Web Framework | Flask | 2.x | HTTP server and routing |
| ORM | SQLAlchemy | 2.x | Database abstraction |
| Migrations | Alembic | 1.13+ | Schema version control |
| Database | PostgreSQL (primary) / SQLite (dev) | 16 / 3.x | Data persistence |
| Task Queue | Celery | 5.4+ | Async background jobs |
| Message Broker | Redis | 5.x | Celery broker + cache |
| PDF Generation | WeasyPrint | — | HTML-to-PDF rendering |
| Excel Export | openpyxl | — | Billing reports |
| Object Storage | Cloudflare R2 / Backblaze B2 | — | Photo evidence storage |
| Auth | Flask-Login | 0.6+ | Session-based authentication |
| Security | Flask-Talisman | 1.1+ | CSP, HSTS, secure headers |
| OCR | Tesseract (pytesseract) | — | Text extraction from images |
| Templates | Jinja2 | — | Server-side HTML rendering |
| Layer | Target Technology |
|---|---|
| Web Framework | FastAPI |
| Graph Database | Neo4j |
| Vector Store | Qdrant |
| Orchestration | LangGraph |
| LLM Gateway | OpenRouter |
| Containerization | Docker + Docker Compose |
| Monitoring | Prometheus + Grafana |
Version: 0.8.0 (Pre‑Production)
The NSA Webservice now offers a comprehensive, end‑to‑end solution for food safety inspections, sample management, adjudication, and reporting. Key capabilities include:
- Inspection Management with photo verification and geo‑tagging.
- Sample Tracking with unique code generation, lab submission, and analyst reporting.
- Case File Generation delivering PDF documents via WeasyPrint and async processing with Celery.
- Adjudication Engine that suggests legal sections and generates adjudication documents.
- FBO Issue State Machine with full audit‑trail logging.
- Billing Dashboard exporting Excel reports.
- Robust Authentication (Flask‑Login) and Security Hardening (CSP, HSTS, CSRF, session hardening).
- Hash‑Chained Audit Log for tamper‑evident record keeping.
- Timeline Engine + Gantt visualizing each case's milestones with warnings for chronologically invalid sequences (Phase 13).
- Full‑text + fuzzy search across case files, adjudications, annexures, and evidence (SQLite FTS5 + RapidFuzz).
- Version history, branching, cross‑reference & TOC reports for edited documents, and backup / export / import of complete cases.
- OCR extraction pipeline foundation (models + services + Celery task) toward lab‑report autopopulation.
- Food Cell DO Intimation workflow (Phase 21) forwarding samples to the Designated Officer.
| Area | Status | Notes |
|---|---|---|
| Inspection CRUD | ✅ Complete | With photo verification pipeline |
| Sample Management | ✅ Complete | Code generation, lab tracking |
| Case File Generation | ✅ Complete | PDF generation, Celery async |
| Adjudication | ✅ Complete | Section suggestion, document generation |
| FBO Issue State Machine | ✅ Complete | With audit trail |
| Billing Dashboard | ✅ Complete | Excel export, filtering |
| Authentication | ✅ Complete | Flask‑Login, global gate |
| Audit Trail | ✅ Complete | Hash‑chained + RecordAudit |
| Security Hardening | ✅ Complete | CSP, HSTS, CSRF, session hardening |
| Timeline Engine + Gantt | ✅ Complete | Phase 13 — 21 tests, global picker + entry points |
| Search (FTS5 + fuzzy) | ✅ Complete | Phase 10 — 56 tests |
| Version Control | ✅ Complete | Compare/restore/branch, history UI |
| Backup / Export / Import | ✅ Complete | Phase 16 — JSON/ZIP export, case import |
| OCR Pipeline | Phase A done; Phases B–E pending | |
| Food Cell (DO Intimation) | ✅ Complete | Phase 21 — 15 tests |
| CI/CD | pip‑audit + Dependabot configured | |
| RBAC / Roles | ❌ Not Started | All users have full access |
| PostgreSQL Migration | Schema ready, production pending | |
| Tests | ✅ 39 modules | ~700+ test cases, incl. end‑to‑end |
- ✅ PostgreSQL production migration (targeted for Q3 2026)
- ✅ Persistent Celery worker deployment
- ✅ RBAC implementation (FSO, Admin, Auditor roles)
- FastAPI migration for async APIs
- OpenAPI/Swagger documentation
- Structured logging with
structlog - Monitoring (Prometheus + Grafana) and Sentry error tracking
- Neo4j graph database integration for relationship queries
- Qdrant vector store for semantic search over legal corpus
- LangGraph workflow orchestration
- OpenRouter multi‑LLM gateway for AI‑assisted section suggestion and document drafting
- Bulk operations and multi‑tenancy support
- Advanced pattern detection across cases
- Automated document drafting and continuous learning from adjudication outcomes
Note: The MyPy configuration now excludes the build/ directory and stray nul file to avoid duplicate module errors (exclude = "^(build/|nul)$").
- PostgreSQL production migration
- Persistent Celery worker deployment
- RBAC implementation (FSO, Admin, Auditor roles)
- TLS fix for KMC scraper
- End-to-end test suite
- Docker containerization
- FastAPI migration
- OpenAPI / Swagger documentation (flasgger
/apidocs/) - Structured logging (structlog)
- Monitoring (Sentry + Prometheus)
- Redis caching layer
- Health check endpoints (
GET /health)
- Neo4j graph database integration
- Entity relationship queries
- Qdrant vector store for semantic search
- LangGraph workflow orchestration
- OpenRouter multi-LLM gateway
- AI-powered section suggestion
- Document drafting assistance
- Pattern detection across cases
- Bulk operations
- Multi-tenancy
- Python 3.12+
- PostgreSQL 16+ (or SQLite for development)
- Redis 5.0+ (for Celery)
- GTK libraries (for WeasyPrint — see WeasyPrint docs)
# 1. Clone the repository
git clone https://github.com/sumanksaha/NSA_webservice.git
cd NSA_webservice
# 2. Create virtual environment
python -m venv venv
source venv/bin/activate # Linux/Mac
# venv\Scripts\activate # Windows
# 3. Install dependencies
pip install -r requirements.txt
# 4. Install Chromium for Playwright (if using browser features)
playwright install chromium
# 5. Configure environment
cp .env.example .env # Create .env file
# Edit .env with your settings (DATABASE_URL, SECRET_KEY, etc.)
# 6. Initialize the database
flask db upgrade
# 7. Run the application
flask runNote: Docker Compose configuration is not yet available. This section is a placeholder for the planned containerization effort (see Roadmap).
# (Coming in Phase 1 — Docker containerization)
# Build and run
docker compose up -d
# Run migrations
docker compose exec web flask db upgradeNSA_webservice/
├── app/ # Application package
│ ├── __init__.py # App factory
│ ├── extensions.py # Flask extension initialization
│ ├── models/ # SQLAlchemy models (modular: auth, document, inspection, billing, config, issue)
│ ├── audit_hooks.py # SQLAlchemy event listeners
│ ├── adjudication/ # Adjudication blueprint
│ ├── audit/ # Audit log viewer blueprint
│ ├── auth/ # Authentication blueprint
│ ├── billing/ # Billing blueprint
│ ├── bill_generator/ # Bill generation blueprint
│ ├── case_file_generator/ # Case file blueprint
│ ├── fbo_issue/ # FBO issue tracking blueprint
│ ├── inspection/ # Inspection blueprint
│ ├── sample/ # Sample management blueprint
│ ├── services/ # Shared services
│ ├── settings/ # Settings blueprint
│ ├── shared/ # Shared contracts and helpers
│ ├── static/ # Static assets (CSS, JS)
│ ├── templates/ # Base templates
│ └── utils/ # Utility modules
├── migrations/ # Alembic database migrations
├── tests/ # Test suite
├── scripts/ # Utility scripts
├── docs/ # Documentation
├── celery_app.py # Celery application factory
├── render.yaml # Render deployment blueprint
├── requirements.txt # Python dependencies
├── fso_list.md # FSO master data
├── fss_sections.md # FSS Act legal sections
└── app.py # WSGI entry point
- Create a feature branch from
upgradation - Make changes following coding standards
- Write tests for new functionality
- Run tests locally:
pytest - Run linter:
black --check . && ruff check . - Commit with conventional commits
- Push and create a pull request
# Run all tests
pytest
# Run with verbose output
pytest -v
# Run specific module tests
pytest tests/test_step1.py -v
pytest tests/test_step2.py -v
# Run with coverage report
pytest --cov=app --cov-report=term-missing
# Run route collision regression
pytest tests/test_route_collisions.py -v| Test File | Coverage |
|---|---|
test_step1.py |
FSO model, markdown sync, Sample model, code generation |
test_step2.py |
Billing utilities, Excel export, filtering |
test_step3.py |
Inspection model, code generation, deadline calculation |
test_step4.py |
Derived-state queries, dismiss action, adjudication linkage |
test_step5_integration.py |
Cross-module integration scenarios |
test_route_collisions.py |
Regression: duplicate route detection |
test_bill_generator.py |
Bill generation logic |
test_pdf_photo_embedding.py |
PDF photo embedding edge cases |
test_timeline.py |
Phase 13: timeline engine, routes, picker, entry points (21) |
test_case_backup.py |
Phase 16: JSON/ZIP export, case import (14) |
test_ocr_extraction.py |
Phase A: OCR extraction + task persistence (14) |
test_food_cell_do_intimation.py |
Phase 21: DO intimation generate/forward/sync (15) |
The project includes a render.yaml blueprint for one-click deployment on Render.
# 1. Push to GitHub
git push origin main
# 2. Deploy via Render Blueprint
# Render Dashboard → New → Blueprint → Select repositorySee POSTGRES_MIGRATION.md for detailed deployment instructions.
# Build steps
pip install -r requirements.txt
flask db upgrade
# Run with Gunicorn (production)
gunicorn --bind 0.0.0.0:10000 app:app
# Run with Celery worker (background tasks)
celery -A celery_app.celery worker --loglevel=info| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
SECRET_KEY |
Yes | Flask secret key (min 32 chars) |
REDIS_URL |
For Celery | Redis connection string |
GOOGLE_CREDENTIALS_JSON |
For Sheets | Google service account JSON |
SPREADSHEET_ID |
For Sheets | Google Sheets document ID |
R2_ACCESS_KEY |
For Storage | R2/B2 access key |
R2_SECRET_KEY |
For Storage | R2/B2 secret key |
R2_BUCKET |
For Storage | Storage bucket name |
R2_ENDPOINT |
For Storage | Storage endpoint URL |
SKIP_FSO_STARTUP_SYNC |
No | Skip FSO sync on startup |
AIRTABLE_API_KEY |
For Airtable backup | Airtable API key |
AIRTABLE_BASE_ID |
For Airtable backup | Airtable base ID (auto-rotates when full) |
MS_TENANT_ID |
For Excel backup | Azure AD tenant ID |
MS_CLIENT_ID |
For Excel backup | Azure AD app registration ID |
MS_CLIENT_SECRET |
For Excel backup | Azure AD client secret |
MS_DRIVE_ID |
For Excel backup | OneDrive/SharePoint drive ID |
MS_SPREADSHEET_ID |
For Excel backup | Excel file ID in OneDrive |
Note: API documentation is auto-generated from code. Endpoints follow a RESTful convention.
| Blueprint | Prefix | Description |
|---|---|---|
| Auth | /auth |
Login/logout |
| Inspection | /inspection |
Inspection CRUD + photo evidence |
| Sample | /sample |
Sample management |
| Case File | /case_file_generator |
Case file generation |
| Adjudication | /adjudication |
Adjudication management |
| Billing | /billing |
Billing summary + export |
| Bill Generator | /bill_generator |
Bill PDF (async via QStash) |
| FBO Issue | /fbo-issue |
FBO issue state machine |
| Annexure | /annexure |
Annexure upload + metadata |
| Evidence | /evidence |
Evidence library (photos, reports, etc.) |
| Document Viewer | /document_viewer |
Quill editor, save/restore, PDF |
| Legal Analysis | /legal |
Legal paragraph detection workbench |
| Search | /search |
FTS5 + fuzzy search API |
| Version Control | /api/version-control |
Version history UI + API |
| Timeline | /timeline |
Case milestone timeline + Gantt |
| Food Cell | /food-cell |
DO Intimation workflow (Phase 21) |
| Audit | /admin |
Audit log viewer |
| Settings | /settings |
Admin settings |
| Health | /health |
Health probe (public) |
All API endpoints return JSON with consistent status codes:
200— Success201— Created204— Deleted (no content)400— Bad request404— Not found409— Conflict (optimistic locking)500— Server error
- Style: Black with 120-character line length
- Linting: Ruff — strict ruleset
- Type Hints: Required for all function signatures (PEP 484)
- Docstrings: Google style docstrings for all modules, classes, and functions
- Imports: Grouped (standard library → third-party → local), alphabetically sorted
| Element | Convention | Example |
|---|---|---|
| Modules | snake_case |
inspection_utils.py |
| Classes | PascalCase |
class InspectionPhoto |
| Functions | snake_case |
def generate_inspection_code() |
| Variables | snake_case |
compliance_deadline |
| Constants | UPPER_CASE |
MAX_FILE_SIZE |
| DB Columns | snake_case |
food_safety_officer_name |
| Blueprints | snake_case |
inspection_bp |
Use Conventional Commits:
feat: add inspection photo verification pipeline
fix: handle StaleDataError in inspection update route
docs: update deployment guide for PostgreSQL
test: add boundary tests for compliance deadline calculation
refactor: extract date parsing into shared utility
chore: update ruff configuration in pyproject.toml
Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.
Please read SECURITY.md for security vulnerability reporting and our responsible disclosure policy.
- Flask web framework with blueprints
- SQLAlchemy ORM with Alembic migrations
- Basic authentication (Flask-Login)
- Core inspection, sample, adjudication CRUD
- Google Sheets sync
- PDF document generation (WeasyPrint)
- Celery background tasks
- S3-compatible object storage (R2/B2)
- Flask-Talisman (CSP, HSTS, secure cookies)
- CSRF protection (flask-wtf)
- Session hardening (30min TTL, HttpOnly, SameSite)
- Hash-chained audit logging
- Optimistic concurrency control
- Module-specific pytest suite
- Route collision regression guard
- Code generation with race-safe sequences
- Photo evidence verification pipeline (EXIF, IP geo, distance check)
- PostgreSQL production migration
- Connection pooling
- Database indexes optimization
- Query performance tuning (N+1 fixes)
- FastAPI migration
- OpenAPI/Swagger documentation
- Dependency injection
- Async request handling
- Structured logging (structlog)
- Monitoring (Prometheus + Grafana)
- Error tracking (Sentry)
- Health check endpoints
- Distributed tracing
- Neo4j graph database
- Entity relationship mapping (FSO→FBO→Case→Section)
- Graph-based pattern detection
- Case similarity queries
- Qdrant vector store integration
- Semantic search over legal corpus
- AI-powered section suggestion
- Document embedding pipeline
- LangGraph workflow orchestration
- OpenRouter multi-LLM gateway
- Agentic adjudication pipeline
- Automated document drafting
- Continuous learning from adjudication outcomes
This project is licensed under the MIT License — see the LICENSE file for details.
Why MIT? As a public-sector digital platform for food safety adjudication, MIT was chosen because:
- Maximum adoption: Other government bodies and jurisdictions can reuse and adapt the software without legal friction
- Transparency: Public sector technology benefits from permissive licensing
- Compatibility: Fully compatible with all project dependencies (MIT, BSD, Apache-2.0)
- Simplicity: MIT is one of the simplest, most widely understood licenses
- No restrictions: Allows commercial use, modification, distribution, and private use