# tools/core/reporters/segment.reporter.ts

> 57 lines of code and 9 definitions.

Tree: Coordination tree
Language: typescript
Layer: operations
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-reporters-segment-reporter-ts
Source text: https://banes-lab.com/assets/sources/source.04efbe0b45847637ae7368c5f7e687d566227a5392687ab20b3af0f251c47be9.generated.txt

## Definitions

- `Report` (interface_declaration, line 7, exported)
- `HitRecord` (interface_declaration, line 18, exported)
- `EditRecord` (interface_declaration, line 25, exported)
- `Coverage` (interface_declaration, line 33, exported)
- `toHitRecords` (lexical_declaration, line 38, exported)
- `toEditRecords` (lexical_declaration, line 47, exported)
- `verdictOf` (lexical_declaration, line 57, exported)
- `writeReport` (lexical_declaration, line 61, exported)
- `target` (lexical_declaration, line 62, exported)

## Source

```typescript
import type { Edit, Finding, Hit, Verdict } from "../types/segment.types.ts";
import { dirname, join } from "node:path";

import { mkdirSync, writeFileSync } from "node:fs";
import { GENERATED_DIR } from "../constants/path.constants.ts";

export interface Report {
    readonly tool: string;
    readonly verdict: Verdict;
    readonly scanned: number;
    readonly findings: readonly Finding[];
    readonly hits: readonly HitRecord[];
    readonly edits: readonly EditRecord[];
    readonly rejected: readonly EditRecord[];
    readonly coverage: Coverage;
}

export interface HitRecord {
    readonly pattern: string;
    readonly path: string;
    readonly line: number;
    readonly text: string;
}

export interface EditRecord {
    readonly path: string;
    readonly reason: string;
    readonly start: number;
    readonly end: number;
    readonly replacement: string;
}

export interface Coverage {
    readonly roots: readonly string[];
    readonly filesByExtension: Readonly<Record<string, number>>;
}

export const toHitRecords = function toHitRecords(hits: readonly Hit[]): HitRecord[] {
    return hits.map((hit) => ({
        line: hit.span.line,
        path: hit.path,
        pattern: hit.patternId,
        text: hit.segments.map((s) => s.text).join("\n"),
    }));
};

export const toEditRecords = function toEditRecords(edits: readonly Edit[]): EditRecord[] {
    return edits.map((edit) => ({
        end: edit.end,
        path: edit.path,
        reason: edit.reason,
        replacement: edit.replacement,
        start: edit.start,
    }));
};

export const verdictOf = function verdictOf(findings: readonly Finding[], rejected: readonly Edit[]): Verdict {
    return findings.length === 0 && rejected.length === 0 ? "pass" : "fail";
};

export const writeReport = function writeReport(repoRoot: string, name: string, report: Report): string {
    const target = join(repoRoot, GENERATED_DIR, `${name}.generated.json`);
    mkdirSync(dirname(target), { recursive: true });
    writeFileSync(target, `${JSON.stringify(report, null, 2)}\n`, "utf8");
    return target;
};
```
