@carlonicora/nestjs-neo4jsonapi 4.3.2 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/responder/factories/responder.context.factory.d.ts +2 -1
- package/dist/agents/responder/factories/responder.context.factory.d.ts.map +1 -1
- package/dist/agents/responder/factories/responder.context.factory.js.map +1 -1
- package/dist/agents/responder/services/responder.service.d.ts +16 -1
- package/dist/agents/responder/services/responder.service.d.ts.map +1 -1
- package/dist/agents/responder/services/responder.service.js +14 -2
- package/dist/agents/responder/services/responder.service.js.map +1 -1
- package/dist/bootstrap/app.module.factory.d.ts.map +1 -1
- package/dist/bootstrap/app.module.factory.js +2 -0
- package/dist/bootstrap/app.module.factory.js.map +1 -1
- package/dist/bootstrap/bootstrap.options.d.ts +35 -0
- package/dist/bootstrap/bootstrap.options.d.ts.map +1 -1
- package/dist/common/handlers/relationship.handlers.d.ts +2 -0
- package/dist/common/handlers/relationship.handlers.d.ts.map +1 -1
- package/dist/common/handlers/relationship.handlers.js +1 -0
- package/dist/common/handlers/relationship.handlers.js.map +1 -1
- package/dist/common/index.d.ts +1 -0
- package/dist/common/index.d.ts.map +1 -1
- package/dist/common/index.js +4 -0
- package/dist/common/index.js.map +1 -1
- package/dist/common/repositories/handbook.ai-source-query.provider.d.ts +34 -0
- package/dist/common/repositories/handbook.ai-source-query.provider.d.ts.map +1 -0
- package/dist/common/repositories/handbook.ai-source-query.provider.js +58 -0
- package/dist/common/repositories/handbook.ai-source-query.provider.js.map +1 -0
- package/dist/common/repositories/index.d.ts +1 -0
- package/dist/common/repositories/index.d.ts.map +1 -1
- package/dist/common/repositories/index.js +1 -0
- package/dist/common/repositories/index.js.map +1 -1
- package/dist/common/types/data.limits.d.ts +4 -0
- package/dist/common/types/data.limits.d.ts.map +1 -1
- package/dist/common/utils/chunk-content.util.d.ts +28 -0
- package/dist/common/utils/chunk-content.util.d.ts.map +1 -0
- package/dist/common/utils/chunk-content.util.js +32 -0
- package/dist/common/utils/chunk-content.util.js.map +1 -0
- package/dist/config/base.config.d.ts.map +1 -1
- package/dist/config/base.config.js +1 -0
- package/dist/config/base.config.js.map +1 -1
- package/dist/config/enums/queue.id.d.ts +1 -0
- package/dist/config/enums/queue.id.d.ts.map +1 -1
- package/dist/config/enums/queue.id.js +1 -0
- package/dist/config/enums/queue.id.js.map +1 -1
- package/dist/config/interfaces/config.two.factor.interface.d.ts +10 -3
- package/dist/config/interfaces/config.two.factor.interface.d.ts.map +1 -1
- package/dist/core/core.module.d.ts.map +1 -1
- package/dist/core/core.module.js +8 -1
- package/dist/core/core.module.js.map +1 -1
- package/dist/core/llm/services/model.service.d.ts +13 -0
- package/dist/core/llm/services/model.service.d.ts.map +1 -1
- package/dist/core/llm/services/model.service.js +22 -0
- package/dist/core/llm/services/model.service.js.map +1 -1
- package/dist/core/neo4j/abstracts/abstract.service.d.ts +1 -0
- package/dist/core/neo4j/abstracts/abstract.service.d.ts.map +1 -1
- package/dist/core/neo4j/abstracts/abstract.service.js +9 -1
- package/dist/core/neo4j/abstracts/abstract.service.js.map +1 -1
- package/dist/foundations/assistant/controllers/assistant.controller.d.ts.map +1 -1
- package/dist/foundations/assistant/controllers/assistant.controller.js +6 -2
- package/dist/foundations/assistant/controllers/assistant.controller.js.map +1 -1
- package/dist/foundations/assistant/dtos/assistant-append.dto.d.ts +2 -0
- package/dist/foundations/assistant/dtos/assistant-append.dto.d.ts.map +1 -1
- package/dist/foundations/assistant/dtos/assistant-append.dto.js +10 -0
- package/dist/foundations/assistant/dtos/assistant-append.dto.js.map +1 -1
- package/dist/foundations/assistant/dtos/assistant-post.dto.d.ts +2 -0
- package/dist/foundations/assistant/dtos/assistant-post.dto.d.ts.map +1 -1
- package/dist/foundations/assistant/dtos/assistant-post.dto.js +10 -0
- package/dist/foundations/assistant/dtos/assistant-post.dto.js.map +1 -1
- package/dist/foundations/assistant/services/assistant.service.d.ts +8 -1
- package/dist/foundations/assistant/services/assistant.service.d.ts.map +1 -1
- package/dist/foundations/assistant/services/assistant.service.js +14 -1
- package/dist/foundations/assistant/services/assistant.service.js.map +1 -1
- package/dist/foundations/foundations.modules.d.ts +6 -0
- package/dist/foundations/foundations.modules.d.ts.map +1 -1
- package/dist/foundations/foundations.modules.js +10 -2
- package/dist/foundations/foundations.modules.js.map +1 -1
- package/dist/foundations/handbook/controllers/handbook-thread.controller.d.ts +61 -0
- package/dist/foundations/handbook/controllers/handbook-thread.controller.d.ts.map +1 -0
- package/dist/foundations/handbook/controllers/handbook-thread.controller.js +170 -0
- package/dist/foundations/handbook/controllers/handbook-thread.controller.js.map +1 -0
- package/dist/foundations/handbook/controllers/handbook.controller.d.ts +29 -0
- package/dist/foundations/handbook/controllers/handbook.controller.d.ts.map +1 -0
- package/dist/foundations/handbook/controllers/handbook.controller.js +123 -0
- package/dist/foundations/handbook/controllers/handbook.controller.js.map +1 -0
- package/dist/foundations/handbook/dtos/handbook-page.dto.d.ts +11 -0
- package/dist/foundations/handbook/dtos/handbook-page.dto.d.ts.map +1 -0
- package/dist/foundations/handbook/dtos/handbook-page.dto.js +45 -0
- package/dist/foundations/handbook/dtos/handbook-page.dto.js.map +1 -0
- package/dist/foundations/handbook/dtos/handbook-thread-message-post.dto.d.ts +24 -0
- package/dist/foundations/handbook/dtos/handbook-thread-message-post.dto.d.ts.map +1 -0
- package/dist/foundations/handbook/dtos/handbook-thread-message-post.dto.js +60 -0
- package/dist/foundations/handbook/dtos/handbook-thread-message-post.dto.js.map +1 -0
- package/dist/foundations/handbook/dtos/handbook-thread-patch.dto.d.ts +19 -0
- package/dist/foundations/handbook/dtos/handbook-thread-patch.dto.d.ts.map +1 -0
- package/dist/foundations/handbook/dtos/handbook-thread-patch.dto.js +59 -0
- package/dist/foundations/handbook/dtos/handbook-thread-patch.dto.js.map +1 -0
- package/dist/foundations/handbook/dtos/handbook-thread-post.dto.d.ts +24 -0
- package/dist/foundations/handbook/dtos/handbook-thread-post.dto.d.ts.map +1 -0
- package/dist/foundations/handbook/dtos/handbook-thread-post.dto.js +60 -0
- package/dist/foundations/handbook/dtos/handbook-thread-post.dto.js.map +1 -0
- package/dist/foundations/handbook/entities/handbook-page.d.ts +25 -0
- package/dist/foundations/handbook/entities/handbook-page.d.ts.map +1 -0
- package/dist/foundations/handbook/entities/handbook-page.js +45 -0
- package/dist/foundations/handbook/entities/handbook-page.js.map +1 -0
- package/dist/foundations/handbook/entities/handbook-page.meta.d.ts +3 -0
- package/dist/foundations/handbook/entities/handbook-page.meta.d.ts.map +1 -0
- package/dist/foundations/handbook/entities/handbook-page.meta.js +10 -0
- package/dist/foundations/handbook/entities/handbook-page.meta.js.map +1 -0
- package/dist/foundations/handbook/entities/handbook-section.d.ts +22 -0
- package/dist/foundations/handbook/entities/handbook-section.d.ts.map +1 -0
- package/dist/foundations/handbook/entities/handbook-section.js +24 -0
- package/dist/foundations/handbook/entities/handbook-section.js.map +1 -0
- package/dist/foundations/handbook/entities/handbook-section.meta.d.ts +3 -0
- package/dist/foundations/handbook/entities/handbook-section.meta.d.ts.map +1 -0
- package/dist/foundations/handbook/entities/handbook-section.meta.js +10 -0
- package/dist/foundations/handbook/entities/handbook-section.meta.js.map +1 -0
- package/dist/foundations/handbook/entities/handbook-thread-message.d.ts +36 -0
- package/dist/foundations/handbook/entities/handbook-thread-message.d.ts.map +1 -0
- package/dist/foundations/handbook/entities/handbook-thread-message.js +28 -0
- package/dist/foundations/handbook/entities/handbook-thread-message.js.map +1 -0
- package/dist/foundations/handbook/entities/handbook-thread-message.meta.d.ts +3 -0
- package/dist/foundations/handbook/entities/handbook-thread-message.meta.d.ts.map +1 -0
- package/dist/foundations/handbook/entities/handbook-thread-message.meta.js +10 -0
- package/dist/foundations/handbook/entities/handbook-thread-message.meta.js.map +1 -0
- package/dist/foundations/handbook/entities/handbook-thread.d.ts +47 -0
- package/dist/foundations/handbook/entities/handbook-thread.d.ts.map +1 -0
- package/dist/foundations/handbook/entities/handbook-thread.js +35 -0
- package/dist/foundations/handbook/entities/handbook-thread.js.map +1 -0
- package/dist/foundations/handbook/entities/handbook-thread.meta.d.ts +3 -0
- package/dist/foundations/handbook/entities/handbook-thread.meta.d.ts.map +1 -0
- package/dist/foundations/handbook/entities/handbook-thread.meta.js +10 -0
- package/dist/foundations/handbook/entities/handbook-thread.meta.js.map +1 -0
- package/dist/foundations/handbook/handbook.module.d.ts +21 -0
- package/dist/foundations/handbook/handbook.module.d.ts.map +1 -0
- package/dist/foundations/handbook/handbook.module.js +135 -0
- package/dist/foundations/handbook/handbook.module.js.map +1 -0
- package/dist/foundations/handbook/index.d.ts +23 -0
- package/dist/foundations/handbook/index.d.ts.map +1 -0
- package/dist/foundations/handbook/index.js +39 -0
- package/dist/foundations/handbook/index.js.map +1 -0
- package/dist/foundations/handbook/interfaces/handbook.config.interface.d.ts +26 -0
- package/dist/foundations/handbook/interfaces/handbook.config.interface.d.ts.map +1 -0
- package/dist/foundations/handbook/interfaces/handbook.config.interface.js +10 -0
- package/dist/foundations/handbook/interfaces/handbook.config.interface.js.map +1 -0
- package/dist/foundations/handbook/processors/handbook.processor.d.ts +22 -0
- package/dist/foundations/handbook/processors/handbook.processor.d.ts.map +1 -0
- package/dist/foundations/handbook/processors/handbook.processor.js +108 -0
- package/dist/foundations/handbook/processors/handbook.processor.js.map +1 -0
- package/dist/foundations/handbook/repositories/handbook-page.repository.d.ts +135 -0
- package/dist/foundations/handbook/repositories/handbook-page.repository.d.ts.map +1 -0
- package/dist/foundations/handbook/repositories/handbook-page.repository.js +245 -0
- package/dist/foundations/handbook/repositories/handbook-page.repository.js.map +1 -0
- package/dist/foundations/handbook/repositories/handbook-section.repository.d.ts +36 -0
- package/dist/foundations/handbook/repositories/handbook-section.repository.d.ts.map +1 -0
- package/dist/foundations/handbook/repositories/handbook-section.repository.js +91 -0
- package/dist/foundations/handbook/repositories/handbook-section.repository.js.map +1 -0
- package/dist/foundations/handbook/repositories/handbook-thread-message.repository.d.ts +36 -0
- package/dist/foundations/handbook/repositories/handbook-thread-message.repository.d.ts.map +1 -0
- package/dist/foundations/handbook/repositories/handbook-thread-message.repository.js +63 -0
- package/dist/foundations/handbook/repositories/handbook-thread-message.repository.js.map +1 -0
- package/dist/foundations/handbook/repositories/handbook-thread.repository.d.ts +63 -0
- package/dist/foundations/handbook/repositories/handbook-thread.repository.d.ts.map +1 -0
- package/dist/foundations/handbook/repositories/handbook-thread.repository.js +86 -0
- package/dist/foundations/handbook/repositories/handbook-thread.repository.js.map +1 -0
- package/dist/foundations/handbook/services/handbook-ingest.service.d.ts +101 -0
- package/dist/foundations/handbook/services/handbook-ingest.service.d.ts.map +1 -0
- package/dist/foundations/handbook/services/handbook-ingest.service.js +408 -0
- package/dist/foundations/handbook/services/handbook-ingest.service.js.map +1 -0
- package/dist/foundations/handbook/services/handbook-page.service.d.ts +57 -0
- package/dist/foundations/handbook/services/handbook-page.service.d.ts.map +1 -0
- package/dist/foundations/handbook/services/handbook-page.service.js +116 -0
- package/dist/foundations/handbook/services/handbook-page.service.js.map +1 -0
- package/dist/foundations/handbook/services/handbook-section.service.d.ts +15 -0
- package/dist/foundations/handbook/services/handbook-section.service.d.ts.map +1 -0
- package/dist/foundations/handbook/services/handbook-section.service.js +37 -0
- package/dist/foundations/handbook/services/handbook-section.service.js.map +1 -0
- package/dist/foundations/handbook/services/handbook-thread-message.service.d.ts +27 -0
- package/dist/foundations/handbook/services/handbook-thread-message.service.d.ts.map +1 -0
- package/dist/foundations/handbook/services/handbook-thread-message.service.js +39 -0
- package/dist/foundations/handbook/services/handbook-thread-message.service.js.map +1 -0
- package/dist/foundations/handbook/services/handbook-thread.service.d.ts +164 -0
- package/dist/foundations/handbook/services/handbook-thread.service.d.ts.map +1 -0
- package/dist/foundations/handbook/services/handbook-thread.service.js +297 -0
- package/dist/foundations/handbook/services/handbook-thread.service.js.map +1 -0
- package/dist/foundations/how-to/controllers/how-to.controller.d.ts +7 -1
- package/dist/foundations/how-to/controllers/how-to.controller.d.ts.map +1 -1
- package/dist/foundations/how-to/controllers/how-to.controller.js +18 -12
- package/dist/foundations/how-to/controllers/how-to.controller.js.map +1 -1
- package/dist/foundations/how-to/controllers/how-to.public.controller.d.ts +7 -0
- package/dist/foundations/how-to/controllers/how-to.public.controller.d.ts.map +1 -1
- package/dist/foundations/how-to/controllers/how-to.public.controller.js +7 -0
- package/dist/foundations/how-to/controllers/how-to.public.controller.js.map +1 -1
- package/dist/foundations/how-to/entities/how-to.d.ts.map +1 -1
- package/dist/foundations/how-to/entities/how-to.js +60 -13
- package/dist/foundations/how-to/entities/how-to.js.map +1 -1
- package/dist/foundations/how-to/how-to.module.d.ts +36 -1
- package/dist/foundations/how-to/how-to.module.d.ts.map +1 -1
- package/dist/foundations/how-to/how-to.module.js +80 -4
- package/dist/foundations/how-to/how-to.module.js.map +1 -1
- package/dist/foundations/how-to/index.d.ts +1 -0
- package/dist/foundations/how-to/index.d.ts.map +1 -1
- package/dist/foundations/how-to/index.js +1 -0
- package/dist/foundations/how-to/index.js.map +1 -1
- package/dist/foundations/how-to/interfaces/how-to.config.interface.d.ts +30 -0
- package/dist/foundations/how-to/interfaces/how-to.config.interface.d.ts.map +1 -0
- package/dist/foundations/how-to/interfaces/how-to.config.interface.js +10 -0
- package/dist/foundations/how-to/interfaces/how-to.config.interface.js.map +1 -0
- package/dist/foundations/how-to/processors/how-to.processor.d.ts +3 -1
- package/dist/foundations/how-to/processors/how-to.processor.d.ts.map +1 -1
- package/dist/foundations/how-to/processors/how-to.processor.js +8 -1
- package/dist/foundations/how-to/processors/how-to.processor.js.map +1 -1
- package/dist/foundations/how-to/services/how-to.service.d.ts +4 -0
- package/dist/foundations/how-to/services/how-to.service.d.ts.map +1 -1
- package/dist/foundations/how-to/services/how-to.service.js +47 -24
- package/dist/foundations/how-to/services/how-to.service.js.map +1 -1
- package/dist/foundations/index.d.ts +1 -0
- package/dist/foundations/index.d.ts.map +1 -1
- package/dist/foundations/index.js +1 -0
- package/dist/foundations/index.js.map +1 -1
- package/dist/foundations/two-factor/services/totp.service.d.ts.map +1 -1
- package/dist/foundations/two-factor/services/totp.service.js +2 -1
- package/dist/foundations/two-factor/services/totp.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.HandbookThreadRepository = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const nestjs_cls_1 = require("nestjs-cls");
|
|
15
|
+
const abstract_repository_1 = require("../../../core/neo4j/abstracts/abstract.repository");
|
|
16
|
+
const neo4j_service_1 = require("../../../core/neo4j/services/neo4j.service");
|
|
17
|
+
const security_service_1 = require("../../../core/security/services/security.service");
|
|
18
|
+
const handbook_thread_1 = require("../entities/handbook-thread");
|
|
19
|
+
const handbook_thread_meta_1 = require("../entities/handbook-thread.meta");
|
|
20
|
+
const handbook_thread_message_meta_1 = require("../entities/handbook-thread-message.meta");
|
|
21
|
+
/**
|
|
22
|
+
* HandbookThreadRepository
|
|
23
|
+
*
|
|
24
|
+
* `HandbookThread` is `isCompanyScoped: false`, so `buildDefaultMatch()` emits
|
|
25
|
+
* no company filter at all — the `CREATED_BY` owner edge asserted here is the
|
|
26
|
+
* ENTIRE security boundary. Without this override every administrator would
|
|
27
|
+
* read and mutate every other administrator's threads.
|
|
28
|
+
*
|
|
29
|
+
* `$currentUserId` is auto-injected into queryParams by
|
|
30
|
+
* `Neo4jService.initQuery()` (it reads `clsService.get("userId")`), exactly as
|
|
31
|
+
* `AssistantRepository` relies on.
|
|
32
|
+
*/
|
|
33
|
+
let HandbookThreadRepository = class HandbookThreadRepository extends abstract_repository_1.AbstractRepository {
|
|
34
|
+
constructor(neo4j, securityService, clsService) {
|
|
35
|
+
super(neo4j, securityService, clsService);
|
|
36
|
+
this.descriptor = handbook_thread_1.HandbookThreadDescriptor;
|
|
37
|
+
}
|
|
38
|
+
buildUserHasAccess() {
|
|
39
|
+
const { nodeName } = this.descriptor.model;
|
|
40
|
+
return `WITH ${nodeName}
|
|
41
|
+
WHERE EXISTS {
|
|
42
|
+
MATCH (${nodeName})-[:CREATED_BY]->(:User {id: $currentUserId})
|
|
43
|
+
}
|
|
44
|
+
WITH ${nodeName}`;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Bump `updatedAt` so the thread list — ordered by the descriptor default
|
|
48
|
+
* `updatedAt DESC` — surfaces the conversation a user just spoke in. Neither
|
|
49
|
+
* creating a child message nor writing the `HAS_MESSAGE` edge touches the
|
|
50
|
+
* parent node, so without this an active thread would sink below a thread
|
|
51
|
+
* that was merely renamed.
|
|
52
|
+
*/
|
|
53
|
+
async touch(params) {
|
|
54
|
+
await this.neo4j.writeOne({
|
|
55
|
+
query: `
|
|
56
|
+
MATCH (${handbook_thread_meta_1.handbookThreadMeta.nodeName}:${handbook_thread_meta_1.handbookThreadMeta.labelName} {id: $id})
|
|
57
|
+
SET ${handbook_thread_meta_1.handbookThreadMeta.nodeName}.updatedAt = datetime()
|
|
58
|
+
`,
|
|
59
|
+
queryParams: { id: params.id },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Delete the thread AND its messages. `DETACH DELETE` on the thread alone
|
|
64
|
+
* would drop the `HAS_MESSAGE` edges and orphan every message node, which
|
|
65
|
+
* — because the messages are only ever reachable through their thread —
|
|
66
|
+
* means they could never be read or deleted again.
|
|
67
|
+
*
|
|
68
|
+
* Mirrors `AssistantRepository.delete`.
|
|
69
|
+
*/
|
|
70
|
+
async delete(params) {
|
|
71
|
+
await this.neo4j.writeOne({
|
|
72
|
+
query: `
|
|
73
|
+
MATCH (${handbook_thread_meta_1.handbookThreadMeta.nodeName}:${handbook_thread_meta_1.handbookThreadMeta.labelName} {id: $id})
|
|
74
|
+
OPTIONAL MATCH (${handbook_thread_meta_1.handbookThreadMeta.nodeName})-[:HAS_MESSAGE]->(${handbook_thread_message_meta_1.handbookThreadMessageMeta.nodeName}:${handbook_thread_message_meta_1.handbookThreadMessageMeta.labelName})
|
|
75
|
+
DETACH DELETE ${handbook_thread_meta_1.handbookThreadMeta.nodeName}, ${handbook_thread_message_meta_1.handbookThreadMessageMeta.nodeName}
|
|
76
|
+
`,
|
|
77
|
+
queryParams: { id: params.id },
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
exports.HandbookThreadRepository = HandbookThreadRepository;
|
|
82
|
+
exports.HandbookThreadRepository = HandbookThreadRepository = __decorate([
|
|
83
|
+
(0, common_1.Injectable)(),
|
|
84
|
+
__metadata("design:paramtypes", [neo4j_service_1.Neo4jService, security_service_1.SecurityService, nestjs_cls_1.ClsService])
|
|
85
|
+
], HandbookThreadRepository);
|
|
86
|
+
//# sourceMappingURL=handbook-thread.repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handbook-thread.repository.js","sourceRoot":"","sources":["../../../../src/foundations/handbook/repositories/handbook-thread.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,2CAAwC;AACxC,2FAAuF;AACvF,8EAA0E;AAC1E,uFAAmF;AACnF,iEAAuF;AACvF,2EAAsE;AACtE,2FAAqF;AAErF;;;;;;;;;;;GAWG;AAEI,IAAM,wBAAwB,GAA9B,MAAM,wBAAyB,SAAQ,wCAG7C;IAGC,YAAY,KAAmB,EAAE,eAAgC,EAAE,UAAsB;QACvF,KAAK,CAAC,KAAK,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;QAHzB,eAAU,GAAG,0CAAwB,CAAC;IAIzD,CAAC;IAES,kBAAkB;QAC1B,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAC3C,OAAO,QAAQ,QAAQ;;uBAEJ,QAAQ;;mBAEZ,QAAQ,EAAE,CAAC;IAC5B,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,CAAC,MAAsB;QAChC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YACxB,KAAK,EAAE;iBACI,yCAAkB,CAAC,QAAQ,IAAI,yCAAkB,CAAC,SAAS;cAC9D,yCAAkB,CAAC,QAAQ;OAClC;YACD,WAAW,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;SAC/B,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,MAAM,CAAC,MAAsB;QACjC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YACxB,KAAK,EAAE;iBACI,yCAAkB,CAAC,QAAQ,IAAI,yCAAkB,CAAC,SAAS;0BAClD,yCAAkB,CAAC,QAAQ,sBAAsB,wDAAyB,CAAC,QAAQ,IAAI,wDAAyB,CAAC,SAAS;wBAC5H,yCAAkB,CAAC,QAAQ,KAAK,wDAAyB,CAAC,QAAQ;OACnF;YACD,WAAW,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;SAC/B,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AAtDY,4DAAwB;mCAAxB,wBAAwB;IADpC,IAAA,mBAAU,GAAE;qCAOQ,4BAAY,EAAmB,kCAAe,EAAc,uBAAU;GAN9E,wBAAwB,CAsDpC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { AppLoggingService } from "../../../core/logging/services/logging.service";
|
|
2
|
+
import { ModelService } from "../../../core/llm/services/model.service";
|
|
3
|
+
import { HandbookModuleConfig } from "../interfaces/handbook.config.interface";
|
|
4
|
+
import { HandbookPageRepository } from "../repositories/handbook-page.repository";
|
|
5
|
+
import { HandbookSectionRepository } from "../repositories/handbook-section.repository";
|
|
6
|
+
import { HandbookPageService } from "./handbook-page.service";
|
|
7
|
+
export type HandbookSyncResult = {
|
|
8
|
+
created: number;
|
|
9
|
+
updated: number;
|
|
10
|
+
unchanged: number;
|
|
11
|
+
deleted: number;
|
|
12
|
+
/** Repo-relative paths whose ingest threw. The walk continues past them. */
|
|
13
|
+
failed: string[];
|
|
14
|
+
};
|
|
15
|
+
export declare class HandbookIngestService {
|
|
16
|
+
private readonly config;
|
|
17
|
+
private readonly handbookPageRepository;
|
|
18
|
+
private readonly handbookSectionRepository;
|
|
19
|
+
private readonly handbookPageService;
|
|
20
|
+
private readonly modelService;
|
|
21
|
+
private readonly logger;
|
|
22
|
+
constructor(config: Required<HandbookModuleConfig>, handbookPageRepository: HandbookPageRepository, handbookSectionRepository: HandbookSectionRepository, handbookPageService: HandbookPageService, modelService: ModelService, logger: AppLoggingService);
|
|
23
|
+
sync(): Promise<HandbookSyncResult>;
|
|
24
|
+
/**
|
|
25
|
+
* Writes the display translation onto the pages the English walk produced.
|
|
26
|
+
*
|
|
27
|
+
* The English tree is the source of truth for WHICH pages exist: a translated
|
|
28
|
+
* file whose path has no English counterpart is counted and skipped, never
|
|
29
|
+
* created. Creating it would put an unindexed page in the manual and — worse,
|
|
30
|
+
* once someone pressed sync again — an English-less page in the retrieval
|
|
31
|
+
* store.
|
|
32
|
+
*
|
|
33
|
+
* Nothing here chunks, embeds or enqueues. `updateDisplay` writes three
|
|
34
|
+
* properties; `content`, `contentHash` and `aiStatus` are untouched, so the
|
|
35
|
+
* index after this pass is byte-for-byte the index before it.
|
|
36
|
+
*/
|
|
37
|
+
private syncDisplay;
|
|
38
|
+
private walk;
|
|
39
|
+
/**
|
|
40
|
+
* Glob support is deliberately the smallest thing that serves the config:
|
|
41
|
+
* a literal prefix with a trailing `**`, or an exact path. No dependency,
|
|
42
|
+
* nothing to misread.
|
|
43
|
+
*/
|
|
44
|
+
private isExcluded;
|
|
45
|
+
/**
|
|
46
|
+
* Splits a leading YAML frontmatter block off a markdown file and returns its
|
|
47
|
+
* scalar keys.
|
|
48
|
+
*
|
|
49
|
+
* Still not a YAML parser: the block this reads is a handful of `key: value`
|
|
50
|
+
* lines, and a dependency buys nothing but new failure modes on a malformed
|
|
51
|
+
* block. Nested structures and lists are ignored rather than half-parsed.
|
|
52
|
+
*/
|
|
53
|
+
private splitFrontmatter;
|
|
54
|
+
/**
|
|
55
|
+
* The tree's own `README.md` index, parsed — or empty maps when it has none.
|
|
56
|
+
*
|
|
57
|
+
* Both roots go through this: the English tree and, when one is configured,
|
|
58
|
+
* the display tree. A display README's link paths are relative to the display
|
|
59
|
+
* root, which IS the English relative path, so the summaries it yields key
|
|
60
|
+
* straight onto the English pages.
|
|
61
|
+
*/
|
|
62
|
+
private readIndex;
|
|
63
|
+
private emptyIndex;
|
|
64
|
+
/**
|
|
65
|
+
* Reads the tree's own `README.md` index, when it has one.
|
|
66
|
+
*
|
|
67
|
+
* Two maps come out: section key to its heading title and blurb, and
|
|
68
|
+
* repo-relative path to the one-line description the index gives it. Both are
|
|
69
|
+
* optional by construction — an application with no README gets empty maps,
|
|
70
|
+
* prettified section titles and pages with no summary, and the manual still
|
|
71
|
+
* renders.
|
|
72
|
+
*/
|
|
73
|
+
private parseIndex;
|
|
74
|
+
/**
|
|
75
|
+
* The paragraph beneath a section heading, rebuilt into one sentence.
|
|
76
|
+
*
|
|
77
|
+
* A README wraps its prose, so the blurb arrives as several lines; joining
|
|
78
|
+
* the contiguous run is the difference between a summary and a sentence cut
|
|
79
|
+
* at "and an index". Collection starts at the first line that is neither
|
|
80
|
+
* blank, nor a list item, nor inside a fenced code block, and stops at the
|
|
81
|
+
* first blank line or list item after that.
|
|
82
|
+
*
|
|
83
|
+
* Fenced blocks are stepped over whole: a section that opens with one — the
|
|
84
|
+
* a360 handbook's own `## Checking the handbook` does — must be summarised by
|
|
85
|
+
* its prose, not by a fence or by the command inside it.
|
|
86
|
+
*/
|
|
87
|
+
private blurbOf;
|
|
88
|
+
/**
|
|
89
|
+
* `00-start-here` becomes "Start here". The numeric prefix orders the
|
|
90
|
+
* directories on disk and is noise on screen; a key with no prefix is used
|
|
91
|
+
* as written.
|
|
92
|
+
*/
|
|
93
|
+
private sectionTitle;
|
|
94
|
+
/**
|
|
95
|
+
* Frontmatter `title` first, then the first H1, then the filename. The
|
|
96
|
+
* handbook this was built against uses frontmatter and no H1 at all, so the
|
|
97
|
+
* H1 branch exists for directories that are written the other way.
|
|
98
|
+
*/
|
|
99
|
+
private titleOf;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=handbook-ingest.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handbook-ingest.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/handbook/services/handbook-ingest.service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAExE,OAAO,EAAmB,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAChG,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AA4BF,qBACa,qBAAqB;IAEL,OAAO,CAAC,QAAQ,CAAC,MAAM;IAChD,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAC1C,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBALmB,MAAM,EAAE,QAAQ,CAAC,oBAAoB,CAAC,EAC/D,sBAAsB,EAAE,sBAAsB,EAC9C,yBAAyB,EAAE,yBAAyB,EACpD,mBAAmB,EAAE,mBAAmB,EACxC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,iBAAiB;IAGtC,IAAI,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAsJzC;;;;;;;;;;;;OAYG;YACW,WAAW;IAoCzB,OAAO,CAAC,IAAI;IA+CZ;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAQlB;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;;;;OAOG;IACH,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,UAAU;IAOlB;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAU;IAwBlB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,OAAO;IAwBf;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAMpB;;;;OAIG;IACH,OAAO,CAAC,OAAO;CAShB"}
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.HandbookIngestService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const crypto_1 = require("crypto");
|
|
18
|
+
const fs_1 = require("fs");
|
|
19
|
+
const path_1 = require("path");
|
|
20
|
+
const logging_service_1 = require("../../../core/logging/services/logging.service");
|
|
21
|
+
const model_service_1 = require("../../../core/llm/services/model.service");
|
|
22
|
+
const handbook_config_interface_1 = require("../interfaces/handbook.config.interface");
|
|
23
|
+
const handbook_page_repository_1 = require("../repositories/handbook-page.repository");
|
|
24
|
+
const handbook_section_repository_1 = require("../repositories/handbook-section.repository");
|
|
25
|
+
const handbook_page_service_1 = require("./handbook-page.service");
|
|
26
|
+
/**
|
|
27
|
+
* Bumped whenever the walk changes how a file becomes a page — frontmatter
|
|
28
|
+
* handling, title derivation, what is stripped before chunking.
|
|
29
|
+
*
|
|
30
|
+
* It is mixed into `contentHash`, so a parsing change invalidates every stored
|
|
31
|
+
* page and the next sync re-ingests them. Without it the hash only tracks the
|
|
32
|
+
* file's bytes: a fixed parser leaves every already-ingested page frozen in the
|
|
33
|
+
* shape the old parser gave it, and the fix silently does nothing. That is
|
|
34
|
+
* exactly what happened on the 2026-09-11 verification run.
|
|
35
|
+
*/
|
|
36
|
+
const INGEST_FORMAT_VERSION = "2";
|
|
37
|
+
let HandbookIngestService = class HandbookIngestService {
|
|
38
|
+
constructor(config, handbookPageRepository, handbookSectionRepository, handbookPageService, modelService, logger) {
|
|
39
|
+
this.config = config;
|
|
40
|
+
this.handbookPageRepository = handbookPageRepository;
|
|
41
|
+
this.handbookSectionRepository = handbookSectionRepository;
|
|
42
|
+
this.handbookPageService = handbookPageService;
|
|
43
|
+
this.modelService = modelService;
|
|
44
|
+
this.logger = logger;
|
|
45
|
+
}
|
|
46
|
+
async sync() {
|
|
47
|
+
// FIRST, before the directory is even read. Chunking is not work that
|
|
48
|
+
// degrades gracefully without AI: every chunk is embedded as it is created
|
|
49
|
+
// and every chunk queues an extraction call, so an unconfigured
|
|
50
|
+
// installation would write a thousand nodes and queue a thousand jobs that
|
|
51
|
+
// all fail inside provider construction. Nothing starts.
|
|
52
|
+
if (!this.modelService.isAiConfigured()) {
|
|
53
|
+
this.logger.warn("Handbook sync refused: no usable AI configuration (AI_PROVIDER / AI_MODEL / EMBEDDER_*).");
|
|
54
|
+
throw new common_1.BadRequestException("AI is not configured: set the AI_* and EMBEDDER_* variables (or an AI connection) before ingesting the handbook.");
|
|
55
|
+
}
|
|
56
|
+
const root = this.config.path;
|
|
57
|
+
if (!root)
|
|
58
|
+
throw new common_1.BadRequestException("No handbook directory configured. Set `handbook.path` on FoundationsModule.forRoot().");
|
|
59
|
+
if (!(0, fs_1.existsSync)(root) || !(0, fs_1.statSync)(root).isDirectory())
|
|
60
|
+
throw new common_1.BadRequestException(`Configured handbook directory does not exist: ${root}`);
|
|
61
|
+
// Read once, before the walk: the index is optional by construction, so an
|
|
62
|
+
// application whose documentation tree has no README still ingests — it
|
|
63
|
+
// just gets prettified section titles and pages with no summary.
|
|
64
|
+
const index = this.readIndex(root);
|
|
65
|
+
// The display translation, when the application ships one. It is a mirror
|
|
66
|
+
// of the English tree under `<root>/<displayPath>` — the same relative
|
|
67
|
+
// paths, translated prose — and it is SHOWN, never INDEXED: the English
|
|
68
|
+
// walk skips it through `exclude`, and the pass at the foot of this method
|
|
69
|
+
// writes its text onto pages the English walk already created. Its own
|
|
70
|
+
// README is read here because the section write below needs it.
|
|
71
|
+
const displayPath = this.config.displayPath ?? "";
|
|
72
|
+
const displayRoot = displayPath.length > 0 ? (0, path_1.join)(root, displayPath) : "";
|
|
73
|
+
const hasDisplay = displayRoot.length > 0 && (0, fs_1.existsSync)(displayRoot) && (0, fs_1.statSync)(displayRoot).isDirectory();
|
|
74
|
+
const displayIndex = hasDisplay ? this.readIndex(displayRoot) : this.emptyIndex();
|
|
75
|
+
const files = this.walk(root, index.summaries);
|
|
76
|
+
const existing = await this.handbookPageRepository.findAllPages();
|
|
77
|
+
const byPath = new Map(existing.map((page) => [page.path, page]));
|
|
78
|
+
const result = { created: 0, updated: 0, unchanged: 0, deleted: 0, failed: [] };
|
|
79
|
+
for (const file of files) {
|
|
80
|
+
const page = byPath.get(file.path);
|
|
81
|
+
try {
|
|
82
|
+
if (!page) {
|
|
83
|
+
const id = (0, crypto_1.randomUUID)();
|
|
84
|
+
await this.handbookPageRepository.createPage({
|
|
85
|
+
id,
|
|
86
|
+
path: file.path,
|
|
87
|
+
title: file.title,
|
|
88
|
+
content: file.content,
|
|
89
|
+
contentHash: file.hash,
|
|
90
|
+
wordCount: file.wordCount,
|
|
91
|
+
section: file.section,
|
|
92
|
+
order: file.order,
|
|
93
|
+
summary: file.summary,
|
|
94
|
+
});
|
|
95
|
+
await this.handbookPageService.chunkAndQueue({
|
|
96
|
+
handbookPageId: id,
|
|
97
|
+
markdown: file.content,
|
|
98
|
+
title: file.title,
|
|
99
|
+
});
|
|
100
|
+
result.created++;
|
|
101
|
+
}
|
|
102
|
+
else if (page.contentHash === file.hash) {
|
|
103
|
+
// The bytes did not change, so the chunks are still correct — but the
|
|
104
|
+
// index fields may be new (a README summary added, a frontmatter
|
|
105
|
+
// `section` corrected), and those cost nothing to rewrite.
|
|
106
|
+
await this.handbookPageRepository.updateMetadata({
|
|
107
|
+
id: page.id,
|
|
108
|
+
title: file.title,
|
|
109
|
+
section: file.section,
|
|
110
|
+
order: file.order,
|
|
111
|
+
summary: file.summary,
|
|
112
|
+
});
|
|
113
|
+
result.unchanged++;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
await this.handbookPageRepository.updatePage({
|
|
117
|
+
id: page.id,
|
|
118
|
+
title: file.title,
|
|
119
|
+
content: file.content,
|
|
120
|
+
contentHash: file.hash,
|
|
121
|
+
wordCount: file.wordCount,
|
|
122
|
+
section: file.section,
|
|
123
|
+
order: file.order,
|
|
124
|
+
summary: file.summary,
|
|
125
|
+
});
|
|
126
|
+
await this.handbookPageService.chunkAndQueue({
|
|
127
|
+
handbookPageId: page.id,
|
|
128
|
+
markdown: file.content,
|
|
129
|
+
title: file.title,
|
|
130
|
+
});
|
|
131
|
+
result.updated++;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
// One unreadable or unchunkable file must not abort the pass: the
|
|
136
|
+
// remaining documentation is still worth indexing, and the caller gets
|
|
137
|
+
// the list of what failed.
|
|
138
|
+
this.logger.error(`Handbook ingest failed for ${file.path}: ${error.message}`);
|
|
139
|
+
result.failed.push(file.path);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const seen = new Set(files.map((file) => file.path));
|
|
143
|
+
for (const page of existing) {
|
|
144
|
+
if (seen.has(page.path))
|
|
145
|
+
continue;
|
|
146
|
+
// Through the service, not the repository: it is what also drops the
|
|
147
|
+
// page's chunks and resizes the key-concept weights they carried.
|
|
148
|
+
await this.handbookPageService.delete({ id: page.id });
|
|
149
|
+
result.deleted++;
|
|
150
|
+
}
|
|
151
|
+
// Sections come from the files, never from the index. A README's `##`
|
|
152
|
+
// headings are prose sections as often as they are directories — a360's own
|
|
153
|
+
// index carries `Reading orders`, `Conventions`, `Checking the handbook`,
|
|
154
|
+
// `Adding a page`, `Where to look` and `Gaps and drift` — so accepting
|
|
155
|
+
// arbitrary headings would print six empty junk sections on the contents
|
|
156
|
+
// page. A section IS a directory of pages; the index only describes one,
|
|
157
|
+
// contributing a title and a blurb to a key the walk already observed and
|
|
158
|
+
// nothing at all to a key it did not.
|
|
159
|
+
const keys = new Set(files.map((file) => file.section));
|
|
160
|
+
keys.delete("");
|
|
161
|
+
await this.handbookSectionRepository.replaceAll({
|
|
162
|
+
sections: [...keys].sort().map((key) => ({
|
|
163
|
+
id: (0, crypto_1.randomUUID)(),
|
|
164
|
+
key,
|
|
165
|
+
title: index.sections.get(key)?.title ?? this.sectionTitle(key),
|
|
166
|
+
summary: index.sections.get(key)?.summary,
|
|
167
|
+
order: key,
|
|
168
|
+
// The display README describes the same keys — it is a mirror — so a
|
|
169
|
+
// heading it does not carry simply leaves the section untranslated and
|
|
170
|
+
// the reading surface falls back to the English title.
|
|
171
|
+
displayTitle: displayIndex.sections.get(key)?.title,
|
|
172
|
+
displaySummary: displayIndex.sections.get(key)?.summary,
|
|
173
|
+
})),
|
|
174
|
+
});
|
|
175
|
+
if (hasDisplay)
|
|
176
|
+
await this.syncDisplay({ displayRoot, displayIndex });
|
|
177
|
+
this.logger.log(`Handbook sync: ${result.created} created, ${result.updated} updated, ${result.unchanged} unchanged, ${result.deleted} deleted, ${result.failed.length} failed`);
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Writes the display translation onto the pages the English walk produced.
|
|
182
|
+
*
|
|
183
|
+
* The English tree is the source of truth for WHICH pages exist: a translated
|
|
184
|
+
* file whose path has no English counterpart is counted and skipped, never
|
|
185
|
+
* created. Creating it would put an unindexed page in the manual and — worse,
|
|
186
|
+
* once someone pressed sync again — an English-less page in the retrieval
|
|
187
|
+
* store.
|
|
188
|
+
*
|
|
189
|
+
* Nothing here chunks, embeds or enqueues. `updateDisplay` writes three
|
|
190
|
+
* properties; `content`, `contentHash` and `aiStatus` are untouched, so the
|
|
191
|
+
* index after this pass is byte-for-byte the index before it.
|
|
192
|
+
*/
|
|
193
|
+
async syncDisplay(params) {
|
|
194
|
+
const files = this.walk(params.displayRoot, params.displayIndex.summaries);
|
|
195
|
+
// Re-read rather than reuse the map built before the walk: on a first sync
|
|
196
|
+
// that map is empty, because every page was created moments ago, and every
|
|
197
|
+
// translation would be reported as an orphan.
|
|
198
|
+
const pages = await this.handbookPageRepository.findAllPages();
|
|
199
|
+
const byPath = new Map(pages.map((page) => [page.path, page]));
|
|
200
|
+
let translated = 0;
|
|
201
|
+
let orphaned = 0;
|
|
202
|
+
for (const file of files) {
|
|
203
|
+
const page = byPath.get(file.path);
|
|
204
|
+
if (!page) {
|
|
205
|
+
orphaned++;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
await this.handbookPageRepository.updateDisplay({
|
|
209
|
+
id: page.id,
|
|
210
|
+
displayTitle: file.title,
|
|
211
|
+
displaySummary: file.summary,
|
|
212
|
+
displayContent: file.content,
|
|
213
|
+
});
|
|
214
|
+
translated++;
|
|
215
|
+
}
|
|
216
|
+
this.logger.log(`Handbook display translation (${this.config.displayPath}): ${translated} pages translated, ${orphaned} translated files with no English counterpart`);
|
|
217
|
+
}
|
|
218
|
+
walk(root, summaries = new Map()) {
|
|
219
|
+
const out = [];
|
|
220
|
+
const visit = (directory) => {
|
|
221
|
+
for (const entry of (0, fs_1.readdirSync)(directory, { withFileTypes: true })) {
|
|
222
|
+
const absolute = (0, path_1.join)(directory, entry.name);
|
|
223
|
+
if (entry.isDirectory()) {
|
|
224
|
+
visit(absolute);
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (!entry.name.endsWith(".md"))
|
|
228
|
+
continue;
|
|
229
|
+
const path = (0, path_1.relative)(root, absolute).split(path_1.sep).join("/");
|
|
230
|
+
if (this.isExcluded(path))
|
|
231
|
+
continue;
|
|
232
|
+
const raw = (0, fs_1.readFileSync)(absolute, "utf8");
|
|
233
|
+
const { frontmatter, body } = this.splitFrontmatter(raw);
|
|
234
|
+
// Declared section first, then the directory the file sits in. A file at
|
|
235
|
+
// the tree root with no declaration gets "", and is dropped from the
|
|
236
|
+
// section list rather than inventing an unnamed one.
|
|
237
|
+
const section = frontmatter.section ?? path.split("/").slice(0, -1)[0] ?? "";
|
|
238
|
+
out.push({
|
|
239
|
+
path,
|
|
240
|
+
section,
|
|
241
|
+
order: path.toLowerCase(),
|
|
242
|
+
summary: summaries.get(path),
|
|
243
|
+
// The BODY is what gets stored, rendered and chunked. Frontmatter is
|
|
244
|
+
// metadata about the file, not prose about the subject: embedding
|
|
245
|
+
// `sources_verified: 2026-09-10` teaches the retriever nothing and
|
|
246
|
+
// dilutes the chunk it lands in.
|
|
247
|
+
content: body,
|
|
248
|
+
title: this.titleOf({ frontmatterTitle: frontmatter.title, content: body, path }),
|
|
249
|
+
// Hashed over the RAW file (so editing only the frontmatter still
|
|
250
|
+
// re-ingests the page) plus the format version (so changing the parser
|
|
251
|
+
// re-ingests every page).
|
|
252
|
+
hash: (0, crypto_1.createHash)("sha256").update(`${INGEST_FORMAT_VERSION}\n${raw}`).digest("hex"),
|
|
253
|
+
wordCount: body.split(/\s+/).filter(Boolean).length,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
visit(root);
|
|
258
|
+
return out;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Glob support is deliberately the smallest thing that serves the config:
|
|
262
|
+
* a literal prefix with a trailing `**`, or an exact path. No dependency,
|
|
263
|
+
* nothing to misread.
|
|
264
|
+
*/
|
|
265
|
+
isExcluded(path) {
|
|
266
|
+
return this.config.exclude.some((pattern) => {
|
|
267
|
+
if (pattern.endsWith("/**"))
|
|
268
|
+
return path.startsWith(pattern.slice(0, -2));
|
|
269
|
+
if (pattern.endsWith("**"))
|
|
270
|
+
return path.startsWith(pattern.slice(0, -2));
|
|
271
|
+
return path === pattern;
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Splits a leading YAML frontmatter block off a markdown file and returns its
|
|
276
|
+
* scalar keys.
|
|
277
|
+
*
|
|
278
|
+
* Still not a YAML parser: the block this reads is a handful of `key: value`
|
|
279
|
+
* lines, and a dependency buys nothing but new failure modes on a malformed
|
|
280
|
+
* block. Nested structures and lists are ignored rather than half-parsed.
|
|
281
|
+
*/
|
|
282
|
+
splitFrontmatter(raw) {
|
|
283
|
+
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
|
|
284
|
+
if (!match)
|
|
285
|
+
return { frontmatter: {}, body: raw };
|
|
286
|
+
const frontmatter = {};
|
|
287
|
+
for (const line of match[1].split(/\r?\n/)) {
|
|
288
|
+
const pair = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
|
|
289
|
+
if (!pair)
|
|
290
|
+
continue;
|
|
291
|
+
const value = pair[2].trim().replace(/^["']|["']$/g, "");
|
|
292
|
+
if (value)
|
|
293
|
+
frontmatter[pair[1]] = value;
|
|
294
|
+
}
|
|
295
|
+
return { frontmatter, body: raw.slice(match[0].length).trimStart() };
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* The tree's own `README.md` index, parsed — or empty maps when it has none.
|
|
299
|
+
*
|
|
300
|
+
* Both roots go through this: the English tree and, when one is configured,
|
|
301
|
+
* the display tree. A display README's link paths are relative to the display
|
|
302
|
+
* root, which IS the English relative path, so the summaries it yields key
|
|
303
|
+
* straight onto the English pages.
|
|
304
|
+
*/
|
|
305
|
+
readIndex(directory) {
|
|
306
|
+
const indexPath = (0, path_1.join)(directory, "README.md");
|
|
307
|
+
return (0, fs_1.existsSync)(indexPath) ? this.parseIndex((0, fs_1.readFileSync)(indexPath, "utf8")) : this.emptyIndex();
|
|
308
|
+
}
|
|
309
|
+
emptyIndex() {
|
|
310
|
+
return { sections: new Map(), summaries: new Map() };
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Reads the tree's own `README.md` index, when it has one.
|
|
314
|
+
*
|
|
315
|
+
* Two maps come out: section key to its heading title and blurb, and
|
|
316
|
+
* repo-relative path to the one-line description the index gives it. Both are
|
|
317
|
+
* optional by construction — an application with no README gets empty maps,
|
|
318
|
+
* prettified section titles and pages with no summary, and the manual still
|
|
319
|
+
* renders.
|
|
320
|
+
*/
|
|
321
|
+
parseIndex(readme) {
|
|
322
|
+
const sections = new Map();
|
|
323
|
+
const summaries = new Map();
|
|
324
|
+
const blocks = readme.split(/^##\s+/m).slice(1);
|
|
325
|
+
for (const block of blocks) {
|
|
326
|
+
const lines = block.split(/\r?\n/);
|
|
327
|
+
const key = lines[0].trim();
|
|
328
|
+
sections.set(key, { title: this.sectionTitle(key), summary: this.blurbOf(lines.slice(1)) });
|
|
329
|
+
}
|
|
330
|
+
// `- [Title](path) — summary` across the whole file, section blocks included.
|
|
331
|
+
const entry = /^-\s*\[[^\]]+\]\(([^)]+)\)\s*[—–-]\s*(.+)$/gm;
|
|
332
|
+
for (const match of readme.matchAll(entry)) {
|
|
333
|
+
const path = match[1].split("#")[0].trim();
|
|
334
|
+
if (path.length > 0)
|
|
335
|
+
summaries.set(path, match[2].trim());
|
|
336
|
+
}
|
|
337
|
+
return { sections, summaries };
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* The paragraph beneath a section heading, rebuilt into one sentence.
|
|
341
|
+
*
|
|
342
|
+
* A README wraps its prose, so the blurb arrives as several lines; joining
|
|
343
|
+
* the contiguous run is the difference between a summary and a sentence cut
|
|
344
|
+
* at "and an index". Collection starts at the first line that is neither
|
|
345
|
+
* blank, nor a list item, nor inside a fenced code block, and stops at the
|
|
346
|
+
* first blank line or list item after that.
|
|
347
|
+
*
|
|
348
|
+
* Fenced blocks are stepped over whole: a section that opens with one — the
|
|
349
|
+
* a360 handbook's own `## Checking the handbook` does — must be summarised by
|
|
350
|
+
* its prose, not by a fence or by the command inside it.
|
|
351
|
+
*/
|
|
352
|
+
blurbOf(lines) {
|
|
353
|
+
const paragraph = [];
|
|
354
|
+
let fenced = false;
|
|
355
|
+
for (const raw of lines) {
|
|
356
|
+
const line = raw.trim();
|
|
357
|
+
if (line.startsWith("```")) {
|
|
358
|
+
fenced = !fenced;
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
if (fenced)
|
|
362
|
+
continue;
|
|
363
|
+
if (line.length === 0 || line.startsWith("-")) {
|
|
364
|
+
if (paragraph.length > 0)
|
|
365
|
+
break;
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
paragraph.push(line);
|
|
369
|
+
}
|
|
370
|
+
return paragraph.length > 0 ? paragraph.join(" ") : undefined;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* `00-start-here` becomes "Start here". The numeric prefix orders the
|
|
374
|
+
* directories on disk and is noise on screen; a key with no prefix is used
|
|
375
|
+
* as written.
|
|
376
|
+
*/
|
|
377
|
+
sectionTitle(key) {
|
|
378
|
+
const words = key.replace(/^\d+-/, "").replace(/-/g, " ").trim();
|
|
379
|
+
if (words.length === 0)
|
|
380
|
+
return key;
|
|
381
|
+
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Frontmatter `title` first, then the first H1, then the filename. The
|
|
385
|
+
* handbook this was built against uses frontmatter and no H1 at all, so the
|
|
386
|
+
* H1 branch exists for directories that are written the other way.
|
|
387
|
+
*/
|
|
388
|
+
titleOf(params) {
|
|
389
|
+
if (params.frontmatterTitle)
|
|
390
|
+
return params.frontmatterTitle;
|
|
391
|
+
const heading = params.content.match(/^#\s+(.+)$/m);
|
|
392
|
+
if (heading)
|
|
393
|
+
return heading[1].trim();
|
|
394
|
+
const name = params.path.split("/").pop() ?? params.path;
|
|
395
|
+
return name.replace(/\.md$/, "");
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
exports.HandbookIngestService = HandbookIngestService;
|
|
399
|
+
exports.HandbookIngestService = HandbookIngestService = __decorate([
|
|
400
|
+
(0, common_1.Injectable)(),
|
|
401
|
+
__param(0, (0, common_1.Inject)(handbook_config_interface_1.HANDBOOK_CONFIG)),
|
|
402
|
+
__metadata("design:paramtypes", [Object, handbook_page_repository_1.HandbookPageRepository,
|
|
403
|
+
handbook_section_repository_1.HandbookSectionRepository,
|
|
404
|
+
handbook_page_service_1.HandbookPageService,
|
|
405
|
+
model_service_1.ModelService,
|
|
406
|
+
logging_service_1.AppLoggingService])
|
|
407
|
+
], HandbookIngestService);
|
|
408
|
+
//# sourceMappingURL=handbook-ingest.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handbook-ingest.service.js","sourceRoot":"","sources":["../../../../src/foundations/handbook/services/handbook-ingest.service.ts"],"names":[],"mappings":"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"}
|