{"version":3,"file":"integrity-checker.mjs","sources":["../../../../src/lib/data/integrity/integrity-checker.ts"],"sourcesContent":["/**\n * @file Data Integrity Checker\n * @description Comprehensive data integrity validation for frontend state\n * with referential integrity, constraint validation, and anomaly detection.\n *\n * Features:\n * - Referential integrity checking\n * - Custom constraint validation\n * - Data anomaly detection\n * - Integrity reports with repair suggestions\n * - Batch integrity validation\n *\n * @example\n * ```typescript\n * import { createIntegrityChecker } from '@/lib/data/integrity';\n *\n * const checker = createIntegrityChecker({\n *   entities: ['users', 'posts', 'comments'],\n *   relations: [\n *     { from: 'posts', field: 'authorId', to: 'users' },\n *     { from: 'comments', field: 'postId', to: 'posts' },\n *   ],\n * });\n *\n * const report = checker.check(state.entities);\n * if (!report.valid) {\n *   const repaired = checker.repair(state.entities, report);\n * }\n * ```\n */\n\nimport type { NormalizedEntities, Entity } from '../normalization/normalizer';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Relation definition for integrity checking\n */\nexport interface RelationDefinition {\n  /** Source entity type */\n  from: string;\n  /** Field containing the reference */\n  field: string;\n  /** Target entity type */\n  to: string;\n  /** Whether the relation is required */\n  required?: boolean;\n  /** Whether it's an array relation */\n  isArray?: boolean;\n  /** Cascade delete behavior */\n  onDelete?: 'cascade' | 'set-null' | 'restrict' | 'no-action';\n}\n\n/**\n * Custom constraint definition\n */\nexport interface ConstraintDefinition {\n  /** Constraint name */\n  name: string;\n  /** Entity type to apply constraint to */\n  entity: string;\n  /** Validation function */\n  validate: (entity: Entity, allEntities: NormalizedEntities) => boolean;\n  /** Error message */\n  message: string | ((entity: Entity) => string);\n  /** Severity level */\n  severity?: 'error' | 'warning' | 'info';\n  /** Repair function */\n  repair?: (entity: Entity, allEntities: NormalizedEntities) => Entity;\n}\n\n/**\n * Anomaly detection rule\n */\nexport interface AnomalyRule {\n  /** Rule name */\n  name: string;\n  /** Entity type to check */\n  entity?: string;\n  /** Detection function */\n  detect: (entities: NormalizedEntities) => AnomalyResult[];\n  /** Severity level */\n  severity?: 'error' | 'warning' | 'info';\n}\n\n/**\n * Anomaly detection result\n */\nexport interface AnomalyResult {\n  /** Entity type */\n  entityType: string;\n  /** Entity ID (if applicable) */\n  entityId?: string;\n  /** Anomaly description */\n  description: string;\n  /** Suggested fix */\n  suggestion?: string;\n  /** Additional data */\n  data?: unknown;\n}\n\n/**\n * Integrity violation\n */\nexport interface IntegrityViolation {\n  /** Violation type */\n  type: 'referential' | 'constraint' | 'anomaly' | 'orphan';\n  /** Severity */\n  severity: 'error' | 'warning' | 'info';\n  /** Entity type */\n  entityType: string;\n  /** Entity ID */\n  entityId: string;\n  /** Violation message */\n  message: string;\n  /** Field involved (for referential) */\n  field?: string;\n  /** Related entity info */\n  related?: {\n    entityType: string;\n    entityId: string;\n  };\n  /** Repair suggestion */\n  repair?: {\n    action: 'delete' | 'update' | 'create' | 'nullify';\n    data?: unknown;\n  };\n}\n\n/**\n * Integrity check report\n */\nexport interface IntegrityReport {\n  /** Overall validity */\n  valid: boolean;\n  /** Timestamp */\n  timestamp: number;\n  /** Duration in milliseconds */\n  duration: number;\n  /** Entity counts */\n  entityCounts: Record<string, number>;\n  /** Violations by type */\n  violations: IntegrityViolation[];\n  /** Summary statistics */\n  stats: {\n    total: number;\n    errors: number;\n    warnings: number;\n    info: number;\n  };\n}\n\n/**\n * Integrity checker configuration\n */\nexport interface IntegrityCheckerConfig {\n  /** Entity types to check */\n  entities: string[];\n  /** Relation definitions */\n  relations?: RelationDefinition[];\n  /** Custom constraints */\n  constraints?: ConstraintDefinition[];\n  /** Anomaly detection rules */\n  anomalyRules?: AnomalyRule[];\n  /** ID field name */\n  idField?: string;\n  /** Enable orphan detection */\n  detectOrphans?: boolean;\n  /** Stop on first error */\n  failFast?: boolean;\n}\n\n/**\n * Repair options\n */\nexport interface RepairOptions {\n  /** Only fix errors (not warnings) */\n  errorsOnly?: boolean;\n  /** Dry run (return changes without applying) */\n  dryRun?: boolean;\n  /** Custom repair handlers */\n  handlers?: Record<\n    string,\n    (violation: IntegrityViolation, entities: NormalizedEntities) => NormalizedEntities\n  >;\n}\n\n/**\n * Repair result\n */\nexport interface RepairResult {\n  /** Repaired entities */\n  entities: NormalizedEntities;\n  /** Applied repairs */\n  repairs: Array<{\n    violation: IntegrityViolation;\n    action: string;\n    success: boolean;\n  }>;\n  /** Remaining violations */\n  remaining: IntegrityViolation[];\n}\n\n/**\n * Integrity checker interface\n */\nexport interface IntegrityChecker {\n  /** Run integrity check */\n  check: (entities: NormalizedEntities) => IntegrityReport;\n  /** Check specific entity */\n  checkEntity: (\n    entityType: string,\n    entityId: string,\n    entities: NormalizedEntities\n  ) => IntegrityViolation[];\n  /** Repair violations */\n  repair: (\n    entities: NormalizedEntities,\n    report: IntegrityReport,\n    options?: RepairOptions\n  ) => RepairResult;\n  /** Add constraint */\n  addConstraint: (constraint: ConstraintDefinition) => void;\n  /** Add relation */\n  addRelation: (relation: RelationDefinition) => void;\n  /** Add anomaly rule */\n  addAnomalyRule: (rule: AnomalyRule) => void;\n  /** Get configuration */\n  getConfig: () => IntegrityCheckerConfig;\n}\n\n// =============================================================================\n// INTEGRITY CHECKER FACTORY\n// =============================================================================\n\n/**\n * Create an integrity checker\n *\n * @param config - Checker configuration\n * @returns Integrity checker instance\n *\n * @example\n * ```typescript\n * const checker = createIntegrityChecker({\n *   entities: ['users', 'posts', 'comments'],\n *   relations: [\n *     { from: 'posts', field: 'authorId', to: 'users', required: true },\n *     { from: 'comments', field: 'postId', to: 'posts', required: true },\n *     { from: 'comments', field: 'userId', to: 'users' },\n *   ],\n *   constraints: [\n *     {\n *       name: 'non-empty-title',\n *       entity: 'posts',\n *       validate: (post) => typeof post.title === 'string' && post.title.length > 0,\n *       message: 'Post must have a non-empty title',\n *       severity: 'error',\n *     },\n *   ],\n * });\n *\n * const report = checker.check(normalizedState);\n * console.log(report.violations);\n * ```\n */\nexport function createIntegrityChecker(config: IntegrityCheckerConfig): IntegrityChecker {\n  const relations = [...(config.relations ?? [])];\n  const constraints = [...(config.constraints ?? [])];\n  const anomalyRules = [...(config.anomalyRules ?? [])];\n  const idField = config.idField ?? 'id';\n\n  /**\n   * Check referential integrity for an entity\n   */\n  function checkReferentialIntegrity(\n    entityType: string,\n    entity: Entity,\n    entities: NormalizedEntities\n  ): IntegrityViolation[] {\n    const violations: IntegrityViolation[] = [];\n    const entityRelations = relations.filter((r) => r.from === entityType);\n\n    for (const relation of entityRelations) {\n      const value = entity[relation.field];\n\n      if (relation.isArray === true) {\n        // Array relation\n        if (Array.isArray(value)) {\n          for (const refId of value) {\n            if (refId != null && !entities[relation.to]?.[String(refId)]) {\n              violations.push({\n                type: 'referential',\n                severity: relation.required === true ? 'error' : 'warning',\n                entityType,\n                entityId: String(entity[idField]),\n                message: `Missing referenced ${relation.to} with ID \"${refId}\"`,\n                field: relation.field,\n                related: {\n                  entityType: relation.to,\n                  entityId: String(refId),\n                },\n                repair: {\n                  action: relation.onDelete === 'cascade' ? 'delete' : 'update',\n                  data:\n                    relation.onDelete === 'set-null'\n                      ? { [relation.field]: value.filter((id: string) => id !== refId) }\n                      : undefined,\n                },\n              });\n            }\n          }\n        }\n      } else {\n        // Single relation\n        if (value !== null && value !== undefined) {\n          const valueStr =\n            typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean'\n              ? JSON.stringify(value)\n              : String(value);\n          if (!entities[relation.to]?.[valueStr]) {\n            violations.push({\n              type: 'referential',\n              severity: relation.required === true ? 'error' : 'warning',\n              entityType,\n              entityId: String(entity[idField]),\n              message: `Missing referenced ${relation.to} with ID ${valueStr}`,\n              field: relation.field,\n              related: {\n                entityType: relation.to,\n                entityId: valueStr,\n              },\n              repair: {\n                action: relation.onDelete === 'cascade' ? 'delete' : 'update',\n                data: relation.onDelete === 'set-null' ? { [relation.field]: null } : undefined,\n              },\n            });\n          }\n        } else if (relation.required === true) {\n          violations.push({\n            type: 'referential',\n            severity: 'error',\n            entityType,\n            entityId: String(entity[idField]),\n            message: `Required relation \"${relation.field}\" is missing`,\n            field: relation.field,\n            repair: {\n              action: 'delete',\n            },\n          });\n        }\n      }\n    }\n\n    return violations;\n  }\n\n  /**\n   * Check custom constraints for an entity\n   */\n  function checkConstraints(\n    entityType: string,\n    entity: Entity,\n    entities: NormalizedEntities\n  ): IntegrityViolation[] {\n    const violations: IntegrityViolation[] = [];\n    const entityConstraints = constraints.filter((c) => c.entity === entityType);\n\n    for (const constraint of entityConstraints) {\n      if (!constraint.validate(entity, entities)) {\n        const message =\n          typeof constraint.message === 'function'\n            ? constraint.message(entity)\n            : constraint.message;\n\n        violations.push({\n          type: 'constraint',\n          severity: constraint.severity ?? 'error',\n          entityType,\n          entityId: String(entity[idField]),\n          message: `[${constraint.name}] ${message}`,\n          repair: constraint.repair\n            ? {\n                action: 'update',\n                data: constraint.repair(entity, entities),\n              }\n            : undefined,\n        });\n      }\n    }\n\n    return violations;\n  }\n\n  /**\n   * Detect orphaned entities\n   */\n  function detectOrphans(entities: NormalizedEntities): IntegrityViolation[] {\n    if (config.detectOrphans !== true) {\n      return [];\n    }\n\n    const violations: IntegrityViolation[] = [];\n    const referencedIds = new Map<string, Set<string>>();\n\n    // Collect all referenced IDs\n    for (const entityType of config.entities) {\n      referencedIds.set(entityType, new Set());\n    }\n\n    for (const entityType of config.entities) {\n      const entityMap = entities[entityType];\n      if (!entityMap) continue;\n\n      const entityRelations = relations.filter((r) => r.from === entityType);\n\n      for (const entity of Object.values(entityMap)) {\n        for (const relation of entityRelations) {\n          const value = entity[relation.field];\n\n          if (relation.isArray === true && Array.isArray(value)) {\n            for (const refId of value) {\n              referencedIds.get(relation.to)?.add(String(refId));\n            }\n          } else if (value !== null && value !== undefined) {\n            const valueStr =\n              typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean'\n                ? JSON.stringify(value)\n                : String(value);\n            referencedIds.get(relation.to)?.add(valueStr);\n          }\n        }\n      }\n    }\n\n    // Find entities not referenced by any relation\n    for (const entityType of config.entities) {\n      // Skip root entities (entities that don't have incoming relations)\n      const hasIncomingRelation = relations.some((r) => r.to === entityType);\n      if (!hasIncomingRelation) continue;\n\n      const entityMap = entities[entityType];\n      if (!entityMap) continue;\n\n      const referenced = referencedIds.get(entityType) ?? new Set();\n\n      for (const [entityId] of Object.entries(entityMap)) {\n        if (!referenced.has(entityId)) {\n          violations.push({\n            type: 'orphan',\n            severity: 'warning',\n            entityType,\n            entityId,\n            message: `Orphaned ${entityType} entity not referenced by any relation`,\n            repair: {\n              action: 'delete',\n            },\n          });\n        }\n      }\n    }\n\n    return violations;\n  }\n\n  /**\n   * Run anomaly detection\n   */\n  function runAnomalyDetection(entities: NormalizedEntities): IntegrityViolation[] {\n    const violations: IntegrityViolation[] = [];\n\n    for (const rule of anomalyRules) {\n      const results = rule.detect(entities);\n\n      for (const result of results) {\n        violations.push({\n          type: 'anomaly',\n          severity: rule.severity ?? 'warning',\n          entityType: result.entityType,\n          entityId: result.entityId ?? '',\n          message: `[${rule.name}] ${result.description}`,\n          repair:\n            result.suggestion != null && result.suggestion !== ''\n              ? {\n                  action: 'update',\n                  data: { suggestion: result.suggestion },\n                }\n              : undefined,\n        });\n      }\n    }\n\n    return violations;\n  }\n\n  /**\n   * Run integrity check\n   */\n  function check(entities: NormalizedEntities): IntegrityReport {\n    const startTime = performance.now();\n    const violations: IntegrityViolation[] = [];\n    const entityCounts: Record<string, number> = {};\n\n    // Check each entity type\n    for (const entityType of config.entities) {\n      const entityMap = entities[entityType];\n      if (!entityMap) {\n        entityCounts[entityType] = 0;\n        continue;\n      }\n\n      entityCounts[entityType] = Object.keys(entityMap).length;\n\n      for (const entity of Object.values(entityMap)) {\n        // Referential integrity\n        violations.push(...checkReferentialIntegrity(entityType, entity, entities));\n\n        // Custom constraints\n        violations.push(...checkConstraints(entityType, entity, entities));\n\n        // Early exit if fail fast and has errors\n        if (config.failFast === true && violations.some((v) => v.severity === 'error')) {\n          break;\n        }\n      }\n\n      if (config.failFast === true && violations.some((v) => v.severity === 'error')) {\n        break;\n      }\n    }\n\n    // Orphan detection\n    if (config.failFast !== true || !violations.some((v) => v.severity === 'error')) {\n      violations.push(...detectOrphans(entities));\n    }\n\n    // Anomaly detection\n    if (config.failFast !== true || !violations.some((v) => v.severity === 'error')) {\n      violations.push(...runAnomalyDetection(entities));\n    }\n\n    const duration = performance.now() - startTime;\n\n    return {\n      valid: !violations.some((v) => v.severity === 'error'),\n      timestamp: Date.now(),\n      duration,\n      entityCounts,\n      violations,\n      stats: {\n        total: violations.length,\n        errors: violations.filter((v) => v.severity === 'error').length,\n        warnings: violations.filter((v) => v.severity === 'warning').length,\n        info: violations.filter((v) => v.severity === 'info').length,\n      },\n    };\n  }\n\n  /**\n   * Check specific entity\n   */\n  function checkEntity(\n    entityType: string,\n    entityId: string,\n    entities: NormalizedEntities\n  ): IntegrityViolation[] {\n    const entity = entities[entityType]?.[entityId];\n    if (!entity) {\n      return [\n        {\n          type: 'referential',\n          severity: 'error',\n          entityType,\n          entityId,\n          message: `Entity not found`,\n        },\n      ];\n    }\n\n    const violations: IntegrityViolation[] = [];\n    violations.push(...checkReferentialIntegrity(entityType, entity, entities));\n    violations.push(...checkConstraints(entityType, entity, entities));\n\n    return violations;\n  }\n\n  /**\n   * Repair violations\n   */\n  function repair(\n    entities: NormalizedEntities,\n    report: IntegrityReport,\n    options: RepairOptions = {}\n  ): RepairResult {\n    let repairedEntities: NormalizedEntities = JSON.parse(\n      JSON.stringify(entities)\n    ) as NormalizedEntities;\n    const repairs: RepairResult['repairs'] = [];\n    const remaining: IntegrityViolation[] = [];\n\n    const violationsToFix =\n      options.errorsOnly === true\n        ? report.violations.filter((v) => v.severity === 'error')\n        : report.violations;\n\n    for (const violation of violationsToFix) {\n      // Check for custom handler\n      if (options.handlers?.[violation.type]) {\n        if (options.dryRun !== true) {\n          const handler = options.handlers[violation.type];\n          if (handler) {\n            repairedEntities = handler(violation, repairedEntities);\n          }\n        }\n        repairs.push({ violation, action: 'custom-handler', success: true });\n        continue;\n      }\n\n      // Default repair logic\n      if (!violation.repair) {\n        remaining.push(violation);\n        continue;\n      }\n\n      try {\n        if (options.dryRun !== true) {\n          const entityTypeMap = repairedEntities[violation.entityType];\n          switch (violation.repair.action) {\n            case 'delete':\n              if (entityTypeMap?.[violation.entityId]) {\n                delete entityTypeMap[violation.entityId];\n              }\n              break;\n\n            case 'update':\n              if (entityTypeMap && violation.repair.data != null) {\n                const existing = entityTypeMap[violation.entityId];\n                entityTypeMap[violation.entityId] = {\n                  ...existing,\n                  ...(violation.repair.data as Record<string, unknown>),\n                } as Entity;\n              }\n              break;\n\n            case 'nullify':\n              if (entityTypeMap && violation.field != null && violation.field !== '') {\n                const entity = entityTypeMap[violation.entityId];\n                if (entity) {\n                  entity[violation.field] = null;\n                }\n              }\n              break;\n\n            case 'create':\n              // Creating entities requires more context, skip for now\n              remaining.push(violation);\n              continue;\n          }\n        }\n\n        repairs.push({ violation, action: violation.repair.action, success: true });\n      } catch {\n        repairs.push({ violation, action: violation.repair.action, success: false });\n        remaining.push(violation);\n      }\n    }\n\n    return {\n      entities: repairedEntities,\n      repairs,\n      remaining,\n    };\n  }\n\n  /**\n   * Add constraint\n   */\n  function addConstraint(constraint: ConstraintDefinition): void {\n    constraints.push(constraint);\n  }\n\n  /**\n   * Add relation\n   */\n  function addRelation(relation: RelationDefinition): void {\n    relations.push(relation);\n  }\n\n  /**\n   * Add anomaly rule\n   */\n  function addAnomalyRule(rule: AnomalyRule): void {\n    anomalyRules.push(rule);\n  }\n\n  /**\n   * Get configuration\n   */\n  function getConfig(): IntegrityCheckerConfig {\n    return {\n      ...config,\n      relations: [...relations],\n      constraints: [...constraints],\n      anomalyRules: [...anomalyRules],\n    };\n  }\n\n  return {\n    check,\n    checkEntity,\n    repair,\n    addConstraint,\n    addRelation,\n    addAnomalyRule,\n    getConfig,\n  };\n}\n\n// =============================================================================\n// BUILT-IN ANOMALY RULES\n// =============================================================================\n\n/**\n * Create duplicate detection rule\n */\nexport function createDuplicateDetectionRule(entityType: string, fields: string[]): AnomalyRule {\n  return {\n    name: `duplicate-${entityType}`,\n    entity: entityType,\n    severity: 'warning',\n    detect: (entities) => {\n      const results: AnomalyResult[] = [];\n      const entityMap = entities[entityType];\n      if (!entityMap) return results;\n\n      const seen = new Map<string, string>();\n\n      for (const [id, entity] of Object.entries(entityMap)) {\n        const key = fields\n          .map((f) => {\n            const val = entity[f] ?? '';\n            return typeof val !== 'string' && typeof val !== 'number' && typeof val !== 'boolean'\n              ? JSON.stringify(val)\n              : String(val);\n          })\n          .join('|');\n        const existing = seen.get(key);\n\n        if (existing != null && existing !== '') {\n          results.push({\n            entityType,\n            entityId: id,\n            description: `Duplicate detected: same values as entity \"${existing}\" for fields [${fields.join(', ')}]`,\n            suggestion: `Consider merging or removing duplicate entity`,\n            data: { duplicateOf: existing, fields },\n          });\n        } else {\n          seen.set(key, id);\n        }\n      }\n\n      return results;\n    },\n  };\n}\n\n/**\n * Create stale data detection rule\n */\nexport function createStaleDataRule(\n  entityType: string,\n  timestampField: string,\n  maxAgeMs: number\n): AnomalyRule {\n  return {\n    name: `stale-${entityType}`,\n    entity: entityType,\n    severity: 'info',\n    detect: (entities) => {\n      const results: AnomalyResult[] = [];\n      const entityMap = entities[entityType];\n      if (!entityMap) return results;\n\n      const now = Date.now();\n\n      for (const [id, entity] of Object.entries(entityMap)) {\n        const timestamp = entity[timestampField];\n        if (typeof timestamp === 'number' || typeof timestamp === 'string') {\n          const age = now - new Date(timestamp).getTime();\n          if (age > maxAgeMs) {\n            results.push({\n              entityType,\n              entityId: id,\n              description: `Stale data: last updated ${Math.round(age / 1000 / 60)} minutes ago`,\n              suggestion: `Consider refreshing this entity from the server`,\n              data: { timestamp, age },\n            });\n          }\n        }\n      }\n\n      return results;\n    },\n  };\n}\n\n/**\n * Create missing required fields rule\n */\nexport function createRequiredFieldsRule(\n  entityType: string,\n  requiredFields: string[]\n): AnomalyRule {\n  return {\n    name: `required-fields-${entityType}`,\n    entity: entityType,\n    severity: 'error',\n    detect: (entities) => {\n      const results: AnomalyResult[] = [];\n      const entityMap = entities[entityType];\n      if (!entityMap) return results;\n\n      for (const [id, entity] of Object.entries(entityMap)) {\n        const missingFields = requiredFields.filter(\n          (field) => entity[field] === null || entity[field] === undefined\n        );\n\n        if (missingFields.length > 0) {\n          results.push({\n            entityType,\n            entityId: id,\n            description: `Missing required fields: ${missingFields.join(', ')}`,\n            suggestion: `Populate missing fields or remove the entity`,\n            data: { missingFields },\n          });\n        }\n      }\n\n      return results;\n    },\n  };\n}\n\n/**\n * Create data consistency rule (cross-entity validation)\n */\nexport function createConsistencyRule(\n  name: string,\n  check: (entities: NormalizedEntities) => AnomalyResult[]\n): AnomalyRule {\n  return {\n    name,\n    severity: 'warning',\n    detect: check,\n  };\n}\n\n// =============================================================================\n// BUILT-IN CONSTRAINTS\n// =============================================================================\n\n/**\n * Create unique field constraint\n */\nexport function createUniqueConstraint(entityType: string, field: string): ConstraintDefinition {\n  const seenValues = new Map<string, string>();\n\n  return {\n    name: `unique-${entityType}-${field}`,\n    entity: entityType,\n    validate: (entity, entities) => {\n      const fieldVal = entity[field] ?? '';\n      const value =\n        typeof fieldVal !== 'string' &&\n        typeof fieldVal !== 'number' &&\n        typeof fieldVal !== 'boolean'\n          ? JSON.stringify(fieldVal)\n          : String(fieldVal);\n      const entityId = String(entity.id);\n\n      // Rebuild seen values each check for consistency\n      seenValues.clear();\n      const entityMap = entities[entityType];\n      if (entityMap) {\n        for (const [id, e] of Object.entries(entityMap)) {\n          if (id === entityId) continue;\n          const eFieldVal = e[field] ?? '';\n          const eValue =\n            typeof eFieldVal !== 'string' &&\n            typeof eFieldVal !== 'number' &&\n            typeof eFieldVal !== 'boolean'\n              ? JSON.stringify(eFieldVal)\n              : String(eFieldVal);\n          seenValues.set(eValue, id);\n        }\n      }\n\n      return !seenValues.has(value);\n    },\n    message: (entity) => {\n      const fieldVal = entity[field];\n      let valueStr: string;\n      if (fieldVal == null) {\n        valueStr = 'null';\n      } else if (\n        typeof fieldVal === 'string' ||\n        typeof fieldVal === 'number' ||\n        typeof fieldVal === 'boolean'\n      ) {\n        valueStr = String(fieldVal);\n      } else {\n        valueStr = JSON.stringify(fieldVal);\n      }\n      return `Field \"${field}\" must be unique. Value ${valueStr} already exists.`;\n    },\n    severity: 'error',\n  };\n}\n\n/**\n * Create range constraint\n */\nexport function createRangeConstraint(\n  entityType: string,\n  field: string,\n  min?: number,\n  max?: number\n): ConstraintDefinition {\n  return {\n    name: `range-${entityType}-${field}`,\n    entity: entityType,\n    validate: (entity) => {\n      const value = entity[field];\n      if (typeof value !== 'number') return true;\n      if (min !== undefined && value < min) return false;\n      return !(max !== undefined && value > max);\n    },\n    message: (entity) => {\n      const bounds = [];\n      if (min !== undefined) bounds.push(`>= ${min}`);\n      if (max !== undefined) bounds.push(`<= ${max}`);\n      const fieldVal = entity[field];\n      let valueStr: string;\n      if (fieldVal == null) {\n        valueStr = 'null';\n      } else if (typeof fieldVal === 'number') {\n        valueStr = String(fieldVal);\n      } else {\n        valueStr = JSON.stringify(fieldVal);\n      }\n      return `Field \"${field}\" must be ${bounds.join(' and ')}. Got ${valueStr}.`;\n    },\n    severity: 'error',\n  };\n}\n\n/**\n * Create pattern constraint\n */\nexport function createPatternConstraint(\n  entityType: string,\n  field: string,\n  pattern: RegExp,\n  description: string\n): ConstraintDefinition {\n  return {\n    name: `pattern-${entityType}-${field}`,\n    entity: entityType,\n    validate: (entity) => {\n      const value = entity[field];\n      if (typeof value !== 'string') return true;\n      return pattern.test(value);\n    },\n    message: `Field \"${field}\" must match ${description}`,\n    severity: 'error',\n  };\n}\n\n/**\n * Create enum constraint\n */\nexport function createEnumConstraint(\n  entityType: string,\n  field: string,\n  allowedValues: readonly unknown[]\n): ConstraintDefinition {\n  return {\n    name: `enum-${entityType}-${field}`,\n    entity: entityType,\n    validate: (entity) => {\n      const value = entity[field];\n      return allowedValues.includes(value);\n    },\n    message: (entity) => {\n      const fieldVal = entity[field];\n      let valueStr: string;\n      if (fieldVal == null) {\n        valueStr = 'null';\n      } else if (\n        typeof fieldVal === 'string' ||\n        typeof fieldVal === 'number' ||\n        typeof fieldVal === 'boolean'\n      ) {\n        valueStr = String(fieldVal);\n      } else {\n        valueStr = JSON.stringify(fieldVal);\n      }\n      return `Field \"${field}\" must be one of [${allowedValues.join(', ')}]. Got ${valueStr}.`;\n    },\n    severity: 'error',\n  };\n}\n"],"names":["createIntegrityChecker","config","relations","constraints","anomalyRules","idField","checkReferentialIntegrity","entityType","entity","entities","violations","entityRelations","r","relation","value","refId","id","valueStr","checkConstraints","entityConstraints","c","constraint","message","detectOrphans","referencedIds","entityMap","referenced","entityId","runAnomalyDetection","rule","results","result","check","startTime","entityCounts","v","duration","checkEntity","repair","report","options","repairedEntities","repairs","remaining","violationsToFix","violation","handler","entityTypeMap","existing","addConstraint","addRelation","addAnomalyRule","getConfig","createDuplicateDetectionRule","fields","seen","key","f","val","createStaleDataRule","timestampField","maxAgeMs","now","timestamp","age","createRequiredFieldsRule","requiredFields","missingFields","field","createConsistencyRule","name","createUniqueConstraint","seenValues","fieldVal","e","eFieldVal","eValue","createRangeConstraint","min","max","bounds","createPatternConstraint","pattern","description","createEnumConstraint","allowedValues"],"mappings":"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"}