16ad0955f2
Deploy to route.crispygoat.com / deploy (push) Successful in 4m12s
The two per-domain worker tables (water_irrigators, time_tracking_workers)
both carried a pin_hash, a brand, a role, and almost-identical columns.
Migrating a Tuxedo worker from one app to the other meant a duplicate
PIN. Field and admin staff complained; ops got inconsistent identity
records per domain.
Unify into a single field_workers table. Cycle 10 migration
0097_field_workers.sql:
- creates field_workers (id, brand_id, name, pin_hash, role with CHECK
IN ('worker','time_admin','irrigator','water_admin'),
language_preference, phone, notes, active, last_used_at, …)
- adds brand-scoped RLS, brand index, active index
- nullable field_worker_id on downstream tables, backfilled via
UPDATE … FROM, NULL count verified with RAISE EXCEPTION before
SET NOT NULL
- drops the two old tables and renames FK columns
(irrigator_id → field_worker_id, worker_id → field_worker_id)
- reissues the one-open-clock-in partial unique index against
field_worker_id
Application surface:
- All actions/services now read/write fieldWorkers. Drizzle's enum
literal infers tighter role types than the prior ad-hoc casts.
- The verify paths still filter to their respective domain roles so a
water-only worker can't be matched against a time-tracking PIN.
- API surface preserved: action function names didn't change.
- Seed file updated so QA reseeds work post-deploy.
Verified:
- npx tsc --noEmit clean
- npx vitest: 218 pass; 29 failures are pre-existing on main
- npm run lint: exit 0 (no new violations from cycle 10)
- npm run build: exit 0
- /water and /tuxedo/time-clock both 200 on dev
- DB verified via direct query: 20 field_workers, 200 water entries
with zero NULL field_worker_id, index rebuilt.
PR-reviewer: APPROVED.
35 lines
1.5 KiB
TypeScript
35 lines
1.5 KiB
TypeScript
import { defineConfig } from "vitest/config";
|
|
import react from "@vitejs/plugin-react";
|
|
import path from "node:path";
|
|
|
|
export default defineConfig({
|
|
plugins: [react()],
|
|
resolve: {
|
|
alias: [
|
|
{ find: /^@\/(?!db)/, replacement: path.resolve(__dirname, "src") + "/" },
|
|
// Specific sub-paths must come before the general @/db catch-all.
|
|
{ find: "@/db/schema/water-log", replacement: path.resolve(__dirname, "db/schema/water-log.ts") },
|
|
{ find: "@/db/schema/smartsheet-workspace", replacement: path.resolve(__dirname, "db/schema/smartsheet-workspace.ts") },
|
|
{ find: "@/db/schema/time-tracking", replacement: path.resolve(__dirname, "db/schema/time-tracking.ts") },
|
|
{ find: "@/db/schema/field-workers", replacement: path.resolve(__dirname, "db/schema/field-workers.ts") },
|
|
{ find: "@/db/client", replacement: path.resolve(__dirname, "db/client.ts") },
|
|
{ find: "@/db/schema", replacement: path.resolve(__dirname, "db/schema/index.ts") },
|
|
{ find: "@/db", replacement: path.resolve(__dirname, "db") },
|
|
],
|
|
},
|
|
test: {
|
|
environment: "node",
|
|
include: [
|
|
"tests/unit/**/*.test.ts",
|
|
"tests/unit/**/*.test.tsx",
|
|
"src/lib/__tests__/**/*.test.ts",
|
|
"src/lib/__tests__/**/*.test.tsx",
|
|
"src/lib/offline/**/*.test.ts",
|
|
],
|
|
exclude: ["node_modules", ".next", "tests/e2e/**", "tests/login/**", "tests/smoke.spec.ts"],
|
|
// Supabase REST, Auth.js v5, and Next.js `cookies()` / `headers()` are
|
|
// stubbed in each test — keep the timeout generous.
|
|
testTimeout: 15_000,
|
|
},
|
|
});
|