@carlonicora/nestjs-neo4jsonapi 1.34.0 → 1.34.2
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/README.md +706 -369
- package/dist/core/cache/services/cache.service.d.ts.map +1 -1
- package/dist/core/cache/services/cache.service.js +13 -1
- package/dist/core/cache/services/cache.service.js.map +1 -1
- package/dist/foundations/company/controllers/company.controller.d.ts.map +1 -1
- package/dist/foundations/company/controllers/company.controller.js +0 -20
- package/dist/foundations/company/controllers/company.controller.js.map +1 -1
- package/dist/foundations/company/services/company.service.d.ts.map +1 -1
- package/dist/foundations/company/services/company.service.js +4 -17
- package/dist/foundations/company/services/company.service.js.map +1 -1
- package/dist/foundations/stripe/__tests__/fixtures/stripe.fixtures.d.ts.map +1 -1
- package/dist/foundations/stripe/__tests__/fixtures/stripe.fixtures.js +15 -14
- package/dist/foundations/stripe/__tests__/fixtures/stripe.fixtures.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @carlonicora/nestjs-neo4jsonapi
|
|
2
2
|
|
|
3
|
-
A comprehensive NestJS foundation package providing JSON:API compliant APIs, Neo4j graph database integration, Redis caching, LangChain-based AI agents (including GraphRAG), and common utilities for building modern multi-tenant applications.
|
|
3
|
+
A comprehensive NestJS foundation package providing JSON:API compliant APIs, Neo4j graph database integration, Redis caching, LangChain-based AI agents (including GraphRAG and DRIFT), OAuth 2.0 server, OpenAPI documentation, and common utilities for building modern multi-tenant applications.
|
|
4
4
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
|
|
@@ -9,14 +9,18 @@ A comprehensive NestJS foundation package providing JSON:API compliant APIs, Neo
|
|
|
9
9
|
- [Installation](#installation)
|
|
10
10
|
- [Environment Variables](#environment-variables)
|
|
11
11
|
- [Quick Start](#quick-start)
|
|
12
|
-
- [Advanced Setup (Custom Bootstrap)](#advanced-setup-custom-bootstrap)
|
|
13
12
|
- [Company-User Model (B2B & B2C)](#company-user-model-b2b--b2c)
|
|
14
13
|
- [Required Configuration Files](#required-configuration-files)
|
|
15
14
|
- [Core Modules](#core-modules)
|
|
16
15
|
- [Health Check Endpoints](#health-check-endpoints)
|
|
17
16
|
- [Foundation Modules](#foundation-modules)
|
|
18
17
|
- [AI Agents](#ai-agents)
|
|
18
|
+
- [DRIFT Module (Advanced Semantic Search)](#drift-module-advanced-semantic-search)
|
|
19
|
+
- [OpenAPI Documentation](#openapi-documentation)
|
|
20
|
+
- [OAuth 2.0 Support](#oauth-20-support)
|
|
19
21
|
- [Security & Authentication](#security--authentication)
|
|
22
|
+
- [Company Deletion Handler](#company-deletion-handler)
|
|
23
|
+
- [Entity Descriptors (defineEntity)](#entity-descriptors-defineentity)
|
|
20
24
|
- [Customizing Agent Prompts](#customizing-agent-prompts-optional)
|
|
21
25
|
- [License](#license)
|
|
22
26
|
|
|
@@ -27,10 +31,15 @@ A comprehensive NestJS foundation package providing JSON:API compliant APIs, Neo
|
|
|
27
31
|
- **Neo4j Integration**: Graph database operations with Cypher query builder
|
|
28
32
|
- **Redis Caching**: Built-in caching layer with configurable TTLs
|
|
29
33
|
- **Multi-Tenant Architecture**: Support for both B2B (multi-company) and B2C (single invisible company) scenarios
|
|
30
|
-
- **AI Agents**: LangChain-powered agents including GraphRAG for knowledge extraction, summarization, and intelligent responses
|
|
34
|
+
- **AI Agents**: LangChain-powered agents including GraphRAG and DRIFT for knowledge extraction, summarization, and intelligent responses
|
|
35
|
+
- **DRIFT Search**: Advanced semantic search using community detection and HyDE (Hypothetical Document Embedding)
|
|
36
|
+
- **OAuth 2.0 Server**: RFC 6749/7636 compliant authorization server with PKCE support
|
|
37
|
+
- **OpenAPI Documentation**: Auto-generated JSON:API compliant Swagger/Redoc documentation
|
|
31
38
|
- **Authentication**: JWT-based authentication with role-based access control
|
|
32
39
|
- **Background Jobs**: BullMQ integration for async job processing
|
|
33
40
|
- **WebSockets**: Real-time communication support
|
|
41
|
+
- **Vision LLM Support**: Separate configuration for vision/image analysis models
|
|
42
|
+
- **Transcriber Support**: Speech-to-text transcription capabilities
|
|
34
43
|
- **Tracing**: OpenTelemetry integration for distributed tracing
|
|
35
44
|
- **Logging**: Structured logging with Loki integration
|
|
36
45
|
|
|
@@ -49,6 +58,7 @@ The library is designed to run in two modes from the same codebase:
|
|
|
49
58
|
|
|
50
59
|
- Processes BullMQ jobs asynchronously
|
|
51
60
|
- Runs scheduled tasks (cron jobs)
|
|
61
|
+
- Discord bot integration (when configured)
|
|
52
62
|
- No HTTP server - just job processing
|
|
53
63
|
- Same configuration and modules as API
|
|
54
64
|
|
|
@@ -66,19 +76,20 @@ pnpm start:prod # API mode
|
|
|
66
76
|
pnpm start:worker:prod # Worker mode
|
|
67
77
|
```
|
|
68
78
|
|
|
69
|
-
The mode is determined by the `--mode` flag and configured via `getAppMode()` and `getAppModeConfig()
|
|
79
|
+
The mode is determined by the `--mode` flag and configured via `getAppMode()` and `getAppModeConfig()`.
|
|
70
80
|
|
|
71
81
|
## Architecture
|
|
72
82
|
|
|
73
|
-
The library is organized into
|
|
83
|
+
The library is organized into five main layers:
|
|
74
84
|
|
|
75
85
|
```
|
|
76
86
|
@carlonicora/nestjs-neo4jsonapi
|
|
77
87
|
├── common/ # Shared utilities, abstracts, decorators, guards
|
|
78
88
|
├── config/ # Configuration system and tokens
|
|
79
|
-
├── core/ # Infrastructure modules (
|
|
80
|
-
├── foundations/ # Domain/business modules (
|
|
81
|
-
├── agents/ # AI agent modules (
|
|
89
|
+
├── core/ # Infrastructure modules (19 modules)
|
|
90
|
+
├── foundations/ # Domain/business modules (31 modules)
|
|
91
|
+
├── agents/ # AI agent modules (7 modules)
|
|
92
|
+
├── openapi/ # OpenAPI/Swagger documentation
|
|
82
93
|
└── bootstrap/ # Application bootstrap utilities
|
|
83
94
|
```
|
|
84
95
|
|
|
@@ -208,28 +219,84 @@ CACHE_SKIP_PATTERNS=/access,/auth,/notifications,/websocket,/version
|
|
|
208
219
|
JWT_SECRET=your-jwt-secret
|
|
209
220
|
JWT_EXPIRES_IN=1h
|
|
210
221
|
|
|
222
|
+
# Auth
|
|
223
|
+
ALLOW_REGISTRATION=true
|
|
224
|
+
|
|
225
|
+
# OAuth 2.0 Server (optional)
|
|
226
|
+
OAUTH_ENABLED=false
|
|
227
|
+
OAUTH_AUTHORIZATION_CODE_LIFETIME=600
|
|
228
|
+
OAUTH_ACCESS_TOKEN_LIFETIME=3600
|
|
229
|
+
OAUTH_REFRESH_TOKEN_LIFETIME=604800
|
|
230
|
+
OAUTH_REQUIRE_PKCE_FOR_PUBLIC_CLIENTS=true
|
|
231
|
+
OAUTH_ROTATE_REFRESH_TOKENS=true
|
|
232
|
+
|
|
211
233
|
# CORS
|
|
212
234
|
CORS_ORIGINS=http://localhost:3001
|
|
213
235
|
CORS_CREDENTIALS=true
|
|
236
|
+
CORS_ORIGIN_PATTERNS=
|
|
237
|
+
CORS_METHODS=GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS
|
|
238
|
+
CORS_ALLOWED_HEADERS=
|
|
239
|
+
CORS_MAX_AGE=86400
|
|
240
|
+
CORS_PREFLIGHT_CONTINUE=false
|
|
241
|
+
CORS_OPTIONS_SUCCESS_STATUS=204
|
|
242
|
+
CORS_LOG_VIOLATIONS=true
|
|
214
243
|
|
|
215
244
|
# AI Configuration (optional)
|
|
216
245
|
AI_PROVIDER=openai
|
|
217
246
|
AI_API_KEY=sk-...
|
|
218
247
|
AI_MODEL=gpt-4o-mini
|
|
248
|
+
AI_URL=
|
|
249
|
+
AI_REGION=
|
|
250
|
+
AI_INSTANCE=
|
|
251
|
+
AI_API_VERSION=
|
|
252
|
+
AI_INPUT_COST_PER_1M_TOKENS=0
|
|
253
|
+
AI_OUTPUT_COST_PER_1M_TOKENS=0
|
|
254
|
+
AI_GOOGLE_CREDENTIALS_BASE64=
|
|
255
|
+
|
|
256
|
+
# Vision LLM (optional - falls back to AI_ settings if not set)
|
|
257
|
+
VISION_PROVIDER=openai
|
|
258
|
+
VISION_API_KEY=
|
|
259
|
+
VISION_MODEL=gpt-4o
|
|
260
|
+
VISION_URL=
|
|
261
|
+
VISION_REGION=
|
|
262
|
+
VISION_SECRET=
|
|
263
|
+
VISION_INSTANCE=
|
|
264
|
+
VISION_API_VERSION=
|
|
265
|
+
VISION_INPUT_COST_PER_1M_TOKENS=0
|
|
266
|
+
VISION_OUTPUT_COST_PER_1M_TOKENS=0
|
|
267
|
+
VISION_GOOGLE_CREDENTIALS_BASE64=
|
|
268
|
+
|
|
269
|
+
# Transcriber (optional)
|
|
270
|
+
TRANSCRIBER_PROVIDER=
|
|
271
|
+
TRANSCRIBER_API_KEY=
|
|
272
|
+
TRANSCRIBER_MODEL=
|
|
273
|
+
TRANSCRIBER_URL=
|
|
274
|
+
TRANSCRIBER_API_VERSION=
|
|
219
275
|
|
|
220
276
|
# Embedder (optional)
|
|
221
277
|
EMBEDDER_PROVIDER=openrouter
|
|
222
278
|
EMBEDDER_API_KEY=sk-...
|
|
223
279
|
EMBEDDER_MODEL=openai/text-embedding-3-large
|
|
224
280
|
EMBEDDER_DIMENSIONS=3072
|
|
281
|
+
EMBEDDER_INSTANCE=
|
|
282
|
+
EMBEDDER_API_VERSION=
|
|
283
|
+
EMBEDDER_REGION=
|
|
284
|
+
EMBEDDER_GOOGLE_CREDENTIALS_BASE64=
|
|
225
285
|
|
|
226
286
|
# Logging - Loki (optional)
|
|
227
287
|
LOKI_ENABLED=false
|
|
228
288
|
LOKI_HOST=http://localhost:3100
|
|
289
|
+
LOKI_USERNAME=
|
|
290
|
+
LOKI_PASSWORD=
|
|
291
|
+
LOKI_BATCHING=true
|
|
292
|
+
LOKI_INTERVAL=30
|
|
293
|
+
LOKI_APP_LABEL=
|
|
229
294
|
|
|
230
295
|
# Tracing - Tempo (optional)
|
|
231
296
|
TEMPO_ENABLED=false
|
|
232
297
|
TEMPO_ENDPOINT=http://localhost:4318/v1/traces
|
|
298
|
+
TEMPO_SERVICE_NAME=my-app
|
|
299
|
+
TEMPO_SERVICE_VERSION=1.0.0
|
|
233
300
|
|
|
234
301
|
# S3 Storage (optional)
|
|
235
302
|
S3_TYPE=aws
|
|
@@ -239,15 +306,23 @@ S3_ACCESS_KEY_ID=
|
|
|
239
306
|
S3_SECRET_ACCESS_KEY=
|
|
240
307
|
S3_REGION=eu-west-1
|
|
241
308
|
|
|
242
|
-
# Email (
|
|
309
|
+
# Email (supports: sendgrid, smtp, brevo)
|
|
243
310
|
EMAIL_PROVIDER=sendgrid
|
|
244
311
|
EMAIL_API_KEY=
|
|
245
312
|
EMAIL_FROM=noreply@example.com
|
|
313
|
+
EMAIL_HOST=
|
|
314
|
+
EMAIL_PORT=587
|
|
315
|
+
EMAIL_SECURE=false
|
|
316
|
+
EMAIL_USERNAME=
|
|
317
|
+
EMAIL_PASSWORD=
|
|
246
318
|
|
|
247
319
|
# Stripe (optional)
|
|
248
320
|
STRIPE_SECRET_KEY=
|
|
249
321
|
STRIPE_PUBLISHABLE_KEY=
|
|
250
322
|
STRIPE_WEBHOOK_SECRET=
|
|
323
|
+
STRIPE_API_VERSION=2024-12-18.acacia
|
|
324
|
+
STRIPE_PORTAL_RETURN_URL=
|
|
325
|
+
STRIPE_PORTAL_CONFIGURATION_ID=
|
|
251
326
|
|
|
252
327
|
# Push Notifications (optional)
|
|
253
328
|
VAPID_PUBLIC_KEY=
|
|
@@ -258,15 +333,41 @@ VAPID_EMAIL=
|
|
|
258
333
|
RATE_LIMIT_ENABLED=true
|
|
259
334
|
RATE_LIMIT_TTL=60000
|
|
260
335
|
RATE_LIMIT_REQUESTS=100
|
|
336
|
+
IP_RATE_LIMIT_REQUESTS=20
|
|
261
337
|
|
|
262
338
|
# Encryption
|
|
263
339
|
ENCRYPTION_KEY=your-32-char-encryption-key
|
|
340
|
+
|
|
341
|
+
# Discord (optional)
|
|
342
|
+
DISCORD_CLIENT_ID=
|
|
343
|
+
DISCORD_CLIENT_SECRET=
|
|
344
|
+
DISCORD_TOKEN=
|
|
345
|
+
DISCORD_DEV_GUILD_ID=
|
|
346
|
+
|
|
347
|
+
# Google (optional)
|
|
348
|
+
GOOGLE_CLIENT_ID=
|
|
349
|
+
GOOGLE_CLIENT_SECRET=
|
|
264
350
|
```
|
|
265
351
|
|
|
266
352
|
## Quick Start
|
|
267
353
|
|
|
268
354
|
The library provides a `bootstrap()` function that handles all the complexity of setting up a NestJS application. You only need to provide your app-specific configuration.
|
|
269
355
|
|
|
356
|
+
**What you need:**
|
|
357
|
+
1. `main.ts` - Bootstrap entry point (~25 lines)
|
|
358
|
+
2. `config/config.ts` - Optional custom config extending baseConfig
|
|
359
|
+
3. `features/features.modules.ts` - Your feature modules
|
|
360
|
+
|
|
361
|
+
**What the library handles internally:**
|
|
362
|
+
- AppModule creation (no `app.module.ts` needed)
|
|
363
|
+
- Fastify adapter with multipart support
|
|
364
|
+
- Global validation pipes, exception filters, and interceptors
|
|
365
|
+
- Rate limiting, CORS, and caching
|
|
366
|
+
- i18n internationalization
|
|
367
|
+
- OpenAPI/Swagger documentation
|
|
368
|
+
- Discord bot integration (Worker mode)
|
|
369
|
+
- Graceful shutdown handlers
|
|
370
|
+
|
|
270
371
|
### 1. Create Your Features Module
|
|
271
372
|
|
|
272
373
|
```typescript
|
|
@@ -282,7 +383,7 @@ import { Module } from "@nestjs/common";
|
|
|
282
383
|
export class FeaturesModules {}
|
|
283
384
|
```
|
|
284
385
|
|
|
285
|
-
###
|
|
386
|
+
### 2. Create Configuration File (Optional)
|
|
286
387
|
|
|
287
388
|
If you need custom queues or content types, create a config file:
|
|
288
389
|
|
|
@@ -304,6 +405,33 @@ export default () => ({
|
|
|
304
405
|
});
|
|
305
406
|
```
|
|
306
407
|
|
|
408
|
+
### 3. Create OpenAPI Configuration (Optional)
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
// src/openapi/openapi.config.ts
|
|
412
|
+
import { OpenApiOptions } from "@carlonicora/nestjs-neo4jsonapi";
|
|
413
|
+
import { allEntityDescriptors } from "./entity-registry";
|
|
414
|
+
|
|
415
|
+
export function getOpenApiConfig(): OpenApiOptions {
|
|
416
|
+
const isDevelopment = process.env.NODE_ENV !== "production";
|
|
417
|
+
|
|
418
|
+
return {
|
|
419
|
+
enableSwagger: isDevelopment || process.env.ENABLE_SWAGGER === "true",
|
|
420
|
+
swaggerPath: "/api-docs",
|
|
421
|
+
enableRedoc: isDevelopment || process.env.ENABLE_REDOC === "true",
|
|
422
|
+
redocPath: "/docs",
|
|
423
|
+
entityDescriptors: [...allEntityDescriptors],
|
|
424
|
+
title: "My API",
|
|
425
|
+
description: "RESTful API following JSON:API specification",
|
|
426
|
+
version: process.env.npm_package_version || "1.0.0",
|
|
427
|
+
bearerAuth: true,
|
|
428
|
+
contactEmail: "api@example.com",
|
|
429
|
+
license: "Proprietary",
|
|
430
|
+
licenseUrl: "https://example.com/terms",
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
```
|
|
434
|
+
|
|
307
435
|
### 4. Bootstrap Your Application
|
|
308
436
|
|
|
309
437
|
```typescript
|
|
@@ -315,8 +443,9 @@ import * as path from "path";
|
|
|
315
443
|
dotenv.config({ path: path.resolve(__dirname, "../../../.env") });
|
|
316
444
|
|
|
317
445
|
import { bootstrap } from "@carlonicora/nestjs-neo4jsonapi";
|
|
318
|
-
import config from "./config/config";
|
|
446
|
+
import config from "./config/config";
|
|
319
447
|
import { FeaturesModules } from "./features/features.modules";
|
|
448
|
+
import { getOpenApiConfig } from "./openapi/openapi.config";
|
|
320
449
|
|
|
321
450
|
bootstrap({
|
|
322
451
|
appModules: [FeaturesModules],
|
|
@@ -324,26 +453,25 @@ bootstrap({
|
|
|
324
453
|
fallbackLanguage: "en",
|
|
325
454
|
path: path.join(__dirname, "i18n"),
|
|
326
455
|
},
|
|
327
|
-
config
|
|
456
|
+
config: config,
|
|
457
|
+
contentExtension: {
|
|
458
|
+
additionalRelationships: [],
|
|
459
|
+
},
|
|
460
|
+
openApi: getOpenApiConfig(),
|
|
328
461
|
});
|
|
329
462
|
```
|
|
330
463
|
|
|
331
|
-
That's it! The `bootstrap()` function handles
|
|
332
|
-
|
|
333
|
-
- Tracing initialization
|
|
334
|
-
- API vs Worker mode detection (via `--mode=api` or `--mode=worker` CLI args)
|
|
335
|
-
- Fastify adapter with multipart support
|
|
336
|
-
- Global validation pipes, exception filters, and interceptors
|
|
337
|
-
- Rate limiting, CORS, and caching
|
|
338
|
-
- Graceful shutdown handlers
|
|
464
|
+
That's it! The `bootstrap()` function handles everything else.
|
|
339
465
|
|
|
340
466
|
### Bootstrap Options
|
|
341
467
|
|
|
342
|
-
| Option
|
|
343
|
-
|
|
|
344
|
-
| `appModules`
|
|
345
|
-
| `i18n`
|
|
346
|
-
| `config`
|
|
468
|
+
| Option | Type | Required | Description |
|
|
469
|
+
| ------------------ | -------------------------------- | -------- | -------------------------------------------------------------------- |
|
|
470
|
+
| `appModules` | `(Type<any> \| DynamicModule)[]` | Yes | Your app-specific feature modules |
|
|
471
|
+
| `i18n` | `I18nOptions` | No | i18n configuration (fallbackLanguage, path) |
|
|
472
|
+
| `config` | `() => Record<string, any>` | No | Custom config that extends baseConfig (merged with library defaults) |
|
|
473
|
+
| `contentExtension` | `ContentExtensionOptions` | No | Additional relationships for Content module |
|
|
474
|
+
| `openApi` | `OpenApiOptions` | No | OpenAPI/Swagger documentation configuration |
|
|
347
475
|
|
|
348
476
|
### Configuration Options (via `config`)
|
|
349
477
|
|
|
@@ -356,310 +484,26 @@ The `config` function returns an object that is merged with `baseConfig`. Availa
|
|
|
356
484
|
| `jobNames` | `{ process: Record<string, string>, notifications?: Record<string, string> }` | Job names for BullMQ processors (maps content types to job names) |
|
|
357
485
|
| `prompts.*` | Various | Custom AI agent prompts (see [Customizing Agent Prompts](#customizing-agent-prompts-optional)) |
|
|
358
486
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
## Advanced Setup (Custom Bootstrap)
|
|
362
|
-
|
|
363
|
-
If you need more control over the bootstrap process, you can manually configure the AppModule and main.ts.
|
|
364
|
-
|
|
365
|
-
### 1. Create Configuration File
|
|
366
|
-
|
|
367
|
-
```typescript
|
|
368
|
-
// src/config/config.ts
|
|
369
|
-
import { baseConfig } from "@carlonicora/nestjs-neo4jsonapi";
|
|
370
|
-
import { JobName } from "./enums/job.name";
|
|
371
|
-
import { QueueId } from "./enums/queue.id";
|
|
372
|
-
// Import your content type metas
|
|
373
|
-
import { articleMeta } from "src/features/article/entities/article.meta";
|
|
374
|
-
import { documentMeta } from "src/features/document/entities/document.meta";
|
|
375
|
-
|
|
376
|
-
export default () => ({
|
|
377
|
-
...baseConfig,
|
|
378
|
-
// Register all app queue IDs for background job processing
|
|
379
|
-
chunkQueues: {
|
|
380
|
-
queueIds: Object.values(QueueId),
|
|
381
|
-
},
|
|
382
|
-
// Register content type labels for multi-label Neo4j queries
|
|
383
|
-
contentTypes: {
|
|
384
|
-
types: [
|
|
385
|
-
articleMeta.labelName,
|
|
386
|
-
documentMeta.labelName,
|
|
387
|
-
// Add your content type labels here
|
|
388
|
-
],
|
|
389
|
-
},
|
|
390
|
-
// Register job names for BullMQ processors
|
|
391
|
-
jobNames: JobName,
|
|
392
|
-
});
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
```typescript
|
|
396
|
-
// src/config/enums/queue.id.ts
|
|
397
|
-
export enum QueueId {
|
|
398
|
-
CHUNK = "chunk",
|
|
399
|
-
DOCUMENT = "document",
|
|
400
|
-
ARTICLE = "article",
|
|
401
|
-
// Add your custom queue IDs here (lowercase of content type labelName)
|
|
402
|
-
}
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
```typescript
|
|
406
|
-
// src/config/enums/job.name.ts
|
|
407
|
-
export const JobName = {
|
|
408
|
-
process: {
|
|
409
|
-
chunk: "process_chunk",
|
|
410
|
-
Document: "process_document",
|
|
411
|
-
Article: "process_article",
|
|
412
|
-
// Keys match content type labelName (e.g., "Article", "Document")
|
|
413
|
-
// Values are the job names used by processors
|
|
414
|
-
},
|
|
415
|
-
notifications: {
|
|
416
|
-
// Optional notification job names
|
|
417
|
-
},
|
|
418
|
-
} as const;
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
### 2. Setup App Module
|
|
422
|
-
|
|
423
|
-
```typescript
|
|
424
|
-
// src/app.module.ts
|
|
425
|
-
import { DynamicModule, Module } from "@nestjs/common";
|
|
426
|
-
import { ConfigModule, ConfigService } from "@nestjs/config";
|
|
427
|
-
import { EventEmitterModule } from "@nestjs/event-emitter";
|
|
428
|
-
import { ScheduleModule } from "@nestjs/schedule";
|
|
429
|
-
import { ThrottlerModule } from "@nestjs/throttler";
|
|
430
|
-
import { ClsModule } from "nestjs-cls";
|
|
431
|
-
|
|
432
|
-
import {
|
|
433
|
-
AgentsModule,
|
|
434
|
-
AppModeConfig,
|
|
435
|
-
AppModeModule,
|
|
436
|
-
BaseConfigInterface,
|
|
437
|
-
ConfigRateLimitInterface,
|
|
438
|
-
CoreModule,
|
|
439
|
-
FoundationsModule,
|
|
440
|
-
} from "@carlonicora/nestjs-neo4jsonapi";
|
|
441
|
-
|
|
442
|
-
// App configuration (includes chunkQueues config)
|
|
443
|
-
import config from "./config/config";
|
|
444
|
-
|
|
445
|
-
// App-specific modules
|
|
446
|
-
import { FeaturesModules } from "src/features/features.modules";
|
|
447
|
-
|
|
448
|
-
@Module({})
|
|
449
|
-
export class AppModule {
|
|
450
|
-
static forRoot(modeConfig: AppModeConfig): DynamicModule {
|
|
451
|
-
return {
|
|
452
|
-
module: AppModule,
|
|
453
|
-
imports: [
|
|
454
|
-
// Event emitter for internal events
|
|
455
|
-
EventEmitterModule.forRoot(),
|
|
456
|
-
|
|
457
|
-
// App mode configuration (API vs Worker)
|
|
458
|
-
AppModeModule.forRoot(modeConfig),
|
|
459
|
-
|
|
460
|
-
// Configuration
|
|
461
|
-
ConfigModule.forRoot({
|
|
462
|
-
load: [config],
|
|
463
|
-
isGlobal: true,
|
|
464
|
-
cache: true,
|
|
465
|
-
}),
|
|
466
|
-
|
|
467
|
-
// Rate limiting
|
|
468
|
-
ThrottlerModule.forRootAsync({
|
|
469
|
-
imports: [ConfigModule],
|
|
470
|
-
inject: [ConfigService],
|
|
471
|
-
useFactory: (configService: ConfigService<BaseConfigInterface>) => {
|
|
472
|
-
const rateLimitConfig = configService.get<ConfigRateLimitInterface>("rateLimit");
|
|
473
|
-
return {
|
|
474
|
-
throttlers: [
|
|
475
|
-
{
|
|
476
|
-
name: "default",
|
|
477
|
-
ttl: rateLimitConfig.ttl,
|
|
478
|
-
limit: rateLimitConfig.limit,
|
|
479
|
-
},
|
|
480
|
-
],
|
|
481
|
-
};
|
|
482
|
-
},
|
|
483
|
-
}),
|
|
484
|
-
|
|
485
|
-
// Request-scoped context (CLS) - required for user/company context
|
|
486
|
-
ClsModule.forRoot({
|
|
487
|
-
global: true,
|
|
488
|
-
middleware: { mount: modeConfig.enableControllers },
|
|
489
|
-
}),
|
|
490
|
-
|
|
491
|
-
// Scheduled jobs (only enabled in worker mode)
|
|
492
|
-
...(modeConfig.enableCronJobs ? [ScheduleModule.forRoot()] : []),
|
|
493
|
-
|
|
494
|
-
// ========================================
|
|
495
|
-
// LIBRARY MODULES
|
|
496
|
-
// ========================================
|
|
497
|
-
|
|
498
|
-
// Core infrastructure (Neo4j, Redis, Cache, Security, etc.)
|
|
499
|
-
|
|
500
|
-
// Foundation domain modules (User, Company, Auth, etc.)
|
|
501
|
-
// Queues are configured via baseConfig.chunkQueues in config.ts
|
|
502
|
-
FoundationsModule,
|
|
503
|
-
|
|
504
|
-
// AI Agents (GraphRAG, Summariser, Responder, etc.)
|
|
505
|
-
// Prompts are configured via baseConfig.prompts
|
|
506
|
-
AgentsModule,
|
|
507
|
-
|
|
508
|
-
// ========================================
|
|
509
|
-
// YOUR APP-SPECIFIC MODULES
|
|
510
|
-
// ========================================
|
|
511
|
-
FeaturesModules,
|
|
512
|
-
],
|
|
513
|
-
global: true,
|
|
514
|
-
controllers: [],
|
|
515
|
-
};
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
### 3. Setup main.ts (Bootstrap)
|
|
521
|
-
|
|
522
|
-
```typescript
|
|
523
|
-
// src/main.ts
|
|
524
|
-
import * as dotenv from "dotenv";
|
|
525
|
-
import * as path from "path";
|
|
526
|
-
|
|
527
|
-
// Load environment variables FIRST
|
|
528
|
-
dotenv.config({ path: path.resolve(__dirname, "../../../.env") });
|
|
529
|
-
|
|
530
|
-
// Initialize tracing BEFORE any other imports
|
|
531
|
-
import { tracingSetup } from "@carlonicora/nestjs-neo4jsonapi";
|
|
532
|
-
tracingSetup.initialize();
|
|
533
|
-
|
|
534
|
-
import { ValidationPipe } from "@nestjs/common";
|
|
535
|
-
import { ConfigService } from "@nestjs/config";
|
|
536
|
-
import { NestFactory, Reflector } from "@nestjs/core";
|
|
537
|
-
import { FastifyAdapter, NestFastifyApplication } from "@nestjs/platform-fastify";
|
|
538
|
-
import { EventEmitter } from "stream";
|
|
539
|
-
|
|
540
|
-
import {
|
|
541
|
-
AppLoggingService,
|
|
542
|
-
AppMode,
|
|
543
|
-
AppModeConfig,
|
|
544
|
-
BaseConfigInterface,
|
|
545
|
-
CacheInterceptor,
|
|
546
|
-
CacheService,
|
|
547
|
-
ConfigApiInterface,
|
|
548
|
-
CorsService,
|
|
549
|
-
getAppMode,
|
|
550
|
-
getAppModeConfig,
|
|
551
|
-
HttpExceptionFilter,
|
|
552
|
-
LoggingInterceptor,
|
|
553
|
-
TracingInterceptor,
|
|
554
|
-
} from "@carlonicora/nestjs-neo4jsonapi";
|
|
555
|
-
|
|
556
|
-
import { AppModule } from "./app.module";
|
|
557
|
-
|
|
558
|
-
async function bootstrapAPI(modeConfig: AppModeConfig): Promise<void> {
|
|
559
|
-
const app = await NestFactory.create<NestFastifyApplication>(
|
|
560
|
-
AppModule.forRoot(modeConfig),
|
|
561
|
-
new FastifyAdapter({
|
|
562
|
-
routerOptions: { ignoreTrailingSlash: true },
|
|
563
|
-
bodyLimit: 100 * 1024 * 1024,
|
|
564
|
-
}),
|
|
565
|
-
{ logger: ["error", "warn"] },
|
|
566
|
-
);
|
|
567
|
-
|
|
568
|
-
const configService = app.get(ConfigService<BaseConfigInterface>);
|
|
569
|
-
|
|
570
|
-
// Register multipart support for file uploads
|
|
571
|
-
await app.register(require("@fastify/multipart"), {
|
|
572
|
-
limits: {
|
|
573
|
-
fileSize: 100 * 1024 * 1024,
|
|
574
|
-
fieldSize: 10 * 1024 * 1024,
|
|
575
|
-
files: 10,
|
|
576
|
-
fields: 20,
|
|
577
|
-
},
|
|
578
|
-
attachFieldsToBody: false,
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
// Setup logging
|
|
582
|
-
const loggingService = app.get(AppLoggingService);
|
|
583
|
-
app.useLogger(loggingService);
|
|
584
|
-
|
|
585
|
-
// Add Fastify onSend hook for request logging
|
|
586
|
-
app
|
|
587
|
-
.getHttpAdapter()
|
|
588
|
-
.getInstance()
|
|
589
|
-
.addHook("onSend", async (request, reply, payload) => {
|
|
590
|
-
const startTime = request.raw["requestStartTime"];
|
|
591
|
-
if (startTime) {
|
|
592
|
-
const responseTime = Date.now() - startTime;
|
|
593
|
-
loggingService.logHttpRequest(request.method, request.url, reply.statusCode, responseTime, request.ip);
|
|
594
|
-
loggingService.clearRequestContext();
|
|
595
|
-
}
|
|
596
|
-
return payload;
|
|
597
|
-
});
|
|
598
|
-
|
|
599
|
-
// Global filters and pipes
|
|
600
|
-
app.useGlobalFilters(new HttpExceptionFilter(loggingService));
|
|
601
|
-
app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));
|
|
602
|
-
|
|
603
|
-
// Apply interceptors in order: Tracing -> Cache -> Logging
|
|
604
|
-
app.useGlobalInterceptors(app.get(TracingInterceptor));
|
|
605
|
-
app.useGlobalInterceptors(new CacheInterceptor(app.get(CacheService), app.get(Reflector), loggingService));
|
|
606
|
-
app.useGlobalInterceptors(app.get(LoggingInterceptor));
|
|
607
|
-
|
|
608
|
-
// Setup CORS
|
|
609
|
-
const corsService = app.get(CorsService);
|
|
610
|
-
corsService.validateConfiguration();
|
|
611
|
-
app.enableCors(corsService.getCorsConfiguration());
|
|
612
|
-
|
|
613
|
-
// Start server
|
|
614
|
-
const port = configService.get<ConfigApiInterface>("api").port;
|
|
615
|
-
await app.listen(port, "0.0.0.0");
|
|
616
|
-
loggingService.log(`API server started on port ${port}`);
|
|
617
|
-
|
|
618
|
-
// Graceful shutdown
|
|
619
|
-
process.on("SIGTERM", async () => {
|
|
620
|
-
await app.close();
|
|
621
|
-
process.exit(0);
|
|
622
|
-
});
|
|
623
|
-
process.on("SIGINT", async () => {
|
|
624
|
-
await app.close();
|
|
625
|
-
process.exit(0);
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
async function bootstrapWorker(modeConfig: AppModeConfig): Promise<void> {
|
|
630
|
-
const app = await NestFactory.createApplicationContext(AppModule.forRoot(modeConfig), {
|
|
631
|
-
logger: ["error", "warn"],
|
|
632
|
-
});
|
|
633
|
-
|
|
634
|
-
const loggingService = app.get(AppLoggingService);
|
|
635
|
-
app.useLogger(loggingService);
|
|
636
|
-
loggingService.log("Worker process started");
|
|
487
|
+
### What bootstrap() Handles Internally
|
|
637
488
|
|
|
638
|
-
|
|
639
|
-
await app.close();
|
|
640
|
-
process.exit(0);
|
|
641
|
-
});
|
|
642
|
-
process.on("SIGINT", async () => {
|
|
643
|
-
await app.close();
|
|
644
|
-
process.exit(0);
|
|
645
|
-
});
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
async function bootstrap(): Promise<void> {
|
|
649
|
-
EventEmitter.defaultMaxListeners = 50;
|
|
489
|
+
The `bootstrap()` function creates a dynamic `AppModule` that includes:
|
|
650
490
|
|
|
651
|
-
|
|
652
|
-
|
|
491
|
+
- EventEmitterModule for async events
|
|
492
|
+
- AppModeModule (API vs Worker mode)
|
|
493
|
+
- ConfigModule with merged configuration
|
|
494
|
+
- ThrottlerModule for rate limiting
|
|
495
|
+
- ClsModule for request context
|
|
496
|
+
- I18nModule for internationalization
|
|
497
|
+
- ScheduleModule for cron jobs (Worker mode only)
|
|
498
|
+
- CoreModule (all infrastructure modules)
|
|
499
|
+
- FoundationsModule (all domain modules)
|
|
500
|
+
- AgentsModule (AI agents)
|
|
501
|
+
- OpenApiModule for documentation
|
|
502
|
+
- NecordModule + DiscordModule (Worker mode, when DISCORD_TOKEN is set)
|
|
653
503
|
|
|
654
|
-
|
|
655
|
-
await bootstrapWorker(modeConfig);
|
|
656
|
-
} else {
|
|
657
|
-
await bootstrapAPI(modeConfig);
|
|
658
|
-
}
|
|
659
|
-
}
|
|
504
|
+
> **Note:** For advanced customization scenarios, you can examine the bootstrap source code in `packages/nestjs-neo4jsonapi/src/bootstrap/`. However, the default `bootstrap()` function handles all common use cases.
|
|
660
505
|
|
|
661
|
-
|
|
662
|
-
```
|
|
506
|
+
---
|
|
663
507
|
|
|
664
508
|
## Company-User Model (B2B & B2C)
|
|
665
509
|
|
|
@@ -839,17 +683,20 @@ query.query = `
|
|
|
839
683
|
your-app/
|
|
840
684
|
├── src/
|
|
841
685
|
│ ├── config/
|
|
842
|
-
│ │ ├── config.ts # App configuration
|
|
843
|
-
│ │ ├── company.configurations.ts # Company context loader
|
|
686
|
+
│ │ ├── config.ts # App configuration (optional)
|
|
844
687
|
│ │ └── enums/
|
|
845
|
-
│ │ └── queue.id.ts # Queue identifiers
|
|
688
|
+
│ │ └── queue.id.ts # Queue identifiers (if using jobs)
|
|
846
689
|
│ ├── features/ # Your app-specific modules
|
|
847
|
-
│
|
|
848
|
-
│
|
|
690
|
+
│ │ └── features.modules.ts # Imports all your feature modules
|
|
691
|
+
│ ├── openapi/ # OpenAPI config (optional)
|
|
692
|
+
│ │ └── openapi.config.ts
|
|
693
|
+
│ └── main.ts # Bootstrap entry (~25 lines)
|
|
849
694
|
├── .env
|
|
850
695
|
└── package.json
|
|
851
696
|
```
|
|
852
697
|
|
|
698
|
+
**Note:** No `app.module.ts` is required - the library creates this dynamically via `createAppModule()`.
|
|
699
|
+
|
|
853
700
|
### Queue IDs and Job Names (if using background jobs)
|
|
854
701
|
|
|
855
702
|
Queue IDs must match the lowercase version of your content type `labelName`:
|
|
@@ -882,7 +729,7 @@ export const JobName = {
|
|
|
882
729
|
|
|
883
730
|
## Core Modules
|
|
884
731
|
|
|
885
|
-
The library includes
|
|
732
|
+
The library includes 19 core infrastructure modules:
|
|
886
733
|
|
|
887
734
|
| Module | Description |
|
|
888
735
|
| ----------------- | ------------------------------------------------ |
|
|
@@ -893,7 +740,7 @@ The library includes 18 core infrastructure modules:
|
|
|
893
740
|
| `JsonApiModule` | JSON:API specification compliance |
|
|
894
741
|
| `LoggingModule` | Structured logging with Loki |
|
|
895
742
|
| `TracingModule` | Distributed tracing with OpenTelemetry |
|
|
896
|
-
| `EmailModule` | Email service (SendGrid, SMTP)
|
|
743
|
+
| `EmailModule` | Email service (SendGrid, SMTP, Brevo) |
|
|
897
744
|
| `QueueModule` | BullMQ job queue processing |
|
|
898
745
|
| `WebsocketModule` | Real-time WebSocket communication |
|
|
899
746
|
| `CorsModule` | CORS configuration |
|
|
@@ -1021,35 +868,50 @@ The module includes four health indicators:
|
|
|
1021
868
|
| `Neo4jHealthIndicator` | 3s | Executes `RETURN 1` query |
|
|
1022
869
|
| `RedisHealthIndicator` | 3s | Connection status + PING |
|
|
1023
870
|
| `S3HealthIndicator` | 5s | Bucket access (HeadBucket) |
|
|
1024
|
-
| `DiskHealthIndicator` | - | Free space
|
|
871
|
+
| `DiskHealthIndicator` | - | Free space >= 1GB or 10% |
|
|
1025
872
|
|
|
1026
873
|
## Foundation Modules
|
|
1027
874
|
|
|
1028
|
-
The library includes
|
|
1029
|
-
|
|
1030
|
-
| Module
|
|
1031
|
-
|
|
|
1032
|
-
| `UserModule`
|
|
1033
|
-
| `CompanyModule`
|
|
1034
|
-
| `AuthModule`
|
|
1035
|
-
| `RoleModule`
|
|
1036
|
-
| `
|
|
1037
|
-
| `
|
|
1038
|
-
| `
|
|
1039
|
-
| `
|
|
1040
|
-
| `
|
|
1041
|
-
| `
|
|
1042
|
-
| `
|
|
1043
|
-
| `
|
|
1044
|
-
| `
|
|
1045
|
-
| `
|
|
1046
|
-
| `
|
|
1047
|
-
| `
|
|
1048
|
-
| `
|
|
875
|
+
The library includes 31 foundation modules for business domain logic:
|
|
876
|
+
|
|
877
|
+
| Module | Description |
|
|
878
|
+
| -------------------------- | -------------------------------------------------- |
|
|
879
|
+
| `UserModule` | User management with CRUD operations |
|
|
880
|
+
| `CompanyModule` | Multi-tenant company management with deletion |
|
|
881
|
+
| `AuthModule` | Authentication (login, register, password reset) |
|
|
882
|
+
| `RoleModule` | Role management |
|
|
883
|
+
| `OAuthModule` | OAuth 2.0 Authorization Server (RFC 6749/7636) |
|
|
884
|
+
| `ChunkModule` | Document chunk storage and retrieval |
|
|
885
|
+
| `ChunkerModule` | Document parsing (PDF, DOCX, XLSX, HTML, PPTX) |
|
|
886
|
+
| `AtomicFactModule` | Atomic facts management for knowledge graphs |
|
|
887
|
+
| `KeyConceptModule` | Key concepts for knowledge graphs |
|
|
888
|
+
| `CommunityModule` | Knowledge graph community storage |
|
|
889
|
+
| `ContentModule` | Content management with extension support |
|
|
890
|
+
| `NotificationModule` | User notifications |
|
|
891
|
+
| `PushModule` | Push notifications (VAPID) |
|
|
892
|
+
| `FeatureModule` | Feature flag management |
|
|
893
|
+
| `ModuleModule` | Module/plugin management |
|
|
894
|
+
| `S3Module` | S3-compatible storage |
|
|
895
|
+
| `TokenUsageModule` | AI token usage tracking |
|
|
896
|
+
| `AuditModule` | Audit logging |
|
|
897
|
+
| `RelevancyModule` | Relevancy scoring |
|
|
898
|
+
| `DiscordModule` | Discord bot integration |
|
|
899
|
+
| `DiscordUserModule` | Discord user management |
|
|
900
|
+
| `GoogleUserModule` | Google OAuth user management |
|
|
901
|
+
| **Stripe Sub-modules:** | |
|
|
902
|
+
| `StripeModule` | Core Stripe integration |
|
|
903
|
+
| `StripeCustomerModule` | Stripe customer management |
|
|
904
|
+
| `StripeSubscriptionModule` | Subscription lifecycle management |
|
|
905
|
+
| `StripeProductModule` | Product management |
|
|
906
|
+
| `StripePriceModule` | Price/plan management with feature selection |
|
|
907
|
+
| `StripeInvoiceModule` | Invoice management |
|
|
908
|
+
| `StripeUsageModule` | Usage-based billing |
|
|
909
|
+
| `StripeWebhookModule` | Webhook processing via BullMQ |
|
|
910
|
+
| `StripeTrialModule` | Trial period management with email notifications |
|
|
1049
911
|
|
|
1050
912
|
## AI Agents
|
|
1051
913
|
|
|
1052
|
-
LangChain-powered
|
|
914
|
+
The library includes 7 LangChain-powered agent modules for intelligent document processing:
|
|
1053
915
|
|
|
1054
916
|
### GraphCreatorModule
|
|
1055
917
|
|
|
@@ -1127,13 +989,275 @@ export class MyService {
|
|
|
1127
989
|
}
|
|
1128
990
|
```
|
|
1129
991
|
|
|
992
|
+
### CommunityDetectorModule
|
|
993
|
+
|
|
994
|
+
Detects and creates communities from knowledge graph structure.
|
|
995
|
+
|
|
996
|
+
```typescript
|
|
997
|
+
import { CommunityDetectorService } from "@carlonicora/nestjs-neo4jsonapi";
|
|
998
|
+
|
|
999
|
+
@Injectable()
|
|
1000
|
+
export class MyService {
|
|
1001
|
+
constructor(private readonly communityDetector: CommunityDetectorService) {}
|
|
1002
|
+
|
|
1003
|
+
async detectCommunities() {
|
|
1004
|
+
return this.communityDetector.detect();
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
### CommunitySummariserModule
|
|
1010
|
+
|
|
1011
|
+
Generates summaries for detected communities.
|
|
1012
|
+
|
|
1013
|
+
```typescript
|
|
1014
|
+
import { CommunitySummariserService } from "@carlonicora/nestjs-neo4jsonapi";
|
|
1015
|
+
|
|
1016
|
+
@Injectable()
|
|
1017
|
+
export class MyService {
|
|
1018
|
+
constructor(private readonly summariser: CommunitySummariserService) {}
|
|
1019
|
+
|
|
1020
|
+
async summarizeCommunity(communityId: string) {
|
|
1021
|
+
return this.summariser.summarize({ communityId });
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
### DriftModule
|
|
1027
|
+
|
|
1028
|
+
See [DRIFT Module (Advanced Semantic Search)](#drift-module-advanced-semantic-search) for detailed documentation.
|
|
1029
|
+
|
|
1030
|
+
## DRIFT Module (Advanced Semantic Search)
|
|
1031
|
+
|
|
1032
|
+
DRIFT (Dynamic Retrieval with Intelligence and Future-aware Thinking) is an advanced semantic search system that uses community detection and HyDE (Hypothetical Document Embedding) for sophisticated query understanding.
|
|
1033
|
+
|
|
1034
|
+
### Architecture
|
|
1035
|
+
|
|
1036
|
+
DRIFT uses a multi-node workflow:
|
|
1037
|
+
|
|
1038
|
+
| Node | Purpose |
|
|
1039
|
+
| ---------------------------- | --------------------------------------------- |
|
|
1040
|
+
| `HydeNodeService` | Generates hypothetical document embedding |
|
|
1041
|
+
| `CommunitySearchNodeService` | Vector search against community summaries |
|
|
1042
|
+
| `PrimerAnswerNodeService` | Generates initial answer + follow-up questions|
|
|
1043
|
+
| `FollowUpNodeService` | Processes follow-up questions iteratively |
|
|
1044
|
+
| `SynthesisNodeService` | Combines all answers into final response |
|
|
1045
|
+
|
|
1046
|
+
### Usage
|
|
1047
|
+
|
|
1048
|
+
```typescript
|
|
1049
|
+
import { DriftSearchService } from "@carlonicora/nestjs-neo4jsonapi";
|
|
1050
|
+
|
|
1051
|
+
@Injectable()
|
|
1052
|
+
export class MyService {
|
|
1053
|
+
constructor(private readonly driftSearch: DriftSearchService) {}
|
|
1054
|
+
|
|
1055
|
+
async searchWithDrift(question: string) {
|
|
1056
|
+
// Full DRIFT workflow: HyDE -> Community Search -> Primer Answer -> Follow-ups -> Synthesis
|
|
1057
|
+
const result = await this.driftSearch.search({
|
|
1058
|
+
question,
|
|
1059
|
+
config: {
|
|
1060
|
+
primerTopK: 5, // Top K communities to search
|
|
1061
|
+
followUpDepth: 2, // Depth of follow-up question iterations
|
|
1062
|
+
},
|
|
1063
|
+
});
|
|
1064
|
+
|
|
1065
|
+
// result contains:
|
|
1066
|
+
// - answer: Final synthesized answer
|
|
1067
|
+
// - matchedCommunities: Communities that matched the query
|
|
1068
|
+
// - followUpAnswers: Answers from follow-up questions
|
|
1069
|
+
// - initialAnswer: Initial answer before follow-ups
|
|
1070
|
+
// - confidence: Confidence score
|
|
1071
|
+
// - hydeEmbedding: Generated hypothetical document embedding
|
|
1072
|
+
return result;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
async quickSearch(question: string) {
|
|
1076
|
+
// Quick search without follow-ups (HyDE + Community Search + Primer only)
|
|
1077
|
+
return this.driftSearch.quickSearch({ question, topK: 5 });
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
```
|
|
1081
|
+
|
|
1082
|
+
### How DRIFT Works
|
|
1083
|
+
|
|
1084
|
+
1. **HyDE Generation**: Creates a hypothetical document that would answer the question
|
|
1085
|
+
2. **Community Search**: Uses the HyDE embedding to find relevant communities
|
|
1086
|
+
3. **Primer Answer**: Generates an initial answer and identifies follow-up questions
|
|
1087
|
+
4. **Follow-up Processing**: Recursively explores follow-up questions for deeper context
|
|
1088
|
+
5. **Synthesis**: Combines all gathered information into a comprehensive final answer
|
|
1089
|
+
|
|
1090
|
+
## OpenAPI Documentation
|
|
1091
|
+
|
|
1092
|
+
The library includes comprehensive OpenAPI/Swagger documentation support with JSON:API compliance.
|
|
1093
|
+
|
|
1094
|
+
### Configuration
|
|
1095
|
+
|
|
1096
|
+
Enable OpenAPI in your bootstrap options:
|
|
1097
|
+
|
|
1098
|
+
```typescript
|
|
1099
|
+
import { bootstrap } from "@carlonicora/nestjs-neo4jsonapi";
|
|
1100
|
+
|
|
1101
|
+
bootstrap({
|
|
1102
|
+
appModules: [FeaturesModules],
|
|
1103
|
+
openApi: {
|
|
1104
|
+
enableSwagger: true,
|
|
1105
|
+
swaggerPath: '/api-docs',
|
|
1106
|
+
enableRedoc: true,
|
|
1107
|
+
redocPath: '/docs',
|
|
1108
|
+
title: 'My API',
|
|
1109
|
+
description: 'RESTful API following JSON:API specification',
|
|
1110
|
+
version: '1.0.0',
|
|
1111
|
+
bearerAuth: true,
|
|
1112
|
+
contactEmail: 'api@example.com',
|
|
1113
|
+
license: 'Proprietary',
|
|
1114
|
+
licenseUrl: 'https://example.com/terms',
|
|
1115
|
+
entityDescriptors: [
|
|
1116
|
+
PhotographDescriptor,
|
|
1117
|
+
RollDescriptor,
|
|
1118
|
+
// ... your entity descriptors
|
|
1119
|
+
],
|
|
1120
|
+
},
|
|
1121
|
+
});
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
### OpenAPI Options
|
|
1125
|
+
|
|
1126
|
+
| Option | Type | Default | Description |
|
|
1127
|
+
| ------------------- | ------- | ------------ | -------------------------------------- |
|
|
1128
|
+
| `enableSwagger` | boolean | false | Enable Swagger UI endpoint |
|
|
1129
|
+
| `swaggerPath` | string | '/api-docs' | Path for Swagger UI |
|
|
1130
|
+
| `enableRedoc` | boolean | false | Enable Redoc endpoint |
|
|
1131
|
+
| `redocPath` | string | '/docs' | Path for Redoc |
|
|
1132
|
+
| `title` | string | - | API documentation title |
|
|
1133
|
+
| `description` | string | - | API description (supports markdown) |
|
|
1134
|
+
| `version` | string | - | API version |
|
|
1135
|
+
| `bearerAuth` | boolean | true | Enable JWT Bearer auth in docs |
|
|
1136
|
+
| `contactEmail` | string | - | Contact email |
|
|
1137
|
+
| `license` | string | - | License name |
|
|
1138
|
+
| `licenseUrl` | string | - | License URL |
|
|
1139
|
+
| `entityDescriptors` | array | [] | Entity descriptors for schema generation |
|
|
1140
|
+
|
|
1141
|
+
### JSON:API Decorators
|
|
1142
|
+
|
|
1143
|
+
```typescript
|
|
1144
|
+
import {
|
|
1145
|
+
ApiJsonApiResponse,
|
|
1146
|
+
ApiJsonApiListQuery,
|
|
1147
|
+
ApiJsonApiListErrors,
|
|
1148
|
+
ApiJsonApiCreateErrors,
|
|
1149
|
+
ApiJsonApiDeleteErrors,
|
|
1150
|
+
} from "@carlonicora/nestjs-neo4jsonapi";
|
|
1151
|
+
|
|
1152
|
+
@Controller('photographs')
|
|
1153
|
+
export class PhotographController {
|
|
1154
|
+
@Get(':id')
|
|
1155
|
+
@ApiJsonApiResponse(PhotographDescriptor)
|
|
1156
|
+
async findById() { ... }
|
|
1157
|
+
|
|
1158
|
+
@Get()
|
|
1159
|
+
@ApiJsonApiResponse(PhotographDescriptor, { isList: true })
|
|
1160
|
+
@ApiJsonApiListQuery()
|
|
1161
|
+
@ApiJsonApiListErrors()
|
|
1162
|
+
async findAll() { ... }
|
|
1163
|
+
|
|
1164
|
+
@Post()
|
|
1165
|
+
@ApiJsonApiResponse(PhotographDescriptor, { status: 201 })
|
|
1166
|
+
@ApiJsonApiCreateErrors()
|
|
1167
|
+
async create() { ... }
|
|
1168
|
+
|
|
1169
|
+
@Delete(':id')
|
|
1170
|
+
@HttpCode(HttpStatus.NO_CONTENT)
|
|
1171
|
+
@ApiJsonApiDeleteErrors()
|
|
1172
|
+
async delete() { ... }
|
|
1173
|
+
}
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
## OAuth 2.0 Support
|
|
1177
|
+
|
|
1178
|
+
The library implements a complete OAuth 2.0 Authorization Server following RFC 6749 and RFC 7636 (PKCE).
|
|
1179
|
+
|
|
1180
|
+
### Enabling OAuth
|
|
1181
|
+
|
|
1182
|
+
```env
|
|
1183
|
+
OAUTH_ENABLED=true
|
|
1184
|
+
OAUTH_AUTHORIZATION_CODE_LIFETIME=600
|
|
1185
|
+
OAUTH_ACCESS_TOKEN_LIFETIME=3600
|
|
1186
|
+
OAUTH_REFRESH_TOKEN_LIFETIME=604800
|
|
1187
|
+
OAUTH_REQUIRE_PKCE_FOR_PUBLIC_CLIENTS=true
|
|
1188
|
+
OAUTH_ROTATE_REFRESH_TOKENS=true
|
|
1189
|
+
```
|
|
1190
|
+
|
|
1191
|
+
### OAuth Endpoints
|
|
1192
|
+
|
|
1193
|
+
| Endpoint | Method | Purpose |
|
|
1194
|
+
| ------------------- | ------ | ------------------------------ |
|
|
1195
|
+
| `/oauth/authorize` | GET | Authorization endpoint |
|
|
1196
|
+
| `/oauth/token` | POST | Token endpoint |
|
|
1197
|
+
| `/oauth/revoke` | POST | Token revocation (RFC 7009) |
|
|
1198
|
+
| `/oauth/introspect` | POST | Token introspection (RFC 7662) |
|
|
1199
|
+
| `/oauth/clients` | CRUD | Client management |
|
|
1200
|
+
|
|
1201
|
+
### Protecting Endpoints with OAuth
|
|
1202
|
+
|
|
1203
|
+
```typescript
|
|
1204
|
+
import {
|
|
1205
|
+
JwtOrOAuthGuard,
|
|
1206
|
+
OAuthScopes,
|
|
1207
|
+
} from "@carlonicora/nestjs-neo4jsonapi";
|
|
1208
|
+
|
|
1209
|
+
@Controller('photographs')
|
|
1210
|
+
export class PhotographController {
|
|
1211
|
+
// Accepts both JWT and OAuth tokens (migration path)
|
|
1212
|
+
@Get(':id')
|
|
1213
|
+
@UseGuards(JwtOrOAuthGuard)
|
|
1214
|
+
@OAuthScopes('photographs:read')
|
|
1215
|
+
async findById() { ... }
|
|
1216
|
+
|
|
1217
|
+
@Post()
|
|
1218
|
+
@UseGuards(JwtOrOAuthGuard)
|
|
1219
|
+
@OAuthScopes('photographs:read', 'photographs:write')
|
|
1220
|
+
async create() { ... }
|
|
1221
|
+
}
|
|
1222
|
+
```
|
|
1223
|
+
|
|
1224
|
+
### Context Set by OAuth
|
|
1225
|
+
|
|
1226
|
+
When using OAuth guards, the following context is set in CLS:
|
|
1227
|
+
|
|
1228
|
+
```typescript
|
|
1229
|
+
// In your service
|
|
1230
|
+
const userId = this.cls.get('userId');
|
|
1231
|
+
const companyId = this.cls.get('companyId');
|
|
1232
|
+
const clientId = this.cls.get('oauthClientId');
|
|
1233
|
+
const scopes = this.cls.get('oauthScopes');
|
|
1234
|
+
const authType = this.cls.get('authType'); // 'oauth' or 'jwt'
|
|
1235
|
+
```
|
|
1236
|
+
|
|
1130
1237
|
## Security & Authentication
|
|
1131
1238
|
|
|
1239
|
+
### Available Guards
|
|
1240
|
+
|
|
1241
|
+
| Guard | Purpose |
|
|
1242
|
+
| -------------------- | -------------------------------------------- |
|
|
1243
|
+
| `JwtAuthGuard` | Requires valid JWT token |
|
|
1244
|
+
| `AdminJwtAuthGuard` | Requires Administrator role |
|
|
1245
|
+
| `OptionalJwtAuthGuard` | JWT optional (works for anonymous users) |
|
|
1246
|
+
| `JwtOrOAuthGuard` | Accepts OAuth first, falls back to JWT |
|
|
1247
|
+
|
|
1132
1248
|
### Using Guards
|
|
1133
1249
|
|
|
1134
1250
|
```typescript
|
|
1135
1251
|
import { Controller, Get, UseGuards } from "@nestjs/common";
|
|
1136
|
-
import {
|
|
1252
|
+
import {
|
|
1253
|
+
JwtAuthGuard,
|
|
1254
|
+
AdminJwtAuthGuard,
|
|
1255
|
+
OptionalJwtAuthGuard,
|
|
1256
|
+
JwtOrOAuthGuard,
|
|
1257
|
+
Roles,
|
|
1258
|
+
OAuthScopes,
|
|
1259
|
+
SystemRoles
|
|
1260
|
+
} from "@carlonicora/nestjs-neo4jsonapi";
|
|
1137
1261
|
import { AppRoles } from "./config/roles";
|
|
1138
1262
|
|
|
1139
1263
|
@Controller("api/resources")
|
|
@@ -1153,6 +1277,12 @@ export class ResourceController {
|
|
|
1153
1277
|
@UseGuards(OptionalJwtAuthGuard)
|
|
1154
1278
|
async getPublicResources() { ... }
|
|
1155
1279
|
|
|
1280
|
+
// Accepts both JWT and OAuth tokens
|
|
1281
|
+
@Get("oauth-or-jwt")
|
|
1282
|
+
@UseGuards(JwtOrOAuthGuard)
|
|
1283
|
+
@OAuthScopes('resources:read')
|
|
1284
|
+
async getResourcesWithOAuth() { ... }
|
|
1285
|
+
|
|
1156
1286
|
// Requires specific roles (UUIDs)
|
|
1157
1287
|
@Get("restricted")
|
|
1158
1288
|
@UseGuards(JwtAuthGuard)
|
|
@@ -1184,6 +1314,10 @@ export class MyService {
|
|
|
1184
1314
|
const roles = this.cls.get("roles");
|
|
1185
1315
|
const language = this.cls.get("language");
|
|
1186
1316
|
|
|
1317
|
+
// OAuth-specific context (when using OAuth)
|
|
1318
|
+
const authType = this.cls.get("authType"); // 'oauth' or 'jwt'
|
|
1319
|
+
const oauthScopes = this.cls.get("oauthScopes");
|
|
1320
|
+
|
|
1187
1321
|
if (config?.hasModule("premium-feature")) {
|
|
1188
1322
|
// User's company has access to premium feature
|
|
1189
1323
|
}
|
|
@@ -1191,25 +1325,228 @@ export class MyService {
|
|
|
1191
1325
|
}
|
|
1192
1326
|
```
|
|
1193
1327
|
|
|
1328
|
+
## Company Deletion Handler
|
|
1329
|
+
|
|
1330
|
+
The library supports custom company deletion handlers for application-specific cleanup.
|
|
1331
|
+
|
|
1332
|
+
### Interface
|
|
1333
|
+
|
|
1334
|
+
```typescript
|
|
1335
|
+
import {
|
|
1336
|
+
CompanyDeletionHandler,
|
|
1337
|
+
COMPANY_DELETION_HANDLER,
|
|
1338
|
+
DeletionReason,
|
|
1339
|
+
DeletionOptions
|
|
1340
|
+
} from "@carlonicora/nestjs-neo4jsonapi";
|
|
1341
|
+
|
|
1342
|
+
type DeletionReason = 'trial_expired' | 'subscription_cancelled' | 'immediate_deletion';
|
|
1343
|
+
|
|
1344
|
+
interface DeletionOptions {
|
|
1345
|
+
sendEmail?: boolean;
|
|
1346
|
+
reason?: DeletionReason;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
interface CompanyDeletionHandler {
|
|
1350
|
+
deleteCompany(companyId: string, companyName: string, options?: DeletionOptions): Promise<void>;
|
|
1351
|
+
}
|
|
1352
|
+
```
|
|
1353
|
+
|
|
1354
|
+
### Implementation
|
|
1355
|
+
|
|
1356
|
+
```typescript
|
|
1357
|
+
import { Injectable } from "@nestjs/common";
|
|
1358
|
+
import {
|
|
1359
|
+
CompanyDeletionHandler,
|
|
1360
|
+
DeletionOptions,
|
|
1361
|
+
S3Service,
|
|
1362
|
+
} from "@carlonicora/nestjs-neo4jsonapi";
|
|
1363
|
+
|
|
1364
|
+
@Injectable()
|
|
1365
|
+
export class CompanyDeletionService implements CompanyDeletionHandler {
|
|
1366
|
+
constructor(
|
|
1367
|
+
private readonly s3: S3Service,
|
|
1368
|
+
private readonly auditLogger: AuditLogger,
|
|
1369
|
+
) {}
|
|
1370
|
+
|
|
1371
|
+
async deleteCompany(companyId: string, companyName: string, options?: DeletionOptions) {
|
|
1372
|
+
// 1. Delete S3 objects
|
|
1373
|
+
await this.s3.deleteCompanyObjects(companyId);
|
|
1374
|
+
|
|
1375
|
+
// 2. Log audit event
|
|
1376
|
+
await this.auditLogger.log({
|
|
1377
|
+
action: 'company_deleted',
|
|
1378
|
+
companyId,
|
|
1379
|
+
companyName,
|
|
1380
|
+
reason: options?.reason,
|
|
1381
|
+
});
|
|
1382
|
+
|
|
1383
|
+
// 3. Send notification email if requested
|
|
1384
|
+
if (options?.sendEmail) {
|
|
1385
|
+
await this.sendDeletionEmail(companyName, options.reason);
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
```
|
|
1390
|
+
|
|
1391
|
+
### Registration
|
|
1392
|
+
|
|
1393
|
+
```typescript
|
|
1394
|
+
import { Module, Global } from "@nestjs/common";
|
|
1395
|
+
import { COMPANY_DELETION_HANDLER } from "@carlonicora/nestjs-neo4jsonapi";
|
|
1396
|
+
|
|
1397
|
+
@Global()
|
|
1398
|
+
@Module({
|
|
1399
|
+
providers: [
|
|
1400
|
+
CompanyDeletionService,
|
|
1401
|
+
{
|
|
1402
|
+
provide: COMPANY_DELETION_HANDLER,
|
|
1403
|
+
useExisting: CompanyDeletionService,
|
|
1404
|
+
},
|
|
1405
|
+
],
|
|
1406
|
+
exports: [CompanyDeletionService, COMPANY_DELETION_HANDLER],
|
|
1407
|
+
})
|
|
1408
|
+
export class CompanyDeletionModule {}
|
|
1409
|
+
```
|
|
1410
|
+
|
|
1411
|
+
## Entity Descriptors (defineEntity)
|
|
1412
|
+
|
|
1413
|
+
Entity Descriptors provide a single source of truth for entity configuration, auto-generating mappers, serializers, constraints, and indexes.
|
|
1414
|
+
|
|
1415
|
+
### Basic Usage
|
|
1416
|
+
|
|
1417
|
+
```typescript
|
|
1418
|
+
import { defineEntity, Entity, S3Service } from "@carlonicora/nestjs-neo4jsonapi";
|
|
1419
|
+
import { rollMeta, companyMeta } from "@carlonicora/nestjs-neo4jsonapi";
|
|
1420
|
+
|
|
1421
|
+
// 1. Define entity type
|
|
1422
|
+
export type Photograph = Entity & {
|
|
1423
|
+
url: string;
|
|
1424
|
+
filename?: string;
|
|
1425
|
+
stars: number;
|
|
1426
|
+
roll: Roll;
|
|
1427
|
+
company: Company;
|
|
1428
|
+
};
|
|
1429
|
+
|
|
1430
|
+
// 2. Create entity descriptor
|
|
1431
|
+
export const PhotographDescriptor = defineEntity<Photograph>()({
|
|
1432
|
+
// Meta (replaces .meta.ts file)
|
|
1433
|
+
type: "photographs",
|
|
1434
|
+
endpoint: "photographs",
|
|
1435
|
+
nodeName: "photograph",
|
|
1436
|
+
labelName: "Photograph",
|
|
1437
|
+
|
|
1438
|
+
// Inject services for field transformers
|
|
1439
|
+
injectServices: [S3Service],
|
|
1440
|
+
|
|
1441
|
+
// Field definitions
|
|
1442
|
+
fields: {
|
|
1443
|
+
url: {
|
|
1444
|
+
type: "string",
|
|
1445
|
+
required: true,
|
|
1446
|
+
transform: async (data, services) => {
|
|
1447
|
+
return await services.S3Service.generateSignedUrl({ key: data.url });
|
|
1448
|
+
},
|
|
1449
|
+
},
|
|
1450
|
+
filename: { type: "string" },
|
|
1451
|
+
stars: { type: "number", default: 0 },
|
|
1452
|
+
},
|
|
1453
|
+
|
|
1454
|
+
// Computed fields (from Neo4j record)
|
|
1455
|
+
computed: {
|
|
1456
|
+
position: {
|
|
1457
|
+
compute: (params) => params.record.get("position"),
|
|
1458
|
+
meta: true, // Goes to JSON:API meta
|
|
1459
|
+
},
|
|
1460
|
+
},
|
|
1461
|
+
|
|
1462
|
+
// Relationships
|
|
1463
|
+
relationships: {
|
|
1464
|
+
roll: {
|
|
1465
|
+
model: rollMeta,
|
|
1466
|
+
direction: "out",
|
|
1467
|
+
relationship: "FRAME_OF",
|
|
1468
|
+
cardinality: "one",
|
|
1469
|
+
dtoKey: "roll",
|
|
1470
|
+
fields: [{ name: "position", type: "number", required: true }],
|
|
1471
|
+
},
|
|
1472
|
+
company: {
|
|
1473
|
+
model: companyMeta,
|
|
1474
|
+
direction: "out",
|
|
1475
|
+
relationship: "BELONGS_TO",
|
|
1476
|
+
cardinality: "one",
|
|
1477
|
+
},
|
|
1478
|
+
},
|
|
1479
|
+
});
|
|
1480
|
+
```
|
|
1481
|
+
|
|
1482
|
+
### Field Types
|
|
1483
|
+
|
|
1484
|
+
| Type | Neo4j/Cypher | JSON |
|
|
1485
|
+
| ---------- | --------------- | -------- |
|
|
1486
|
+
| `string` | STRING | string |
|
|
1487
|
+
| `number` | INTEGER/FLOAT | number |
|
|
1488
|
+
| `boolean` | BOOLEAN | boolean |
|
|
1489
|
+
| `date` | DATE | string (ISO) |
|
|
1490
|
+
| `datetime` | DATETIME | string (ISO) |
|
|
1491
|
+
| `json` | MAP | object |
|
|
1492
|
+
| `string[]` | LIST\<STRING\> | string[] |
|
|
1493
|
+
| `number[]` | LIST\<INTEGER\> | number[] |
|
|
1494
|
+
|
|
1495
|
+
### Field Options
|
|
1496
|
+
|
|
1497
|
+
| Option | Type | Description |
|
|
1498
|
+
| ----------- | -------- | ---------------------------------- |
|
|
1499
|
+
| `type` | CypherType | Data type |
|
|
1500
|
+
| `required` | boolean | Required field |
|
|
1501
|
+
| `default` | any | Default value |
|
|
1502
|
+
| `meta` | boolean | Put in JSON:API meta |
|
|
1503
|
+
| `transform` | function | Async transform for serialization |
|
|
1504
|
+
|
|
1505
|
+
### Relationship Options
|
|
1506
|
+
|
|
1507
|
+
| Option | Type | Description |
|
|
1508
|
+
| ------------- | ----------------- | --------------------------------- |
|
|
1509
|
+
| `model` | DataMeta | Related entity metadata |
|
|
1510
|
+
| `direction` | 'in' \| 'out' | Relationship direction |
|
|
1511
|
+
| `relationship`| string | Neo4j relationship type |
|
|
1512
|
+
| `cardinality` | 'one' \| 'many' | Single or collection |
|
|
1513
|
+
| `required` | boolean | Use MATCH vs OPTIONAL MATCH |
|
|
1514
|
+
| `contextKey` | string | CLS context key for value |
|
|
1515
|
+
| `dtoKey` | string | Override key in DTO |
|
|
1516
|
+
| `fields` | array | Edge properties |
|
|
1517
|
+
|
|
1518
|
+
### What defineEntity Auto-Generates
|
|
1519
|
+
|
|
1520
|
+
- **Constraints**: Unique constraint on `id`
|
|
1521
|
+
- **Indexes**: FULLTEXT index on all string fields
|
|
1522
|
+
- **Mapper**: Entity-to-record mapping
|
|
1523
|
+
- **Serializer**: JSON:API compliant serialization
|
|
1524
|
+
|
|
1194
1525
|
## Customizing Agent Prompts (Optional)
|
|
1195
1526
|
|
|
1196
1527
|
The library includes default prompts. Customization is entirely optional.
|
|
1197
1528
|
|
|
1198
1529
|
### Available Prompts
|
|
1199
1530
|
|
|
1200
|
-
| Agent
|
|
1201
|
-
|
|
|
1202
|
-
| **GraphCreator**
|
|
1203
|
-
| **Contextualiser**
|
|
1204
|
-
| **Contextualiser**
|
|
1205
|
-
| **Contextualiser**
|
|
1206
|
-
| **Contextualiser**
|
|
1207
|
-
| **Contextualiser**
|
|
1208
|
-
| **Contextualiser**
|
|
1209
|
-
| **Responder**
|
|
1210
|
-
| **Summariser**
|
|
1211
|
-
| **Summariser**
|
|
1212
|
-
| **Summariser**
|
|
1531
|
+
| Agent | Config Key | Purpose |
|
|
1532
|
+
| ---------------------- | --------------------------------------------- | ------------------------------------- |
|
|
1533
|
+
| **GraphCreator** | `prompts.graphCreator` | Extract atomic facts and key concepts |
|
|
1534
|
+
| **Contextualiser** | `prompts.contextualiser.questionRefiner` | Refine user questions |
|
|
1535
|
+
| **Contextualiser** | `prompts.contextualiser.rationalPlan` | Create rational plans |
|
|
1536
|
+
| **Contextualiser** | `prompts.contextualiser.keyConceptExtractor` | Score key concepts |
|
|
1537
|
+
| **Contextualiser** | `prompts.contextualiser.atomicFactsExtractor` | Evaluate atomic facts |
|
|
1538
|
+
| **Contextualiser** | `prompts.contextualiser.chunk` | Assess text chunks |
|
|
1539
|
+
| **Contextualiser** | `prompts.contextualiser.chunkVector` | Vector-based chunk retrieval |
|
|
1540
|
+
| **Responder** | `prompts.responder` | Generate final answers |
|
|
1541
|
+
| **Summariser** | `prompts.summariser.map` | Summarize individual chunks |
|
|
1542
|
+
| **Summariser** | `prompts.summariser.combine` | Combine summaries |
|
|
1543
|
+
| **Summariser** | `prompts.summariser.tldr` | Create TLDR |
|
|
1544
|
+
| **CommunityDetector** | `prompts.communityDetector` | Community detection |
|
|
1545
|
+
| **CommunitySummariser**| `prompts.communitySummariser` | Community summarization |
|
|
1546
|
+
| **DRIFT** | `prompts.drift.hyde` | HyDE generation |
|
|
1547
|
+
| **DRIFT** | `prompts.drift.primerAnswer` | Initial answer generation |
|
|
1548
|
+
| **DRIFT** | `prompts.drift.followUp` | Follow-up question handling |
|
|
1549
|
+
| **DRIFT** | `prompts.drift.synthesis` | Final answer synthesis |
|
|
1213
1550
|
|
|
1214
1551
|
### Custom Prompts Example
|
|
1215
1552
|
|