← Files NaClARCHIVED FILE
skills/nacl-init/resources/graph-infra/queries/validation-queries.cypher
7.59 KB · Oct 3, 2026 · 06:30 UTC
// =============================================================================
// Validation — Named Cypher Queries
// =============================================================================
// File: graph-infra/queries/validation-queries.cypher
// Task: TECH-007
// =============================================================================
// ---------------------------------------------------------------------------
// Query: val_orphaned_form_fields
// Description: FormFields that have no MAPS_TO edge to a DomainAttribute.
// These are potential data-binding gaps in the UI layer.
// ---------------------------------------------------------------------------
MATCH (f:Form)-[:HAS_FIELD]->(ff:FormField)
WHERE NOT (ff)-[:MAPS_TO]->(:DomainAttribute)
RETURN f.name AS form_name, ff.name AS field_name, ff.field_type AS field_type, ff.label AS label;
// ---------------------------------------------------------------------------
// Query: val_uc_without_requirements
// Description: UseCases that have no HAS_REQUIREMENT edge.
// Every UC should be governed by at least one requirement.
// ---------------------------------------------------------------------------
MATCH (uc:UseCase)
WHERE NOT (uc)-[:HAS_REQUIREMENT]->(:Requirement)
RETURN uc.id, uc.name;
// ---------------------------------------------------------------------------
// Query: val_entity_without_uc
// Description: DomainEntities not referenced by any UseCase's forms.
// These entities exist in the domain model but have no UI surface.
// ---------------------------------------------------------------------------
MATCH (de:DomainEntity)
WHERE NOT (:FormField)-[:MAPS_TO]->(:DomainAttribute)<-[:HAS_ATTRIBUTE]-(de)
RETURN de.id, de.name, de.module;
// ---------------------------------------------------------------------------
// Query: val_disconnected_nodes
// Description: Nodes with zero relationships of any kind.
// These are orphans that may indicate missing data or edges.
// ---------------------------------------------------------------------------
MATCH (n)
WHERE NOT (n)--()
RETURN labels(n)[0] AS label, n.id AS id,
coalesce(n.name, n.term, n.function_name, n.description, n.title) AS display_name;
// ---------------------------------------------------------------------------
// Query: val_ba_sa_consistency
// Description: Every WorkflowStep with stereotype "Автоматизируется" should
// have a corresponding UseCase via AUTOMATES_AS.
// Returns steps that violate this rule.
// ---------------------------------------------------------------------------
MATCH (bp:BusinessProcess)-[:HAS_STEP]->(ws:WorkflowStep {stereotype: "Автоматизируется"})
OPTIONAL MATCH (ws)-[:AUTOMATES_AS]->(uc:UseCase)
RETURN bp.id AS bp_id, bp.name AS bp_name,
ws.id AS ws_id, ws.function_name AS ws_function,
CASE WHEN uc IS NULL THEN 'MISSING' ELSE 'OK' END AS status,
uc.id AS uc_id;
// =============================================================================
// BA Layer Validation — L1 through L8
// =============================================================================
// ---------------------------------------------------------------------------
// Query: val_ba_L1_bp_completeness
// Description: Every BusinessProcess must have trigger, result, and an owner.
// ---------------------------------------------------------------------------
MATCH (bp:BusinessProcess)
WHERE bp.trigger IS NULL OR bp.result IS NULL
OR NOT EXISTS { MATCH (:BusinessRole)-[:OWNS]->(bp) }
RETURN bp.id AS id, bp.name AS name,
CASE WHEN bp.trigger IS NULL THEN 'missing trigger' ELSE '' END +
CASE WHEN bp.result IS NULL THEN ', missing result' ELSE '' END +
CASE WHEN NOT EXISTS { MATCH (:BusinessRole)-[:OWNS]->(bp) } THEN ', missing owner' ELSE '' END AS issues;
// ---------------------------------------------------------------------------
// Query: val_ba_L2_workflow_coverage
// Description: Every BP with has_decomposition=true must have at least one step.
// ---------------------------------------------------------------------------
MATCH (bp:BusinessProcess {has_decomposition: true})
WHERE NOT EXISTS { MATCH (bp)-[:HAS_STEP]->(:WorkflowStep) }
RETURN bp.id AS id, bp.name AS name, 'has_decomposition=true but no steps' AS issue;
// ---------------------------------------------------------------------------
// Query: val_ba_L3_step_performers
// Description: Every WorkflowStep must have a PERFORMED_BY relationship.
// ---------------------------------------------------------------------------
MATCH (bp:BusinessProcess)-[:HAS_STEP]->(ws:WorkflowStep)
WHERE NOT EXISTS { MATCH (ws)-[:PERFORMED_BY]->(:BusinessRole) }
RETURN bp.id AS bp_id, ws.id AS ws_id, ws.function_name AS step_name,
'missing PERFORMED_BY' AS issue;
// ---------------------------------------------------------------------------
// Query: val_ba_L4_entity_attributes
// Description: Every BusinessEntity must have at least one EntityAttribute.
// ---------------------------------------------------------------------------
MATCH (e:BusinessEntity)
WHERE NOT EXISTS { MATCH (e)-[:HAS_ATTRIBUTE]->(:EntityAttribute) }
RETURN e.id AS id, e.name AS name, 'no attributes defined' AS issue;
// ---------------------------------------------------------------------------
// Query: val_ba_L5_entity_process_matrix
// Description: Every BusinessEntity should be referenced by at least one
// workflow step (READS/PRODUCES/MODIFIES).
// ---------------------------------------------------------------------------
MATCH (e:BusinessEntity)
WHERE NOT EXISTS {
MATCH (:WorkflowStep)-[:READS|PRODUCES|MODIFIES]->(e)
}
RETURN e.id AS id, e.name AS name, 'not referenced by any workflow step' AS issue;
// ---------------------------------------------------------------------------
// Query: val_ba_L6_role_process_matrix
// Description: Every BusinessRole should have at least one OWNS or
// PARTICIPATES_IN or PERFORMED_BY relationship.
// ---------------------------------------------------------------------------
MATCH (r:BusinessRole)
WHERE NOT EXISTS { MATCH (r)-[:OWNS]->(:BusinessProcess) }
AND NOT EXISTS { MATCH (r)-[:PARTICIPATES_IN]->(:BusinessProcess) }
AND NOT EXISTS { MATCH (:WorkflowStep)-[:PERFORMED_BY]->(r) }
RETURN r.id AS id, r.full_name AS name, 'role has no process relationships' AS issue;
// ---------------------------------------------------------------------------
// Query: val_ba_L7_glossary_coverage
// Description: Key entities and roles should have GlossaryTerm via DEFINES.
// ---------------------------------------------------------------------------
MATCH (e:BusinessEntity)
WHERE NOT EXISTS { MATCH (:GlossaryTerm)-[:DEFINES]->(e) }
RETURN 'Entity' AS category, e.id AS id, e.name AS name, 'no glossary term' AS issue
UNION ALL
MATCH (r:BusinessRole)
WHERE NOT EXISTS { MATCH (:GlossaryTerm)-[:DEFINES]->(r) }
RETURN 'Role' AS category, r.id AS id, r.full_name AS name, 'no glossary term' AS issue;
// ---------------------------------------------------------------------------
// Query: val_ba_L8_rules_binding
// Description: Every BusinessRule must have at least one traceability link
// (CONSTRAINS, APPLIES_IN, AFFECTS, or APPLIES_AT_STEP).
// ---------------------------------------------------------------------------
MATCH (brq:BusinessRule)
WHERE NOT EXISTS { MATCH (brq)-[:CONSTRAINS]->() }
AND NOT EXISTS { MATCH (brq)-[:APPLIES_IN]->() }
AND NOT EXISTS { MATCH (brq)-[:AFFECTS]->() }
AND NOT EXISTS { MATCH (brq)-[:APPLIES_AT_STEP]->() }
RETURN brq.id AS id, brq.name AS name, 'rule has no traceability links' AS issue;
SHA-256: a2c3fd50b7fb3c36316434d0ba25833a91738a82ca743aa0521206cd793e6935