|
|
@@ -1,9 +1,12 @@
|
|
|
-import { Injectable } from '@nestjs/common';
|
|
|
+import { Injectable, BadRequestException, Inject, forwardRef } from '@nestjs/common';
|
|
|
import { MongoCoreService } from '../../mongo/mongo-core.service';
|
|
|
import { FFBProduction } from '../ffb-production.schema';
|
|
|
import { FFBProductionRepository } from 'src/FFB/mongo-ffb-production.repository';
|
|
|
import { FFBVectorService } from './ffb-vector.service';
|
|
|
import { FFBLangChainService } from './ffb-langchain.service';
|
|
|
+import { SiteService } from '../../site/services/site.service';
|
|
|
+import { PhaseService } from '../../site/services/phase.service';
|
|
|
+import { BlockService } from '../../site/services/block.service';
|
|
|
|
|
|
@Injectable()
|
|
|
export class FFBProductionService {
|
|
|
@@ -11,10 +14,17 @@ export class FFBProductionService {
|
|
|
|
|
|
constructor(
|
|
|
private readonly mongoCore: MongoCoreService,
|
|
|
- private readonly vectorService: FFBVectorService, // Inject vector service
|
|
|
+ private readonly vectorService: FFBVectorService,
|
|
|
private readonly ffbLangChainService: FFBLangChainService,
|
|
|
+ @Inject(forwardRef(() => SiteService))
|
|
|
+ private readonly siteService: SiteService,
|
|
|
+ @Inject(forwardRef(() => PhaseService))
|
|
|
+ private readonly phaseService: PhaseService,
|
|
|
+ @Inject(forwardRef(() => BlockService))
|
|
|
+ private readonly blockService: BlockService,
|
|
|
) { }
|
|
|
|
|
|
+
|
|
|
/** Lazily get or create the repository */
|
|
|
private async getRepository(): Promise<FFBProductionRepository> {
|
|
|
if (!this.repo) {
|
|
|
@@ -27,10 +37,44 @@ export class FFBProductionService {
|
|
|
|
|
|
/** Create a new record with embedding */
|
|
|
async create(record: FFBProduction) {
|
|
|
+ // 1. Validate Site
|
|
|
+ const site = await this.siteService.findById(record.site.id);
|
|
|
+ if (!site) {
|
|
|
+ throw new BadRequestException(`Site with ID ${record.site.id} does not exist.`);
|
|
|
+ }
|
|
|
+ if (site.name !== record.site.name) {
|
|
|
+ throw new BadRequestException(`Site name mismatch: expected ${site.name}, got ${record.site.name}.`);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. Validate Phase
|
|
|
+ const phase = await this.phaseService.findById(record.phase.id);
|
|
|
+ if (!phase) {
|
|
|
+ throw new BadRequestException(`Phase with ID ${record.phase.id} does not exist.`);
|
|
|
+ }
|
|
|
+ if (phase.name !== record.phase.name) {
|
|
|
+ throw new BadRequestException(`Phase name mismatch: expected ${phase.name}, got ${record.phase.name}.`);
|
|
|
+ }
|
|
|
+ if (phase.siteId !== record.site.id) {
|
|
|
+ throw new BadRequestException(`Phase with ID ${record.phase.id} does not belong to Site ${record.site.id}.`);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. Validate Block
|
|
|
+ const block = await this.blockService.findById(record.block.id);
|
|
|
+ if (!block) {
|
|
|
+ throw new BadRequestException(`Block with ID ${record.block.id} does not exist.`);
|
|
|
+ }
|
|
|
+ if (block.name !== record.block.name) {
|
|
|
+ throw new BadRequestException(`Block name mismatch: expected ${block.name}, got ${record.block.name}.`);
|
|
|
+ }
|
|
|
+ if (block.phaseId !== record.phase.id) {
|
|
|
+ throw new BadRequestException(`Block with ID ${record.block.id} does not belong to Phase ${record.phase.id}.`);
|
|
|
+ }
|
|
|
+
|
|
|
// Use vector service to insert with embedding
|
|
|
return this.vectorService.insertWithVector(record);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/** Find all records (no embedding required) */
|
|
|
async findAll(filter: Record<string, any> = {}, options: { page?: number, limit?: number } = {}) {
|
|
|
const repo = await this.getRepository();
|
|
|
@@ -49,6 +93,13 @@ export class FFBProductionService {
|
|
|
return repo.delete(id);
|
|
|
}
|
|
|
|
|
|
+ /** Delete many records by filter */
|
|
|
+ async deleteMany(filter: Record<string, any>) {
|
|
|
+ const repo = await this.getRepository();
|
|
|
+ return repo.deleteMany(filter);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
/** Search for top-k similar records using a text query */
|
|
|
async search(query: string, k = 5) {
|
|
|
return this.vectorService.vectorSearch(query, k);
|