Files
breakpilot-compliance/ai-compliance-sdk/migrations/152_iace_projects_reconcile.sql
T
Benjamin Admin afb3f83f30 feat(iace): cross-domain precision overhaul + component review + schema reconcile
Engine precision (stop foreign-machine patterns leaking into a project):
- Wire project.MachineType into the engine machine-type gate (empty input no
  longer fires every machine class — press/cnc/excavator/crane/medical...).
- Capability-domain gating extended by 7 domains (outdoor, ventilation,
  machining, bulk, palletizer, playground, fitness) so domain-specific hazards
  only fire when the narrative names that domain; emitted via keyword_dictionary.
- Relevance backstop moved into iace (single gating contract, testable), and its
  dominant false-anchor class removed (a long pattern word no longer matches a
  short common token; prepositions/leitung added to the generic stoplist).
- New guard tests: TestCrossDomainPrecision (full pipeline, 0 foreign per GT) and
  TestPatternReachability now asserts 0 dead patterns. Both GTs keep coverage 1.0.

Reachability fix: the 51 dead patterns required electrical/pneumatic/hydraulic
tags nothing produced — renamed to the canonical electrical_energy/
pneumatic_pressure/hydraulic_pressure/hydraulic_part.

Component review (negation is best-effort + expert-correctable):
- Parser surfaces negated components (ComponentMatch.Negated) instead of dropping
  them; negated contribute no tags/energy → no phantom hazards.
- presence_status (vorhanden|nicht_vorhanden|geloescht) + ce_marked on components;
  only `vorhanden` feed matching. CE+safety-relevant flags the PL/SIL obligation.
- Force re-seed preserves the expert's component decisions instead of wiping them.
- Tag-based component→hazard assignment (was: all on the first component).
- Negation-aware narrative parsing ("keine Pneumatik" no longer extracts it).

Local-dev DB: ai-sdk sets search_path=compliance,core,public; reconcile migrations
152-156 bring the consolidated local iace tables to the current schema + add the
presence_status/ce_marked columns. Machine-type vocabulary endpoint for the form.

[migration-approved]

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 17:15:55 +02:00

48 lines
2.3 KiB
SQL

-- Migration 152: reconcile iace_projects with the current Go schema.
-- ==========================================================================
-- The iace tables were created ad-hoc (no CREATE migration) and drifted across
-- environments. The consolidation copied an OLDER iace_projects into the local
-- `compliance` schema: it carried legacy columns (intended_use,
-- limits_description, reasonably_foreseeable_misuse, completeness_pct,
-- can_export) and lacked the columns the current store layer reads/writes
-- (store_projects.go CreateProject/GetProject): customer_name, description,
-- narrative_text, ce_marking_target, completeness_score, risk_summary,
-- triggered_regulations, archived_at.
--
-- This migration brings the table to the code's expectation. Idempotent and
-- guarded so it is a no-op where the table already matches. Legacy columns are
-- only made nullable (not dropped) so any historical data survives while the
-- current INSERT (which omits them) no longer fails on NOT NULL.
-- ==========================================================================
ALTER TABLE iace_projects
ADD COLUMN IF NOT EXISTS parent_project_id uuid,
ADD COLUMN IF NOT EXISTS customer_name text,
ADD COLUMN IF NOT EXISTS description text,
ADD COLUMN IF NOT EXISTS narrative_text text,
ADD COLUMN IF NOT EXISTS ce_marking_target text,
ADD COLUMN IF NOT EXISTS completeness_score double precision,
ADD COLUMN IF NOT EXISTS risk_summary jsonb,
ADD COLUMN IF NOT EXISTS triggered_regulations jsonb,
ADD COLUMN IF NOT EXISTS archived_at timestamptz;
-- Relax legacy NOT NULL columns the current code never writes, so INSERTs that
-- omit them succeed. DROP NOT NULL is a no-op when already nullable; the guard
-- skips columns that do not exist in this schema variant.
DO $$
DECLARE
col text;
BEGIN
FOREACH col IN ARRAY ARRAY[
'intended_use', 'limits_description', 'reasonably_foreseeable_misuse',
'completeness_pct', 'can_export'
] LOOP
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'iace_projects' AND column_name = col
) THEN
EXECUTE format('ALTER TABLE iace_projects ALTER COLUMN %I DROP NOT NULL', col);
END IF;
END LOOP;
END $$;