|
|
@@ -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
|