Files
accounted/package.json
T
Jakob Wennberg ab63da8324 test: add real-Postgres smoke gate (pg-real) (#357)
* test: add real-Postgres smoke gate (pg-real)

Mocked Supabase tests cannot exercise triggers, RPCs, or RLS policies —
a migration that drops enforce_period_lock, mangles user_company_ids(),
or weakens an RLS policy ships green today. Closes that gap with a
small Vitest project `pg-real` running 5 smoke tests against a real
supabase/postgres:15 container in CI.

Covers: closed-period INSERT rejection, commit_journal_entry voucher
atomicity under concurrency, posted-entry immutability, RLS tenant
isolation on journal_entries, and audit_log UPDATE/DELETE rejection.

Also lands the bankid anonymization migration that was sitting
untracked from a prior task.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(pg-real): fix storage schema bootstrap + de-scope + PR review fixes

- Drop bankid anonymization migration from this PR. That change is
  separate scope (and has open compliance questions flagged by the
  Swedish review bot on #357); it will land in its own PR.
- Add tests/pg/bootstrap.sql to align storage.buckets/objects/foldername
  with what migrations expect before the replay loop. The supabase/postgres
  image ships only a partial storage schema; the rest comes from the
  storage-api service at runtime, which CI does not run. First pg-real run
  failed at migration 24 on "column public of relation buckets does not exist".
- Add concurrency group to the workflow so stacked PR commits cancel
  in-progress runs instead of queueing.
- Gate the pg-real vitest project on DATABASE_URL so a bare `vitest run`
  with no DB configured runs only the unit project. npm run test:pg is
  the opt-in entry point.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(pg-real): widen JWT claim setup so auth.uid() resolves under RLS

The rls.pg test came back with 0 rows instead of 1 — user_company_ids()
returned empty because auth.uid() didn't resolve to the seeded user.
Two fixes:
- Set both request.jwt.claims (whole object) and request.jwt.claim.sub
  (individual claim). Different Supabase auth.uid() versions read one or
  the other.
- Assert auth.uid() = expected userId immediately after the context
  switch, so the next failure points at the right layer instead of an
  unrelated empty-result assertion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:24:45 +02:00

82 lines
2.3 KiB
JSON

{
"name": "erp-base",
"version": "0.1.0",
"private": true,
"license": "AGPL-3.0-or-later",
"scripts": {
"setup:extensions": "npx tsx scripts/generate-extension-registry.ts",
"predev": "npm run setup:extensions",
"dev": "next dev",
"prebuild": "npm run setup:extensions",
"build": "next build",
"start": "next start",
"lint": "eslint",
"test": "vitest run --project unit",
"test:pg": "vitest run --project pg-real"
},
"dependencies": {
"@aws-sdk/client-bedrock-runtime": "^3.1022.0",
"@hookform/resolvers": "^5.2.2",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-progress": "^1.1.8",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-toast": "^1.2.15",
"@radix-ui/react-tooltip": "^1.2.8",
"@react-pdf/renderer": "^4.3.2",
"@supabase/ssr": "^0.8.0",
"@supabase/supabase-js": "^2.93.1",
"@tailwindcss/typography": "^0.5.19",
"@types/qrcode": "^1.5.6",
"@upstash/ratelimit": "^2.0.8",
"@upstash/redis": "^1.37.0",
"@use-gesture/react": "^10.3.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"framer-motion": "^12.29.2",
"fuse.js": "^7.1.0",
"ics": "^3.8.1",
"jszip": "^3.10.1",
"lucide-react": "^0.563.0",
"next": "16.1.5",
"next-themes": "^0.4.6",
"pdfjs-dist": "^5.4.530",
"qrcode": "^1.5.4",
"react": "19.2.3",
"react-dom": "19.2.3",
"react-hook-form": "^7.71.1",
"react-markdown": "^10.1.0",
"recharts": "^3.7.0",
"resend": "^6.9.1",
"server-only": "^0.0.1",
"sharp": "^0.34.5",
"svix": "^1.85.0",
"tailwind-merge": "^3.4.0",
"web-push": "^3.6.7",
"xlsx": "^0.18.5",
"zod": "^4.3.6"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/pg": "^8.20.0",
"@types/react": "^19",
"@types/react-dom": "^19",
"@types/sharp": "^0.31.1",
"@types/web-push": "^3.6.4",
"dotenv": "^17.2.3",
"eslint": "^9",
"eslint-config-next": "16.1.5",
"pg": "^8.20.0",
"tailwindcss": "^4",
"typescript": "^5",
"vitest": "^4.0.18"
}
}