feat(pipeline): v3 — scoped control applicability + source_type classification
Some checks failed
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Failing after 36s
CI/CD / test-python-backend-compliance (push) Successful in 36s
CI/CD / test-python-document-crawler (push) Successful in 27s
CI/CD / test-python-dsms-gateway (push) Successful in 18s
CI/CD / validate-canonical-controls (push) Successful in 11s
CI/CD / Deploy (push) Has been skipped

Phase 4: source_type (law/guideline/standard/restricted) on source_citation
- NIST/OWASP/ENISA correctly shown as "Standard" instead of "Gesetzliche Grundlage"
- Dynamic frontend labels based on source_type
- Backfill endpoint POST /v1/canonical/generate/backfill-source-type

Phase v3: Scoped Control Applicability
- 3 new fields: applicable_industries, applicable_company_size, scope_conditions
- LLM prompt extended with 39 industries, 5 company sizes, 10 scope signals
- All 5 generation paths (Rule 1/2/3, batch structure, batch reform) updated
- _build_control_from_json: parsing + validation (string→list, size validation)
- _store_control: writes 3 new JSONB columns
- API: response models, create/update requests, SELECT queries extended
- Migration 063: 3 new JSONB columns with GIN indexes
- 110 generator tests + 28 route tests = 138 total, all passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-18 16:28:05 +01:00
parent 3bb9fffab6
commit f2819b99af
9 changed files with 685 additions and 139 deletions

View File

@@ -0,0 +1,23 @@
-- Migration 063: Scoped Control Applicability
--
-- Adds 3 new JSONB columns to canonical_controls for filtering controls
-- based on customer industry, company size, and compliance scope.
--
-- v3 pipeline generates these fields automatically via LLM.
-- Old controls (v1/v2) will be backfilled separately.
ALTER TABLE canonical_controls
ADD COLUMN IF NOT EXISTS applicable_industries JSONB DEFAULT NULL,
ADD COLUMN IF NOT EXISTS applicable_company_size JSONB DEFAULT NULL,
ADD COLUMN IF NOT EXISTS scope_conditions JSONB DEFAULT NULL;
-- GIN index for JSONB containment queries (e.g. applicable_industries @> '"Telekommunikation"')
CREATE INDEX IF NOT EXISTS idx_cc_applicable_industries
ON canonical_controls USING gin (applicable_industries);
CREATE INDEX IF NOT EXISTS idx_cc_applicable_company_size
ON canonical_controls USING gin (applicable_company_size);
COMMENT ON COLUMN canonical_controls.applicable_industries IS 'Industries this control applies to, e.g. ["all"] or ["Telekommunikation", "Energie"]. NULL = not yet classified.';
COMMENT ON COLUMN canonical_controls.applicable_company_size IS 'Company sizes this control applies to, e.g. ["all"] or ["medium", "large", "enterprise"]. NULL = not yet classified.';
COMMENT ON COLUMN canonical_controls.scope_conditions IS 'Optional scope conditions, e.g. {"requires_any": ["uses_ai"], "description": "..."}. NULL = no conditions.';