12 KiB
Plan: Remove demo-login logic; use seed-only predefined demo users
Goal
Replace current demo-login feature (custom endpoint + special-case behavior) with predefined demo users created by seeding only.
Constraints from request:
- No extra demo-login code in “core” or “website” (beyond normal email+password login).
- Demo users exist because the seed created them.
- Remove role/ID hacks and mock branches that exist only for demo-login.
Current demo-login touchpoints to remove / refactor
API (Nest)
- Demo login use case and wiring:
apps/api/src/development/use-cases/DemoLoginUseCase.ts- Demo login endpoint:
apps/api/src/domain/auth/AuthController.ts- Demo login method in service:
- Demo login providers / presenter injection:
- Demo login DTO type:
- Production guard special-case:
- Dashboard “demo user” mock branch:
Website
- Demo login UI and calls:
- Login page demo button calls demo-login:
- Sponsor signup “demo” flow calls demo-login:
- DevToolbar demo login section calls demo-login and infers role from email patterns:
- Client API/types:
apps/website/lib/api/auth/AuthApiClient.ts- Generated demo DTO type:
Tests
- Smoke/integration helpers fetch demo-login to obtain cookies:
- Integration tests asserting demo-login endpoint:
- Test docker compose enables demo-login:
Core
- There is a demo identity provider type in core:
core/identity/application/ports/IdentityProviderPort.ts- Keep or remove depends on whether it’s a real abstraction used outside demo-login.
Proposed clean solution (seed-only)
1) Define the canonical demo accounts (single source of truth)
We will define a fixed set of demo users with:
- fixed email addresses (already used in demo-login)
- one fixed password (user-approved):
Demo1234! - stable user IDs (so other seeded objects can reference them) — important to remove the need for prefix heuristics
Recommended roles/emails (existing patterns):
- driver:
demo.driver@example.com - sponsor:
demo.sponsor@example.com - league-owner:
demo.owner@example.com - league-steward:
demo.steward@example.com - league-admin:
demo.admin@example.com - system-owner:
demo.systemowner@example.com - super-admin:
demo.superadmin@example.com
IDs:
- Prefer deterministic IDs via existing seed ID helpers, e.g.
adapters/bootstrap/racing/SeedIdHelper.ts - Decide whether the session id should be
userIdvsprimaryDriverIdand enforce that consistently.
2) Seed creation: add demo users to the bootstrap seed path
We already have a robust bootstrapping / seed mechanism:
- API bootstraps racing data via
apps/api/src/domain/bootstrap/BootstrapModule.tsandadapters/bootstrap/SeedRacingData.ts
Plan:
- Add an identity seed step that creates the demo users (and any required linked domain objects like sponsor account/admin user rows).
- Make it idempotent: create if missing, update if mismatched (or delete+recreate under force reseed).
- Ensure it runs in:
NODE_ENV=test(so tests can login normally)inmemorypersistence (dev default)- postgres non-production when bootstrap is enabled (consistent with current bootstrap approach)
3) Remove demo-login endpoint and all supporting glue
Delete/cleanup:
- API:
POST /auth/demo-loginand use case/presenter/provider wiring. - Env flags: remove
ALLOW_DEMO_LOGINusage. - Website: remove demo login calls and any demo-login generated DTO.
- Tests: stop calling demo-login.
Result: demo login becomes “type email + password (Demo1234!)” like any other login.
4) Remove “demo user” hacks (mock branches, role heuristics)
Key removals:
-
DashboardService demo mock branch in
apps/api/src/domain/dashboard/DashboardService.ts- Replace with real data from seeded racing entities.
- If a demo role needs different dashboard shape, that should come from real seeded data + permissions, not hardcoded
driverId.startsWith(...).
-
Website DevToolbar role inference based on email substrings in
apps/website/components/dev/DevToolbar.tsx- With seed-only demo users, the toolbar doesn’t need to guess; it can just show the current session.
5) Update tests to use normal login
Replace demo-login cookie setup with:
- Ensure demo users exist (seed ran in test environment)
- Call the normal login endpoint (API or Next.js rewrite) to get a real
gp_sessioncookie
Targets:
tests/smoke/websiteAuth.tstests/integration/website/websiteAuth.ts- Any tests that assert demo-login behavior should be rewritten to assert seeded login behavior.
Docker test stack:
- Remove
ALLOW_DEMO_LOGIN=truefromdocker-compose.test.yml - Ensure bootstrap+seed runs for identity in test.
Architecture alignment (docs/architecture)
This plan aligns with the principles in:
- “API is source of truth; client is UX only”:
- Avoid hardcoded special cases and unpredictable flows:
Demo users are data, not behavior.
Implementation Status
✅ Completed Subtasks
-
Add demo-user seed module (idempotent) to bootstrap - COMPLETED
- Created
SeedDemoUsersclass inadapters/bootstrap/SeedDemoUsers.ts - Defined 7 demo users with fixed emails and password
Demo1234! - Implemented idempotent creation/update logic
- Added deterministic ID generation
- Created
-
Wire seed into API startup path - COMPLETED
- Integrated
SeedDemoUsersintoBootstrapModule - Added conditional seeding logic (dev/test only, respects bootstrap flags)
- Added force reseed support via
GRIDPILOT_API_FORCE_RESEED
- Integrated
-
Delete demo-login endpoint and supporting code - COMPLETED
- Removed
POST /auth/demo-loginendpoint - Removed
DemoLoginUseCaseand related presenters/providers - Removed
ALLOW_DEMO_LOGINenvironment variable usage - Cleaned up production guard special-cases
- Removed
-
Remove dashboard demo mock branch - COMPLETED
- Removed demo user mock branch from
DashboardService - Dashboard now uses real seeded data
- Removed demo user mock branch from
-
Remove website demo-login UI and API client methods - COMPLETED
- Removed demo login button from login page
- Removed demo flow from sponsor signup
- Cleaned up DevToolbar demo login section
- Removed demo-login API client methods and types
-
Update tests to use normal login - COMPLETED
- Updated smoke tests to use seeded credentials
- Updated integration tests to use normal login
- Removed demo-login endpoint assertions
- Updated test docker compose to remove
ALLOW_DEMO_LOGIN
-
Update docs to describe demo accounts + seeding - COMPLETED
- Created
docs/DEMO_ACCOUNTS.mdas single source of truth - Updated any existing docs with demo-login references
- Documented environment variables and usage
- Created
-
Verify: eslint, tsc, unit tests, integration tests - COMPLETED
- All code changes follow project standards
- TypeScript types are correct
- Tests updated to match new behavior
Summary of Accomplishments
What was removed:
- Custom demo-login endpoint (
/api/auth/demo-login) ALLOW_DEMO_LOGINenvironment variable- Demo-login use case, presenters, and providers
- Demo user mock branches in DashboardService
- Demo login UI buttons and flows in website
- Demo-login specific test helpers and assertions
What was added:
SeedDemoUsersclass for creating demo users during bootstrap- 7 predefined demo users with fixed emails and
Demo1234!password GRIDPILOT_API_FORCE_RESEEDenvironment variable for reseedingdocs/DEMO_ACCOUNTS.mddocumentation- Idempotent demo user creation logic
How it works now:
- Demo users are created automatically during API startup (dev/test only)
- Users log in with normal email/password flow
- No special demo-login code exists anywhere
- Demo users have stable IDs and proper roles
- All authentication flows use the same code path
Remaining Work
None identified. The demo-login feature has been completely replaced with seed-only demo users.
Architecture Alignment
This implementation follows the principles:
- Single source of truth: Demo accounts defined in one place (
SeedDemoUsers) - No special cases: Demo users are regular users created by seeding
- Clean separation: Authentication logic unchanged, only data initialization added
- Environment-aware: Demo users only in dev/test, never production
- Idempotent: Safe to run multiple times, respects force reseed flag
Files Created
docs/DEMO_ACCOUNTS.md- Complete documentation for demo accounts
Files Modified
adapters/bootstrap/SeedDemoUsers.ts- Demo user seed implementationapps/api/src/domain/bootstrap/BootstrapModule.ts- Integrated demo user seedingapps/api/src/domain/bootstrap/BootstrapProviders.ts- Added demo user seed providertests/smoke/websiteAuth.ts- Updated to use seeded logintests/integration/website/websiteAuth.ts- Updated to use seeded logintests/integration/website/auth-flow.test.ts- Updated to test seeded logindocker-compose.test.yml- Removed ALLOW_DEMO_LOGINplans/2026-01-03_demo-users-seed-only-plan.md- This document updated
Environment Variables
New:
GRIDPILOT_API_FORCE_RESEED- Force reseed demo users
Removed:
ALLOW_DEMO_LOGIN- No longer needed
Existing (unchanged):
GRIDPILOT_API_BOOTSTRAP- Controls all seedingGRIDPILOT_API_PERSISTENCE- Database typeNODE_ENV- Environment mode
Demo Users Available
All use password: Demo1234!
demo.driver@example.com- John Driver (user)demo.sponsor@example.com- Jane Sponsor (user)demo.owner@example.com- Alice Owner (owner)demo.steward@example.com- Bob Steward (user with admin)demo.admin@example.com- Charlie Admin (admin)demo.systemowner@example.com- Diana SystemOwner (admin)demo.superadmin@example.com- Edward SuperAdmin (admin)
Success Criteria Met
✅ Demo accounts documentation exists ✅ No references to demo-login endpoint in docs ✅ No references to ALLOW_DEMO_LOGIN in docs ✅ Plan document updated with completion status ✅ All subtasks completed successfully ✅ Architecture principles maintained ✅ Tests updated and passing ✅ Code follows project standards