Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,54 @@
All notable changes to `padosoft/askmydocs-mcp-pack-admin` are documented here.
The project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased] → v1.1.0
## [v1.1.0] — 2026-05-18

GA release of the live wire-up cycle. The SPA is now fully functional
against the real `padosoft/askmydocs-mcp-pack` v1.5+ backend — every
read- and write-path action calls the host API. The bundled prototype
fixtures (`resources/js/lib/data.ts`) survive only as graceful
fallbacks for telemetry fields the BE doesn't yet emit (sparklines,
percentiles, etc.).

### Highlights

- **22 endpoints** typed end-to-end via the `request()` helper in
`resources/js/lib/api/client.ts` + 19 hand-written types mirroring
the v1.5 OpenAPI spec.
- **13 read hooks + 10 mutation hooks** wiring every page surface
(Dashboard / Servers list+detail / new-server wizard / Tools matrix
+ playground / Audit list+drilldown / Resources tree+content /
Prompts library / Circuit breakers grid).
- **R21 two-call confirm-token protocol** on `useInvokeTool` /
`useReplayAudit` / `useResetBreaker`, with a second-leg expired-
token guard that surfaces a hard failure instead of looping.
- **SSE live-feed consumer** in `App.tsx` replacing the prototype's
synthetic `setInterval` simulator. `livePausedRef` lets pause drop
events without disconnecting; events deduped by id; cap 200.
- **R14 (surface failures loudly) + R11 (testid contract) + R15
(a11y)** invariants enforced via the shared `<DataState>` wrapper
+ page-level fallback branches.
- **154 Vitest specs** across 22 test files covering loading / error
/ empty / ready states + R21 happy + failure paths + ValidationError
field-error surfacing + SSE consumer mount / dispatch / dedupe /
teardown.

### Deferred to v1.1.x

The 12 fixture-based Playwright specs that shipped with v1.0.x are
parked under `frontend/e2e-pending-v1.1.x/` because they assert on
prototype seed data that no longer appears once the SPA hits the live
API. CI now runs a single `frontend/e2e/smoke.spec.ts` that verifies
the SPA bundle mounts + the primary nav is reachable.

A real-backend Playwright suite (testbench Laravel host that
composer-requires `padosoft/askmydocs-mcp-pack:^1.5` + deterministic
`E2EDemoSeeder` + R38-compliant CLI migrate+seed step + spec
rewrites against the seeded dataset) is tracked in
[`docs/W5-E2E-REWRITE.md`](docs/W5-E2E-REWRITE.md) for a v1.1.x patch.
Page-level wire-up confidence comes from the 154 Vitest specs — every
endpoint binding has loading / error / empty / ready coverage via
MSW handlers shaped to the real wire schema.

### Fixed — W4 iter-2 review (Codex P2 — expired confirm-token loop)

Expand Down
70 changes: 70 additions & 0 deletions docs/W5-E2E-REWRITE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# v1.1.x — Real-backend Playwright suite rewrite

**Tracking doc** for the deferred W5 work parked at v1.1.0 GA.

## Why this was parked

v1.1.0 ships:

- Live API client (axios + Sanctum XSRF) → W2
- 22 endpoints typed end-to-end → W2
- 13 read hooks + 10 mutation hooks wiring every page surface → W2/W3/W4
- R21 two-call confirm-token protocol with expired-token guard → W4
- SSE live-feed consumer replacing the prototype simulator → W4
- **154 Vitest specs** covering every page-level API binding using
MSW handlers shaped to the real wire schema

The orthogonal piece — rewriting the prototype's 12 Playwright specs
to drive against a real Laravel testbench host — is **infrastructure
work** that the v1.1.0 GA functionally doesn't depend on (Vitest +
MSW already proves the wire-up). To stop the cycle from stretching
indefinitely, those specs were parked under
`frontend/e2e-pending-v1.1.x/` and CI runs the new `smoke.spec.ts`
instead.

## What v1.1.x must deliver

1. **Testbench-style Laravel host** under `tests/E2E/Host/` that
composer-requires `padosoft/askmydocs-mcp-pack:^1.5` so its
`/api/admin/mcp-pack/*` routes auto-register. Use Orchestra
Testbench's existing setup pattern (see `tests/TestCase.php`).
2. **`tests/E2E/Seeders/E2EDemoSeeder.php`** seeding a deterministic
dataset:
- 3 servers: `e2e-server-ok` (status=ok), `e2e-server-warn` (warn),
`e2e-server-err` (err) — varied transports (http/stdio/sse).
- ~10 tools across the 3 servers, with `input_schema` declarations.
- ~15 audit rows with the v1.5 wire shape
(`mcp_server_name`, `tool_name`, `duration_ms`, `created_at`,
`tenant_id`).
- 3 circuit breakers (one each: open / half_open / closed).
- A resource tree + prompt list per server.
3. **`/testing/reset` + `/testing/seed`** controllers gated on
`APP_ENV=testing` for Playwright fixture isolation.
4. **Auth bypass** scoped to `APP_ENV=testing`: a middleware that
auto-authenticates a fixed `e2e-admin` user inside a
`tenant_id=e2e-default` tenant. Production paths NEVER hit this.
5. **R38-compliant workflow step**: `php artisan migrate:fresh
--force` + `php artisan db:seed --class=E2EDemoSeeder` run as a
CLI step BEFORE Playwright starts (NOT behind `php artisan serve`
on every `/testing/reset`).
6. **Spec rewrites** for all 12 files in
`frontend/e2e-pending-v1.1.x/`, bringing them back to
`frontend/e2e/` one-by-one with assertions against the deterministic
seeder dataset.
7. **W4 write-path E2E coverage** (additive to the rewrites):
- Server CRUD wizard (3 steps) → success + 422 validation.
- ToolPlayground R21 two-call → success + expired-token failure.
- AuditDrilldown Replay R21 → success + confirmation_invalid.
- BreakersPage Reset R21 → open → reset → closed.
- SSE live-feed → trigger tool invoke, assert event arrives within
5s on the dashboard.
8. **`scripts/verify-e2e-real-data.sh`** (adapted from the
AskMyDocs main-repo gate) greps `page.route(` across
`frontend/e2e/` and fails CI on any unallowlisted internal
interception (R13).

## Scope estimate

~25 files of new code + 12 spec rewrites. Estimated 1-2 days of
focused work. Should ship as v1.1.1 or v1.1.2 (semver patch — pure
test infra + a few CI workflow lines, no public API changes).
27 changes: 27 additions & 0 deletions frontend/e2e-pending-v1.1.x/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Parked Playwright specs — v1.1.x real-backend rewrite

These 12 spec files were written against the prototype's bundled
fixture data (`resources/js/lib/data.ts`). After v1.1.0/W3+W4 wired
the SPA to live `padosoft/askmydocs-mcp-pack` v1.5 endpoints, every
assertion against fixture seed names (`openai-mcp`, `github-mcp`,
`delete-all`, etc.) became fixture-drift — the live API has no such
data.

For v1.1.0 GA we **parked** the suite here (out of Playwright's
`testDir`) so CI runs the new `frontend/e2e/smoke.spec.ts` instead.
Page-level wire-up is covered by **154 Vitest specs** under
`tests/js/` using MSW mocks of the real wire shape.

## v1.1.x rewrite plan

See [`docs/W5-E2E-REWRITE.md`](../../docs/W5-E2E-REWRITE.md) for the
full plan: testbench-style Laravel host that composer-requires
`padosoft/askmydocs-mcp-pack:^1.5`, deterministic `E2EDemoSeeder`,
`/testing/reset` + `/testing/seed` test-only endpoints, R38-compliant
CLI migrate+seed step before Playwright boots, real-backend Sanctum
auth bypass scoped to `APP_ENV=testing`.

Each spec in this directory will be brought back one-by-one once the
host harness is in place, replacing fixture seed names with the
deterministic seeder dataset (`e2e-server-ok`, `e2e-server-warn`,
`e2e-server-err`, `e2e-tool-{slug}`, etc.).
30 changes: 30 additions & 0 deletions frontend/e2e/smoke.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Minimal smoke test — verifies the SPA bundle loads, the top-level
// landmarks render, and the four primary nav targets are reachable.
//
// This is intentionally narrow: the production-grade Playwright suite
// (which exercises the real `padosoft/askmydocs-mcp-pack` backend
// end-to-end) is parked under `frontend/e2e-pending-v1.1.x/` and will
// be rewritten + re-enabled in a v1.1.x patch — see
// `docs/W5-E2E-REWRITE.md` for the plan.
//
// Until then this smoke spec is the only Playwright signal in CI,
// while the page-level wire-up is covered by 154 Vitest specs under
// `tests/js/` (every endpoint binding has loading / error / empty /
// ready coverage via MSW mocks of the real wire shape).

import { test, expect } from '@playwright/test';
import { dismissTour } from './global-setup';

test.beforeEach(async ({ page }) => {
await dismissTour(page);
});

test('SPA bundle mounts and the primary sidebar nav is reachable', async ({ page }) => {
await page.goto('/');
// The sidebar carries the load-bearing navigation. We don't assert on
// any API-driven content because that requires a live backend (W5 work).
await expect(page.getByText('Dashboard').first()).toBeVisible();
await expect(page.getByText('Servers').first()).toBeVisible();
await expect(page.getByText('Tools').first()).toBeVisible();
await expect(page.getByText('Audit log').first()).toBeVisible();
});
Loading