Web Client
Web Client is build on vite and react.
App Overview - Structure & Architecture
Section titled “App Overview - Structure & Architecture”Architecture
Section titled “Architecture”- Frontend: React Router v7 SPA (Vite) - Port 4202
- Backend: Fastify + Drizzle ORM + PostgreSQL - Port 4200
- API-First Design: Same API serves web, future desktop, and mobile clients
Route Structure
Section titled “Route Structure”Public Routes (_public/)
Section titled “Public Routes (_public/)”/login- User authentication/register- User registration/demo/*- Demo routes mirroring real app with sample data/demo/events/:id/*/demo/contacts/:id/*/demo/lessons/:id/*
Protected Routes (_protected/)
Section titled “Protected Routes (_protected/)”All routes require authentication. Auth check in layout loader redirects to /login if not authenticated.
Sub-Apps (Master-Detail Pattern)
Section titled “Sub-Apps (Master-Detail Pattern)”Each sub-app has:
- Sidebar with list/search
- Detail view with nested routes for different forms/sections
Events App (/events/:id/)
/events/:id/detail- Event details form/events/:id/songs- Songs management/events/:id/setlist- Setlist builder- Additional sub-routes as needed
Contacts App (/contacts/:id/)
/contacts/:id/detail- Contact information- Additional sub-routes as needed
Lessons App (/lessons/:id/)
/lessons/:id/detail- Lesson details- Additional sub-routes as needed
Users App (/users/)
/users/profile- User profile management (email, password, settings)
Navigation Hierarchy
Section titled “Navigation Hierarchy”Three-Level Header System
Section titled “Three-Level Header System”- Site Header - Logo, login/user menu (always visible)
- Workspace Selector - Top-level groupings (Organize, Events, Projects)
- Sub-App Header - Specific apps within each grouping (Contacts, Lessons, Events)
Navigation State Persistence (DB)
Section titled “Navigation State Persistence (DB)”Stored in users table:
{ "last_group": "events", "last_routes": { "events": "/contacts/123/detail", "projects": "/tasks/456", "organize": "/lessons/789" }}- Clicking workspace group navigates to last-visited sub-app in that group
- Cross-device sync ensures consistent experience
- Browser history handles navigation within current session
- URLs are shareable and bookmarkable
Data Flow
Section titled “Data Flow”Form Strategy
Section titled “Form Strategy”- Display and edit use same page/component
- Individual forms per section (not one big form)
- Each form submits via PATCH to update specific fields
- Leverages React Router
<Form>andclientAction
Route Loaders
Section titled “Route Loaders”- Parent route (
/events/:id/) loads main entity data once - Stays mounted while child routes swap via
<Outlet /> - Sidebar and shared state persist across sub-route navigation
- Child routes inherit parent loader data
Key Patterns
Section titled “Key Patterns”Master-Detail with Nested Routes
Section titled “Master-Detail with Nested Routes”/events/:id → EventApp (sidebar + data loader) /events/:id/detail → DetailForm (swaps in <Outlet />) /events/:id/songs → SongsForm (swaps in <Outlet />)Protected Layout
Section titled “Protected Layout”_protected/route.tsxloader checks authentication- All nested routes automatically protected
- Single point of auth logic
Demo Routes
Section titled “Demo Routes”- Mirror real route structure under
/demo/* - Use hardcoded sample data (no API calls)
- Same components,
isDemoprop to toggle data source - Allows discovery before registration
Single User Model
Section titled “Single User Model”- User logs in and accesses only their own data
- No multi-tenancy or user management features
- Simplified auth and data access patterns