What I learned
Mapbox GL JS is powerful but opinionated — the biggest lesson was learning to treat the map as a first-class, stateful UI peer rather than a passive display surface. Keeping React state and Mapbox layer state in sync without double-renders or stale closures took deliberate architecture work (context + refs over naive useState).
The auth + admin layer also reinforced how much complexity lives in role-based access: it’s not just “show the button or don’t.” Row-level permissions, audit logs, and server-side route protection all need to agree or cracks appear. Prisma and NextAuth.js v5 together made that coherent.
What I did
- Built an interactive Mapbox GL map with 455+ brewery locations loaded from PostgreSQL via Prisma, with a custom brewery layer, popups, and smooth clustering.
- Implemented unified search combining Mapbox Searchbox API for location lookup and a brewery-name search backed by the database.
- Added NextAuth.js v5 authentication with role-based access control (Admin / User) and a Prisma adapter for session persistence.
- Built a full admin panel for CRUD operations on the brewery dataset, protected by server-side role checks and instrumented with audit logging.
- Achieved comprehensive test coverage with Vitest (unit/integration) and Playwright (e2e), including MSW API mocks, custom test utilities, and 100% coverage on core validation and error modules.
- Deployed to Vercel with PostgreSQL on a managed provider, environment-variable-gated credentials, and a Zod-validated API layer.
What I shipped
A live full-stack map app at https://sammys-brews.vercel.app — 455+ craft breweries on an interactive Mapbox map, searchable by location or name, with a hardened auth system and an admin panel for ongoing data management.