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 } }, { $lookup: { from: this.collectionName, localField: "_id", foreignField: "_id", as: "doc" } }, { $unwind: "$doc" }, { $project: { _id: "$doc._id", productionDate: "$doc.productionDate", site: "$doc.site", phase: "$doc.phase", block: "$doc.block", quantity: "$doc.quantity", quantityUom: "$doc.quantityUom", weight: "$doc.weight", weightUom: "$doc.weightUom", // vector: "$doc.vector", score: "$_score" } } ]) .toArray(); } }