Internal dashboard prototype for IntoPrep operations. The app is built with Next.js App Router, TypeScript, and Tailwind CSS, and it implements the role model discussed in planning:
engineer: full platform access, governance control, and admin-role managementadmin: full portal visibilitystaff: enrollment, academics, messaging, and billing visibilityta: assigned-cohort support, family messaging, and score operationsinstructor: assigned classes, attendance, same-day scores, and read-only trends only
The portal is also wired as an installable web app, so users can install it from the browser and receive updates through normal web deployments.
npm install
npm run devOpen http://localhost:3000. The root route redirects to the admin dashboard.
- In a supported browser, sign in to the production portal and use the
Install appbutton in the sidebar or the browser install prompt. - The installed app updates from normal deployments; users do not need to reinstall it for each release.
- This is the recommended first delivery model because it behaves like an app while keeping release iteration fast.
- A Tauri-based desktop shell now lives in src-tauri.
- The shell loads the live production portal instead of bundling a separate copy of the app, so normal GitHub and Vercel releases update the in-app experience automatically.
- Browser-only PWA behavior is disabled inside the desktop shell, and the shell now opens directly at
/dashboardso logged-in users avoid an extra startup redirect. - The desktop shell now supports in-app native updates when updater secrets are configured and a newer tagged desktop release is published.
- Build locally with:
npm run desktop:build- Run locally against the Next.js dev server with:
npm run desktop:dev- Override the production portal URL for desktop builds with
DESKTOP_APP_URLif you move from the current Vercel hostname to a custom domain. - Desktop release automation is defined in desktop-release.yml.
- macOS internet downloads must be signed and notarized. Configure the Apple GitHub secrets listed in release-and-migrations.md or Gatekeeper will show the “Apple could not verify” warning.
- The desktop updater also requires GitHub secrets for
TAURI_SIGNING_PRIVATE_KEY,TAURI_SIGNING_PRIVATE_KEY_PASSWORD, andTAURI_UPDATER_PUBLIC_KEY. - If Apple signing secrets are not configured, the desktop release workflow still publishes the macOS build, but it will be unsigned and Gatekeeper will warn users when they open it.
- Copy
.env.exampleto.env.localand fill in:
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
CRON_SECRET=
RESEND_API_KEY=
SYNC_ALERT_EMAIL_FROM=
SYNC_ALERT_EMAIL_TO=- Apply the scoped schema in:
- supabase/migrations/20260314221500_portal_auth_and_attendance.sql
- supabase/migrations/20260314241000_engineer_role_and_role_management.sql
- supabase/migrations/20260314241100_engineer_policy_updates.sql
- supabase/migrations/20260315004500_account_governance_hardening.sql
- supabase/migrations/20260315013000_live_staff_ta_writes.sql
- supabase/migrations/20260315021500_google_forms_sync_source.sql
- supabase/migrations/20260315031500_scheduled_syncs_and_billing_sources.sql
- Seed the demo operational slice with supabase/seed.sql.
- Bootstrap accounts through Supabase seed data or the Settings screen:
- first create or seed an
engineeraccount - engineer provisions
adminaccounts with email + default password - admin provisions
staff,ta, andinstructoraccounts
- first create or seed an
When Supabase is configured:
/loginbecomes the real entrypoint.- self-signup is disabled; accounts must be provisioned in Settings by an engineer or admin.
- first-login accounts are forced through
/reset-passwordbefore they can access live portal data. /forgot-passwordand/auth/confirmhandle email-based password recovery.- route protection is enforced in src/proxy.ts
- attendance writes go through route.ts
- live academic notes, resource publishing, score writes, messaging replies, and cohort assignment updates now persist to Supabase through the
/api/academics/*,/api/messaging/reply, and/api/settings/users/assignmentsroutes - Google Forms/CSV intake imports go through route.ts
- linked Google Forms sync source configuration goes through route.ts
- linked Google Forms sync execution goes through route.ts
- linked QuickBooks sync source configuration goes through route.ts
- linked QuickBooks sync execution goes through route.ts
- manual QuickBooks snapshot imports go through route.ts
- the morning automation bundle runs through route.ts
- all current portal sections use live Supabase-backed data, including
dashboard,calendar,cohorts,students,families,programs,academics,messaging,billing,integrations,attendance, andsettings
Each route accepts a role query parameter so you can preview permissions before wiring real auth:
/dashboard?role=admin/dashboard?role=engineer/dashboard?role=staff/dashboard?role=ta/dashboard?role=instructor
The same role query parameter works on every section route:
/calendar/cohorts/attendance/students/families/programs/academics/messaging/billing/integrations/settings
- Save the CSV export URL from the Google Sheet linked to your Google Form responses in
/integrations. - Live linked sync and manual CSV fallback are available from
/integrationsforengineer,admin, andstaff. - Use intake-import-template.csv as the starter shape for Google Forms exports and linked-sheet columns.
- The importer creates or updates
leads,families,students, andenrollments, logs the run inintake_import_runs, and updates theGoogle Forms registration importsync card. registeredandwaitlistrows create enrollments when the cohort is explicit or can be inferred from the target program and campus.
- Save a linked QuickBooks invoice CSV URL in
/integrationsor upload a manual CSV snapshot from finance. - Use quickbooks-import-template.csv as the expected column shape for invoice snapshots.
- The billing sync matches invoices to
familiesby email first, then family name, upsertsinvoices, records sync-job runs, and updates theQuickBooks invoice snapshotsync card. - Warning or error-state syncs can send alert emails when
RESEND_API_KEY,SYNC_ALERT_EMAIL_FROM, and eitherSYNC_ALERT_EMAIL_TOor active engineer/admin profile emails are configured.
- vercel.json schedules the morning sync bundle twice per day in UTC (
11:00and12:00) so one invocation lands in the 7 AM New York hour across daylight-saving changes. - The cron route only executes inside the 7 AM Eastern window and deduplicates by local date, so only one morning sync run is accepted each day.
- Set
CRON_SECRETin Vercel so the platform sends theAuthorization: Bearer ...header automatically to the cron route. - next.config.mjs now adds production-safe security headers, and route.ts exposes a lightweight health endpoint.
npm run lint
npm run typecheck
npm run test
npm run buildOr run the full local gate in one command:
npm run ci- CI workflow runs on pull requests and pushes to
main. - Deploy workflow reruns checks, applies Supabase migrations, deploys to Vercel, and optionally hits
/api/health. - Desktop release workflow publishes macOS and Windows installers from GitHub when you tag
desktop-v*or run it manually. - The release and migration rules are documented in release-and-migrations.md.
- The current implementation is seeded with mock data grounded in the public IntoPrep workflows researched during planning.
- Supabase auth, core cohort/schedule/student/family reads, program catalog summaries, governance views, academic notes/resources, billing snapshots, cohort messaging, lead intake, sync monitoring, and attendance persistence are implemented.
- Linked Google Forms sync, linked QuickBooks sync, manual CSV fallback, and sync run logging are implemented for the first real lead/enrollment and billing pipelines.
- The portal can be installed as a PWA via manifest.ts, sw.js, and pwa-register.tsx.
- Engineers can provision, edit, and delete admin accounts from src/app/api/settings/users/route.ts via the Settings screen.
- Admins can provision, edit, and delete
staff,ta, andinstructoraccounts, but cannot create, edit, or deleteadminorengineeraccounts. - Engineers and admins can send password reset emails, suspend accounts, and review the live governance audit log in Settings.
- TA and staff users can now save coaching notes, publish cohort resources, update same-day assessment scores, and reply inside cohort-scoped messaging threads.
- Admins can update TA and instructor cohort assignments directly from Settings, and those changes sync back to
user_templates. - Suspended users are blocked from live portal data, and users with
must_change_passwordcannot access live sections until the password is updated. - Google Forms intake now supports linked-sheet CSV sync plus manual CSV fallback, and QuickBooks now supports linked CSV snapshots plus manual CSV fallback. The older portal and scheduling bridge still remain integration surfaces rather than direct API connections.
- GitHub Actions and additive Supabase migrations are the intended update path. Do not destroy or reset production tables during normal releases; ship new migrations instead.
- Instructor-facing surfaces intentionally hide family, billing, and broader student profile information.