# core/validators/writing.validator.ts

> 27 lines of code and 6 definitions.

Tree: Build tree
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/build#file-build-core-validators-writing-validator-ts
Source text: https://banes-lab.com/assets/sources/source.fa94fe5a9e573c005604e352041138128a6e364f8dec76d6c83e7ac61b36d3fa.generated.txt

## Definitions

- `signoffKey` (lexical_declaration, line 6)
- `unsignedSections` (lexical_declaration, line 10, exported)
- `signed` (lexical_declaration, line 16, exported)
- `everSigned` (lexical_declaration, line 17, exported)
- `unreadCount` (lexical_declaration, line 27, exported)
- `inScope` (lexical_declaration, line 28, exported)

## Source

```typescript
import type { PageSection, ReadingSignoff } from "#types/writing.types";
import { SIGNOFF_CHANGED, SIGNOFF_MISSING } from "#configuration/strings/derivation.strings";
import type { Finding } from "#types/derivation.types";
import { SIGNOFF_SEPARATOR } from "#configuration/constants/writing.constants";

const signoffKey = function signoffKey(key: string, fingerprint: string): string {
    return key + SIGNOFF_SEPARATOR + fingerprint;
};

export const unsignedSections = function unsignedSections(
    scope: readonly string[],
    signoffs: readonly ReadingSignoff[],
    sections: readonly PageSection[],
): Finding[] {
    const inScope = new Set(scope);
    const signed = new Set(signoffs.map((signoff) => signoffKey(signoff.key, signoff.fingerprint)));
    const everSigned = new Set(signoffs.map((signoff) => signoff.key));
    return sections
        .filter((section) => inScope.has(section.page))
        .filter((section) => !signed.has(signoffKey(section.key, section.fingerprint)))
        .map((section) => ({
            file: section.key,
            message: `${everSigned.has(section.key) ? SIGNOFF_CHANGED : SIGNOFF_MISSING}${section.fingerprint}`,
        }));
};

export const unreadCount = function unreadCount(scope: readonly string[], sections: readonly PageSection[]): number {
    const inScope = new Set(scope);
    return sections.filter((section) => !inScope.has(section.page)).length;
};
```
