I'm an HR manager by trade — SHRM-CP, multi-state compliance, employee relations, the full disciplinary and onboarding lifecycle. The JM Growth HR Hub is what happened when the HR problems in front of me stopped fitting inside spreadsheets and email chains. I designed, built, and now operate it myself, which means every feature answers a real operational need rather than a guessed-at requirement. When something is clumsy to use, I feel it the next morning. That feedback loop — builder and operator in one head — is the whole reason the system is shaped the way it is.
It replaced paper forms, a stack of Excel workbooks, and manual email routing with one integrated platform that handles the complete employee lifecycle: hiring and onboarding, progressive attendance discipline, performance reviews, terminations, compliance tracking, approvals, and document management — across nine locations.
Two-track progressive discipline
Tardy and absence tracked as independent tracks, each with its own threshold ladder and a 90-day window anchored to the documented verbal warning. The engine re-derives every employee's level from scratch on each run — no accumulator drift — and an HR override can freeze any record out of automated processing entirely.
Excuse-and-recompute
A manager can excuse a counted absence with a required comment; the level recomputes immediately and HR is notified of every override. Built by reusing the existing discipline engine rather than reimplementing it — and proven on a live employee record before any button was wired to it.
Signed documents that can't vanish
Every completed HR PDF is written to private server-side storage the moment it's submitted, independent of any local machine or email. A role-scoped search-by-name with short-lived signed URLs lets HR and district managers retrieve any document — closing a gap that had let a real signed evaluation go missing.
Accountable approval queue
Disciplinary and termination forms move through a structured queue with three-day signature deadlines, escalating reminders, and a full audit trail. Void, acknowledge, delete, and manager-dismiss are each gated to the right role — enforced on the server, not just hidden in the UI.
The compliance register I almost retired
A feature looked empty and unused, and I decided to retire it. Before deleting anything, a read-only pass to map what removal would touch turned up the truth: the register wasn't empty. It held fifty-four real compliance items — nineteen flagged at-risk, including an active federal-mandate item with real financial exposure. The "empty" was a misleading dashboard badge, not missing data.
The retire decision reversed on the spot. Deleting it would have destroyed live compliance records tied to a real obligation. The habit that saved it — map before you remove — is worth more than any feature I added that week.
The integration I chose not to build
Leadership wanted self-reported absences to feed the discipline engine. It sounded like a natural completion of the feature. Tracing the premise first told a different story: the attendance system already captures those absences through the timekeeping import — a missed shift already counts. Wiring self-reports in on top would have counted the same absence twice, pushing real people toward termination faster than policy intends.
So I recommended not building it. Self-reports stay where they belong — advance notice and context that help a manager decide whether to excuse — and the discipline count stays single-sourced. Knowing what not to ship is the senior move; here it protected people's jobs.
The document that went missing
A district manager asked for a signed performance evaluation. It was nowhere — not in storage, not in email, not anywhere. Diagnosis: completed documents had exactly one fragile copy, generated in the submitter's browser and dependent on a local script and an email surviving.
The fix wasn't just recovery — it was closing the class of failure. Now every completed document is written to durable server-side storage at submission time, with in-app retrieval by name. One lost file became a permanent guarantee that none can be lost the same way again.
Diagnose before building
Every load-bearing change opened with a read-only investigation, not a patch. Mapping the real behavior first repeatedly turned "big scary rewrite" into "small safe change" — and caught problems that would otherwise have shipped as silent bugs.
Verify at the data level, not the console
A change isn't done because the UI looks right. It's done when the database row is right. The manager-excuse feature was proven by watching a real employee's discipline level drop correctly — and restore cleanly — before it was ever wired to a button.
Stage it, and prove each step
Schema, then endpoint, then notification, then interface — each deployed and confirmed before the next. When the change touches the core discipline engine, reusing the proven code path beats reimplementing it, every time.
Authorization on the server, not the UI
Hiding a button is not security — every logged-in browser holds the same secret. Admin-only actions are gated by a server-side token; manager actions are scoped so a store only ever sees and acts on its own records.
Deploy with guardrails
A custom deploy wrapper refuses to ship uncommitted code — there's always a rollback point. Pre-deploy syntax and structure checks catch a whole class of failure at the door, one of them born from a real production incident.
| Layer | Choice | Why |
|---|---|---|
| Frontend | Vanilla HTML / CSS / JS | Zero build step; deploys as static assets; works on the iPads, PCs, and phones stores actually use. |
| Hosting & API | Cloudflare Workers | Edge-deployed, no cold starts, integrated cron scheduling, DDoS protection — and cost-effective at this scale. |
| Database | Supabase / Postgres | Managed Postgres with a REST API and row-level security; no server to maintain. |
| Storage | Supabase Storage | Private buckets for signed HR documents; service-role-only access, retrieval via short-lived signed URLs. |
| Google Apps Script + Resend | Dual-path delivery — a route that needed no domain verification meant full email on day one. | |
| Documents | jsPDF + pdf-lib | Client-side generation for instant download; server-side for regulated forms. |
| Pipelines | Power Automate + Apps Script | Email-triggered data imports from the HRIS and complaint workbooks — no manual re-keying. |
| Assistive AI | Claude API (proxied) | Natural-language policy search over the embedded HR policy library, behind a serverless proxy. |
- Paper forms scanned, emailed, and filed by hand
- Attendance reviewed in Excel; disciplinary steps missed
- Approvals lived in email chains with no tracking
- Absences called in by phone, leaving no record
- Signed documents survived only as one fragile copy
- Morning review meant checking ten systems and threads
- Digital form → auto-PDF → auto-filed, durably stored
- Two-track engine flags every threshold crossing
- Structured queue with deadlines and a full audit trail
- Employee self-service with instant multi-party notice
- Every document written to server storage on submit
- One dashboard, priority-ordered, read in under a minute
The measure of the system isn't how much it does. It's that the things it does, it does correctly — on a platform where a wrong number can cost someone their job.
End-to-end delivery
Frontend, serverless API design across 36+ endpoints, Postgres schema and row-level security, PDF generation, and object storage — owned from schema to interface.
Systems that meet the business where it is
HRIS import parsing, email-triggered pipelines, SharePoint report delivery, and an AI proxy — automating away manual re-entry across multiple recurring workflows.
HR expertise encoded in software
Progressive discipline, termination review, compliance tracking, and multi-store, multi-district access — modeled correctly because the person modeling them runs them.
Engineering discipline on a live system
Diagnosis, staged delivery, data-level verification, server-side authorization — and the restraint to reverse and decline changes that looked reasonable but weren't.