64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
|
|
/**
|
||
|
|
* Document service — registers ingested documents and emits the §4 events.
|
||
|
|
*
|
||
|
|
* The ingest pipeline (`src/source/pdf/ingest.ts`) is a pure function over
|
||
|
|
* bytes — it does not touch the engine. The app composition root calls
|
||
|
|
* `ingestPdf` then hands the result to `documentService.register()`, which
|
||
|
|
* is where the engine takes over: persist into the repos, emit
|
||
|
|
* `DocumentImported` + `DocumentRepresentationGenerated`.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import type { Document, DocumentRepresentation } from "@shared/document";
|
||
|
|
import type { DocumentId, RepresentationId } from "@shared/ids";
|
||
|
|
|
||
|
|
import type { EventBus } from "../events";
|
||
|
|
import type { DocumentRepository, RepresentationRepository } from "../repos";
|
||
|
|
|
||
|
|
export interface DocumentService {
|
||
|
|
register(input: {
|
||
|
|
readonly document: Document;
|
||
|
|
readonly representation: DocumentRepresentation;
|
||
|
|
}): { readonly document: Document; readonly representation: DocumentRepresentation };
|
||
|
|
get(id: DocumentId): Document | null;
|
||
|
|
list(): readonly Document[];
|
||
|
|
getRepresentation(id: RepresentationId): DocumentRepresentation | null;
|
||
|
|
listRepresentations(documentId: DocumentId): readonly DocumentRepresentation[];
|
||
|
|
}
|
||
|
|
|
||
|
|
export function createDocumentService(
|
||
|
|
documents: DocumentRepository,
|
||
|
|
representations: RepresentationRepository,
|
||
|
|
bus: EventBus,
|
||
|
|
): DocumentService {
|
||
|
|
return {
|
||
|
|
register({ document, representation }) {
|
||
|
|
const storedDocument = documents.create(document);
|
||
|
|
const storedRepresentation = representations.create(representation);
|
||
|
|
bus.emit({
|
||
|
|
type: "DocumentImported",
|
||
|
|
documentId: storedDocument.id,
|
||
|
|
document: storedDocument,
|
||
|
|
});
|
||
|
|
bus.emit({
|
||
|
|
type: "DocumentRepresentationGenerated",
|
||
|
|
documentId: storedDocument.id,
|
||
|
|
representationId: storedRepresentation.id,
|
||
|
|
representation: storedRepresentation,
|
||
|
|
});
|
||
|
|
return { document: storedDocument, representation: storedRepresentation };
|
||
|
|
},
|
||
|
|
get(id) {
|
||
|
|
return documents.get(id);
|
||
|
|
},
|
||
|
|
list() {
|
||
|
|
return documents.list();
|
||
|
|
},
|
||
|
|
getRepresentation(id) {
|
||
|
|
return representations.get(id);
|
||
|
|
},
|
||
|
|
listRepresentations(documentId) {
|
||
|
|
return representations.listByDocument(documentId);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
}
|