The test_db fixture calls Base.metadata.create_all on a fresh test DB.
That only creates tables for models that have been imported (and thus
registered with Base.metadata) by the time the fixture runs.
app.main imports app.core.database (which gives us Base) but does NOT
eagerly import the model modules — most are pulled in lazily inside
scheduler functions (archive_stale_ai_sessions etc.) and route
modules. At fixture-setup time, only the handful of models touched by
those eager imports are on the metadata, so any test that exercises
PSA, network diagrams, ratings, escalations, etc. fails with
\`UndefinedTableError: relation "X" does not exist\` and a cascade of
500s on every endpoint that queries the missing table.
Adding \`from app import models as _models\` (rather than the bare
\`import app.models\` which would shadow the \`app\` FastAPI instance
imported just above) pulls in app/models/__init__.py, which itself
imports every model module — registering all ~60 tables with
Base.metadata before create_all runs.
Verified locally: tests/test_psa_writeback_phase4.py went from
1 failed / 6 errors → 4 failed / 3 passed (the cascading errors were
masking the actual passes).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The new react-hooks lint rule "Calling setState synchronously within an
effect can trigger cascading renders" flagged real anti-patterns in
four spots. Refactored each per the rule's intent (derive during render,
or use useSyncExternalStore for external subscriptions).
1. hooks/useMediaQuery.ts — replaced the useState + useEffect pair with
useSyncExternalStore. That's the canonical React hook for
subscribing to external stores (matchMedia in this case) without
mirroring into local state via an effect. Snapshot/getServerSnapshot
pair preserves the SSR-safe behaviour.
2. components/network/nodes/DeviceNode.tsx — the prop-sync useEffect
that copied nodeData.label into labelValue was redundant.
labelValue is the EDIT BUFFER; while not editing, the displayed
span now reads nodeData.label directly. The buffer is initialized
only when an edit session starts (onDoubleClick).
3. components/network/nodes/GroupNode.tsx — same pattern, same fix.
4. components/dashboard/TicketQueue.tsx — the
setTickets([]) + setLoading(true) + fetchTickets() chain in the
effect was the cascade. Pushed those writes inside fetchTickets
(after the function boundary, so they batch with the eventual
setTickets(result)). Added a request-id ref so a slow first
response can't overwrite a fast second one.
Frontend lint: 20 errors → 0 errors. tsc -b clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Five files, all stylistic:
- useFlowPilotSession.ts: typed the axios error shape with a narrow
inline type instead of \`as any\`.
- FlowPilotSessionPage.tsx: same — typed location.state once, then
destructured.
- ScriptBuilderTab.tsx: handleViewScript was a placeholder no-op;
declared the args properly with \`void script; void filename\` so the
signature matches ScriptBuilderChatProps without no-unused-vars
firing.
- TicketsPage.tsx: replaced 8 ternaries-as-statements (\`x ? f() : g()\`)
with proper if/else blocks. Same control flow, satisfies
no-unused-expressions, and reads better in the URL-param update paths.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
react-refresh/only-export-components fires when a file with the
\`router\` const export also defines a component (the redirect helper).
Moves the small helper to its own file under components/routing/ so
HMR can keep the route-component module hot-reload-eligible.
No behavior change.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
pytest-asyncio==0.24.0 (added on the FlowPilot branch as part of the
RLS test infra refactor) declares pytest>=8.2 — but requirements-dev.txt
still pinned pytest==7.4.3, so a clean pip install fails with
ResolutionImpossible. CI runners that started from a fresh image would
have refused to install dev deps; the FlowPilot tests passed locally
only because the dev container had a pre-installed pytest 8.x lying
around.
pytest-cov 4.1.0 also needs >= 5.0 to play nicely with pytest 8.
No code changes — pytest 8 is API-compatible with the existing test
suite once the install resolves.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>