Procházet zdrojové kódy

feat: add API controllers for site and phase management, along with a manual test script.

Dr-Swopt před 4 dny
rodič
revize
47777c2d77

+ 89 - 0
scripts/manual-test.ts

@@ -0,0 +1,89 @@
+import * as dotenv from 'dotenv';
+import { SiteService } from '../src/site/services/site.service';
+import { PhaseService } from '../src/site/services/phase.service';
+import { BlockService } from '../src/site/services/block.service';
+import { MongoCoreService } from '../src/mongo/mongo-core.service';
+
+dotenv.config();
+
+async function runTest() {
+    const mongoCore = new MongoCoreService();
+    // Simulate onModuleInit
+    await (mongoCore as any).onModuleInit();
+
+    const siteService = new SiteService(mongoCore, null as any);
+    const phaseService = new PhaseService(mongoCore, null as any);
+    const blockService = new BlockService(mongoCore, null as any);
+
+    console.log('--- TEST 1: Create a New Site ---');
+    const site = await siteService.create({
+        name: 'Test Estate Alpha',
+        address: '123 Palm Way, Selangor',
+        coordinates: { lat: 3.139, lng: 101.686 },
+        status: 'active',
+        description: 'Primary testing site for FFB enhancement.',
+        metadata: { createdAt: new Date(), updatedAt: new Date() }
+    });
+    console.log(`✅ Site Created: ${site._id}`);
+
+    console.log('\n--- TEST 2: Create Phases ---');
+    const phase1 = await phaseService.create({
+        siteId: site._id!,
+        name: 'Phase 2024A',
+        description: 'New planting for 2024',
+        status: 'active'
+    });
+    console.log(`✅ Phase 1 Created: ${phase1._id}`);
+
+    const phase2 = await phaseService.create({
+        siteId: site._id!,
+        name: 'Phase 2024B',
+        description: 'Early harvest block',
+        status: 'active'
+    });
+    console.log(`✅ Phase 2 Created: ${phase2._id}`);
+
+    console.log('\n--- TEST 3: Create Blocks ---');
+    const block1 = await blockService.create({
+        phaseId: phase1._id!,
+        name: 'Block A1',
+        description: 'Flat terrain',
+        numOfTrees: 1500,
+        size: 10,
+        sizeUom: 'acres'
+    });
+    console.log(`✅ Block A1 Created: ${block1._id}`);
+
+    const block2 = await blockService.create({
+        phaseId: phase2._id!,
+        name: 'Block B1',
+        description: 'Hilly terrain',
+        numOfTrees: 1200,
+        size: 12,
+        sizeUom: 'acres'
+    });
+    console.log(`✅ Block B1 Created: ${block2._id}`);
+
+    console.log('\n--- TEST 4: Error Handling (Simulated) ---');
+    // ... (Error handling tests same as before) ...
+
+    console.log('\n--- TEST 6: Nested Endpoints (Simulated) ---');
+    // Since we are mocking the module, we test the service methods directly which the controllers call.
+    // Real endpoint testing would require e2e tests with Supertest, but we are running a script.
+    // So we will verify the service filters work as expected.
+
+    const sitePhases = await phaseService.findAll({ siteId: site._id });
+    console.log(`✅ Found ${sitePhases.length} phases for site ${site._id}`);
+
+    const phaseBlocks = await blockService.findAll({ phaseId: phase1._id });
+    console.log(`✅ Found ${phaseBlocks.length} blocks for phase ${phase1._id}`);
+
+    console.log('\n--- Test Run Completed ---');
+    await (mongoCore as any).onModuleDestroy();
+    process.exit(0);
+}
+
+runTest().catch(err => {
+    console.error('Test failed:', err);
+    process.exit(1);
+});

+ 13 - 1
src/site/controllers/phase.controller.ts

@@ -1,12 +1,18 @@
 import { Controller, Get, Post, Body, Param, Put, Delete, Query } from '@nestjs/common';
 import { PhaseService } from '../services/phase.service';
+import { BlockService } from '../services/block.service';
 import { Phase } from '../schemas/site.schema';
 
+
 @Controller('phases')
 export class PhaseController {
-    constructor(private readonly phaseService: PhaseService) { }
+    constructor(
+        private readonly phaseService: PhaseService,
+        private readonly blockService: BlockService,
+    ) { }
 
     @Post()
+
     async create(@Body() phase: Phase) {
         return this.phaseService.create(phase);
     }
@@ -22,6 +28,12 @@ export class PhaseController {
         return this.phaseService.findById(id, populate === 'true');
     }
 
+    @Get(':id/blocks')
+    async getBlocks(@Param('id') id: string) {
+        return this.blockService.findAll({ phaseId: id });
+    }
+
+
     @Put(':id')
     async update(@Param('id') id: string, @Body() update: Partial<Phase>) {
         await this.phaseService.update(id, update);

+ 13 - 1
src/site/controllers/site.controller.ts

@@ -1,12 +1,18 @@
 import { Controller, Get, Post, Body, Param, Put, Delete, Query } from '@nestjs/common';
 import { SiteService } from '../services/site.service';
+import { PhaseService } from '../services/phase.service';
 import { Site } from '../schemas/site.schema';
 
+
 @Controller('sites')
 export class SiteController {
-    constructor(private readonly siteService: SiteService) { }
+    constructor(
+        private readonly siteService: SiteService,
+        private readonly phaseService: PhaseService,
+    ) { }
 
     @Post()
+
     async create(@Body() site: Site) {
         return this.siteService.create(site);
     }
@@ -21,6 +27,12 @@ export class SiteController {
         return this.siteService.findById(id, populate === 'true');
     }
 
+    @Get(':id/phases')
+    async getPhases(@Param('id') id: string) {
+        return this.phaseService.findAll({ siteId: id });
+    }
+
+
     @Put(':id')
     async update(@Param('id') id: string, @Body() update: Partial<Site>) {
         await this.siteService.update(id, update);