
Overview
WorkPulse automates the parts of workplace admin that usually happen manually: logging documents, tracking activity, and turning that raw data into a report someone actually reads. Automation is core to the product, not a side script — every background job (document intake, scheduled reports, email delivery) runs through n8n workflows instead of hand-rolled cron jobs, orchestrated alongside a Flask API and Supabase Postgres store. EasyOCR reads incoming documents, and an AI assistant surfaces insights instead of leaving managers to read raw logs.
Key features
- End-to-end automation built on n8n — document intake, scheduled reports, and email delivery all run as n8n workflows rather than custom background scripts
- Manager and employee dashboards with role-aware views and permissions
- Automated document intake with OCR-based text extraction from uploads and receipts
- AI assistant surfacing productivity insights instead of raw activity logs
- Scheduled reporting and email delivery via automated n8n workflows
- JWT-secured API with Supabase-backed row-level security
Architecture & engineering decisions
Flask REST API backend with JWT-based authentication and role-aware endpoints
Supabase (PostgreSQL) as the primary data store, handling relational data and auth policies
n8n workflow automation orchestrating background jobs — document ingestion, notifications, scheduled reports
EasyOCR pipeline extracting structured text from uploaded documents
Resend API integration for transactional email notifications
Product gallery
View full gallery →



Challenges & how I solved them
Coordinating asynchronous n8n workflows with the Flask API without race conditions on shared Supabase tables
Used Supabase row-level policies plus idempotent workflow steps so retried or overlapping n8n runs couldn't corrupt shared state.
Tuning EasyOCR accuracy across varied document formats and image quality
Added a preprocessing step (contrast/deskew normalization) before OCR and validated output against a set of real sample documents before trusting it in the pipeline.
Keeping the JWT auth flow simple on the frontend while still enforcing Supabase RLS
Passed the Supabase-issued JWT straight through from the client, letting RLS policies do enforcement server-side instead of duplicating auth logic in Flask.
Lessons learned
- Automation tools like n8n are excellent for orchestration but still need the same idempotency discipline as any backend job queue.
- OCR is only as good as the preprocessing in front of it — the model choice mattered less than image quality.
Stack