How isreeharim/expcal works
Purpose and Entry Points
ExpCal is a Next.js 16 App Router PWA for tracking project-level income, expenses, and work time. It has public landing/auth entry points, authenticated user dashboards, and an admin area. Primary routes are app/page.tsx, app/(auth)/login/page.tsx, app/(dashboard)/dashboard/page.tsx, and app/(dashboard)/admin/page.tsx.
Application Shell and Access Boundary
The root layout establishes global application styling and shell behavior in app/layout.tsx and app/globals.css. Authentication callbacks are handled by app/auth/callback/route.ts; request-level session/access enforcement is centralized in middleware.ts. The dashboard route group applies its authenticated layout via app/(dashboard)/layout.tsx, separating protected product routes from auth and landing pages.
Supabase Data, Identity, and Authorization
Supabase is the system of record for PostgreSQL data, Auth sessions, RLS enforcement, and receipt/media storage. Browser and server Supabase clients are separated in lib/supabase/client.ts and lib/supabase/server.ts. Database evolution defines the core domain and backup support in supabase/migrations/001_initial_schema.sql and supabase/migrations/002_google_sheets_backup.sql; performance indexes are added in supabase/migrations/003_performance_indexes.sql.
Domain Mutation Layer
Server-side action modules form the primary application service boundary between UI and Supabase: authentication in lib/actions/auth.ts, project lifecycle operations in lib/actions/projects.ts, and financial/time entry operations in lib/actions/entries.ts. Shared domain contracts reside in lib/types.ts. This layer should own authorization-aware mutations, aggregation inputs, and storage-related entry workflows rather than placing those concerns in page components.
User Project and Entry Flow
Users create and browse projects from app/(dashboard)/projects/page.tsx and components/dashboard/create-project-dialog.tsx. A selected project is rendered at app/(dashboard)/project/[id]/page.tsx, where entry capture and review flow through components/project/entry-form.tsx, components/project/add-entry-button.tsx, and components/project/entries-table.tsx. Entries combine time ranges, income, categorized expenses, and potentially receipt photos.
Reporting and Administration
User-facing rollups are exposed through the dashboard and analysis pages: app/(dashboard)/dashboard/page.tsx, app/(dashboard)/analysis/page.tsx, and chart components such as components/dashboard/dashboard-chart.tsx and components/project/project-chart.tsx. Admin-only system views are rooted at app/(dashboard)/admin/page.tsx, with user/project oversight in app/(dashboard)/admin/users/page.tsx and app/(dashboard)/admin/projects/page.tsx. Role distinctions depend on the Supabase-backed authorization model.
Backup, PWA, and Operational Integrations
Backup/export is a distinct privileged integration boundary: UI/action orchestration in components/admin/backup-sync-card.tsx and lib/actions/backup.ts, with HTTP routes at app/api/backup/export/route.ts and app/api/backup/sheets/route.ts. Google Sheets support includes lib/constants/google-apps-script.ts and deployable script content in public/google-apps-script-backup.js. PWA install/offline behavior is supplied by public/manifest.json, public/sw.js, and components/pwa/install-prompt.tsx. A keep-alive endpoint, app/api/keep-alive/route.ts, is invoked operationally by .github/workflows/keep-alive.yml.
Components 20
Next.js application
- Root shell · Global styling and application shell.
app/layout.tsx - Landing & login
app/(auth)/login/page.tsx - Auth callback
app/auth/callback/route.ts - Session access guard · Enforces request-level session and route access.
middleware.ts - Protected dashboard shell
app/(dashboard)/layout.tsx - Projects & entry workspace · Project creation, entry capture, and entry review.
app/(dashboard)/project/[id]/page.tsx - Dashboard & analysis · User-facing financial and time rollups.
app/(dashboard)/analysis/page.tsx - Admin views · Role-gated user and project oversight.
app/(dashboard)/admin/page.tsx
Domain services
- Auth actions
lib/actions/auth.ts - Project actions · Authorization-aware project lifecycle operations.
lib/actions/projects.ts - Entry actions · Creates financial, time, and receipt-related entries.
lib/actions/entries.ts - Domain contracts
lib/types.ts
Supabase platform
- Browser & server clients · Separate Supabase clients for browser and server runtimes.
lib/supabase/server.ts - Supabase · System of record with Auth sessions, RLS, and receipt storage.
- Domain schema & backups · Defines core entities, backup support, and indexes.
supabase/migrations/001_initial_schema.sql
Integrations & operations
- Backup sync · Privileged export and Sheets sync orchestration.
lib/actions/backup.ts - Backup HTTP APIs
app/api/backup/sheets/route.ts - Google Sheets backup · Deployable Google Apps Script receives backup data.
public/google-apps-script-backup.js - PWA offline install
public/sw.js - Keep-alive automation · Scheduled workflow invokes the operational endpoint.
.github/workflows/keep-alive.yml
Connections 25
- Root shell → Landing & login: renders public entry
- Root shell → Protected dashboard shell: hosts protected routes
- Landing & login → Auth actions: sign in
- Auth callback → Browser & server clients: exchanges session
- Session access guard → Browser & server clients: reads session
- Session access guard → Protected dashboard shell: permits protected access
- Protected dashboard shell → Projects & entry workspace: contains
- Protected dashboard shell → Dashboard & analysis: contains
- Protected dashboard shell → Admin views: contains
- Projects & entry workspace → Project actions: creates and browses projects
- Projects & entry workspace → Entry actions: captures entries
- Dashboard & analysis → Entry actions: requests rollup inputs
- Admin views → Backup sync: starts backup
- Auth actions → Browser & server clients: auth operations
- Project actions → Browser & server clients: project mutations
- Entry actions → Browser & server clients: entry and receipt workflows
- Domain contracts → Project actions: contracts
- Domain contracts → Entry actions: contracts
- Browser & server clients → Supabase: queries, sessions, storage
- Domain schema & backups → Supabase: provisions schema and indexes
- Backup sync → Backup HTTP APIs: invokes export and sync
- Backup HTTP APIs → Supabase: exports authorized data
- Backup HTTP APIs → Google Sheets backup: sends backup payload
- PWA offline install → Root shell: adds install and offline behavior
- Keep-alive automation → Supabase: keeps service active