Skip to content

Commit 8f64292

Browse files
Copilothotlong
andcommitted
refactor: address code review feedback — extract constant, improve types, add docs
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 4d4fe3c commit 8f64292

3 files changed

Lines changed: 15 additions & 3 deletions

File tree

packages/runtime/src/app-plugin.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { Plugin, PluginContext } from '@objectstack/core';
44
import { SeedLoaderService } from './seed-loader.js';
5+
import type { IMetadataService } from '@objectstack/spec/contracts';
56

67
/**
78
* AppPlugin
@@ -139,7 +140,7 @@ export class AppPlugin implements Plugin {
139140

140141
// Use SeedLoaderService for metadata-driven loading with reference resolution
141142
try {
142-
const metadata = ctx.getService('metadata') as any;
143+
const metadata = ctx.getService('metadata') as IMetadataService | undefined;
143144
if (metadata) {
144145
const seedLoader = new SeedLoaderService(ql, metadata, ctx.logger);
145146
const { SeedLoaderRequestSchema } = await import('@objectstack/spec/data');

packages/runtime/src/seed-loader.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ interface Logger {
2121
debug(message: string, meta?: Record<string, any>): void;
2222
}
2323

24+
/** Default field used for externalId matching on target objects */
25+
const DEFAULT_EXTERNAL_ID_FIELD = 'name';
26+
2427
/**
2528
* SeedLoaderService — Runtime implementation of ISeedLoaderService
2629
*
@@ -132,7 +135,7 @@ export class SeedLoaderService implements ISeedLoaderService {
132135
references.push({
133136
field: fieldName,
134137
targetObject,
135-
targetField: 'name', // Default externalId
138+
targetField: DEFAULT_EXTERNAL_ID_FIELD,
136139
fieldType: fieldDef.type as 'lookup' | 'master_detail',
137140
});
138141
}
@@ -483,6 +486,8 @@ export class SeedLoaderService implements ISeedLoaderService {
483486
// Build adjacency list and in-degree counts
484487
for (const node of nodes) {
485488
for (const dep of node.dependsOn) {
489+
// Exclude self-references from ordering (e.g., employee.manager_id → employee).
490+
// Self-referencing fields are still tracked in node.references for resolution.
486491
if (objectSet.has(dep) && dep !== node.object) {
487492
adjacency.get(dep)!.push(node.object);
488493
inDegree.set(node.object, (inDegree.get(node.object) || 0) + 1);
@@ -578,7 +583,7 @@ export class SeedLoaderService implements ISeedLoaderService {
578583

579584
private filterByEnv(datasets: Dataset[], env?: string): Dataset[] {
580585
if (!env) return datasets;
581-
return datasets.filter(d => d.env.includes(env as any));
586+
return datasets.filter(d => (d.env as string[]).includes(env));
582587
}
583588

584589
private orderDatasets(datasets: Dataset[], insertOrder: string[]): Dataset[] {

packages/spec/src/contracts/seed-loader-service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ export interface ISeedLoaderService {
3030
/**
3131
* Load one or more datasets with full reference resolution and dependency ordering.
3232
*
33+
* The loader automatically:
34+
* 1. Filters datasets by environment if `config.env` is set
35+
* 2. Builds a dependency graph from object metadata (lookup/master_detail fields)
36+
* 3. Topologically sorts datasets so parent objects are inserted before children
37+
* 4. Resolves references via externalId, with multi-pass for circular dependencies
38+
*
3339
* @param request - Parsed SeedLoaderRequest (datasets + config)
3440
* @returns Structured result with per-object stats, errors, and summary
3541
*/

0 commit comments

Comments
 (0)