FeatherSharkGovtech · Multi-tenant SaaSFeb 2023 – Oct 2024
Modernized a live govtech SaaS: six migrations, seven modules, zero deploy gaps.
Sole frontend engineer on a two-person team building FeatherShark, a multi-tenant SaaS used by US municipal fire departments and building-inspection offices. Walked into JavaScript on Create React App with hand-rolled hooks and no auth state machine. Ran a JS→TS migration concurrent with feature work, swapped CRA for Vite, rebuilt the data layer on RTK Query, and made Zod schemas the canonical type source for forms and API edges. Shipped seven domain modules on top: ArcGIS-powered occupancies, multi-tenant runtime configuration, a 2FA auth state machine, an AI-assisted inspection workflow with human-in-the-loop, and a contractor-facing portal.
Multi-tenant
Maps
State machines
AI
Role
Senior Frontend Engineer (Primary)
Scope
20 months · 2-person team
Highlights
- Migrated 229 frontend files from JavaScript on CRA to TypeScript on Vite in three months without blocking a single release. Used `allowJs` to convert module-by-module, starting with forms and data hooks where types caught the most real bugs.
- Replaced a patchwork of hand-rolled fetch hooks with RTK Query as the load-bearing data layer; tag-based cache invalidation eliminated whole classes of stale-data and loading-state-inconsistency bugs.
- Made Zod schemas the canonical type source for forms and API edges — write once, use everywhere. Schemas drove validation, `useState` shapes, and DTOs through react-hook-form, ending the sync drift between validators and types.
- Multi-source autocomplete coordinator over server records, ArcGIS suggestions, and tenant-defined custom locations. Parallel fan-out with deterministic precedence ranking; per-source errors fall through silently rather than blocking the typeahead, even when ArcGIS rate-limits.
- Interactive ArcGIS map for the occupancies module: drag-and-drop safety markers (hydrants, extinguishers, hazmat, exits), persistent zoom/pan across navigation, and staged marker updates that eliminated re-render flicker.
- 2FA implemented as an auth state machine. Explicit transitions for credentials submitted, awaiting code, hydrating session, recovery code, refresh-mid-flow — one auditable transition graph instead of patches scattered across route guards.
- Multi-tenant runtime configuration shifted from `.env` to a server-driven settings endpoint feeding theme tokens, default map coordinates, and admin-UI shape. Onboarding a new municipality stopped requiring a redeploy.
- OpenAI-assisted 'improve with AI' on inspection rich-text fields: prompts tuned for professional fire-inspection language, exponential backoff on transient failures, deterministic fallback when the API was down, human-in-the-loop edit before save. AI as an option, never a blocker.
- Hierarchical checklist-template admin with drag-and-drop section and item reordering, fee-type fields, and cascading deletes — the authoring surface the entire product depends on.
- Contractor-facing portal as a distinct surface on the same platform: separate routing tree, role-scoped components, permit listing, activities, invoices, and document uploads.
Outcomes
- Sole frontend for 20 months on a two-engineer team. Six foundational migrations (CRA→Vite, JS→TS, ad-hoc fetch→RTK Query, manual forms→react-hook-form+Zod, Google Maps→ArcGIS, ESLint+Prettier→Biome) shipped without a deployability gap.
- Frontend stopped being the team bottleneck. The team trusted the FE to absorb feature work without producing regressions — the metric that actually matters at the end of a long engagement.
- Multi-tenant runtime config ended the deploy-to-onboard pattern. New municipalities onboarded via settings, not releases.
- Platform went live across US municipal fire departments and building-inspection offices before engagement close.
Stack
- React 18
- TypeScript
- Vite
- Redux Toolkit
- RTK Query
- react-hook-form
- Zod
- ArcGIS Maps SDK
- MUI
- MUI DataGrid Pro
- Mobiscroll
- OpenAI
- Biome
- Yarn 4 PnP