# core/converters/lesson.converter.ts

> 74 lines of code and 15 definitions.

Tree: Build tree
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/build#file-build-core-converters-lesson-converter-ts
Source text: https://banes-lab.com/assets/sources/source.a4fb2580b554d2d50ca7588ac9937cc9b0c0c3c8dab72cf59465da5aa58914a9.generated.txt

## Definitions

- `seedOf` (lexical_declaration, line 30)
- `kernelOf` (lexical_declaration, line 7)
- `validationOf` (lexical_declaration, line 11)
- `causesOf` (lexical_declaration, line 20)
- `algoSeeds` (lexical_declaration, line 76, exported)
- `SOURCE` (lexical_declaration, line 5)
- `entry` (lexical_declaration, line 12)
- `record` (lexical_declaration, line 16)
- `names` (lexical_declaration, line 21)
- `before` (lexical_declaration, line 31)
- `missingFieldsOf` (lexical_declaration, line 48, exported)
- `reportOf` (lexical_declaration, line 65, exported)
- `incomplete` (lexical_declaration, line 66, exported)
- `missing` (lexical_declaration, line 68, exported)
- `contracts` (lexical_declaration, line 77, exported)

## Source

```typescript
import type { Faces, IncompleteSeed, LessonSeed, SeedReport } from "#types/lesson.types";
import { SEED_LEVELS, VERIFY_STAGE } from "#configuration/constants/seed.constants";
import type { Contract } from "@govlab/context/algo";

const SOURCE = "algo";

const kernelOf = function kernelOf(contracts: readonly Contract[], domain: string): Contract | null {
    return contracts.find((contract) => contract.domain === domain && contract.derivationMap !== undefined) ?? null;
};

const validationOf = function validationOf(faces: Faces, kernel: Contract | null): string | null {
    const entry = kernel?.derivationMap?.find((mapped) => mapped.stage === VERIFY_STAGE);
    if (entry === undefined) {
        return null;
    }
    const record = faces.algo.get(entry.record);
    return record === null || record.invariant.length === 0 ? null : record.invariant;
};

const causesOf = function causesOf(faces: Faces, forces: readonly string[]): string[] {
    const names = new Set<string>();
    for (const force of forces) {
        for (const principle of faces.arch.query({ scope: force })) {
            names.add(principle.name);
        }
    }
    return [...names].sort((a, b) => a.localeCompare(b));
};

const seedOf = function seedOf(faces: Faces, meta: Contract, kernel: Contract | null): LessonSeed {
    const before = kernel?.exemplar?.before ?? null;
    return {
        application: meta.flow,
        boundary: null,
        cause: causesOf(faces, meta.force),
        decision: meta.intent,
        domain: meta.domain,
        failureMode: before,
        id: meta.id,
        level: SEED_LEVELS[SOURCE],
        principle: meta.invariant,
        problem: before,
        source: SOURCE,
        validation: validationOf(faces, kernel),
    };
};

export const missingFieldsOf = function missingFieldsOf(seed: LessonSeed): string[] {
    const missing: string[] = [];
    if (seed.problem === null) {
        missing.push("problem");
    }
    if (seed.cause.length === 0) {
        missing.push("cause");
    }
    if (seed.validation === null) {
        missing.push("validation");
    }
    if (seed.principle.length === 0) {
        missing.push("principle");
    }
    return missing;
};

export const reportOf = function reportOf(seeds: readonly LessonSeed[]): SeedReport {
    const incomplete: IncompleteSeed[] = [];
    for (const seed of seeds) {
        const missing = missingFieldsOf(seed);
        if (missing.length > 0) {
            incomplete.push({ id: seed.id, missing });
        }
    }
    return { incomplete, seeds };
};

export const algoSeeds = function algoSeeds(faces: Faces): LessonSeed[] {
    const contracts = faces.algo.all();
    return faces.algo
        .query({ meta: true })
        .map((meta) => seedOf(faces, meta, kernelOf(contracts, meta.domain)))
        .sort((a, b) => a.id.localeCompare(b.id));
};
```
