|
|
@@ -0,0 +1,104 @@
|
|
|
+import { Injectable, OnModuleInit, OnModuleDestroy, Logger } from '@nestjs/common';
|
|
|
+import { MongoClient, Db, Collection, ObjectId } from 'mongodb';
|
|
|
+
|
|
|
+@Injectable()
|
|
|
+export class MongoService implements OnModuleInit, OnModuleDestroy {
|
|
|
+ private client: MongoClient;
|
|
|
+ private db: Db;
|
|
|
+ private readonly logger = new Logger(MongoService.name);
|
|
|
+
|
|
|
+ async onModuleInit() {
|
|
|
+ const uri = process.env.MONGO_URI;
|
|
|
+ if (!uri) throw new Error('MONGO_URI not set in environment variables');
|
|
|
+
|
|
|
+ this.client = new MongoClient(uri);
|
|
|
+ await this.client.connect();
|
|
|
+
|
|
|
+ this.db = this.client.db('swopt-ai-test-a');
|
|
|
+ this.logger.log('Connected to MongoDB');
|
|
|
+ }
|
|
|
+
|
|
|
+ async onModuleDestroy() {
|
|
|
+ await this.client.close();
|
|
|
+ this.logger.log('MongoDB connection closed');
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get collection reference
|
|
|
+ private collection(name: string): Collection {
|
|
|
+ return this.db.collection(name);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* ------------------------------
|
|
|
+ * CRUD OPERATIONS (activities)
|
|
|
+ * ------------------------------ */
|
|
|
+
|
|
|
+ async createActivity(data: any) {
|
|
|
+ const result = await this.collection('activities').insertOne(data);
|
|
|
+ return { insertedId: result.insertedId };
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAllActivities(filter: Record<string, any> = {}) {
|
|
|
+ return this.collection('activities').find(filter).toArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ async getActivityById(id: string) {
|
|
|
+ return this.collection('activities').findOne({ _id: new ObjectId(id) });
|
|
|
+ }
|
|
|
+
|
|
|
+ async updateActivity(id: string, update: Record<string, any>) {
|
|
|
+ const result = await this.collection('activities').updateOne(
|
|
|
+ { _id: new ObjectId(id) },
|
|
|
+ { $set: update },
|
|
|
+ );
|
|
|
+ return { modifiedCount: result.modifiedCount };
|
|
|
+ }
|
|
|
+
|
|
|
+ async deleteActivity(id: string) {
|
|
|
+ const result = await this.collection('activities').deleteOne({ _id: new ObjectId(id) });
|
|
|
+ return { deletedCount: result.deletedCount };
|
|
|
+ }
|
|
|
+
|
|
|
+ /* ------------------------------
|
|
|
+ * AGGREGATION EXAMPLES
|
|
|
+ * ------------------------------ */
|
|
|
+
|
|
|
+ // Example 1: Get total hours worked per resource type
|
|
|
+ async getTotalResourceHours() {
|
|
|
+ return this.collection('activities')
|
|
|
+ .aggregate([
|
|
|
+ { $unwind: '$resources' },
|
|
|
+ {
|
|
|
+ $group: {
|
|
|
+ _id: '$resources.type',
|
|
|
+ totalHours: { $sum: { $toDecimal: '$resources.value.quantity' } },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ])
|
|
|
+ .toArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ // Example 2: Get total outputs by weight (e.g., total FFB harvested)
|
|
|
+ async getTotalOutputWeight() {
|
|
|
+ return this.collection('activities')
|
|
|
+ .aggregate([
|
|
|
+ { $unwind: '$outputs' },
|
|
|
+ {
|
|
|
+ $group: {
|
|
|
+ _id: '$outputs.type',
|
|
|
+ totalWeightKg: { $sum: { $toDecimal: '$outputs.weightValue.weight' } },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ])
|
|
|
+ .toArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ // Example 3: Activities within date range
|
|
|
+ async getActivitiesByDateRange(start: Date, end: Date) {
|
|
|
+ return this.collection('activities')
|
|
|
+ .find({
|
|
|
+ dateStart: { $gte: start },
|
|
|
+ dateEnd: { $lte: end },
|
|
|
+ })
|
|
|
+ .toArray();
|
|
|
+ }
|
|
|
+}
|