Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
53da66c
fix(scheduling): derive scheduled_start_ms on reschedule when the row…
important-new Aug 2, 2026
cfd8e2c
feat(library): delete canned comments, one row or many (#291)
important-new Aug 2, 2026
1f2d4f2
perf(gates): stop pre-commit paying for work the staged change cannot…
important-new Aug 2, 2026
9f8cf55
chore: delete the one-shot data backfills — there is nothing left to …
important-new Aug 2, 2026
8acc808
chore(i18n): let server code read compiled messages, through one guar…
important-new Aug 2, 2026
aeab1f5
i18n(notices): move the seven stored notice titles into the catalogue
important-new Aug 2, 2026
8592dcc
fix(qbo): push card payments to QuickBooks, and make the push idempotent
important-new Aug 2, 2026
53a1d40
feat(services): seed the service catalogue, and give a service its vi…
important-new Aug 2, 2026
b783fe0
feat(services): warn when two services would default to the same temp…
important-new Aug 2, 2026
bb957bb
feat(roster): one accessor for "who worked this inspection"
important-new Aug 2, 2026
b7f8564
fix(roster): one authority for "who worked this inspection", and free…
important-new Aug 2, 2026
4c76ee5
feat(services): soft-delete inspection service lines before anything …
important-new Aug 3, 2026
a0b7f71
feat(reports): the reports entity — one order, several reports
important-new Aug 3, 2026
338ec60
feat(reports): move results and versions onto reports
important-new Aug 3, 2026
62a56cd
fix(reports): per-report signature chain and per-report collab document
important-new Aug 3, 2026
c4d7f6b
fix(collab): key the Durable Object's D1 projection on the report too
important-new Aug 3, 2026
80f2395
feat(reports): document the order-wide gate, and add a per-inspection…
important-new Aug 3, 2026
a2ddd94
feat(hub): unlock control for the order-wide report gate, and setting…
important-new Aug 3, 2026
2916822
docs(reports): record the surfaces the multi-report blast radius name…
important-new Aug 3, 2026
a07333b
docs: replace the key-files table with prose
important-new Aug 3, 2026
bdf3e2b
fix(tests): the two resolvers only real workerd could catch
important-new Aug 3, 2026
b44c528
fix(reports): create the primary report at inspection creation
important-new Aug 3, 2026
319f894
fix(reports): use REPORT_STATUS.IN_PROGRESS, not a bare literal
important-new Aug 3, 2026
10df09a
ci: cache react-router typegen the way paraglide already is
important-new Aug 3, 2026
ff28ac7
test(presence): wait for the roster to converge instead of sleeping 50ms
important-new Aug 3, 2026
db73f22
refactor(assignment): make inspection_inspectors the only place assig…
important-new Aug 3, 2026
adbbea5
ci: cache the Playwright browser, and declare the dependency e2e reli…
important-new Aug 3, 2026
9b533d5
perf(tests): stop paying for a DOM and a serial suite that nothing ne…
important-new Aug 3, 2026
4176243
docs(testing): record what running e2e projects in parallel now requires
important-new Aug 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 6 additions & 1 deletion .githooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,12 @@ needs_typegen() {
# Editing a route module's body does not change its generated types — those
# infer from `typeof loader` when tsc runs. A route file APPEARING or
# DISAPPEARING changes the tree, and that does.
echo "$STAGED_TREE" | grep -qE '^app/routes/'
#
# A colocated SPEC is not a route: `app/routes/foo.test.tsx` never enters
# routes.ts, so typegen's output cannot differ because one arrived. The Test
# Layout in CLAUDE.md REQUIRES frontend specs to sit beside what they test,
# so this fires on ordinary work — and typegen costs ~60s measured here.
echo "$STAGED_TREE" | grep -E '^app/routes/' | grep -qvE '\.(test|spec)\.(ts|tsx)$'
}

step "Type check"
Expand Down
66 changes: 66 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ jobs:
path: app/paraglide
key: paraglide-${{ hashFiles('messages/**', 'project.inlang/**') }}
- run: npm run i18n:compile:cached
# Same shape as the paraglide cache above, and for the same reason: the
# output is a pure function of the route TREE, so a key built from those
# inputs can only restore what they produced. Five jobs need these types
# and every one of them was paying the full ~60s generate — five runner
# minutes per CI run for identical output. Hashing the route file bodies
# over-invalidates (editing a loader cannot change the generated types)
# but never under-invalidates, which is the safe direction for a cache.
- uses: actions/cache@v4
with:
path: .react-router/types
key: rr-typegen-${{ hashFiles('app/routes.ts', 'app/routes/**', 'react-router.config.ts', 'package-lock.json') }}
- run: npx react-router typegen
- run: npm run type-check:app

Expand Down Expand Up @@ -114,6 +125,17 @@ jobs:
path: app/paraglide
key: paraglide-${{ hashFiles('messages/**', 'project.inlang/**') }}
- run: npm run i18n:compile:cached
# Same shape as the paraglide cache above, and for the same reason: the
# output is a pure function of the route TREE, so a key built from those
# inputs can only restore what they produced. Five jobs need these types
# and every one of them was paying the full ~60s generate — five runner
# minutes per CI run for identical output. Hashing the route file bodies
# over-invalidates (editing a loader cannot change the generated types)
# but never under-invalidates, which is the safe direction for a cache.
- uses: actions/cache@v4
with:
path: .react-router/types
key: rr-typegen-${{ hashFiles('app/routes.ts', 'app/routes/**', 'react-router.config.ts', 'package-lock.json') }}
- run: npx react-router typegen
- run: npm run test:types

Expand Down Expand Up @@ -141,6 +163,17 @@ jobs:
path: app/paraglide
key: paraglide-${{ hashFiles('messages/**', 'project.inlang/**') }}
- run: npm run i18n:compile:cached
# Same shape as the paraglide cache above, and for the same reason: the
# output is a pure function of the route TREE, so a key built from those
# inputs can only restore what they produced. Five jobs need these types
# and every one of them was paying the full ~60s generate — five runner
# minutes per CI run for identical output. Hashing the route file bodies
# over-invalidates (editing a loader cannot change the generated types)
# but never under-invalidates, which is the safe direction for a cache.
- uses: actions/cache@v4
with:
path: .react-router/types
key: rr-typegen-${{ hashFiles('app/routes.ts', 'app/routes/**', 'react-router.config.ts', 'package-lock.json') }}
- run: npx react-router typegen
- run: npm run lint:eslint

Expand Down Expand Up @@ -168,6 +201,17 @@ jobs:
# the generated route types present or it reports the whole of app/routes
# as unresolved. In the old serial job these existed only because
# type-check had already run; nothing declared the dependency.
# Same shape as the paraglide cache above, and for the same reason: the
# output is a pure function of the route TREE, so a key built from those
# inputs can only restore what they produced. Five jobs need these types
# and every one of them was paying the full ~60s generate — five runner
# minutes per CI run for identical output. Hashing the route file bodies
# over-invalidates (editing a loader cannot change the generated types)
# but never under-invalidates, which is the safe direction for a cache.
- uses: actions/cache@v4
with:
path: .react-router/types
key: rr-typegen-${{ hashFiles('app/routes.ts', 'app/routes/**', 'react-router.config.ts', 'package-lock.json') }}
- run: npx react-router typegen
- run: npm run lint:gates-full
- name: Migration drift gate (schema vs migrations)
Expand Down Expand Up @@ -220,6 +264,17 @@ jobs:
path: app/paraglide
key: paraglide-${{ hashFiles('messages/**', 'project.inlang/**') }}
- run: npm run i18n:compile:cached
# Same shape as the paraglide cache above, and for the same reason: the
# output is a pure function of the route TREE, so a key built from those
# inputs can only restore what they produced. Five jobs need these types
# and every one of them was paying the full ~60s generate — five runner
# minutes per CI run for identical output. Hashing the route file bodies
# over-invalidates (editing a loader cannot change the generated types)
# but never under-invalidates, which is the safe direction for a cache.
- uses: actions/cache@v4
with:
path: .react-router/types
key: rr-typegen-${{ hashFiles('app/routes.ts', 'app/routes/**', 'react-router.config.ts', 'package-lock.json') }}
- run: npx react-router typegen
- run: npm run test:web

Expand Down Expand Up @@ -316,6 +371,17 @@ jobs:
- name: Provision ephemeral E2E secrets
run: node scripts/gen-e2e-dev-vars.mjs

# Keyed on the resolved Playwright version, because the browser build a
# given Playwright pins is a pure function of it — a hit can only ever
# restore the binary that version asked for. `--with-deps` still runs on a
# hit; it installs system libraries into /usr, which is outside the cached
# path and cheap once the download is skipped.
- name: Cache Playwright browser
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}

- name: Install Playwright browser (chromium)
run: npx playwright install --with-deps chromium

Expand Down
23 changes: 4 additions & 19 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,10 @@ applies the same config resolution to direct wrangler commands (db:migrate).

## Key Files & Directories

| File/Dir | Purpose |
|---|---|
| `workers/app.ts` | Single-worker entry — Hono mounts the full API in-process + delegates page routes to React Router SSR |
| `server/index.ts` | Hono API entry point and route configuration |
| `server/api/` | API route handlers (Auth, Inspections, Bookings, etc.) |
| `server/lib/db/` | Drizzle ORM schema (`server/lib/db/schema`) and database utilities |
| `server/lib/middleware/` | Hono middleware (Authentication, RBAC, etc.) |
| `server/lib/validations/` | Zod schemas per module |
| `server/services/` | Business logic, DB queries (Drizzle) |
| `migrations/` | D1 migration SQL (drizzle-kit schema-first: `0000_baseline.sql` + forward) |
| `tests/` | See "Test Layout" below |
| `app/routes/` | React Router v8 route files |
| `app/components/` | React components |
| `app/hooks/` | React hooks (useInspection, useFindings, useKeyboard, etc.) |
| `app/lib/` | API client (hono/client over the in-process binding), session management, helpers |
| `app/styles/tailwind.css` | Design System 0523 token layer (Tailwind v4) |
| `public/` | Static assets (fonts, logo, service worker, widget) |
| `packages/shared-ui/src/` | shared React components (Button, Pill, Card, etc.) |
| `packages/api-types/` | CoreApiType re-export for hono/client |
The layout is conventional and discoverable — `server/` (api, lib/db, lib/middleware,
lib/validations, services), `app/` (routes, components, hooks, lib), `packages/`
(shared-ui, api-types), `migrations/`, `public/`. `workers/app.ts` is the single
worker entry; see Core Architecture below for what it does and why.

### Test Layout

Expand Down
1 change: 1 addition & 0 deletions app/components/AuthShell.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect } from 'vitest';
import { render } from '@testing-library/react';
import { AuthShell } from '~/components/AuthShell';
Expand Down
1 change: 1 addition & 0 deletions app/components/CommandPalette.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen, fireEvent } from '@testing-library/react';
import { createRoutesStub } from 'react-router';
import { CommandPalette } from './CommandPalette';
Expand Down
1 change: 1 addition & 0 deletions app/components/CostExportButtons.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen } from "@testing-library/react";
import { CostExportButtons } from "./CostExportButtons";

Expand Down
1 change: 1 addition & 0 deletions app/components/LoadFailedNotice.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
/**
* The sentence that keeps "this did not load" apart from "there is nothing
* here" (IA-118).
Expand Down
1 change: 1 addition & 0 deletions app/components/MoneyInput.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen, fireEvent } from "@testing-library/react";
import { vi } from "vitest";
import { MoneyInput } from "./MoneyInput";
Expand Down
1 change: 1 addition & 0 deletions app/components/NewInspectionWizard.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
/**
* Free-tier "at cap" gate — the New Inspection wizard should show the
* upgrade panel IMMEDIATELY when it opens for a tenant already at the free
Expand Down
1 change: 1 addition & 0 deletions app/components/QuotaBanner.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect } from 'vitest';
import { render } from '@testing-library/react';
import { QuotaBanner } from '~/components/QuotaBanner';
Expand Down
1 change: 1 addition & 0 deletions app/components/Toast.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect, afterEach } from 'vitest';
import { act, render, cleanup } from '@testing-library/react';
import { ToastPortal } from '~/components/Toast';
Expand Down
1 change: 1 addition & 0 deletions app/components/address/AddressAutocomplete.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect, vi } from "vitest";
import { useState } from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
Expand Down
1 change: 1 addition & 0 deletions app/components/address/GoogleMap.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect, vi, beforeEach } from "vitest";
import { render } from "@testing-library/react";

Expand Down
1 change: 1 addition & 0 deletions app/components/agent/cross-portal-reuse.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
/**
* The same entity must read the same in both portals.
*
Expand Down
1 change: 1 addition & 0 deletions app/components/audit/EntityAuditTrail.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen, fireEvent } from '@testing-library/react';
import { createRoutesStub } from 'react-router';
import { EntityAuditTrail, type AuditEntry } from './EntityAuditTrail';
Expand Down
1 change: 1 addition & 0 deletions app/components/booking/HolidayAdvisoryBanner.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect } from "vitest";
import { renderToStaticMarkup } from "react-dom/server";
import { createMemoryRouter, RouterProvider } from "react-router";
Expand Down
1 change: 1 addition & 0 deletions app/components/calendar/CalendarDatePicker.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect, vi } from "vitest";
import { createRef } from "react";
import { render, fireEvent } from "@testing-library/react";
Expand Down
1 change: 1 addition & 0 deletions app/components/calendar/CalendarScopeToolbar.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, expect, it, vi } from "vitest";
import { render } from "@testing-library/react";
import { CalendarScopeToolbar } from "./CalendarScopeToolbar";
Expand Down
1 change: 1 addition & 0 deletions app/components/calendar/InspectorSyncBadge.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, expect, it } from "vitest";
import { render } from "@testing-library/react";
import { InspectorSyncBadge, syncBadgeState } from "./InspectorSyncBadge";
Expand Down
1 change: 1 addition & 0 deletions app/components/collab/version-compare.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
// #181 PR-H (Task H2) — VersionCompare modal + VersionHistoryPanel compare flow.
//
// happy-dom + react-dom/client (no RTL in this repo). JSX avoided so the file
Expand Down
1 change: 1 addition & 0 deletions app/components/collab/version-history-panel.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
// #181 Task 12a — VersionHistoryPanel UI behaviour.
//
// Renders the panel under happy-dom via react-dom/client (no RTL dep in this
Expand Down
1 change: 1 addition & 0 deletions app/components/comment-editor.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen } from '@testing-library/react';
import { createRoutesStub } from 'react-router';
import { CommentEditor } from './CommentEditor';
Expand Down
1 change: 1 addition & 0 deletions app/components/contacts/CapabilityMatrix.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
/**
* Task 11 (two-layer role model) — the `?` capability matrix on the Roles page.
* Five booleans with no explanation is how email_template_id became IA-93:
Expand Down
1 change: 1 addition & 0 deletions app/components/contacts/RoleProfileModal.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
/**
* The modal auto-closes itself when a save succeeds, and the value it reads to
* decide that — `fetcher.data` — outlives the submission that produced it.
Expand Down
1 change: 1 addition & 0 deletions app/components/contacts/RolesTable.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
/**
* Admin Roles tab table (Plan 1B Task 4). Covers the behaviors the review
* checks for: renders the role-profile list, flags isSystem rows with a
Expand Down
1 change: 1 addition & 0 deletions app/components/dashboard/DashboardInspectionRow.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
/**
* The price on a dashboard row is integer CENTS and must be formatted as money.
*
Expand Down
1 change: 1 addition & 0 deletions app/components/defect-category-editor.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen } from '@testing-library/react';
import { createRoutesStub } from 'react-router';
import { DefectCategoryEditor } from './DefectCategoryEditor';
Expand Down
1 change: 1 addition & 0 deletions app/components/editor-shared/InlineRename.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen, fireEvent } from "@testing-library/react";
import { vi } from "vitest";
import { InlineRename } from "~/components/editor-shared/InlineRename";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor-shared/ItemList.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen } from '@testing-library/react';
import { vi } from 'vitest';
import { ItemList } from '~/components/editor-shared/ItemList';
Expand Down
1 change: 1 addition & 0 deletions app/components/editor-shared/RatingSegment.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect, afterEach } from "vitest";
import { render, screen, cleanup, fireEvent } from "@testing-library/react";
import { RatingSegment } from "./RatingSegment";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor-shared/SectionRail.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen, fireEvent } from '@testing-library/react';
import { vi } from 'vitest';
import { SectionRail } from '~/components/editor-shared/SectionRail';
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/BreadcrumbDropdown.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen, fireEvent } from "@testing-library/react";
import { vi } from "vitest";
import { BreadcrumbDropdown, type UnitScopeRow } from "~/components/editor/BreadcrumbDropdown";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/CommentLibraryList.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect, vi } from "vitest";
import { render, screen, fireEvent } from "@testing-library/react";
import { CommentLibraryList } from "../../../app/components/editor/CommentLibraryList";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/CommentTypeahead.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
// tests/web/unit/CommentTypeahead.spec.tsx
import { describe, it, expect, vi } from "vitest";
import { render, screen, fireEvent } from "@testing-library/react";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/CostItemsHost.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen, waitFor } from "@testing-library/react";
import { vi, beforeEach, afterEach } from "vitest";
import { CostItemsHost } from "./CostItemsHost";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/CostItemsPanel.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { vi, beforeEach, afterEach } from "vitest";
import { CostItemsPanel } from "./CostItemsPanel";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/SideRail.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen } from '@testing-library/react';
import { SideRail } from '~/components/editor/SideRail';

Expand Down
1 change: 1 addition & 0 deletions app/components/editor/UnitProgress.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen, fireEvent } from "@testing-library/react";
import { vi } from "vitest";
import { UnitProgress } from "~/components/editor/UnitProgress";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/UnitsManager.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, screen, fireEvent } from "@testing-library/react";
import { vi, beforeEach, afterEach } from "vitest";
import { UnitsManager, type UnitsManagerProps } from "~/components/editor/UnitsManager";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/batch-action-bar.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect, vi } from 'vitest';
import { renderToStaticMarkup } from 'react-dom/server';
import React from 'react';
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/item-editor-nonrich.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect, vi } from "vitest";
import { render, screen, fireEvent } from "@testing-library/react";
import { ItemEditor } from "../../../app/components/editor/ItemEditor";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/property-info-form.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { useState } from "react";
import { render, fireEvent, screen, waitFor } from "@testing-library/react";
import { createRoutesStub } from "react-router";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/side-rail-library-gate.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import { SideRail } from "../../../app/components/editor/SideRail";
Expand Down
1 change: 1 addition & 0 deletions app/components/editor/structure-delete-modal.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect } from 'vitest';
import { renderToStaticMarkup } from 'react-dom/server';
import { createElement } from 'react';
Expand Down
1 change: 1 addition & 0 deletions app/components/inspection-edit/compliance-panel.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { render, fireEvent, waitFor } from "@testing-library/react";
import { createRoutesStub, useLoaderData } from "react-router";
import { CompliancePanel, type CompliancePanelData } from "~/components/inspection-edit/CompliancePanel";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
/**
* IA-102 — adding a person to an inspection is an AUTHORIZATION act wearing
* the clothes of a data-entry one. Naming someone on the inspection is what
Expand Down
1 change: 1 addition & 0 deletions app/components/inspection/LinkExpiryControl.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
/**
* IA-36 ⑦ — one control, two places (Settings → Inspection, and the People
* card). It expresses a DURATION, never a date: the value therefore cannot land
Expand Down
1 change: 1 addition & 0 deletions app/components/inspection/PeopleEditor.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
/**
* Plan 1B Task 5 — editable People section on the inspection detail page.
* Covers what the review checks for: renders people grouped by role kind
Expand Down
1 change: 1 addition & 0 deletions app/components/inspection/SendReportModal.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
/**
* Spec 2 Task 7 — "Send report" modal. `SendReportModal` receives its
* fetcher as a prop (independent per-mutation fetcher, B-17), so tests build
Expand Down
1 change: 1 addition & 0 deletions app/components/inspection/pca-narrative-panel.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @vitest-environment happy-dom
import { describe, it, expect, vi } from "vitest";
import { render, fireEvent } from "@testing-library/react";
import { PcaNarrativePanel } from "~/components/inspection/PcaNarrativePanel";
Expand Down
Loading
Loading