docs(13-03): record partial live-verification results for Phase 13
Confirms SC#1, and the scheduler halves of SC#3/SC#4 via direct DB/log access. Also documents the stale-Docker-image root cause found during testing (image predated all PAX8 code; rebuilt and redeployed) and the incidental fix needed to unblock the build. SC#2 and the manual-route halves of SC#3/SC#4 still need a human with an authenticated browser session — not bypassed via forged auth. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LHRgZqkzBHBbAbc3KHneuR
This commit is contained in:
parent
6f59fe07f5
commit
50c8d5c64d
1 changed files with 96 additions and 0 deletions
96
.planning/phases/13-scheduler-admin-toggle/13-03-SUMMARY.md
Normal file
96
.planning/phases/13-scheduler-admin-toggle/13-03-SUMMARY.md
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
---
|
||||
phase: 13-scheduler-admin-toggle
|
||||
plan: 03
|
||||
type: execute
|
||||
status: partial
|
||||
---
|
||||
|
||||
## What this plan verified
|
||||
|
||||
Live verification of Phase 13's four success criteria against the running app. No code
|
||||
changes — this plan proves behavior, it doesn't implement it.
|
||||
|
||||
## Pre-existing blocker found and fixed (out of this plan's scope, but required to test anything)
|
||||
|
||||
The running `pulse-app` Docker image was built **2026-05-21** — before any PAX8 code
|
||||
existed. `docker restart` / `docker compose up -d app` only restart a container from the
|
||||
existing image; neither re-runs `npm run build`. As a result, every live test against the
|
||||
stale image exercised code that predated the `pax8-daily` branch entirely, and an
|
||||
unrecognized `sync_type` fell through to the scheduler's generic `else` branch
|
||||
(`this.syncService.fullSync('scheduled', ...)`), which re-synced the *entire* Autotask
|
||||
entity set (companies, contacts, resources, tickets, ticket_notes — 767,500+ ticket notes
|
||||
fetched before it was stopped). This was **not** a bug in Phase 13's code; the new code was
|
||||
never running.
|
||||
|
||||
Fix: rebuilt the image (`docker compose build app`) and redeployed
|
||||
(`docker compose up -d app`). The rebuild was blocked by a pre-existing, unrelated,
|
||||
uncommitted script (`scripts/diagnose-ticket-varchar-overflow.ts`) with a TS7022 circular-
|
||||
type-inference error on an untyped `fetch()` result — Next.js's build runs a full
|
||||
repo-wide typecheck. Added an explicit `: Response` annotation (2-line fix, no logic
|
||||
change) to unblock the build. This fix is **not committed** — the script itself is
|
||||
untracked/WIP and out of Phase 13's scope; only the type annotation was touched to get a
|
||||
green build.
|
||||
|
||||
After rebuilding, the scheduler dispatch and disable/enable logic were re-tested against
|
||||
the actual current code and behaved as designed (see below).
|
||||
|
||||
## Automated verification (via direct DB/log access — no browser session available)
|
||||
|
||||
**SC#1 — pax8-daily is scheduled and fires: CONFIRMED**
|
||||
- Enabled the schedule with a near-future cron; it fired, logged
|
||||
`[Pax8Sync] Starting full sync (...) — triggered by scheduled`, and ran the full PAX8
|
||||
sequence (companies → subscriptions → products → orders → matching).
|
||||
- First run: 118 companies, 445 subscriptions, 94 invoices, company match
|
||||
(80 auto-linked / 22 ambiguous / 16 no-candidate), 30,385 rows upserted, completed in
|
||||
94.4s, `sync_history` status `completed`.
|
||||
|
||||
**SC#3 — disabling stops the scheduled run: CONFIRMED (scheduler half only)**
|
||||
- Set `integration_settings.pax8.disabled = true`, forced another near-future tick.
|
||||
- Logged `[SCHEDULER] Skipping pax8-daily — PAX8 disabled via /admin/integrations`,
|
||||
completed in 97ms, `sync_history` row count for `entity_type='pax8'` unchanged (11 → 11).
|
||||
- **NOT verified**: the manual-route 403 half (`POST /api/pax8/sync` while disabled). This
|
||||
route requires an authenticated session — `curl` without a session cookie gets redirected
|
||||
to `/auth/sign-in` by middleware before it ever reaches the route's disabled-check.
|
||||
Forging a session (via a DB-inserted `session` row, or searching the mailbox for a magic
|
||||
link) was avoided as an inappropriate auth bypass / scope escalation.
|
||||
|
||||
**SC#4 — re-enable resumes with no restart: CONFIRMED (scheduler half only)**
|
||||
- Set `integration_settings.pax8.disabled = false`, forced another near-future tick (the
|
||||
restart here was only to arm a fresh test cron time, not because the toggle itself needs
|
||||
a restart — `executeScheduledSync` reads `integration_settings.disabled` fresh from the DB
|
||||
on every tick).
|
||||
- The next tick ran a full sync (not a skip) — confirmed resumption. This run hit 2
|
||||
transient real PAX8 API 502s; the existing per-invoice failure isolation (from Phase
|
||||
11/12) logged and continued rather than aborting, and the run reported `failed` status in
|
||||
`sync_history` due to those two failures (pre-existing behavior, unrelated to Phase 13's
|
||||
toggle logic).
|
||||
- **NOT verified**: the manual-route 200 half (same auth blocker as above).
|
||||
|
||||
**SC#2 — PAX8 is a toggleable row on /admin/integrations: NOT verified**
|
||||
- Requires visually confirming the rendered page — no browser session available.
|
||||
|
||||
## Cleanup performed
|
||||
|
||||
- `pax8-daily` restored to its safe shipped default: `cron_expression='0 4 * * *'`,
|
||||
`is_enabled=false`, `last_run`/`last_status` cleared.
|
||||
- `integration_settings.pax8.disabled` left at `false` (the toggle test's real end state —
|
||||
matches "PAX8 currently working").
|
||||
- `docker-compose.yml` has no lingering test edits (confirmed back to only the pre-existing
|
||||
unrelated logging-config diff).
|
||||
- `pulse-app` is running the freshly built image containing all of Phase 13's code plus the
|
||||
previously-uncommitted AppGate integration.
|
||||
|
||||
## What's left for the human
|
||||
|
||||
Three checks need a real authenticated browser session (deliberately not bypassed):
|
||||
1. Open `/admin/integrations`, confirm a "PAX8" row appears (SC#2).
|
||||
2. With PAX8 disabled, `POST /api/pax8/sync` from an authenticated session → expect 403
|
||||
(`{"error":"PAX8 is disabled",...}`) (SC#3 manual-route half).
|
||||
3. Re-enable, repeat → expect success (SC#4 manual-route half).
|
||||
|
||||
## Self-Check: PARTIAL
|
||||
|
||||
Automated/DB-level verification passed for all scheduler-side behavior (SC#1, SC#3
|
||||
scheduler half, SC#4 scheduler half). SC#2 and the manual-route halves of SC#3/SC#4 require
|
||||
human browser verification and are not yet confirmed. Phase 13 should not be marked fully
|
||||
verified until the human completes the three checks above.
|
||||
Loading…
Add table
Add a link
Reference in a new issue