소스 검색

feat: implement dynamic data file resolution and phase mapping in app controller seeder

Dr-Swopt 8 시간 전
부모
커밋
27bd0c5715
1개의 변경된 파일38개의 추가작업 그리고 13개의 파일을 삭제
  1. 38 13
      src/app.controller.ts

+ 38 - 13
src/app.controller.ts

@@ -1,10 +1,10 @@
 /**
- * * **Current State:** The `AppController` has a simple `getHello()` method and does not contain any seeding logic or master references.
- * * **Intended Mutation:** We will add a `@Get('seed')` route to `AppController` which injects `PhaseService`, `BlockService`, and `FFBProductionService`. The handler `seedSystemData` will chronologically:
- *   1. Parse `PhaseData.json`, map the properties, and insert them via `PhaseService.create()`.
- *   2. Parse `BlockData.json`, map the properties (programmatically appending `phaseCode: "PH01"`), and insert them via `BlockService.create()`.
- *   3. Parse `FFBProductionData.json`, slice the array to the first 20 elements to prevent API rate-limiting/timeouts, map their properties, and stream each directly to `FFBProductionService.create()` inside `try/catch` blocks.
- * * **Risk Check:** The Gemini Embedding API can experience throttling, rate-limiting, or timeouts during batch ingestion. We will isolate each record ingestion step inside a localized `try/catch` block, log errors individually, and continue streaming remaining records to guarantee high-resiliency.
+ * * **Current State:** The `AppController` seeder uses hardcoded absolute paths ('e:\Task\Research and Development\RAG\mongo stuff\...') to read data files, and maps all seeded blocks statically to 'PH01'.
+ * * **Intended Mutation:**
+ *   1. Resolve JSON data files dynamically relative to the execution root directory using `process.cwd()` and `path.resolve`.
+ *   2. Implement dynamic phase resolution inside the `rawBlocks` iteration loop by extracting the numeric prefix from the blockCode (e.g. "01E01" -> "PH01") or matching alternate section prefixes (e.g. "CARPE", "MAR01", etc.).
+ *   3. Provide a fallback known root code ('PH01') and log a warning instead of throwing if the block cannot be programmatically parsed.
+ * * **Risk Check:** Different environment cwd (working directory) setups could affect `process.cwd()`. To guarantee correctness, we leverage `process.cwd()` which is standard for NestJS workspace launches, combined with explicit warnings and fallback values to make the seeding operation robust.
  */
 
 import { Controller, Get, Logger, BadRequestException } from '@nestjs/common';
@@ -13,6 +13,7 @@ import { PhaseService } from './site/services/phase.service';
 import { BlockService } from './site/services/block.service';
 import { FFBProductionService } from './FFB/services/ffb-production.service';
 import * as fs from 'fs';
+import * as path from 'path';
 
 @Controller()
 export class AppController {
@@ -34,10 +35,15 @@ export class AppController {
   async seedSystemData() {
     this.logger.log('🚀 Starting chronological seeding...');
 
+    // Resolve JSON data file locations dynamically relative to process.cwd()
+    const rootDir = process.cwd();
+    const phaseDataPath = path.resolve(rootDir, '../mongo stuff/PhaseData.json');
+    const blockDataPath = path.resolve(rootDir, '../mongo stuff/BlockData.json');
+    const ffbDataPath = path.resolve(rootDir, '../mongo stuff/FFBProductionData.json');
+
     // 1. PHASE SEEDING
-    const phaseDataPath = 'e:\\Task\\Research and Development\\RAG\\mongo stuff\\PhaseData.json';
     if (!fs.existsSync(phaseDataPath)) {
-      throw new BadRequestException('PhaseData.json not found!');
+      throw new BadRequestException(`PhaseData.json not found at ${phaseDataPath}`);
     }
     const rawPhases = JSON.parse(fs.readFileSync(phaseDataPath, 'utf8'));
     this.logger.log(`Found ${rawPhases.length} phases to process.`);
@@ -58,19 +64,39 @@ export class AppController {
     console.log('[SEED] Phase collection initialization pass complete.');
 
     // 2. BLOCK SEEDING
-    const blockDataPath = 'e:\\Task\\Research and Development\\RAG\\mongo stuff\\BlockData.json';
     if (!fs.existsSync(blockDataPath)) {
-      throw new BadRequestException('BlockData.json not found!');
+      throw new BadRequestException(`BlockData.json not found at ${blockDataPath}`);
     }
     const rawBlocks = JSON.parse(fs.readFileSync(blockDataPath, 'utf8'));
     this.logger.log(`Found ${rawBlocks.length} blocks to process.`);
 
     for (const rawBlock of rawBlocks) {
       try {
+        // Dynamic Phase Resolution & Fallback Defaulting
+        let phaseCode = 'PH01'; // Fallback root code
+        if (rawBlock.phaseCode) {
+          phaseCode = rawBlock.phaseCode;
+        } else if (rawBlock.blockCode) {
+          const match = rawBlock.blockCode.match(/^(\d+)/);
+          if (match) {
+            const numStr = match[1];
+            phaseCode = 'PH' + numStr.padStart(2, '0');
+          } else {
+            // Alternate reference check against known sections
+            const knownPhases = ['CARPE', 'MAR01', 'MR', 'NB01', 'NC', 'NR', 'PH01', 'PH02', 'PH03', 'PH04', 'PH05', 'PN', 'TRNSC'];
+            const foundPhase = knownPhases.find(p => rawBlock.blockCode.toUpperCase().startsWith(p.toUpperCase()));
+            if (foundPhase) {
+              phaseCode = foundPhase;
+            } else {
+              this.logger.warn(`[SEED] Block ${rawBlock.blockCode} could not be programmatically mapped. Defaulting to PH01.`);
+            }
+          }
+        }
+
         const mappedBlock = {
           locId: Number(rawBlock.loc_id),
           blockCode: rawBlock.blockCode,
-          phaseCode: 'PH01', // Anchor parameter programmatically appended
+          phaseCode: phaseCode, // Programmatically and dynamically mapped
           blockDesc: rawBlock.blockDesc,
           locType: rawBlock.loc_type,
           entryNo: Number(rawBlock.entry_no),
@@ -94,9 +120,8 @@ export class AppController {
     console.log('[SEED] Block collection initialization pass complete.');
 
     // 3. FFB TRANSACTION INGESTION & VECTOR ENRICHMENT STREAM
-    const ffbDataPath = 'e:\\Task\\Research and Development\\RAG\\mongo stuff\\FFBProductionData.json';
     if (!fs.existsSync(ffbDataPath)) {
-      throw new BadRequestException('FFBProductionData.json not found!');
+      throw new BadRequestException(`FFBProductionData.json not found at ${ffbDataPath}`);
     }
     const rawFfbs = JSON.parse(fs.readFileSync(ffbDataPath, 'utf8'));
     // Slice to the first 20 records to keep seeding process snappy and safe from rate limit throttling