fix(projects): unbreak Create — drop $1::text reuse + tighten CM CHECK to 6 digits
Two issues m hit and reported in one breath while adding a project:
1. **Internal error on POST /projects** (prod-only, surfaced at 10:23). Both
ProjectService.Create and CreateCounterclaim re-referenced the uuid
parameter `$1` as `$1::text` to fill the path placeholder. Postgres'
planner deduced conflicting types for `$1` (uuid in the id column,
text in the cast) and rejected the prepared statement with 42P08
"inconsistent types deduced for parameter". The path placeholder
value is irrelevant — paliad.projects_sync_path() (BEFORE INSERT
trigger from mig 018/021) always overwrites it from id and parent
path. Fix: replace `$1::text` with a literal '' in both INSERTs,
keeping the parameter list decoupled from the id column's type.
Same comment now anchors the rationale on both call sites.
2. **CM number length — 6 digits, not 7.** m's correction; mig 018's
`^[0-9]{7}$` CHECK on paliad.projects.client_number and
matter_number was wrong. Mig 094 snapshots affected rows to
paliad.projects_pre_094, NULL-s the 3 surviving 7-digit test
values (2 client_numbers, 1 matter_number), then swaps the legacy
`projekte_*_check` constraints from {7} to {6}. Frontend pattern,
maxLength, placeholder, labels, and i18n hint flipped from 7 → 6
on both DE and EN sides; format hint reads CCCCCC.MMMMMM now.
Dry-run against live DB (BEGIN..ROLLBACK):
- Fixed Create SQL: trigger populates path = id::text (36 chars). ✓
- Mig 094: 2 rows snapshotted, 0 clients/matters remain after clear,
0 rows violate the new 6-digit CHECK. ✓
go build, go test ./internal/..., bun run build all clean.
This commit is contained in:
32
internal/db/migrations/094_clientmatter_six_digit.down.sql
Normal file
32
internal/db/migrations/094_clientmatter_six_digit.down.sql
Normal file
@@ -0,0 +1,32 @@
|
||||
-- mig 094 DOWN — restore the 7-digit CHECK and the snapshotted
|
||||
-- pre-clear client_number / matter_number values from
|
||||
-- paliad.projects_pre_094. Symmetric to the up migration.
|
||||
|
||||
SELECT set_config(
|
||||
'paliad.audit_reason',
|
||||
'mig 094 DOWN: restore 7-digit CHECK and pre-094 client_number/matter_number values from snapshot',
|
||||
true);
|
||||
|
||||
-- 1. Drop the 6-digit CHECKs.
|
||||
ALTER TABLE paliad.projects
|
||||
DROP CONSTRAINT projekte_client_number_check,
|
||||
DROP CONSTRAINT projekte_matter_number_check;
|
||||
|
||||
-- 2. Restore the original values from the snapshot. Only rows that
|
||||
-- existed at snapshot time are touched; rows added since stay as
|
||||
-- they were.
|
||||
UPDATE paliad.projects p
|
||||
SET client_number = s.client_number,
|
||||
matter_number = s.matter_number
|
||||
FROM paliad.projects_pre_094 s
|
||||
WHERE p.id = s.id;
|
||||
|
||||
-- 3. Re-add the legacy 7-digit CHECKs.
|
||||
ALTER TABLE paliad.projects
|
||||
ADD CONSTRAINT projekte_client_number_check
|
||||
CHECK (client_number IS NULL OR client_number ~ '^[0-9]{7}$'),
|
||||
ADD CONSTRAINT projekte_matter_number_check
|
||||
CHECK (matter_number IS NULL OR matter_number ~ '^[0-9]{7}$');
|
||||
|
||||
-- 4. Drop the snapshot. The down migration is the only consumer.
|
||||
DROP TABLE IF EXISTS paliad.projects_pre_094;
|
||||
97
internal/db/migrations/094_clientmatter_six_digit.up.sql
Normal file
97
internal/db/migrations/094_clientmatter_six_digit.up.sql
Normal file
@@ -0,0 +1,97 @@
|
||||
-- mig 094 — tighten paliad.projects.client_number + matter_number CHECK
|
||||
-- from 7-digit to 6-digit. The "7-Ziffern" rule in mig 018 was wrong;
|
||||
-- HLC's real Client/Matter format is 6 digits each (m's correction,
|
||||
-- 2026-05-17). The constraints carry the legacy 'projekte_*_check'
|
||||
-- name from before the table was renamed (mig 021), so the ALTER
|
||||
-- TABLE DROP / ADD has to use those names verbatim.
|
||||
--
|
||||
-- Existing rows: only test data (2 client_numbers, 1 matter_number),
|
||||
-- all 7-digit. They violate the new pattern, so we NULL them out
|
||||
-- before tightening — preserving the project rows themselves, just
|
||||
-- clearing the wrong-shaped billing identifiers. The rows are
|
||||
-- snapshotted in projects_pre_094 first so the down migration can
|
||||
-- restore them byte-identically.
|
||||
--
|
||||
-- audit_reason wrapper at top: the trigger on paliad.projects logs
|
||||
-- every row-level UPDATE; the message persists in the audit table as
|
||||
-- the permanent record of why those test values were cleared.
|
||||
|
||||
SELECT set_config(
|
||||
'paliad.audit_reason',
|
||||
'mig 094: clear test 7-digit client_number/matter_number values before tightening CHECK to 6-digit (HLC real format correction, 2026-05-17)',
|
||||
true);
|
||||
|
||||
-- =============================================================================
|
||||
-- 1. Backup snapshot. Full row copy of every paliad.projects row that
|
||||
-- has either field populated. Idempotent via CREATE TABLE IF NOT
|
||||
-- EXISTS — re-running the migration after an aborted run re-uses
|
||||
-- the existing snapshot.
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS paliad.projects_pre_094 AS
|
||||
SELECT *, now() AS snapshotted_at
|
||||
FROM paliad.projects
|
||||
WHERE client_number IS NOT NULL OR matter_number IS NOT NULL;
|
||||
|
||||
COMMENT ON TABLE paliad.projects_pre_094 IS
|
||||
'Snapshot of paliad.projects rows that had a client_number or '
|
||||
'matter_number set before mig 094 tightened the CHECK from '
|
||||
'7-digit to 6-digit. The 094 UPDATE NULL-ed those values out '
|
||||
'because they were leftover 7-digit test data. Persists as the '
|
||||
'permanent audit anchor; the down migration restores from it.';
|
||||
|
||||
-- =============================================================================
|
||||
-- 2. Clear the 7-digit test values. Only rows that already violate
|
||||
-- the new pattern are touched — anything that happens to already
|
||||
-- be 6 digits (none today, but the WHERE keeps the migration
|
||||
-- re-runnable after future inserts) is left alone.
|
||||
-- =============================================================================
|
||||
|
||||
UPDATE paliad.projects
|
||||
SET client_number = NULL
|
||||
WHERE client_number IS NOT NULL
|
||||
AND client_number !~ '^[0-9]{6}$';
|
||||
|
||||
UPDATE paliad.projects
|
||||
SET matter_number = NULL
|
||||
WHERE matter_number IS NOT NULL
|
||||
AND matter_number !~ '^[0-9]{6}$';
|
||||
|
||||
-- =============================================================================
|
||||
-- 3. Replace the legacy 7-digit CHECKs with 6-digit ones. The
|
||||
-- constraint names carry the pre-rename `projekte_*` prefix from
|
||||
-- mig 018; keep them stable so external audit tools that scan
|
||||
-- pg_constraint by name don't drift.
|
||||
-- =============================================================================
|
||||
|
||||
ALTER TABLE paliad.projects
|
||||
DROP CONSTRAINT projekte_client_number_check,
|
||||
DROP CONSTRAINT projekte_matter_number_check;
|
||||
|
||||
ALTER TABLE paliad.projects
|
||||
ADD CONSTRAINT projekte_client_number_check
|
||||
CHECK (client_number IS NULL OR client_number ~ '^[0-9]{6}$'),
|
||||
ADD CONSTRAINT projekte_matter_number_check
|
||||
CHECK (matter_number IS NULL OR matter_number ~ '^[0-9]{6}$');
|
||||
|
||||
-- =============================================================================
|
||||
-- 4. Hard assertions. Any row that survived the UPDATE+ALTER must
|
||||
-- satisfy the new pattern; the count of cleared test rows must
|
||||
-- match the snapshot.
|
||||
-- =============================================================================
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
n_violations int;
|
||||
BEGIN
|
||||
SELECT count(*) INTO n_violations
|
||||
FROM paliad.projects
|
||||
WHERE (client_number IS NOT NULL AND client_number !~ '^[0-9]{6}$')
|
||||
OR (matter_number IS NOT NULL AND matter_number !~ '^[0-9]{6}$');
|
||||
|
||||
IF n_violations > 0 THEN
|
||||
RAISE EXCEPTION 'mig 094: % rows still violate the 6-digit pattern after UPDATE — should be 0', n_violations;
|
||||
END IF;
|
||||
|
||||
RAISE NOTICE 'mig 094: 6-digit CHECKs in place, all rows compliant';
|
||||
END $$;
|
||||
Reference in New Issue
Block a user