Files
gridpilot.gg/plans/2026-01-03_demo-users-seed-only-plan.md
2026-01-03 11:38:51 +01:00

290 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`](apps/api/src/development/use-cases/DemoLoginUseCase.ts)
* Demo login endpoint:
* [`apps/api/src/domain/auth/AuthController.ts`](apps/api/src/domain/auth/AuthController.ts)
* Demo login method in service:
* [`apps/api/src/domain/auth/AuthService.ts`](apps/api/src/domain/auth/AuthService.ts)
* Demo login providers / presenter injection:
* [`apps/api/src/domain/auth/AuthProviders.ts`](apps/api/src/domain/auth/AuthProviders.ts)
* [`apps/api/src/domain/auth/presenters/DemoLoginPresenter.ts`](apps/api/src/domain/auth/presenters/DemoLoginPresenter.ts)
* Demo login DTO type:
* [`apps/api/src/domain/auth/dtos/AuthDto.ts`](apps/api/src/domain/auth/dtos/AuthDto.ts)
* Production guard special-case:
* [`apps/api/src/domain/auth/ProductionGuard.ts`](apps/api/src/domain/auth/ProductionGuard.ts)
* Dashboard “demo user” mock branch:
* [`apps/api/src/domain/dashboard/DashboardService.ts`](apps/api/src/domain/dashboard/DashboardService.ts)
### Website
* Demo login UI and calls:
* Login page demo button calls demo-login:
* [`apps/website/app/auth/login/page.tsx`](apps/website/app/auth/login/page.tsx)
* Sponsor signup “demo” flow calls demo-login:
* [`apps/website/app/sponsor/signup/page.tsx`](apps/website/app/sponsor/signup/page.tsx)
* DevToolbar demo login section calls demo-login and infers role from email patterns:
* [`apps/website/components/dev/DevToolbar.tsx`](apps/website/components/dev/DevToolbar.tsx)
* Client API/types:
* [`apps/website/lib/api/auth/AuthApiClient.ts`](apps/website/lib/api/auth/AuthApiClient.ts)
* Generated demo DTO type:
* [`apps/website/lib/types/generated/DemoLoginDTO.ts`](apps/website/lib/types/generated/DemoLoginDTO.ts)
### Tests
* Smoke/integration helpers fetch demo-login to obtain cookies:
* [`tests/smoke/websiteAuth.ts`](tests/smoke/websiteAuth.ts)
* [`tests/integration/website/websiteAuth.ts`](tests/integration/website/websiteAuth.ts)
* Integration tests asserting demo-login endpoint:
* [`tests/integration/website/auth-flow.test.ts`](tests/integration/website/auth-flow.test.ts)
* Test docker compose enables demo-login:
* [`docker-compose.test.yml`](docker-compose.test.yml)
### Core
* There is a demo identity provider type in core:
* [`core/identity/application/ports/IdentityProviderPort.ts`](core/identity/application/ports/IdentityProviderPort.ts)
* Keep or remove depends on whether its 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`](adapters/bootstrap/racing/SeedIdHelper.ts)
* Decide whether the **session id** should be `userId` vs `primaryDriverId` and 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.ts`](apps/api/src/domain/bootstrap/BootstrapModule.ts) and [`adapters/bootstrap/SeedRacingData.ts`](adapters/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)
* `inmemory` persistence (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-login` and use case/presenter/provider wiring.
* Env flags: remove `ALLOW_DEMO_LOGIN` usage.
* 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`](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`](apps/website/components/dev/DevToolbar.tsx)
* With seed-only demo users, the toolbar doesnt 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_session` cookie
Targets:
* [`tests/smoke/websiteAuth.ts`](tests/smoke/websiteAuth.ts)
* [`tests/integration/website/websiteAuth.ts`](tests/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=true` from [`docker-compose.test.yml`](docker-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”:
* [`docs/architecture/QUICK_AUTH_REFERENCE.md`](docs/architecture/QUICK_AUTH_REFERENCE.md)
* Avoid hardcoded special cases and unpredictable flows:
* [`docs/architecture/CLEAN_AUTH_SOLUTION.md`](docs/architecture/CLEAN_AUTH_SOLUTION.md)
* [`docs/architecture/UNIFIED_AUTH_CONCEPT.md`](docs/architecture/UNIFIED_AUTH_CONCEPT.md)
Demo users are data, not behavior.
## Implementation Status
### ✅ Completed Subtasks
1. **Add demo-user seed module (idempotent) to bootstrap** - COMPLETED
- Created `SeedDemoUsers` class in `adapters/bootstrap/SeedDemoUsers.ts`
- Defined 7 demo users with fixed emails and password `Demo1234!`
- Implemented idempotent creation/update logic
- Added deterministic ID generation
2. **Wire seed into API startup path** - COMPLETED
- Integrated `SeedDemoUsers` into `BootstrapModule`
- Added conditional seeding logic (dev/test only, respects bootstrap flags)
- Added force reseed support via `GRIDPILOT_API_FORCE_RESEED`
3. **Delete demo-login endpoint and supporting code** - COMPLETED
- Removed `POST /auth/demo-login` endpoint
- Removed `DemoLoginUseCase` and related presenters/providers
- Removed `ALLOW_DEMO_LOGIN` environment variable usage
- Cleaned up production guard special-cases
4. **Remove dashboard demo mock branch** - COMPLETED
- Removed demo user mock branch from `DashboardService`
- Dashboard now uses real seeded data
5. **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
6. **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`
7. **Update docs to describe demo accounts + seeding** - COMPLETED
- Created `docs/DEMO_ACCOUNTS.md` as single source of truth
- Updated any existing docs with demo-login references
- Documented environment variables and usage
8. **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_LOGIN` environment 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:**
- `SeedDemoUsers` class for creating demo users during bootstrap
- 7 predefined demo users with fixed emails and `Demo1234!` password
- `GRIDPILOT_API_FORCE_RESEED` environment variable for reseeding
- `docs/DEMO_ACCOUNTS.md` documentation
- Idempotent demo user creation logic
**How it works now:**
1. Demo users are created automatically during API startup (dev/test only)
2. Users log in with normal email/password flow
3. No special demo-login code exists anywhere
4. Demo users have stable IDs and proper roles
5. 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 implementation
- `apps/api/src/domain/bootstrap/BootstrapModule.ts` - Integrated demo user seeding
- `apps/api/src/domain/bootstrap/BootstrapProviders.ts` - Added demo user seed provider
- `tests/smoke/websiteAuth.ts` - Updated to use seeded login
- `tests/integration/website/websiteAuth.ts` - Updated to use seeded login
- `tests/integration/website/auth-flow.test.ts` - Updated to test seeded login
- `docker-compose.test.yml` - Removed ALLOW_DEMO_LOGIN
- `plans/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 seeding
- `GRIDPILOT_API_PERSISTENCE` - Database type
- `NODE_ENV` - Environment mode
### Demo Users Available
All use password: `Demo1234!`
1. `demo.driver@example.com` - John Driver (user)
2. `demo.sponsor@example.com` - Jane Sponsor (user)
3. `demo.owner@example.com` - Alice Owner (owner)
4. `demo.steward@example.com` - Bob Steward (user with admin)
5. `demo.admin@example.com` - Charlie Admin (admin)
6. `demo.systemowner@example.com` - Diana SystemOwner (admin)
7. `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