# core/validators/repair.validator.ts

> 62 lines of code and 17 definitions.

Tree: GovLab Context
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/context#file-context-core-validators-repair-validator-ts
Source text: https://banes-lab.com/source/context/core/validators/repair.validator.ts.txt

Listed in [core/validators](https://banes-lab.com/api/source/context/core/validators.md), after [core/validators/record.validator.ts](https://banes-lab.com/source/context/core/validators/record.validator.ts.md) and before [core/validators/syntax.validator.ts](https://banes-lab.com/source/context/core/validators/syntax.validator.ts.md).

## Definitions

- `repairDefectsOf` (lexical_declaration, line 60, exported)
- `fieldDefects` (lexical_declaration, line 32)
- `repairKindLookup` (lexical_declaration, line 20, exported)
- `shapeDefects` (lexical_declaration, line 48)
- `REF_SEPARATOR` (lexical_declaration, line 14)
- `FORMED_BY` (lexical_declaration, line 15)
- `VIOLATED_BY` (lexical_declaration, line 16)
- `KindLookup` (type_alias_declaration, line 18)
- `at` (lexical_declaration, line 22, exported)
- `collection` (lexical_declaration, line 23, exported)
- `id` (lexical_declaration, line 24, exported)
- `admitted` (lexical_declaration, line 38)
- `kind` (lexical_declaration, line 40)
- `ref` (lexical_declaration, line 49)
- `negative` (lexical_declaration, line 50)
- `formed` (lexical_declaration, line 51)
- `violated` (lexical_declaration, line 52)

## Contained in

- [core/validators](https://banes-lab.com/anatomy/context/folder-context-core-validators.md)

## Uses

- [configuration/strings/validation.strings.ts](https://banes-lab.com/source/context/configuration/strings/validation.strings.ts.md)

## Used by

- [core/validators/ontology.validator.ts](https://banes-lab.com/source/context/core/validators/ontology.validator.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/context/folder-context-configuration-strings.md)
- [core/validators](https://banes-lab.com/anatomy/context/folder-context-core-validators.md)

## Source

```typescript
import {
    FORMED_BY_MISPLACED,
    FORMED_BY_MISSING,
    REPAIR_NO_RECORD,
    VIOLATED_BY_MISSING,
    repairWrongKind,
} from "#configuration/strings/validation.strings";
import { NEGATIVE_KIND, REPAIR_FIELDS, REPAIR_RANGES } from "#configuration/constants/architecture.constants";
import type { Principle, RepairField } from "#types/architecture.types";
import { COLLECTIONS } from "#configuration/constants/ontology.constants";
import type { Faces } from "#types/context.types";
import type { RepairDefect } from "#types/validation.types";

const REF_SEPARATOR = ":";
const FORMED_BY = "formed_by";
const VIOLATED_BY = "violated_by";

type KindLookup = (ref: string) => string | null;

export const repairKindLookup = function repairKindLookup(faces: Pick<Faces, "arch" | "lex">): KindLookup {
    return (ref) => {
        const at = ref.indexOf(REF_SEPARATOR);
        const collection = ref.slice(0, at);
        const id = ref.slice(at + 1);
        if (collection === COLLECTIONS.architecture) {
            return faces.arch.get(id)?.type ?? null;
        }
        return collection === COLLECTIONS.lexicon ? (faces.lex.get(id)?.kind ?? null) : null;
    };
};

const fieldDefects = function fieldDefects(
    kindOf: KindLookup,
    principle: Principle,
    field: RepairField,
): RepairDefect[] {
    const ref = `${COLLECTIONS.architecture}${REF_SEPARATOR}${principle.id}`;
    const admitted = REPAIR_RANGES[field];
    return (principle[field] ?? []).flatMap((target) => {
        const kind = kindOf(target);
        if (kind === null) {
            return [{ field, reason: REPAIR_NO_RECORD, ref, target }];
        }
        return admitted.has(kind) ? [] : [{ field, reason: repairWrongKind(kind, [...admitted]), ref, target }];
    });
};

const shapeDefects = function shapeDefects(principle: Principle): RepairDefect[] {
    const ref = `${COLLECTIONS.architecture}${REF_SEPARATOR}${principle.id}`;
    const negative = principle.type === NEGATIVE_KIND;
    const formed = principle.formed_by !== undefined;
    const violated = (principle.violated_by ?? []).length > 0;
    return [
        ...(negative && !formed ? [{ field: FORMED_BY, reason: FORMED_BY_MISSING, ref, target: "" }] : []),
        ...(!negative && formed ? [{ field: FORMED_BY, reason: FORMED_BY_MISPLACED, ref, target: "" }] : []),
        ...(!negative && !violated ? [{ field: VIOLATED_BY, reason: VIOLATED_BY_MISSING, ref, target: "" }] : []),
    ];
};

export const repairDefectsOf = function repairDefectsOf(
    principles: readonly Principle[],
    kindOf: KindLookup,
): RepairDefect[] {
    return principles.flatMap((principle) => [
        ...shapeDefects(principle),
        ...REPAIR_FIELDS.flatMap((field) => fieldDefects(kindOf, principle, field)),
    ]);
};
```
