-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathinterfaces.ts
More file actions
183 lines (163 loc) · 6.98 KB
/
interfaces.ts
File metadata and controls
183 lines (163 loc) · 6.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/**
* @module Infrastructure/RenderLib/Aggregator/Interfaces
* @category Intelligence Operations / Supporting Infrastructure
* @name Shared pipeline interfaces and types
*
* @description
* Centralised type definitions for the article.md generation pipeline.
* Every stage (read → validate → aggregate → enrich → write) uses these
* interfaces as its contract, enabling independent testing and composability.
*
* @author Hack23 AB (Infrastructure Team)
* @license Apache-2.0
*/
// ─── Pipeline Stage Contracts ────────────────────────────────────────────────
/**
* Discriminated union result type for pipeline stages. The `ok` discriminant
* guarantees TypeScript can narrow to exactly one branch — `ok: true` always
* carries `value: T` and never `error`; `ok: false` always carries `error`
* and never `value`. This prevents impossible states such as
* `{ ok: true, error: '…' }` and eliminates the need for non-null assertions
* in well-typed consumers.
*/
export type PipelineResult<T> =
| { readonly ok: true; readonly value: T; readonly warnings?: readonly string[] }
| { readonly ok: false; readonly error: string; readonly warnings?: readonly string[] };
/**
* A single pipeline stage: takes an input and produces a typed result.
* Stages are composable — the output of one stage feeds the next.
*/
export interface PipelineStage<TInput, TOutput> {
readonly name: string;
execute(input: TInput): PipelineResult<TOutput>;
}
// ─── Read Stage ──────────────────────────────────────────────────────────────
/**
* Input to the read stage: filesystem location of analysis artifacts.
*/
export interface ReadStageInput {
/** Absolute path to `analysis/daily/$DATE/$SUBFOLDER`. */
readonly subfolderAbsPath: string;
/** Repo-relative path (e.g. `analysis/daily/2026-04-23/propositions`). */
readonly subfolderRepoRelPath: string;
/** `$DATE` (YYYY-MM-DD). */
readonly date: string;
/** `$SUBFOLDER` (e.g. `propositions`). */
readonly subfolder: string;
}
/**
* A single analysis artifact read from disk.
*/
export interface ArtifactFile {
/** Filename relative to the subfolder (e.g. `executive-brief.md`). */
readonly fileName: string;
/** Raw file content (UTF-8). */
readonly content: string;
}
/**
* Output of the read stage: inventory of all available artifacts.
*/
export interface ReadStageOutput {
/** All markdown artifacts found in the subfolder. */
readonly artifacts: readonly ArtifactFile[];
/** Whether a `documents/` subdirectory with per-document analyses exists. */
readonly hasDocuments: boolean;
/** Set of filenames available (for Reader Guide filtering). */
readonly availableFiles: ReadonlySet<string>;
}
// ─── Validate Stage ──────────────────────────────────────────────────────────
/**
* Validation diagnostics for a single artifact or the folder as a whole.
*/
export interface ValidationDiagnostic {
readonly level: 'error' | 'warning' | 'info';
readonly message: string;
readonly file?: string;
}
/**
* Output of the validate stage.
*/
export interface ValidateStageOutput {
/** Whether the artifact set passes the analysis gate. */
readonly passed: boolean;
/** Ordered list of diagnostics. */
readonly diagnostics: readonly ValidationDiagnostic[];
}
// ─── Aggregate Stage ─────────────────────────────────────────────────────────
/**
* A rendered section of the final article (post-cleaning, with heading).
*/
export interface ArticleSection {
/** The artifact filename this section was sourced from (or synthetic ID). */
readonly sourceFile: string;
/** Rendered markdown for this section (including ## heading). */
readonly markdown: string;
}
/**
* Output of the aggregate stage: ordered sections ready for assembly.
*/
export interface AggregateStageOutput {
/** Article title (from executive-brief). */
readonly title: string;
/** Article description / lede (from executive-brief BLUF). */
readonly description: string;
/** Ordered sections composing the article body. */
readonly sections: readonly ArticleSection[];
/** Ordered list of artifact filenames consumed. */
readonly artifactsUsed: readonly string[];
}
// ─── Enrich Stage ────────────────────────────────────────────────────────────
/**
* SEO and metadata fields added during enrichment. Field names are aligned
* with `FrontMatterFields` (snake_case) so there is no impedance mismatch
* when passing this struct into `buildFrontMatter()`.
*/
export interface EnrichmentMetadata {
readonly title: string;
readonly description: string;
readonly date: string;
readonly subfolder: string;
readonly slug: string;
/** Repo-relative path to the source analysis folder. */
readonly source_folder: string;
/** ISO-8601 generation timestamp. */
readonly generated_at: string;
readonly language: string;
/** Article layout template (defaults to `'article'`). */
readonly layout: string;
}
/**
* Output of the enrich stage.
*/
export interface EnrichStageOutput {
readonly metadata: EnrichmentMetadata;
readonly sections: readonly ArticleSection[];
readonly artifactsUsed: readonly string[];
}
// ─── Write Stage ─────────────────────────────────────────────────────────────
/**
* Output of the write stage: the final article.md content.
*/
export interface WriteStageOutput {
/** Complete markdown content (front-matter + body). */
readonly markdown: string;
/** Article title for summary reporting. */
readonly title: string;
/** Article description for summary reporting. */
readonly description: string;
/** Ordered list of artifacts consumed. */
readonly artifactsUsed: readonly string[];
}
// ─── Full Pipeline ───────────────────────────────────────────────────────────
/**
* Configuration for the full article pipeline. Field names mirror
* `FrontMatterFields` (snake_case) to avoid impedance mismatch.
*/
export interface ArticlePipelineConfig {
/** Override the `generated_at` front-matter field (ISO-8601). Used for deterministic tests. */
readonly generated_at?: string;
/** Language code injected into front-matter (defaults to `'en'`). */
readonly language?: string;
/** Layout template injected into front-matter (defaults to `'article'`). */
readonly layout?: string;
}