
TimeSheet Platform
Enterprise time-tracking SaaS
Rolled out to 350+ employees, cutting the firm's reporting time roughly 80% and retiring the legacy Access database after a ~295k-row migration.
| Day | Customer / case | Hours |
|---|---|---|
| Mon | Cedar Retail Group | 8.0 |
| Tue | Cedar Retail Group | 7.5 |
| Wed | Harbor Foods SAL | 8.0 |
| Thu | Internal: training | 6.5 |
| Fri | Cedar Retail Group | 7.0 |
| Total | 37.0 |
One synthetic week, Mon to Fri. Hours log against customers or internal cases; a manager approval flips the week's status, like the production workflow.
Synthetic preview. Fictional employees, customers, and hours; no real client data. The production platform is private client work for a regional accounting and audit firm.
Synthetic preview. Fictional employees, customers, and hours. No real client data.
Built in-house as AI Solutions Lead at BDO (a regional accounting & audit firm), so source, branding, and data are confidential. Happy to walk through the architecture.
Request accessA production in-house platform that replaced a regional accounting and audit firm's legacy Access (MDB) database with a secure, audited web system for time tracking, customer and employee management, and reporting. The Flask 3 + SQLAlchemy 2 + PostgreSQL backend spans 16 route modules: JWT auth with Argon2id hashing and refresh tokens, role-based access control enforced at both the API and UI layers, an append-only audit log stored in UTC with timezone-converted views, automated email reminders, and an analytics service that runs SQL aggregations, year-over-year comparisons, and productivity heatmaps into ReportLab PDF and CSV exports. The React + TypeScript frontend uses TanStack Query and Router with Chart.js dashboards; employees log hours against customers or internal cases (leave, holidays, training) through an employee hierarchy with manager task views and a customer approval workflow. A staged import pipeline moved ~295k task rows and ~1,670 customer records off Access into Postgres. Ships as Docker Compose behind Caddy TLS, with 41 test files across pytest and Vitest.
- React
- TypeScript
- Flask 3
- SQLAlchemy 2
- PostgreSQL
- Alembic
- JWT / Argon2
- ReportLab
- Docker
- Caddy
Architecture · legacy Access → audited time-tracking SaaS
Data migration
~295k task rows migrated off a legacy MS Access database into PostgreSQL.
Time capture + approval
Employees log hours against customers or internal cases through an employee hierarchy with manager task views and a customer approval workflow.
Auth + audit
JWT / Argon2id auth with RBAC and a full audit log across 16 route modules.
Analytics
A reporting service runs SQL aggregations, YoY comparisons, and productivity heatmaps.
Reports + delivery
Generates PDF/CSV reports; self-hosted via Docker Compose + Caddy TLS.
- Reporting time
- ~80% reduction (350+ employees)
- Rows migrated
- ~295,000 (from MS Access)
- Records
- 350+ employees · ~1,670 customers
- Tests
- 41 files
What I'd improve
The Access migration left compromises worth paying down: migrated task rows carry placeholder location values, and the import pipeline needed a follow-up script just to extract rows that failed to load, so a proper migration reconciliation report is the next data task. Operationally it runs as Docker Compose on a single company VM with manual pg_dump backups; scheduled, restore-tested backups and observability beyond container logs are what I would build next.