import { Db, ObjectId, WithId } from 'mongodb'; import { FFBProduction } from 'src/FFB/ffb-production.schema'; export class FFBProductionRepository { private readonly collectionName = 'FFB Production'; constructor(private readonly db: Db) { } private get collection() { return this.db.collection(this.collectionName); } async init() { const collections = await this.db.listCollections({ name: this.collectionName }).toArray(); if (collections.length === 0) { await this.db.createCollection(this.collectionName); console.log(`✅ Created collection: ${this.collectionName}`); } } async create(ffb: FFBProduction & { vector?: number[] }): Promise { const result = await this.collection.insertOne({ ...ffb, productionDate: new Date(ffb.productionDate), vector: ffb.vector, // optional vector }); return { ...ffb, _id: result.insertedId.toString() }; } async findAll(filter: Record = {}): Promise<(FFBProduction & { vector?: number[] })[]> { const results = await this.collection.find(filter).toArray(); return results.map((r: WithId) => ({ ...r, _id: r._id?.toString(), })); } async findById(id: string): Promise<(FFBProduction & { vector?: number[] }) | null> { const result = await this.collection.findOne({ _id: new ObjectId(id) as any }); return result ? { ...result, _id: result._id.toString() } : null; } async delete(id: string) { return this.collection.deleteOne({ _id: new ObjectId(id) as any }); } /** Optional: helper for vector search via aggregation */ async vectorSearch(vector: number[], k = 5, numCandidates = 50) { return this.collection .aggregate([ { $vectorSearch: { index: 'vector_index', queryVector: vector, path: 'vector', numCandidates, limit: k } }, { $project: { _id: 1, productionDate: 1, site: 1, phase: 1, block: 1, quantity: 1, quantityUom: 1, weight: 1, weightUom: 1, score: { "$meta": "vectorSearchScore" } // correctly get the score } } ]) .toArray(); } }