@quanticjs/create-app 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/dist/deps.d.ts +4 -0
  2. package/dist/deps.js +97 -0
  3. package/dist/deps.js.map +1 -0
  4. package/dist/generators/backend.d.ts +2 -0
  5. package/dist/generators/backend.js +20 -0
  6. package/dist/generators/backend.js.map +1 -0
  7. package/dist/generators/bff.d.ts +2 -0
  8. package/dist/generators/bff.js +9 -0
  9. package/dist/generators/bff.js.map +1 -0
  10. package/dist/generators/claude.d.ts +2 -0
  11. package/dist/generators/claude.js +45 -0
  12. package/dist/generators/claude.js.map +1 -0
  13. package/dist/generators/docker.d.ts +2 -0
  14. package/dist/generators/docker.js +10 -0
  15. package/dist/generators/docker.js.map +1 -0
  16. package/dist/generators/e2e.d.ts +2 -0
  17. package/dist/generators/e2e.js +8 -0
  18. package/dist/generators/e2e.js.map +1 -0
  19. package/dist/generators/frontend.d.ts +2 -0
  20. package/dist/generators/frontend.js +28 -0
  21. package/dist/generators/frontend.js.map +1 -0
  22. package/dist/generators/module.d.ts +2 -0
  23. package/dist/generators/module.js +35 -0
  24. package/dist/generators/module.js.map +1 -0
  25. package/dist/generators/root.d.ts +2 -0
  26. package/dist/generators/root.js +7 -0
  27. package/dist/generators/root.js.map +1 -0
  28. package/dist/generators/scripts.d.ts +2 -0
  29. package/dist/generators/scripts.js +10 -0
  30. package/dist/generators/scripts.js.map +1 -0
  31. package/dist/index.d.ts +2 -0
  32. package/dist/index.js +40 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/prompts.d.ts +8 -0
  35. package/dist/prompts.js +53 -0
  36. package/dist/prompts.js.map +1 -0
  37. package/dist/scaffold.d.ts +2 -0
  38. package/dist/scaffold.js +79 -0
  39. package/dist/scaffold.js.map +1 -0
  40. package/dist/utils/exec.d.ts +2 -0
  41. package/dist/utils/exec.js +14 -0
  42. package/dist/utils/exec.js.map +1 -0
  43. package/dist/utils/template.d.ts +10 -0
  44. package/dist/utils/template.js +20 -0
  45. package/dist/utils/template.js.map +1 -0
  46. package/dist/utils/validate.d.ts +4 -0
  47. package/dist/utils/validate.js +27 -0
  48. package/dist/utils/validate.js.map +1 -0
  49. package/package.json +50 -0
  50. package/templates/backend/app.module.ts.ejs +61 -0
  51. package/templates/backend/bff.controller.ts.ejs +60 -0
  52. package/templates/backend/bff.module.ts.ejs +10 -0
  53. package/templates/backend/bff.service.ts.ejs +6 -0
  54. package/templates/backend/create-schema.migration.ts.ejs +15 -0
  55. package/templates/backend/data-source.ts.ejs +13 -0
  56. package/templates/backend/env.example.ejs +30 -0
  57. package/templates/backend/main.ts.ejs +43 -0
  58. package/templates/backend/module.ts.ejs +14 -0
  59. package/templates/backend/nest-cli.json.ejs +8 -0
  60. package/templates/backend/package.json.ejs +23 -0
  61. package/templates/backend/tsconfig.build.json.ejs +4 -0
  62. package/templates/backend/tsconfig.json.ejs +24 -0
  63. package/templates/claude/CLAUDE.md.ejs +86 -0
  64. package/templates/claude/hooks/auto-format.sh +22 -0
  65. package/templates/claude/hooks/check-secrets.sh +49 -0
  66. package/templates/claude/hooks/guard-destructive.sh +42 -0
  67. package/templates/claude/hooks/on-compaction.sh +29 -0
  68. package/templates/claude/mcp.json +10 -0
  69. package/templates/claude/rules/api-patterns.md +86 -0
  70. package/templates/claude/rules/auth-patterns.md +109 -0
  71. package/templates/claude/rules/backend-patterns.md +421 -0
  72. package/templates/claude/rules/database-patterns.md +96 -0
  73. package/templates/claude/rules/docker-patterns.md +86 -0
  74. package/templates/claude/rules/frontend-patterns.md +262 -0
  75. package/templates/claude/rules/observability-backend.md +132 -0
  76. package/templates/claude/rules/observability-frontend.md +49 -0
  77. package/templates/claude/rules/playwright-mcp.md +80 -0
  78. package/templates/claude/rules/resilience-ops.md +103 -0
  79. package/templates/claude/rules/testing-e2e-ui.md +190 -0
  80. package/templates/claude/rules/testing-patterns.md +94 -0
  81. package/templates/claude/rules/workflow-backend.md +64 -0
  82. package/templates/claude/rules/workflow-frontend.md +60 -0
  83. package/templates/claude/settings.json +68 -0
  84. package/templates/claude/skills/add-api-endpoint/SKILL.md +59 -0
  85. package/templates/claude/skills/add-auth-endpoint/SKILL.md +68 -0
  86. package/templates/claude/skills/add-entity/SKILL.md +56 -0
  87. package/templates/claude/skills/add-event/SKILL.md +127 -0
  88. package/templates/claude/skills/add-feature/SKILL.md +20 -0
  89. package/templates/claude/skills/add-frontend-page/SKILL.md +75 -0
  90. package/templates/claude/skills/add-handler/SKILL.md +105 -0
  91. package/templates/claude/skills/add-integration/SKILL.md +176 -0
  92. package/templates/claude/skills/add-migration/SKILL.md +20 -0
  93. package/templates/claude/skills/add-module/SKILL.md +89 -0
  94. package/templates/claude/skills/add-realtime/SKILL.md +119 -0
  95. package/templates/claude/skills/audit-rules/SKILL.md +120 -0
  96. package/templates/claude/skills/debugging/SKILL.md +105 -0
  97. package/templates/claude/skills/docker-dev/SKILL.md +86 -0
  98. package/templates/claude/skills/e2e-audit/SKILL.md +85 -0
  99. package/templates/claude/skills/e2e-full/SKILL.md +132 -0
  100. package/templates/claude/skills/e2e-scan/SKILL.md +171 -0
  101. package/templates/claude/skills/e2e-verify/SKILL.md +145 -0
  102. package/templates/claude/skills/fix-bug/SKILL.md +33 -0
  103. package/templates/claude/skills/implement-spec/SKILL.md +98 -0
  104. package/templates/claude/skills/review-code/SKILL.md +109 -0
  105. package/templates/claude/skills/review-spec/SKILL.md +216 -0
  106. package/templates/claude/skills/run-tests/SKILL.md +37 -0
  107. package/templates/claude/skills/specify/SKILL.md +87 -0
  108. package/templates/claude/skills/write-backend-tests/SKILL.md +182 -0
  109. package/templates/claude/skills/write-ui-tests/SKILL.md +118 -0
  110. package/templates/docker/Dockerfile.client.ejs +14 -0
  111. package/templates/docker/Dockerfile.ejs +28 -0
  112. package/templates/docker/docker-compose.test.yml.ejs +54 -0
  113. package/templates/docker/docker-compose.yml.ejs +76 -0
  114. package/templates/docker/nginx.conf.ejs +21 -0
  115. package/templates/frontend/App.tsx.ejs +64 -0
  116. package/templates/frontend/DashboardPage.tsx.ejs +37 -0
  117. package/templates/frontend/LoginPage.tsx.ejs +20 -0
  118. package/templates/frontend/NotFoundPage.tsx.ejs +15 -0
  119. package/templates/frontend/api-client.ts.ejs +15 -0
  120. package/templates/frontend/index.css.ejs +57 -0
  121. package/templates/frontend/index.html.ejs +13 -0
  122. package/templates/frontend/main.tsx.ejs +10 -0
  123. package/templates/frontend/package.json.ejs +16 -0
  124. package/templates/frontend/playwright.config.ts.ejs +20 -0
  125. package/templates/frontend/postcss.config.js.ejs +3 -0
  126. package/templates/frontend/smoke.spec.ts.ejs +37 -0
  127. package/templates/frontend/tailwind.config.ts.ejs +56 -0
  128. package/templates/frontend/tsconfig.json.ejs +25 -0
  129. package/templates/frontend/tsconfig.node.json.ejs +15 -0
  130. package/templates/frontend/utils.ts.ejs +6 -0
  131. package/templates/frontend/vite-env.d.ts.ejs +1 -0
  132. package/templates/frontend/vite.config.ts.ejs +20 -0
  133. package/templates/root/gitignore.ejs +9 -0
  134. package/templates/root/prettierrc.ejs +7 -0
  135. package/templates/scripts/init-db.sh.ejs +8 -0
  136. package/templates/scripts/save-auth-state.ts.ejs +24 -0
@@ -0,0 +1,86 @@
1
+ # Docker Dev Environment
2
+
3
+ ## Architecture
4
+ ```
5
+ Backend (NestJS) → Docker Compose (volume-mounted, watch mode)
6
+ Frontend (Vite) → Native on host (NOT in Docker — HMR reliability)
7
+ Infrastructure → Docker internal network (no ports exposed except API + Keycloak)
8
+ ```
9
+
10
+ ## Commands
11
+ | Action | Command |
12
+ |--------|---------|
13
+ | Start all | `docker compose up` |
14
+ | Start with rebuild | `docker compose up --build` |
15
+ | Start backend only | `docker compose up backend` |
16
+ | View logs | `docker compose logs -f backend` |
17
+ | Stop all | `docker compose down` |
18
+ | Reset data | `docker compose down -v && docker compose up` |
19
+ | Shell into container | `docker compose exec backend sh` |
20
+ | Check health | `docker compose ps` |
21
+
22
+ ## Ports (exposed to host)
23
+ | Port | Service | Purpose |
24
+ |------|---------|---------|
25
+ | 3000 | Backend API | Vite proxies `/api/*` and `/auth/*` here |
26
+ | 8080 | Keycloak | OIDC browser redirects require direct access |
27
+ | 5173 | Vite (native) | Frontend dev server — NOT in Docker |
28
+
29
+ All other infrastructure (PostgreSQL, Redis, ELK, etc.) stays on Docker's internal network with no host ports.
30
+
31
+ ## Daily Workflow
32
+ ```bash
33
+ # Terminal 1: Backend + infrastructure
34
+ docker compose up
35
+
36
+ # Terminal 2: Frontend (native Vite)
37
+ cd client && npm run dev
38
+
39
+ # Browser: http://localhost:5173
40
+ ```
41
+
42
+ ## Troubleshooting
43
+
44
+ ### Container won't start
45
+ ```bash
46
+ docker compose logs <service> --tail=50
47
+ docker compose ps # check health status
48
+ ```
49
+
50
+ ### Database issues
51
+ ```bash
52
+ docker compose exec postgres psql -U postgres -d autoflux
53
+ npx typeorm migration:show # check pending migrations
54
+ npx typeorm migration:run # apply pending
55
+ ```
56
+
57
+ ### Redis issues
58
+ ```bash
59
+ docker compose exec redis redis-cli PING
60
+ docker compose exec redis redis-cli MONITOR # watch all commands
61
+ ```
62
+
63
+ ### Port conflicts
64
+ ```bash
65
+ lsof -i :3000 # find what's using the port
66
+ docker compose down && docker compose up # restart clean
67
+ ```
68
+
69
+ ### Volume mount not syncing
70
+ ```bash
71
+ docker compose restart backend # force re-read of mounted source
72
+ ```
73
+
74
+ ## Adding Infrastructure
75
+ 1. Add service to `docker-compose.yml` with healthcheck
76
+ 2. Add to backend `depends_on` with `condition: service_healthy`
77
+ 3. Use Docker hostname in backend config (e.g., `postgres`, `redis`) — NOT `localhost`
78
+ 4. Do NOT expose port to host unless absolutely required
79
+
80
+ ## Rules
81
+ - NEVER run Vite inside Docker — HMR is unreliable with volume mounts
82
+ - NEVER expose infrastructure ports to host (except Keycloak for OIDC redirects)
83
+ - NEVER hardcode API URLs in frontend — use relative paths (`/api/...`)
84
+ - NEVER use `docker compose up` for tests — use `docker-compose.test.yml`
85
+ - NEVER run services as root in production images
86
+ - Backend uses Docker hostnames (`postgres`, `redis`, `keycloak`) — NOT `localhost`
@@ -0,0 +1,85 @@
1
+ # E2E Audit — Verify Existing Specs Against Real Pages
2
+
3
+ ## Usage
4
+ ```
5
+ /e2e-audit # Audit all specs
6
+ /e2e-audit client/e2e/projects-list.spec.ts # Audit one spec
7
+ ```
8
+
9
+ ## What this does
10
+
11
+ For each spec file in `client/e2e/`, open the corresponding page via Playwright MCP and compare what's on screen vs what the spec tests. Report gaps and fix them.
12
+
13
+ **Announce "using Playwright MCP" before the first `browser_navigate`.**
14
+
15
+ ## Reproducing Failing Coded Specs
16
+
17
+ If a coded spec in `client/e2e/` is failing in CI, do NOT guess at the fix from the stack trace alone. Open the exact route via MCP, read the accessibility tree, and diff it against the selectors in the failing test. Paste the a11y snapshot into the fix commit message so the next reviewer can see what the live DOM looked like.
18
+
19
+ ## Prerequisites
20
+
21
+ 1. Docker test stack running: `docker compose -f docker-compose.test.yml up -d`
22
+ 2. Frontend dev server running: `cd client && VITE_API_URL=http://localhost:3099 npm run dev -- --port 5199`
23
+ 3. Auth state saved (or authenticate via MCP on first `browser_navigate`)
24
+
25
+ **IMPORTANT:** Always use the isolated test stack (`docker-compose.test.yml`) — NEVER `docker compose up` against the dev stack. Test ports: API 3099, Keycloak 8099, Frontend 5199.
26
+
27
+ ## Base URL
28
+
29
+ `http://localhost:5199`
30
+
31
+ ## Process per spec file
32
+
33
+ ### 1. Read the spec
34
+ Read the spec file. Note which route it tests, what selectors it uses, and which states it covers.
35
+
36
+ ### 2. Open the page via MCP
37
+ - `browser_navigate` to the route
38
+ - `browser_screenshot` to see the current layout
39
+ - Read the accessibility tree
40
+
41
+ ### 3. Compare and report
42
+
43
+ For each spec, check:
44
+
45
+ | Check | Pass/Fail |
46
+ |-------|-----------|
47
+ | **All 4 states tested?** (happy, error, empty, loading) | |
48
+ | **Selectors match real elements?** (heading text, button labels, etc.) | |
49
+ | **No stale selectors?** (elements that no longer exist) | |
50
+ | **No missing elements?** (interactive elements on page not tested) | |
51
+ | **Auth boundary tested?** (unauthenticated redirect) | |
52
+ | **No anti-patterns?** (CSS selectors, waitForTimeout, isVisible().toBe(true)) | |
53
+
54
+ ### 4. Fix issues found
55
+ - Update stale selectors to match current accessibility tree
56
+ - Add missing state tests (error, empty, loading)
57
+ - Remove tests for elements that no longer exist
58
+ - Add tests for new elements discovered via MCP
59
+
60
+ ## Spec files to audit
61
+
62
+ ```
63
+ client/e2e/login.spec.ts
64
+ client/e2e/dashboard.spec.ts
65
+ client/e2e/projects-list.spec.ts
66
+ client/e2e/create-project.spec.ts
67
+ client/e2e/project-detail.spec.ts
68
+ client/e2e/prompt-templates.spec.ts
69
+ client/e2e/profile.spec.ts
70
+ client/e2e/settings.spec.ts
71
+ client/e2e/users.spec.ts
72
+ ```
73
+
74
+ ## Output format
75
+
76
+ Print a summary table at the end:
77
+
78
+ ```
79
+ | Spec | 4 States | Selectors OK | Anti-patterns | Action |
80
+ |------|----------|--------------|---------------|--------|
81
+ | login.spec.ts | 3/4 (missing empty) | OK | None | N/A — no data endpoint |
82
+ | dashboard.spec.ts | 2/4 | OK | .animate-spin | Added loading test |
83
+ | projects-list.spec.ts | 4/4 | 1 stale | None | Fixed heading selector |
84
+ | ... | ... | ... | ... | ... |
85
+ ```
@@ -0,0 +1,132 @@
1
+ # E2E Full — Orchestrated Test Suite
2
+
3
+ Run all E2E skills in the correct sequence. Each phase feeds into the next.
4
+
5
+ ## Usage
6
+
7
+ - `/e2e-full` — run all 3 phases in order
8
+ - `/e2e-full scan` — run only the scan phase
9
+ - `/e2e-full audit` — run only the audit phase
10
+ - `/e2e-full verify` — run only the verify phase
11
+
12
+ ## Prerequisites
13
+
14
+ - Base URL: `http://localhost:5199`
15
+ - Docker test stack running: `docker compose -f docker-compose.test.yml up -d`
16
+ - Frontend dev server running: `cd client && VITE_API_URL=http://localhost:3099 npm run dev -- --port 5199`
17
+
18
+ Phase 0 handles the rest automatically.
19
+
20
+ **IMPORTANT:** E2E tests MUST use the isolated test stack (`docker-compose.test.yml`) with separate ports — NEVER the dev stack. Test ports: API 3099, Keycloak 8099, Frontend 5199.
21
+
22
+ ## Execution Order
23
+
24
+ ### Phase 0: Clean Stack (automatic)
25
+
26
+ **Purpose:** Guarantee a clean database, fresh containers, and a working MCP toolchain before any test phase runs.
27
+
28
+ 1. **MCP preflight** — verify the toolchain before touching Docker:
29
+ - `node --version` must report **v18 or higher**
30
+ - Confirm `.claude/mcp.json` pins a specific `@playwright/mcp` version (NOT `@latest`)
31
+ - Run `npx playwright install` to ensure browser binaries match the pinned MCP version
32
+ 2. Tear down any existing test stack:
33
+ ```bash
34
+ docker compose -f docker-compose.test.yml down -v
35
+ ```
36
+ 3. Rebuild and start the test stack:
37
+ ```bash
38
+ docker compose -f docker-compose.test.yml up -d --build
39
+ ```
40
+ 4. Wait for all services to be healthy (postgres, redis, keycloak, backend)
41
+ 5. Start frontend dev server on test port:
42
+ ```bash
43
+ cd client && VITE_API_URL=http://localhost:3099 npm run dev -- --port 5199 &
44
+ ```
45
+ 6. Save auth state for MCP journeys (against test stack):
46
+ ```bash
47
+ cd client && KEYCLOAK_PORT=8099 API_PORT=3099 npx tsx ../scripts/save-auth-state.ts
48
+ ```
49
+ 7. **MCP smoke test** — before declaring Phase 0 done, `browser_navigate` to `http://localhost:5199/` and confirm the accessibility tree returns. If MCP tools don't respond, STOP and report the MCP failure rather than running journeys blind.
50
+
51
+ **Stop condition:** If any service fails to become healthy within 3 minutes, STOP and report which service is unhealthy. Do not proceed to Phase 1. If the MCP smoke test fails, STOP — re-check `.claude/mcp.json` and Node version.
52
+
53
+ **Output:** Service health status table.
54
+
55
+ ---
56
+
57
+ ### Phase 1: Scan (`/e2e-scan`)
58
+
59
+ **Purpose:** Find missing journey coverage before testing.
60
+
61
+ 1. Load `/e2e-scan` skill
62
+ 2. Execute the scan — it reads routes, forms, hooks, and diffs against existing specs in `client/e2e/`
63
+ 3. If gaps are found, the scan generates missing spec files
64
+
65
+ **Stop condition:** None — scan always completes. Report any gaps found.
66
+
67
+ **Output:** Gap report table + list of specs generated (if any).
68
+
69
+ ---
70
+
71
+ ### Phase 2: Audit (`/e2e-audit`)
72
+
73
+ **Purpose:** Verify Playwright spec files match the real UI after code changes.
74
+
75
+ 1. Load `/e2e-audit` skill
76
+ 2. For each spec file in `client/e2e/`, open the page via MCP and compare selectors against the accessibility tree
77
+ 3. Report stale selectors, missing state tests, anti-patterns
78
+
79
+ **Stop condition:** None — audit always completes. Report all findings.
80
+
81
+ **Output:** Per-spec table with status (OK / STALE / MISSING) and recommended fixes.
82
+
83
+ ---
84
+
85
+ ### Phase 3: Verify (`/e2e-verify`)
86
+
87
+ **Purpose:** Walk through all user journeys and confirm pages render, forms work, navigation flows.
88
+
89
+ 1. Load `/e2e-verify` skill
90
+ 2. Execute ALL journeys (currently 10) — do not stop early
91
+ 3. Report each journey as PASS / FAIL / SKIP / UNTESTED
92
+
93
+ **Stop condition:** If more than 3 journeys FAIL, stop and report. Likely a systemic issue (auth expired, server down) rather than individual bugs.
94
+
95
+ **Session recovery:** If any journey redirects to `/login` unexpectedly mid-run, the storage state has expired. Re-run `cd client && npx tsx ../scripts/save-auth-state.ts` and retry the failed journey ONCE before marking it FAIL.
96
+
97
+ **Output:** Completion checklist table with result per journey.
98
+
99
+ ---
100
+
101
+ ## Final Report
102
+
103
+ After all phases complete, produce a summary:
104
+
105
+ ```
106
+ ## E2E Full Run Summary
107
+
108
+ | Phase | Status | Details |
109
+ |-------|--------|---------|
110
+ | 0. Clean Stack | DONE | test stack down -v + up --build, all services healthy |
111
+ | 1. Scan | DONE | X gaps found, Y specs generated |
112
+ | 2. Audit | DONE | X specs OK, Y stale, Z missing |
113
+ | 3. Verify | DONE | X pass, Y fail, Z skip |
114
+
115
+ ### Failed Journeys (action required)
116
+ - [Phase 3] Journey #N: <name> — <what failed>
117
+
118
+ ### Stale Specs (action required)
119
+ - <spec file> — <selector> no longer matches
120
+
121
+ ### Gaps Added (review recommended)
122
+ - <spec file> generated for <route>
123
+ ```
124
+
125
+ ## Rules
126
+
127
+ - **NEVER skip Phase 0.** Every `/e2e-full` run starts with a clean `docker compose -f docker-compose.test.yml down -v` + `up --build`. Stale data causes false passes.
128
+ - **NEVER use the dev stack (`docker compose up`) for E2E tests.** Always use `docker-compose.test.yml` with isolated test ports (API 3099, Keycloak 8099, Frontend 5199).
129
+ - **NEVER skip a phase silently.** If you can't run a phase, report it as SKIPPED with reason.
130
+ - **NEVER combine phases.** Each phase is a distinct section with its own output.
131
+ - **If running a single phase** (e.g. `/e2e-full verify`), only run that phase and produce its section of the report.
132
+ - **Context management:** If context is running low during Phase 3, mark remaining journeys as UNTESTED rather than silently omitting them.
@@ -0,0 +1,171 @@
1
+ # E2E Scan — Discover Missing Test Coverage & Generate Specs
2
+
3
+ ## Usage
4
+ ```
5
+ /e2e-scan # Full scan — all pages, all flows
6
+ /e2e-scan project # Scan only project-related flows
7
+ /e2e-scan --report-only # Report gaps without generating specs
8
+ ```
9
+
10
+ ## What this does
11
+
12
+ Scans the codebase to discover all user-facing flows (pages, forms, multi-step wizards, interactions), compares them against existing Playwright specs in `client/e2e/`, reports gaps, and generates missing spec files.
13
+
14
+ ## Process
15
+
16
+ ### Phase 1: Discover All Flows
17
+
18
+ Scan these sources to build a complete inventory of user-facing flows:
19
+
20
+ #### 1a. Routes & Pages
21
+ - Read the router config (React Router) for all route definitions
22
+ - Read each page component in `client/src/pages/` — note form steps, tabs, interactive elements
23
+ - Note protected vs public routes
24
+
25
+ #### 1b. Multi-Step Forms
26
+ - Search `client/src/pages/` for step-based forms (look for `step`, `currentStep`, `setStep`, stepper patterns)
27
+ - For each form, list all steps and the fields/interactions in each step
28
+ - Note form submission endpoints and success redirects
29
+
30
+ #### 1c. Interactive Features
31
+ - Search for drawers, modals, dialogs (`Dialog`, `Drawer`, `Sheet`) and what triggers them
32
+ - Search for tab switchers (`Tabs`, `TabsList`, tab state) and what content each tab shows
33
+ - Search for filter/search components and what they filter
34
+ - Search for infinite scroll / pagination (`usePaginatedQuery`, "Load more")
35
+
36
+ #### 1d. API-Driven Flows
37
+ - Read `client/src/hooks/` for all `useApiQuery`/`useApiMutation` hooks — each mutation represents a flow
38
+ - Note which hooks are used by which pages (grep for hook names in pages)
39
+ - Pay attention to mutations that trigger navigation or state changes
40
+
41
+ #### 1e. Schema Drift Check
42
+ - Read backend DTOs (`src/**/dtos/*.dto.ts`) for field additions/removals
43
+ - Cross-reference with E2E mock data — if a DTO field exists that no mock covers, the E2E coverage has a gap
44
+
45
+ ### Phase 2: Read Existing Test Coverage
46
+
47
+ - List all spec files in `client/e2e/` — extract the routes and flows each covers
48
+ - Read each spec to understand which states are tested (happy, error, empty, loading)
49
+ - Build a coverage matrix: route → states tested
50
+
51
+ ### Phase 3: Gap Analysis
52
+
53
+ For each discovered flow, check:
54
+
55
+ | Check | Covered? |
56
+ |-------|----------|
57
+ | Page renders & basic navigation | Spec file exists? |
58
+ | Happy path (data loads, displays correctly) | `test('shows ... on success')` exists? |
59
+ | Error state (API failure) | `test('shows error')` exists? |
60
+ | Empty state (no data) | `test('shows empty state')` exists? |
61
+ | Loading state (skeleton/spinner) | `test('shows loading')` exists? |
62
+ | Form submission + validation errors | Mutation flow tested? |
63
+ | All tabs/views on the page | Each tab has assertions? |
64
+ | Responsive (mobile viewport) | Mobile test exists? |
65
+
66
+ ### Phase 4: Report
67
+
68
+ Print a gap analysis table:
69
+
70
+ ```
71
+ ## E2E Coverage Report
72
+
73
+ | Route / Flow | Spec File | Happy | Error | Empty | Loading | Gap |
74
+ |---|---|---|---|---|---|---|
75
+ | /projects | projects.spec.ts | ✅ | ✅ | ❌ | ❌ | Missing empty + loading states |
76
+ | /projects/:id | - | ❌ | ❌ | ❌ | ❌ | No spec file |
77
+ | /settings | settings.spec.ts | ✅ | ❌ | N/A | ❌ | Missing error + loading |
78
+ | ...
79
+
80
+ ### Summary
81
+ - **Covered:** N routes with full 4-state coverage
82
+ - **Partial:** M routes missing some states
83
+ - **Uncovered:** K routes with no spec at all
84
+ ```
85
+
86
+ ### Phase 5: Generate Missing Specs
87
+
88
+ For each uncovered or partially covered route, generate a spec file following the `/write-ui-tests` pattern:
89
+
90
+ 1. Create spec at `client/e2e/<route-name>.spec.ts`
91
+ 2. Include all 4 mandatory states (happy, error, empty, loading)
92
+ 3. Mock auth via `page.route('**/auth/me', ...)`
93
+ 4. Mock API endpoints via `page.route()`
94
+ 5. Use semantic locators (`getByRole`, `getByText`) — NEVER CSS selectors
95
+
96
+ #### Spec template
97
+
98
+ ```typescript
99
+ import { test, expect } from '@playwright/test';
100
+
101
+ test.describe('<PageName> Page', () => {
102
+ test.beforeEach(async ({ page }) => {
103
+ await page.route('**/auth/me', route => route.fulfill({
104
+ status: 200,
105
+ contentType: 'application/json',
106
+ body: JSON.stringify({ keycloakId: 'kc-1', email: 'test@test.com', roles: ['user'] }),
107
+ }));
108
+ });
109
+
110
+ test('shows data on success', async ({ page }) => {
111
+ await page.route('**/api/<endpoint>*', route => route.fulfill({
112
+ status: 200, json: { data: [/* mock data */] },
113
+ }));
114
+ await page.goto('/<route>');
115
+ await expect(page.getByRole('heading', { name: '<expected>' })).toBeVisible();
116
+ });
117
+
118
+ test('shows error on API failure', async ({ page }) => {
119
+ await page.route('**/api/<endpoint>*', route => route.fulfill({ status: 500 }));
120
+ await page.goto('/<route>');
121
+ await expect(page.getByText(/something went wrong|error|try again/i)).toBeVisible();
122
+ });
123
+
124
+ test('shows empty state when no data', async ({ page }) => {
125
+ await page.route('**/api/<endpoint>*', route => route.fulfill({
126
+ status: 200, json: { data: [] },
127
+ }));
128
+ await page.goto('/<route>');
129
+ await expect(page.getByText(/no <items>/i)).toBeVisible();
130
+ });
131
+
132
+ test('shows loading while fetching', async ({ page }) => {
133
+ await page.route('**/api/<endpoint>*', async route => {
134
+ await new Promise(r => setTimeout(r, 2000));
135
+ await route.fulfill({ status: 200, json: { data: [] } });
136
+ });
137
+ await page.goto('/<route>');
138
+ // Assert skeleton visible
139
+ });
140
+ });
141
+ ```
142
+
143
+ ### Phase 6: Verify Generated Specs
144
+
145
+ - Read each generated spec to confirm selectors are plausible (based on component source)
146
+ - Confirm mock data shape matches the actual API response DTOs
147
+ - Run: `cd client && npx playwright test <spec-file> --reporter=list`
148
+
149
+ ## What NOT to do
150
+
151
+ - Don't generate specs for static pages with no API calls (just a heading check is enough)
152
+ - Don't duplicate coverage already in existing specs
153
+ - Don't guess at selectors — read the component source to find actual text/roles
154
+ - Don't test third-party service behavior
155
+ - Don't test backend-only flows (those belong in `/write-backend-tests`)
156
+
157
+ ## Output
158
+
159
+ End with a summary:
160
+
161
+ ```
162
+ ## Generated Specs
163
+
164
+ - client/e2e/project-detail.spec.ts — covers /projects/:id (4 states)
165
+ - client/e2e/settings.spec.ts — added missing error + loading tests
166
+
167
+ ## Still Needs Manual Attention
168
+
169
+ - /ai-gateway/* — complex multi-step flow, needs manual spec design
170
+ - /admin/* — requires admin role seeding
171
+ ```
@@ -0,0 +1,145 @@
1
+ # E2E Verify — Playwright MCP Journeys
2
+
3
+ Walk through user journeys interactively using Playwright MCP browser control. No spec files, no selectors to maintain.
4
+
5
+ **Announce "using Playwright MCP" before the first `browser_navigate`** — this prevents Claude from falling back to Bash-driven Playwright.
6
+
7
+ ## Viewport Matrix
8
+
9
+ For journeys that verify rendering/layout, resize the browser and re-check at two viewports:
10
+
11
+ | Viewport | Size | Purpose |
12
+ |----------|------|---------|
13
+ | Desktop | 1440 × 900 | Primary layout with sidebar |
14
+ | Tablet | 768 × 1024 | Collapsed sidebar, responsive grid |
15
+
16
+ Use `browser_resize` between viewports.
17
+
18
+ ## Prerequisites
19
+
20
+ 1. Docker test stack running: `docker compose -f docker-compose.test.yml up -d`
21
+ 2. Frontend dev server running: `cd client && VITE_API_URL=http://localhost:3099 npm run dev -- --port 5199`
22
+ 3. Auth state saved (against test stack): `cd client && KEYCLOAK_PORT=8099 API_PORT=3099 npx tsx ../scripts/save-auth-state.ts`
23
+ - This completes the BFF OIDC login flow and saves the httpOnly session cookie
24
+ - The app uses BFF cookies for auth — NOT sessionStorage/localStorage tokens
25
+ 4. If auth state is empty or expired, authenticate via MCP:
26
+ - Navigate to `/auth/login?provider=keycloak&returnTo=/`
27
+ - Fill Keycloak form (testuser / TestPassword1!)
28
+ - Verify redirect back to app with session cookie set
29
+
30
+ **IMPORTANT:** Always use the isolated test stack (`docker-compose.test.yml`) — NEVER `docker compose up` against the dev stack. Test ports: API 3099, Keycloak 8099, Frontend 5199.
31
+
32
+ ## Base URL
33
+
34
+ `http://localhost:5199`
35
+
36
+ ## Journeys
37
+
38
+ ### 1. Auth Boundaries
39
+ 1. Without auth, navigate to `/projects` — verify redirect to `/login`
40
+ 2. Navigate to `/login` — verify login page with Keycloak and Google sign-in buttons
41
+ 3. Authenticate via BFF `/auth/login?provider=keycloak` — verify Keycloak form, login, redirect to app
42
+ 4. After auth, navigate to `/login` — verify redirect to `/` (dashboard)
43
+
44
+ ### 2. Dashboard
45
+ 1. Navigate to `/` — verify heading "Dashboard"
46
+ 2. Verify welcome message shows user display name ("Welcome back, <name>")
47
+ 3. Verify "Getting Started" card with "Your AutoFlux workspace is ready" description
48
+ 4. Verify navigation hint to Projects
49
+
50
+ ### 3. Sidebar Navigation
51
+ 1. Verify sidebar renders with navigation links: Dashboard, Projects, Users, Settings
52
+ 2. Verify active link styling matches current route
53
+ 3. Click collapse toggle — verify sidebar collapses (icons only)
54
+ 4. Click expand toggle — verify sidebar expands back
55
+ 5. Verify logout button present and functional
56
+ 6. Verify admin links visible only for admin role (Prompt Templates)
57
+
58
+ ### 4. Projects List
59
+ 1. Navigate to `/projects` — verify heading "Projects"
60
+ 2. If projects exist — verify project cards render with name and GitHub repo URL
61
+ 3. If no projects — verify empty state "No projects yet" with "Create your first project" CTA
62
+ 4. Verify "New Project" link/button navigates to `/projects/new`
63
+
64
+ ### 5. Create Project
65
+ 1. Navigate to `/projects/new` — verify heading "Create Project"
66
+ 2. Verify form fields: Project Name input, GitHub Organization dropdown (async-loaded), Repository Name input
67
+ 3. Verify organization dropdown shows loading state then populates from GitHub API
68
+ 4. Enter repo name — verify real-time validation (alphanumeric, hyphens, underscores, dots)
69
+ 5. Enter invalid repo name (e.g. "my repo!") — verify validation error message
70
+ 6. Fill all fields with valid data — verify preview URL shows `github.com/<org>/<repo>`
71
+ 7. Click "Create Project" — verify submission spinner, then redirect to `/projects`
72
+ 8. Verify cancel button navigates back to `/projects`
73
+
74
+ ### 6. Project Detail & Planning
75
+ 1. Navigate to `/projects/:id` — verify project name heading, GitHub repo URL link
76
+ 2. Verify BRD upload section renders with drag-and-drop zone
77
+ 3. Verify "Start Planning" button is disabled before file selection
78
+ 4. Select a file (drag or click) — verify file name shown, "Start Planning" enabled, "Clear" visible
79
+ 5. Click "Start Planning" — verify spinner during upload
80
+ 6. After success — verify "Planning run started" message
81
+ 7. If API returns error — verify error message displayed
82
+
83
+ ### 7. Profile
84
+ 1. Navigate to `/profile` — verify heading "Profile"
85
+ 2. Verify avatar with initials (derived from display name)
86
+ 3. Verify display name, email, role, and user ID displayed
87
+ 4. Verify card layout with proper labels
88
+
89
+ ### 8. Admin — Prompt Templates
90
+ 1. Navigate to `/admin/prompt-templates` — verify heading "Prompt Templates"
91
+ 2. If templates exist — verify step cards with step number, name, template preview, approver roles
92
+ 3. If no templates — verify "None defined yet" empty state
93
+ 4. Click "Add Step" — verify create form opens with step name input, template textarea
94
+ 5. Fill form and submit — verify new step appears in list
95
+ 6. Click "Edit" on a template — verify inline edit mode with textarea
96
+ 7. Edit and save — verify updated content persists
97
+ 8. Verify error handling on create failure (validation error displayed)
98
+
99
+ ### 9. Settings (Stub)
100
+ 1. Navigate to `/settings` — verify heading "Settings" with "Configure your workspace" subtitle
101
+ 2. Verify "Workspace Settings" card with admin-only description
102
+
103
+ ### 10. Users (Stub)
104
+ 1. Navigate to `/users` — verify heading "Users" with "Manage users and their roles" subtitle
105
+ 2. Verify "User Management" card with admin-only description
106
+
107
+ ## Reporting
108
+
109
+ **MANDATORY: Complete ALL journeys.** Do not stop early. If context is running low, summarize remaining journeys as UNTESTED rather than silently omitting them.
110
+
111
+ For each journey, report:
112
+ - **PASS** — all pages render correctly, navigation works
113
+ - **FAIL** — specify which step failed and what was wrong (include screenshot)
114
+ - **SKIP** — if prerequisite data doesn't exist
115
+ - **UNTESTED** — journey was not attempted (context limit, blocker, etc.)
116
+
117
+ ### Completion Checklist (copy into your final report)
118
+
119
+ ```
120
+ | # | Journey | Result |
121
+ |----|----------------------------|----------|
122
+ | 1 | Auth Boundaries | |
123
+ | 2 | Dashboard | |
124
+ | 3 | Sidebar Navigation | |
125
+ | 4 | Projects List | |
126
+ | 5 | Create Project | |
127
+ | 6 | Project Detail & Planning | |
128
+ | 7 | Profile | |
129
+ | 8 | Admin — Prompt Templates | |
130
+ | 9 | Settings (Stub) | |
131
+ | 10 | Users (Stub) | |
132
+ ```
133
+
134
+ **Every row must have a result.** An incomplete checklist is a failed run.
135
+
136
+ ## What MCP Covers vs What Coded Tests Cover
137
+
138
+ | MCP Journeys | Coded Tests (`client/e2e/`) |
139
+ |---|---|
140
+ | Page renders correctly | Mock-based state assertions |
141
+ | Navigation flows work | 4-state coverage (happy/error/empty/loading) |
142
+ | Forms display fields & validate | API response shape verification |
143
+ | Visual layout intact | Isolated page-level testing |
144
+ | Interactive elements respond | Auth boundary testing |
145
+ | File upload UX works | Form submission flows |
@@ -0,0 +1,33 @@
1
+ # Fix Bug
2
+
3
+ ## Usage
4
+ ```
5
+ /fix-bug <issue-number-or-description>
6
+ ```
7
+
8
+ ## Process (this order is mandatory)
9
+
10
+ ### Step 1: Reproduce
11
+ - Read the bug report (issue, error log, or description)
12
+ - Identify the failing behavior and expected behavior
13
+ - Find the relevant code paths
14
+
15
+ ### Step 2: Regression Test FIRST
16
+ - Write a test that reproduces the bug
17
+ - Run it — **verify it fails** (this proves the bug exists and the test catches it)
18
+ - If the test passes, your test is wrong — it does not reproduce the bug
19
+
20
+ ### Step 3: Fix
21
+ - Analyze the root cause (not just the symptom)
22
+ - Implement the minimal fix
23
+ - Run the regression test — **verify it now passes**
24
+ - Run `npm run build && npm test` — verify nothing else broke
25
+
26
+ ### Step 4: Commit
27
+ - Commit with message: `fix: <what-was-fixed> (#<issue-number>)`
28
+
29
+ ## Rules
30
+ - The regression test MUST exist before the fix — no exceptions
31
+ - Fix the root cause, not the symptom
32
+ - Keep the fix minimal — don't refactor surrounding code
33
+ - Follow project conventions in CLAUDE.md and `.claude/rules/`