ERP/CRM for visa and document-service agencies: customer onboarding, application workflows, document collection + OCR, invoices, payments, and deadline calendars.
π― Project Presentation & Portfolio Showcase β β Architecture diagrams, business flows, and a detailed walkthrough of the system designed for technical review.
Quick links: Architecture Β· Backend Β· Frontend Β· Async Processing Β· Deployment Β· Copilot Rules
BusinessSuite is built for agencies that process visa/stay-permit applications and need an auditable, deadline-driven workflow with async automation (OCR, document validation, calendar sync, invoice jobs).
| What | Placeholder | Notes |
|---|---|---|
| Dashboard | Add: docs/assets/screenshot-dashboard.png |
KPIs, pipeline, finance widgets |
| Application detail | Add: docs/assets/screenshot-application.png |
Document checklist, workflow steps, OCR job status |
| Invoices | Add: docs/assets/screenshot-invoices.png |
Invoice list/detail, async downloads |
| Architecture | See diagram below | System boundaries and queues |
- Customer + product catalog with required/optional document sets
- Application workflows with deadlines and Google Calendar sync
- Async OCR and document validation/categorization jobs
- Invoice generation (sync/async) and payment reconciliation
- Reports, admin tools, backups/restore utilities, runtime toggles
- Hybrid caching (cacheops + per-user namespace) with optional browser caching
- Dynamic Role-Based Access Control (RBAC): Fine-grained menu visibility and field-level permissions (redaction/masking) controlled directly via the Django Admin UI.
Visa/document workflows are high-variance and time-sensitive: external APIs fail, documents arrive late, and finance must be traceable. The architecture keeps the request path fast while pushing heavy and failure-prone work into resilient background jobs.
flowchart LR
subgraph Frontend [Angular 21 SPA]
UI[Standalone components & signals]
APIClient[OpenAPI-generated client]
Cache[IndexedDB + cache interceptor]
end
subgraph Backend [Django 6 + DRF]
Views[ViewSets/APIViews]
Services[Service layer & managers]
Models[PostgreSQL models]
CacheMW[Namespace cache + cacheops]
Auth[JWT + optional mock auth]
end
subgraph Async [Dramatiq + Redis]
Queues[Queues: realtime, default, scheduled, low, doc_conversion]
Workers[Workers]
Scheduler[Scheduler]
end
subgraph Data [Postgres + Redis]
PG[(PostgreSQL)]
RQ[(Redis broker/results/cache)]
end
UI -->|HTTPS| APIClient --> Views --> Services --> Models --> PG
Views --> CacheMW --> RQ
Services -->|enqueue actors| Queues --> Workers --> Models
Scheduler --> Queues
CacheMW --> Cache
More detail: docs/architecture.md.
| Layer | Technology | Notes |
|---|---|---|
| Backend API | Django 6, DRF, SimpleJWT | camelCase JSON via djangorestframework-camel-case |
| Async | Dramatiq 2 + Redis | queues: realtime, default, scheduled, low, doc_conversion |
| Frontend | Angular 21 + Bun | standalone components, signals, OnPush; SSR in production |
| DB | PostgreSQL 18 | source of truth |
| Cache | django-cacheops + namespace wrapper | per-user isolation + automatic invalidation |
| Observability | logs/ + collectors | Alloy/Promtail + Grafana/Loki (collector-driven) |
- Angular calls DRF endpoints using a generated OpenAPI client.
- JWT (
Authorization: Bearer ...) is attached by an interceptor; refresh happens on 401. - RBAC Matrix Sync: Upon authentication, the frontend fetches a fully evaluated permission matrix (
menus,fields) specific to the user's groups and roles, caching it heavily via Angular Signals. - Backend DRF ViewSets automatically sanitize responses via
RbacFieldFilterMixin(scrubbing restricted fields), and the Angular UI natively auto-masks these fields in lists and forms without destroying layouts. - Writes happen in Django services/models; external IO is queued to Dramatiq.
- Workers run task actors with retries + tracing; long jobs persist progress to DB.
- Caching layers: IndexedDB (frontend) β per-user namespace (backend) β cacheops β Postgres.
- Create a customer and select a product (visa/stay permit).
- Open an application and start collecting required documents.
- Trigger OCR/validation jobs; staff reviews results while work continues in the background.
- Deadlines are mirrored locally and synced to Google Calendar asynchronously.
- Generate an invoice (sync or async) and track payments until settled.
- Use reports to monitor pipeline health and finance KPIs.
- Python 3.12+ (backend deps are managed via
uv) - Bun 1.3+ (frontend)
- Docker (for local Postgres/Redis and optional all-in-one stack)
This runs DB + Redis + backend + workers + scheduler + frontend containers (plus optional Grafana/Loki).
cp .env.example .env # if you have one; otherwise create .env
docker compose -f docker-compose-local.yml --profile app up -dIf you do not want the local observability stack, start only the app services:
docker compose -f docker-compose-local.yml --profile app up -d db redis bs-core bs-worker bs-scheduler bs-frontendDefault local ports (from docker-compose-local.yml):
| Service | URL |
|---|---|
| Backend API | http://localhost:8000 |
| Frontend | http://localhost:4200 |
| Grafana (optional) | http://localhost:3000 |
| Loki (optional) | http://localhost:3100 |
docker compose -f docker-compose-local.yml up -d db redis
uv sync
cd frontend && bun installAt minimum, set these env vars in .env:
DB_HOST,DB_PORT,DB_NAME,DB_USER,DB_PASSREDIS_URL(orREDIS_HOST+REDIS_PORT)SECRET_KEY,JWT_SIGNING_KEY
- Keep API changes contract-first: update serializer/view β regenerate
backend/schema.yamlβ regenerate the Angular client. - Prefer extending shared UI components in
frontend/src/app/shared/components/(updatedocs/shared_components.mdwhen adding new ones). - Use runtime toggles for risky changes that need controlled rollout.
- In CI, enforce schema/client drift checks and run backend/frontend tests.
-
Install Docker + docker compose plugin.
-
Clone repo and create
.env(DB/Redis/auth secrets + integration keys). -
Run the stack:
docker compose -f docker-compose-local.yml --profile app up -d
-
Put a reverse proxy (Nginx/Caddy) in front of ports 8000/4200, enable TLS, and lock down admin endpoints.
docker-compose.yml is more production-oriented (OTel wiring, external network/volumes). Review and adapt it to your environment and proxy setup.
More detail: docs/deployment.md.
# Infra
docker compose -f docker-compose-local.yml up -d db redis
# Backend
uv sync
cd backend
uv run python manage.py migrate
uv run python manage.py runserver 0.0.0.0:8000
# Workers (separate terminal)
cd backend && uv run dramatiq business_suite.dramatiq --queues realtime,default,scheduled,low,doc_conversion
# Scheduler (separate terminal)
cd backend && uv run python manage.py run_dramatiq_scheduler
# Frontend (separate terminal)
cd frontend && bun install && bun run startPreferred:
./refresh-schema-and-api.shManual:
cd backend && uv run python manage.py spectacular --file schema.yaml
cd frontend && bun run generate:api- Read:
docs/coding-standards.mdanddocs/extension-guide.md. - For AI/Copilot assistance, rules and patterns are in
.github/copilot-instructions.md. - Keep views thin; put business logic in services/managers/models; add tests for new logic.
- Update docs when changing architecture or developer workflows.
- For UI work: reuse shared components and update
docs/shared_components.md.
- Multi-tenant hardening and per-tenant cache namespaces
- More configurable AI validation policies and workflow automation
- Deployment templates for Kubernetes
- Expanded accessibility regression coverage in CI (Playwright + axe)
MIT (see LICENSE).