@objectstack/metadata-protocol 11.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/framework/framework/packages/metadata-protocol/dist/chunk-JRNTUZG6.cjs","../src/seed-loader.ts"],"names":[],"mappings":"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","file":"/home/runner/work/framework/framework/packages/metadata-protocol/dist/chunk-JRNTUZG6.cjs","sourcesContent":[null,"// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { IDataEngine, IMetadataService, ISeedLoaderService } from '@objectstack/spec/contracts';\nimport type {\n SeedLoaderRequest,\n SeedLoaderResult,\n SeedLoaderConfig,\n SeedLoaderConfigInput,\n ObjectDependencyGraph,\n ObjectDependencyNode,\n ReferenceResolution,\n ReferenceResolutionError,\n SeedLoadResult,\n Seed,\n} from '@objectstack/spec/data';\nimport { SeedLoaderConfigSchema } from '@objectstack/spec/data';\nimport { resolveSeedRecord } from '@objectstack/formula';\n\ninterface Logger {\n info(message: string, meta?: Record<string, any>): void;\n warn(message: string, meta?: Record<string, any>): void;\n error(message: string, error?: Error, meta?: Record<string, any>): void;\n debug(message: string, meta?: Record<string, any>): void;\n}\n\n/** Default field used for externalId matching on target objects */\nconst DEFAULT_EXTERNAL_ID_FIELD = 'name';\n\n/**\n * SeedLoaderService — Runtime implementation of ISeedLoaderService\n *\n * Provides metadata-driven seed data loading with:\n * - Automatic lookup/master_detail reference resolution via externalId\n * - Topological dependency ordering (parents before children)\n * - Multi-pass loading for circular references\n * - Dry-run validation mode\n * - Upsert support honoring SeedSchema mode\n * - Actionable error reporting\n */\nexport class SeedLoaderService implements ISeedLoaderService {\n private engine: IDataEngine;\n private metadata: IMetadataService;\n private logger: Logger;\n /**\n * Tenant org to stamp BUSINESS seed rows with when the caller pinned no\n * explicit `config.organizationId` (resolved per {@link resolveSoleOrganizationId}).\n * Set once per {@link load}; never applied to `sys_`/`cloud_`/`ai_` platform\n * seeds (those stay intentionally global/cross-tenant).\n */\n private fallbackOrgId?: string;\n\n constructor(engine: IDataEngine, metadata: IMetadataService, logger: Logger) {\n this.engine = engine;\n this.metadata = metadata;\n this.logger = logger;\n }\n\n // ==========================================================================\n // Public API\n // ==========================================================================\n\n async load(request: SeedLoaderRequest): Promise<SeedLoaderResult> {\n const startTime = Date.now();\n const config = request.config;\n const allErrors: ReferenceResolutionError[] = [];\n const allResults: SeedLoadResult[] = [];\n\n // When the caller pinned no target org (an in-process publish has no active\n // user session — the AI build agent's publish path), BUSINESS seed rows\n // would land `organization_id = NULL` and then vanish under strict\n // org-scoping. If the tenant has exactly ONE organization, adopt it as a\n // fallback so business seeds carry the tenant key like a normal write.\n // Zero/many orgs → leave unset (genuinely ambiguous → keep the historical\n // global/cross-tenant behavior; the publisher must scope explicitly).\n this.fallbackOrgId =\n config.organizationId == null ? await this.resolveSoleOrganizationId() : undefined;\n\n // 1. Filter datasets by environment\n const datasets = this.filterByEnv(request.seeds, config.env);\n\n if (datasets.length === 0) {\n return this.buildEmptyResult(config, Date.now() - startTime);\n }\n\n // 2. Build dependency graph\n const objectNames = datasets.map(d => d.object);\n const graph = await this.buildDependencyGraph(objectNames);\n\n this.logger.info('[SeedLoader] Dependency graph built', {\n objects: objectNames.length,\n insertOrder: graph.insertOrder,\n circularDeps: graph.circularDependencies.length,\n });\n\n // 3. Order datasets by topological insert order\n const orderedDatasets = this.orderDatasets(datasets, graph.insertOrder);\n\n // 4. Build reference lookup map from metadata (field → target object)\n const refMap = this.buildReferenceMap(graph);\n\n // 5. Pass 1: Insert/upsert records, resolving references\n const insertedRecords = new Map<string, Map<string, string>>(); // object → externalIdValue → internalId\n const deferredUpdates: DeferredUpdate[] = [];\n\n for (const dataset of orderedDatasets) {\n const result = await this.loadDataset(\n dataset, config, refMap, insertedRecords, deferredUpdates, allErrors\n );\n allResults.push(result);\n\n if (config.haltOnError && result.errored > 0) {\n this.logger.warn('[SeedLoader] Halting on first error', { object: dataset.object });\n break;\n }\n }\n\n // 6. Pass 2: Resolve deferred references (circular dependencies)\n if (config.multiPass && deferredUpdates.length > 0 && !config.dryRun) {\n this.logger.info('[SeedLoader] Pass 2: resolving deferred references', {\n count: deferredUpdates.length,\n });\n await this.resolveDeferredUpdates(deferredUpdates, insertedRecords, allResults, allErrors, config.organizationId);\n }\n\n // 7. Build final result\n const durationMs = Date.now() - startTime;\n return this.buildResult(config, graph, allResults, allErrors, durationMs);\n }\n\n async buildDependencyGraph(objectNames: string[]): Promise<ObjectDependencyGraph> {\n const nodes: ObjectDependencyNode[] = [];\n const objectSet = new Set(objectNames);\n\n for (const objectName of objectNames) {\n const objDef = await this.metadata.getObject(objectName) as any;\n const dependsOn: string[] = [];\n const references: ReferenceResolution[] = [];\n\n if (objDef && objDef.fields) {\n const fields = objDef.fields as Record<string, any>;\n for (const [fieldName, fieldDef] of Object.entries(fields)) {\n if (\n (fieldDef.type === 'lookup' || fieldDef.type === 'master_detail' || fieldDef.type === 'user') &&\n fieldDef.reference\n ) {\n const targetObject = fieldDef.reference as string;\n\n // Track dependency ordering only for objects within the graph\n if (objectSet.has(targetObject) && !dependsOn.includes(targetObject)) {\n dependsOn.push(targetObject);\n }\n\n // Track ALL references for resolution (target may exist in database)\n references.push({\n field: fieldName,\n targetObject,\n targetField: DEFAULT_EXTERNAL_ID_FIELD,\n fieldType: fieldDef.type as 'lookup' | 'master_detail' | 'user',\n });\n }\n }\n }\n\n nodes.push({ object: objectName, dependsOn, references });\n }\n\n // Topological sort\n const { insertOrder, circularDependencies } = this.topologicalSort(nodes);\n\n return { nodes, insertOrder, circularDependencies };\n }\n\n async validate(datasets: Seed[], config?: SeedLoaderConfigInput): Promise<SeedLoaderResult> {\n const parsedConfig = SeedLoaderConfigSchema.parse({ ...config, dryRun: true });\n return this.load({ seeds: datasets, config: parsedConfig });\n }\n\n // ==========================================================================\n // Internal: Seed Loading\n // ==========================================================================\n\n private async loadDataset(\n dataset: Seed,\n config: SeedLoaderConfig,\n refMap: Map<string, ReferenceResolution[]>,\n insertedRecords: Map<string, Map<string, string>>,\n deferredUpdates: DeferredUpdate[],\n allErrors: ReferenceResolutionError[],\n ): Promise<SeedLoadResult> {\n const objectName = dataset.object;\n const mode = dataset.mode || config.defaultMode;\n const externalId = dataset.externalId || 'name';\n\n let inserted = 0;\n let updated = 0;\n let skipped = 0;\n let errored = 0;\n let referencesResolved = 0;\n let referencesDeferred = 0;\n const errors: ReferenceResolutionError[] = [];\n\n // Ensure the object's record map exists\n if (!insertedRecords.has(objectName)) {\n insertedRecords.set(objectName, new Map());\n }\n\n // Pre-load existing records for upsert matching. When a target\n // organization is set, scope the lookup so each tenant gets its\n // own copy (otherwise upsert would clobber other tenants' rows\n // that share the same natural key — e.g. `name: 'Acme Corp'`).\n let existingRecords: Map<string, any> | undefined;\n if ((mode === 'upsert' || mode === 'update' || mode === 'ignore') && !config.dryRun) {\n existingRecords = await this.loadExistingRecords(\n objectName,\n externalId,\n config.organizationId,\n );\n }\n\n // Get reference resolutions for this object\n const objectRefs = refMap.get(objectName) || [];\n\n // Pin a single `now()` snapshot for the entire dataset so multi-pass\n // loads see one logical clock — the M9 determinism guarantee for seeds.\n const seedNow = new Date();\n\n // Identity/context bound to seed CEL expressions. `os.user` / `os.org`\n // resolve from here, so `owner_id: cel\\`os.user.id\\`` works.\n //\n // When no real user identity is supplied (the normal case — seeds run\n // before the first human sign-up), `os.user` is bound to a NULL identity\n // (`{ id: null }`) rather than left undefined. This makes `os.user.id`\n // resolve to `null` instead of crashing the expression, so a seed's\n // `owner_id: cel\\`os.user.id\\`` simply lands NULL — semantically \"owned by\n // whoever becomes the first admin\", which the first-admin handoff\n // (`claimSeedOwnership`) then fills in. The platform therefore never has to\n // mint a placeholder `usr_system` row just to satisfy this expression.\n const seedIdentity = config.identity;\n const baseEvalCtx = {\n now: seedNow,\n // `id: null` is a legitimate seed-time state (the owning admin does not\n // exist yet) that the formula EvalContext's `user.id: string` type does\n // not yet model — cast the fallback so `os.user.id` evaluates to null.\n user: seedIdentity?.user ?? ({ id: null } as unknown as NonNullable<typeof seedIdentity>['user']),\n // Fall back to the per-tenant organizationId so `os.org.id` resolves\n // during per-org replay even without an explicit identity.org.\n org: seedIdentity?.org ?? (config.organizationId ? { id: config.organizationId } : undefined),\n env: config.env,\n };\n\n for (let i = 0; i < dataset.records.length; i++) {\n // Resolve any embedded Expression envelopes (e.g. `cel\\`daysFromNow(30)\\``,\n // `cel\\`os.user.id\\``) BEFORE reference resolution so downstream lookups\n // see resolved values.\n const seedResult = resolveSeedRecord(\n dataset.records[i] as Record<string, never>,\n baseEvalCtx,\n );\n if (!seedResult.ok) {\n // LOUD FAILURE: a record whose dynamic values cannot be resolved is\n // dropped — but never silently. Record an actionable error (so it\n // surfaces in result.errors and flips success=false) instead of\n // writing the unresolved Expression envelope into the database.\n errored++;\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: '(expression)',\n targetObject: objectName,\n targetField: '(expression)',\n attemptedValue: dataset.records[i],\n recordIndex: i,\n message:\n `Cannot resolve dynamic seed values for ${objectName} record #${i}: ${seedResult.error.message}. ` +\n '`os.user.id` resolves to null at seed time (the owning admin does not exist yet) and ' +\n 'owner-style fields are assigned by the first-admin handoff — so a required, non-owner ' +\n 'field must not depend on it. Provide a literal value or make the field optional.',\n };\n errors.push(error);\n allErrors.push(error);\n this.logger.warn(`[SeedLoader] ${error.message}`);\n continue;\n }\n const record = { ...(seedResult.value as Record<string, unknown>) };\n\n // Per-tenant tagging: stamp every seeded row with the target org — the\n // caller's explicit `config.organizationId`, or (when none was pinned) the\n // single-org fallback for BUSINESS objects only. A `sys_`/`cloud_`/`ai_`\n // platform seed never takes the fallback: those stay global/cross-tenant.\n // A record that supplies its own `organization_id` always wins; objects\n // without the column ignore the extra key at the engine.\n const tenantOrg =\n config.organizationId ??\n (/^(sys_|cloud_|ai_)/.test(objectName) ? undefined : this.fallbackOrgId);\n if (tenantOrg && record['organization_id'] == null) {\n record['organization_id'] = tenantOrg;\n }\n\n // Resolve references\n for (const ref of objectRefs) {\n const fieldValue = record[ref.field];\n if (fieldValue === undefined || fieldValue === null) continue;\n\n // LOUD FAILURE: a reference must be a natural-key string (or an\n // internal id). An object value — e.g. the wrapper `{ externalId: 'X' }`\n // — never resolves: it would otherwise fall through unresolved and reach\n // the driver as a non-bindable value (\"SQLite3 can only bind ...\"). This\n // used to be silently skipped (and only crashed on a persistent DB's\n // update path), so catch it here and report the actionable fix instead.\n if (typeof fieldValue === 'object') {\n const wrapped = (fieldValue as Record<string, unknown>).externalId;\n const hint =\n wrapped !== undefined\n ? ` Pass the natural key directly: ${ref.field}: ${JSON.stringify(wrapped)}.`\n : ` Pass the target's ${ref.targetField} value as a plain string.`;\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: ref.field,\n targetObject: ref.targetObject,\n targetField: ref.targetField,\n attemptedValue: fieldValue,\n recordIndex: i,\n message:\n `Invalid reference for ${objectName}.${ref.field}: expected a ` +\n `${ref.targetObject}.${ref.targetField} natural-key string but got an object.${hint}`,\n };\n errors.push(error);\n allErrors.push(error);\n this.logger.warn(`[SeedLoader] ${error.message}`, { recordIndex: i });\n // Drop the unresolvable value so it never reaches the driver.\n record[ref.field] = null;\n continue;\n }\n\n // Skip if value looks like an internal ID (not a natural key)\n if (typeof fieldValue !== 'string' || this.looksLikeInternalId(fieldValue)) continue;\n\n // Try to resolve via already-inserted records\n const targetMap = insertedRecords.get(ref.targetObject);\n const resolvedId = targetMap?.get(String(fieldValue));\n\n if (resolvedId) {\n record[ref.field] = resolvedId;\n referencesResolved++;\n } else if (!config.dryRun) {\n // Try to resolve from existing data in the database\n const dbId = await this.resolveFromDatabase(ref.targetObject, ref.targetField, fieldValue, config.organizationId);\n if (dbId) {\n record[ref.field] = dbId;\n referencesResolved++;\n } else if (config.multiPass) {\n // Defer to pass 2\n record[ref.field] = null;\n deferredUpdates.push({\n objectName,\n recordExternalId: String(record[externalId] ?? ''),\n field: ref.field,\n targetObject: ref.targetObject,\n targetField: ref.targetField,\n attemptedValue: fieldValue,\n recordIndex: i,\n });\n referencesDeferred++;\n } else {\n // Cannot resolve - record error\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: ref.field,\n targetObject: ref.targetObject,\n targetField: ref.targetField,\n attemptedValue: fieldValue,\n recordIndex: i,\n message: `Cannot resolve reference: ${objectName}.${ref.field} = '${fieldValue}' → ${ref.targetObject}.${ref.targetField} not found`,\n };\n errors.push(error);\n allErrors.push(error);\n }\n } else {\n // Dry-run: attempt resolution, report error if not found\n const targetMap2 = insertedRecords.get(ref.targetObject);\n if (!targetMap2?.has(String(fieldValue))) {\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: ref.field,\n targetObject: ref.targetObject,\n targetField: ref.targetField,\n attemptedValue: fieldValue,\n recordIndex: i,\n message: `[dry-run] Reference may not resolve: ${objectName}.${ref.field} = '${fieldValue}' → ${ref.targetObject}.${ref.targetField}`,\n };\n errors.push(error);\n allErrors.push(error);\n }\n }\n }\n\n // Insert/upsert the record\n if (!config.dryRun) {\n try {\n const result = await this.writeRecord(\n objectName, record, mode, externalId, existingRecords\n );\n\n if (result.action === 'inserted') inserted++;\n else if (result.action === 'updated') updated++;\n else if (result.action === 'skipped') skipped++;\n\n // Track the inserted/updated record's ID for reference resolution\n const externalIdValue = String(record[externalId] ?? '');\n const internalId = result.id;\n if (externalIdValue && internalId) {\n insertedRecords.get(objectName)!.set(externalIdValue, String(internalId));\n }\n } catch (err: any) {\n // LOUD FAILURE: write errors were previously only counted +\n // warn-logged, so dropped rows were invisible in result.errors and\n // the boot summary. Surface them as actionable errors too, so the\n // overall load is marked unsuccessful and the reason is reported.\n errored++;\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: '(write)',\n targetObject: objectName,\n targetField: externalId,\n attemptedValue: record[externalId] ?? null,\n recordIndex: i,\n message: `Failed to write ${objectName} record #${i} (${externalId}=${String(record[externalId] ?? '')}): ${err.message}`,\n };\n errors.push(error);\n allErrors.push(error);\n this.logger.warn(`[SeedLoader] ${error.message}`, { recordIndex: i });\n }\n } else {\n // Dry-run: simulate insert tracking\n const externalIdValue = String(record[externalId] ?? '');\n if (externalIdValue) {\n insertedRecords.get(objectName)!.set(externalIdValue, `dry-run-id-${i}`);\n }\n inserted++; // Count as \"would be inserted\"\n }\n }\n\n return {\n object: objectName,\n mode,\n inserted,\n updated,\n skipped,\n errored,\n total: dataset.records.length,\n referencesResolved,\n referencesDeferred,\n errors,\n };\n }\n\n // ==========================================================================\n // Internal: Reference Resolution\n // ==========================================================================\n\n /**\n * Best-effort resolve the tenant's SOLE organization id — used to stamp\n * business seed rows when the caller pinned no `config.organizationId` (an\n * in-process publish has no active user session). A fresh env has exactly one\n * org, so its seeds should carry it like a normal write instead of landing\n * org-less (→ invisible under strict org-scoping). Returns undefined when\n * there are zero or several orgs (genuinely ambiguous — keep the historical\n * global/cross-tenant NULL) or when `sys_organization` is absent.\n */\n private async resolveSoleOrganizationId(): Promise<string | undefined> {\n try {\n const rows = await this.engine.find('sys_organization', {\n fields: ['id'],\n limit: 2,\n context: { isSystem: true },\n } as any);\n if (Array.isArray(rows) && rows.length === 1) {\n const id = (rows[0] as { id?: unknown; _id?: unknown })?.id ?? (rows[0] as { _id?: unknown })?._id;\n return id ? String(id) : undefined;\n }\n } catch {\n // sys_organization may not exist (single-tenant runtime) — ignore.\n }\n return undefined;\n }\n\n private async resolveFromDatabase(\n targetObject: string,\n targetField: string,\n value: unknown,\n organizationId?: string,\n ): Promise<string | null> {\n try {\n const where: Record<string, unknown> = { [targetField]: value };\n // Per-tenant replay: when scoping is requested, only consider\n // rows that belong to the target tenant so cross-tenant rows\n // never get borrowed as a \"resolved\" reference (would silently\n // create a cross-org FK).\n if (organizationId) where.organization_id = organizationId;\n const records = await this.engine.find(targetObject, {\n where,\n fields: ['id'],\n limit: 1,\n context: { isSystem: true },\n } as any);\n if (records && records.length > 0) {\n return String(records[0].id || records[0]._id);\n }\n // Fallback: the value may already be the target's internal id rather than\n // its natural key — a seed that wires a lookup to a real existing record\n // (e.g. a people field → the current user, whose id is not a UUID/ObjectId\n // so `looksLikeInternalId` did not short-circuit). Resolving by id lets a\n // valid id resolve instead of dangling null, with no risk of a false\n // natural-key match (an id either exists or it does not).\n if (targetField !== 'id') {\n const byId: Record<string, unknown> = { id: value };\n if (organizationId) byId.organization_id = organizationId;\n const idMatch = await this.engine.find(targetObject, {\n where: byId,\n fields: ['id'],\n limit: 1,\n context: { isSystem: true },\n } as any);\n if (idMatch && idMatch.length > 0) {\n return String(idMatch[0].id || idMatch[0]._id);\n }\n }\n } catch {\n // Target object may not exist yet\n }\n return null;\n }\n\n private async resolveDeferredUpdates(\n deferredUpdates: DeferredUpdate[],\n insertedRecords: Map<string, Map<string, string>>,\n allResults: SeedLoadResult[],\n allErrors: ReferenceResolutionError[],\n organizationId?: string,\n ): Promise<void> {\n for (const deferred of deferredUpdates) {\n // Try to resolve from inserted records\n const targetMap = insertedRecords.get(deferred.targetObject);\n let resolvedId = targetMap?.get(String(deferred.attemptedValue));\n\n // Try database fallback\n if (!resolvedId) {\n resolvedId = (await this.resolveFromDatabase(\n deferred.targetObject, deferred.targetField, deferred.attemptedValue, organizationId\n )) ?? undefined;\n }\n\n if (resolvedId) {\n // Find the record and update the reference\n const objectRecordMap = insertedRecords.get(deferred.objectName);\n const recordId = objectRecordMap?.get(deferred.recordExternalId);\n\n if (recordId) {\n try {\n await this.engine.update(deferred.objectName, {\n id: recordId,\n [deferred.field]: resolvedId,\n }, { context: { isSystem: true } } as any);\n\n // Update result stats\n const resultEntry = allResults.find(r => r.object === deferred.objectName);\n if (resultEntry) {\n resultEntry.referencesResolved++;\n resultEntry.referencesDeferred--;\n }\n } catch (err: any) {\n this.logger.warn('[SeedLoader] Failed to resolve deferred reference', {\n object: deferred.objectName,\n field: deferred.field,\n error: err.message,\n });\n }\n }\n } else {\n // Still unresolved after pass 2\n const error: ReferenceResolutionError = {\n sourceObject: deferred.objectName,\n field: deferred.field,\n targetObject: deferred.targetObject,\n targetField: deferred.targetField,\n attemptedValue: deferred.attemptedValue,\n recordIndex: deferred.recordIndex,\n message: `Deferred reference unresolved after pass 2: ${deferred.objectName}.${deferred.field} = '${deferred.attemptedValue}' → ${deferred.targetObject}.${deferred.targetField} not found`,\n };\n\n const resultEntry = allResults.find(r => r.object === deferred.objectName);\n if (resultEntry) {\n resultEntry.errors.push(error);\n }\n allErrors.push(error);\n }\n }\n }\n\n // ==========================================================================\n // Internal: Write Operations\n // ==========================================================================\n\n /**\n * Seed writes always run as a privileged system context. This bypasses\n * RBAC checks (so seeds can target system tables like `sys_*`) and\n * disables the SecurityPlugin's auto-injection of `organization_id` /\n * `owner_id` — seeds either declare those fields explicitly per\n * record, or are intentionally cross-tenant / global.\n */\n private static readonly SEED_OPTIONS = { context: { isSystem: true } } as const;\n\n private async writeRecord(\n objectName: string,\n record: Record<string, unknown>,\n mode: string,\n externalId: string,\n existingRecords?: Map<string, any>,\n ): Promise<{ action: 'inserted' | 'updated' | 'skipped'; id?: string }> {\n const externalIdValue = record[externalId];\n const existing = existingRecords?.get(String(externalIdValue ?? ''));\n const opts = SeedLoaderService.SEED_OPTIONS as any;\n\n switch (mode) {\n case 'insert': {\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n\n case 'update': {\n if (!existing) {\n return { action: 'skipped' };\n }\n const id = this.extractId(existing);\n await this.engine.update(objectName, { ...record, id }, opts);\n return { action: 'updated', id };\n }\n\n case 'upsert': {\n if (existing) {\n const id = this.extractId(existing);\n await this.engine.update(objectName, { ...record, id }, opts);\n return { action: 'updated', id };\n } else {\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n }\n\n case 'ignore': {\n if (existing) {\n return { action: 'skipped', id: this.extractId(existing) };\n }\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n\n case 'replace': {\n // Replace mode: just insert (caller should have cleared the table)\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n\n default: {\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n }\n }\n\n // ==========================================================================\n // Internal: Dependency Graph\n // ==========================================================================\n\n /**\n * Kahn's algorithm for topological sort with cycle detection.\n */\n private topologicalSort(\n nodes: ObjectDependencyNode[],\n ): { insertOrder: string[]; circularDependencies: string[][] } {\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n const objectSet = new Set(nodes.map(n => n.object));\n\n // Initialize\n for (const node of nodes) {\n inDegree.set(node.object, 0);\n adjacency.set(node.object, []);\n }\n\n // Build adjacency list and in-degree counts\n for (const node of nodes) {\n for (const dep of node.dependsOn) {\n // Exclude self-references from ordering (e.g., employee.manager_id → employee).\n // Self-referencing fields are still tracked in node.references for resolution.\n if (objectSet.has(dep) && dep !== node.object) {\n adjacency.get(dep)!.push(node.object);\n inDegree.set(node.object, (inDegree.get(node.object) || 0) + 1);\n }\n }\n }\n\n // Kahn's algorithm\n const queue: string[] = [];\n for (const [obj, degree] of inDegree) {\n if (degree === 0) queue.push(obj);\n }\n\n const insertOrder: string[] = [];\n while (queue.length > 0) {\n const current = queue.shift()!;\n insertOrder.push(current);\n\n for (const neighbor of (adjacency.get(current) || [])) {\n const newDegree = (inDegree.get(neighbor) || 0) - 1;\n inDegree.set(neighbor, newDegree);\n if (newDegree === 0) {\n queue.push(neighbor);\n }\n }\n }\n\n // Detect circular dependencies\n const circularDependencies: string[][] = [];\n const remaining = nodes.filter(n => !insertOrder.includes(n.object));\n\n if (remaining.length > 0) {\n // Find cycles using DFS\n const cycles = this.findCycles(remaining);\n circularDependencies.push(...cycles);\n\n // Add remaining objects to insertOrder (they'll need multi-pass)\n for (const node of remaining) {\n if (!insertOrder.includes(node.object)) {\n insertOrder.push(node.object);\n }\n }\n }\n\n return { insertOrder, circularDependencies };\n }\n\n private findCycles(nodes: ObjectDependencyNode[]): string[][] {\n const cycles: string[][] = [];\n const nodeMap = new Map(nodes.map(n => [n.object, n]));\n const visited = new Set<string>();\n const inStack = new Set<string>();\n\n const dfs = (current: string, path: string[]) => {\n if (inStack.has(current)) {\n // Found a cycle\n const cycleStart = path.indexOf(current);\n if (cycleStart !== -1) {\n cycles.push([...path.slice(cycleStart), current]);\n }\n return;\n }\n if (visited.has(current)) return;\n\n visited.add(current);\n inStack.add(current);\n path.push(current);\n\n const node = nodeMap.get(current);\n if (node) {\n for (const dep of node.dependsOn) {\n if (nodeMap.has(dep)) {\n dfs(dep, [...path]);\n }\n }\n }\n\n inStack.delete(current);\n };\n\n for (const node of nodes) {\n if (!visited.has(node.object)) {\n dfs(node.object, []);\n }\n }\n\n return cycles;\n }\n\n // ==========================================================================\n // Internal: Helpers\n // ==========================================================================\n\n private filterByEnv(datasets: Seed[], env?: string): Seed[] {\n if (!env) return datasets;\n return datasets.filter(d => (d.env as string[]).includes(env));\n }\n\n private orderDatasets(datasets: Seed[], insertOrder: string[]): Seed[] {\n const orderMap = new Map(insertOrder.map((name, i) => [name, i]));\n return [...datasets].sort((a, b) => {\n const orderA = orderMap.get(a.object) ?? Number.MAX_SAFE_INTEGER;\n const orderB = orderMap.get(b.object) ?? Number.MAX_SAFE_INTEGER;\n return orderA - orderB;\n });\n }\n\n private buildReferenceMap(graph: ObjectDependencyGraph): Map<string, ReferenceResolution[]> {\n const map = new Map<string, ReferenceResolution[]>();\n for (const node of graph.nodes) {\n if (node.references.length > 0) {\n map.set(node.object, node.references);\n }\n }\n return map;\n }\n\n private async loadExistingRecords(\n objectName: string,\n externalId: string,\n organizationId?: string,\n ): Promise<Map<string, any>> {\n const map = new Map<string, any>();\n try {\n const findArgs: Record<string, unknown> = {\n fields: ['id', externalId],\n context: { isSystem: true },\n };\n // Per-tenant replay: restrict to the target tenant's own rows\n // so upsert key matching never returns another tenant's record\n // (would silently steal/overwrite rows across orgs).\n if (organizationId) findArgs.where = { organization_id: organizationId };\n const records = await this.engine.find(objectName, findArgs as any);\n for (const record of records || []) {\n const key = String(record[externalId] ?? '');\n if (key) {\n map.set(key, record);\n }\n }\n } catch {\n // Object may not have records yet\n }\n return map;\n }\n\n private looksLikeInternalId(value: string): boolean {\n // UUID v4 pattern\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)) {\n return true;\n }\n // MongoDB ObjectId pattern (24 hex chars)\n if (/^[0-9a-f]{24}$/i.test(value)) {\n return true;\n }\n return false;\n }\n\n private extractId(record: any): string | undefined {\n if (!record) return undefined;\n return String(record.id || record._id || '');\n }\n\n private buildEmptyResult(config: SeedLoaderConfig, durationMs: number): SeedLoaderResult {\n return {\n success: true,\n dryRun: config.dryRun,\n dependencyGraph: { nodes: [], insertOrder: [], circularDependencies: [] },\n results: [],\n errors: [],\n summary: {\n objectsProcessed: 0,\n totalRecords: 0,\n totalInserted: 0,\n totalUpdated: 0,\n totalSkipped: 0,\n totalErrored: 0,\n totalReferencesResolved: 0,\n totalReferencesDeferred: 0,\n circularDependencyCount: 0,\n durationMs,\n },\n };\n }\n\n private buildResult(\n config: SeedLoaderConfig,\n graph: ObjectDependencyGraph,\n results: SeedLoadResult[],\n errors: ReferenceResolutionError[],\n durationMs: number,\n ): SeedLoaderResult {\n const summary = {\n objectsProcessed: results.length,\n totalRecords: results.reduce((sum, r) => sum + r.total, 0),\n totalInserted: results.reduce((sum, r) => sum + r.inserted, 0),\n totalUpdated: results.reduce((sum, r) => sum + r.updated, 0),\n totalSkipped: results.reduce((sum, r) => sum + r.skipped, 0),\n totalErrored: results.reduce((sum, r) => sum + r.errored, 0),\n totalReferencesResolved: results.reduce((sum, r) => sum + r.referencesResolved, 0),\n totalReferencesDeferred: results.reduce((sum, r) => sum + r.referencesDeferred, 0),\n circularDependencyCount: graph.circularDependencies.length,\n durationMs,\n };\n\n const hasErrors = errors.length > 0 || summary.totalErrored > 0;\n\n return {\n success: !hasErrors,\n dryRun: config.dryRun,\n dependencyGraph: graph,\n results,\n errors,\n summary,\n };\n }\n}\n\n// ==========================================================================\n// Internal Types\n// ==========================================================================\n\ninterface DeferredUpdate {\n objectName: string;\n recordExternalId: string;\n field: string;\n targetObject: string;\n targetField: string;\n attemptedValue: unknown;\n recordIndex: number;\n}\n"]}
@@ -0,0 +1,161 @@
1
+ // src/build-probes.ts
2
+ function asRec(v) {
3
+ return v && typeof v === "object" && !Array.isArray(v) ? v : void 0;
4
+ }
5
+ function asArr(v) {
6
+ return Array.isArray(v) ? v : [];
7
+ }
8
+ function resultRows(result) {
9
+ if (Array.isArray(result)) return result;
10
+ const r = asRec(result);
11
+ if (!r) return [];
12
+ if (Array.isArray(r.rows)) return r.rows;
13
+ if (Array.isArray(r.data)) return r.data;
14
+ return [];
15
+ }
16
+ async function hasRows(engine, objectName, organizationId) {
17
+ const rows = await engine.find(objectName, {
18
+ fields: ["id"],
19
+ limit: 1,
20
+ ...organizationId ? { where: { organization_id: organizationId } } : {},
21
+ context: { isSystem: true }
22
+ });
23
+ return Array.isArray(rows) && rows.length > 0;
24
+ }
25
+ async function runBuildProbes(opts) {
26
+ const issues = [];
27
+ const checked = { seeds: 0, views: 0, widgets: 0 };
28
+ const { engine, getItem, published, analytics, organizationId } = opts;
29
+ const itemCache = /* @__PURE__ */ new Map();
30
+ const readItem = async (type, name) => {
31
+ const key = `${type} ${name}`;
32
+ if (itemCache.has(key)) return itemCache.get(key);
33
+ let item;
34
+ try {
35
+ item = await getItem(type, name);
36
+ } catch {
37
+ item = void 0;
38
+ }
39
+ itemCache.set(key, item);
40
+ return item;
41
+ };
42
+ for (const p of published.filter((x) => x.type === "seed")) {
43
+ const body = asRec(await readItem("seed", p.name));
44
+ const objectName = typeof body?.object === "string" ? body.object : void 0;
45
+ if (!objectName) continue;
46
+ checked.seeds += 1;
47
+ try {
48
+ if (!await hasRows(engine, objectName, organizationId)) {
49
+ issues.push({
50
+ layer: "runtime",
51
+ severity: "error",
52
+ artifact: { type: "seed", name: p.name },
53
+ ref: { type: "object", name: objectName },
54
+ code: "seed_not_applied",
55
+ message: `Seed "${p.name}" was published but object "${objectName}" has no rows \u2014 the sample data never materialized.`,
56
+ fix: `Check the publish response's seedApplied for the load error, fix the seed rows (field names/types), and republish the seed.`
57
+ });
58
+ }
59
+ } catch (e) {
60
+ issues.push({
61
+ layer: "runtime",
62
+ severity: "error",
63
+ artifact: { type: "seed", name: p.name },
64
+ ref: { type: "object", name: objectName },
65
+ code: "seed_not_applied",
66
+ message: `Seed "${p.name}" probe could not read object "${objectName}": ${String(e?.message ?? e)}`
67
+ });
68
+ }
69
+ }
70
+ for (const p of published.filter((x) => x.type === "view")) {
71
+ const body = asRec(await readItem("view", p.name));
72
+ const config = asRec(body?.config);
73
+ const dataObj = asRec(config?.data)?.object;
74
+ const objectName = typeof body?.object === "string" ? body.object : typeof dataObj === "string" ? dataObj : void 0;
75
+ if (!objectName) continue;
76
+ checked.views += 1;
77
+ try {
78
+ await engine.find(objectName, {
79
+ fields: ["id"],
80
+ limit: 1,
81
+ ...organizationId ? { where: { organization_id: organizationId } } : {},
82
+ context: { isSystem: true }
83
+ });
84
+ } catch (e) {
85
+ issues.push({
86
+ layer: "runtime",
87
+ severity: "error",
88
+ artifact: { type: "view", name: p.name },
89
+ ref: { type: "object", name: objectName },
90
+ code: "view_read_failed",
91
+ message: `View "${p.name}" cannot read object "${objectName}": ${String(e?.message ?? e)} \u2014 it will render as an error for every user.`,
92
+ fix: `Verify object "${objectName}" published successfully (its table must exist) and that the view's binding is correct.`
93
+ });
94
+ }
95
+ }
96
+ const dashboards = published.filter((x) => x.type === "dashboard");
97
+ let widgetsToProbe = 0;
98
+ for (const p of dashboards) {
99
+ const body = asRec(await readItem("dashboard", p.name));
100
+ const widgets = asArr(body?.widgets).map(asRec).filter((w) => !!w);
101
+ const datasetBound = widgets.filter((w) => typeof w.dataset === "string" && w.dataset);
102
+ widgetsToProbe += datasetBound.length;
103
+ if (!analytics || typeof analytics.queryDataset !== "function") continue;
104
+ for (const w of datasetBound) {
105
+ const widgetId = String(w.id ?? w.title ?? "?");
106
+ const dsName = w.dataset;
107
+ const dataset = asRec(await readItem("dataset", dsName));
108
+ if (!dataset) continue;
109
+ checked.widgets += 1;
110
+ const measures = asArr(w.values).filter((v) => typeof v === "string" && v.length > 0);
111
+ const firstMeasure = asRec(asArr(dataset.measures)[0])?.name;
112
+ const selection = {
113
+ measures: measures.length ? measures : typeof firstMeasure === "string" ? [firstMeasure] : [],
114
+ dimensions: [],
115
+ limit: 1
116
+ };
117
+ if (selection.measures.length === 0) continue;
118
+ const objectName = typeof dataset.object === "string" ? dataset.object : void 0;
119
+ try {
120
+ const result = await analytics.queryDataset(dataset, selection, void 0);
121
+ const rows = resultRows(result);
122
+ if (rows.length === 0 && objectName && await hasRows(engine, objectName, organizationId)) {
123
+ issues.push({
124
+ layer: "runtime",
125
+ severity: "error",
126
+ artifact: { type: "dashboard", name: p.name },
127
+ ref: { type: "dataset", name: dsName, member: widgetId },
128
+ code: "empty_query",
129
+ message: `Dashboard "${p.name}" widget "${widgetId}" returns NO data from dataset "${dsName}" although object "${objectName}" has rows \u2014 the widget will render empty for every user.`,
130
+ fix: `Run the dataset query directly to see the compiled strategy/SQL; check the dataset's measure/dimension field bindings against object "${objectName}".`
131
+ });
132
+ }
133
+ } catch (e) {
134
+ issues.push({
135
+ layer: "runtime",
136
+ severity: "error",
137
+ artifact: { type: "dashboard", name: p.name },
138
+ ref: { type: "dataset", name: dsName, member: widgetId },
139
+ code: "widget_query_failed",
140
+ message: `Dashboard "${p.name}" widget "${widgetId}" query against dataset "${dsName}" failed: ${String(e?.message ?? e)}`,
141
+ fix: `Fix the dataset definition (or the widget's values/dimensions) so the query compiles, then republish.`
142
+ });
143
+ }
144
+ }
145
+ }
146
+ if (widgetsToProbe > 0 && (!analytics || typeof analytics.queryDataset !== "function")) {
147
+ issues.push({
148
+ layer: "runtime",
149
+ severity: "warning",
150
+ artifact: { type: "dashboard", name: dashboards.map((d) => d.name).join(", ") },
151
+ code: "probes_unavailable",
152
+ message: `${widgetsToProbe} dashboard widget(s) could not be probed: no analytics service is mounted on this kernel.`
153
+ });
154
+ }
155
+ return { issues, checked };
156
+ }
157
+
158
+ export {
159
+ runBuildProbes
160
+ };
161
+ //# sourceMappingURL=chunk-KJGVCNUC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/build-probes.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n//\n// ADR-0038 L3 — runtime probes: after a publish, exercise the published app\n// the way a user would (one real read per artifact) and report what is\n// actually broken AT RUNTIME. Schema-valid ≠ renders ≠ returns data: the\n// 2026-06-10/11 incident set shipped seeds that never materialized, dataset\n// queries that returned 0 on populated objects, and \"Published!\" states the\n// runtime couldn't read back — all invisible until something actually\n// queried. These probes are that something, run by the build pipeline (not\n// the user), generalizing the `seedApplied` pattern to the whole artifact\n// graph.\n//\n// Every finding is a BuildIssue (the ADR-0038 verification contract — same\n// shape the cloud L1 graph lint emits) with `layer: 'runtime'`, so agents,\n// chat surfaces, and eval harnesses consume one stream regardless of which\n// verification plane found the problem.\n\n/** One runtime-verification finding (ADR-0038 BuildIssue, layer 'runtime'). */\nexport interface RuntimeBuildIssue {\n layer: 'runtime';\n severity: 'error' | 'warning';\n /** The artifact whose runtime behaviour is broken. */\n artifact: { type: string; name: string };\n /** What it exercised, when narrower than the artifact (e.g. a widget). */\n ref?: { type: string; name: string; member?: string };\n /** 'seed_not_applied' | 'view_read_failed' | 'empty_query' | 'widget_query_failed' | 'probes_unavailable' */\n code: string;\n message: string;\n fix?: string;\n}\n\n/** Aggregate result of one post-publish probe pass. */\nexport interface BuildProbeReport {\n /** Findings, empty when every probe passed. */\n issues: RuntimeBuildIssue[];\n /** How many probes actually ran, per plane (0s mean nothing to probe). */\n checked: { seeds: number; views: number; widgets: number };\n}\n\n/** The single read the probes need from the data engine. */\nexport interface ProbeEngine {\n find(objectName: string, query: unknown): Promise<Array<Record<string, unknown>>>;\n}\n\n/** Optional analytics surface — when absent, widget probes degrade to a warning. */\nexport interface ProbeAnalytics {\n queryDataset(dataset: unknown, selection: unknown, context?: unknown): Promise<unknown>;\n}\n\nexport interface RunBuildProbesOptions {\n engine: ProbeEngine;\n /** Read an ACTIVE (published) item body by type+name; undefined when absent. */\n getItem: (type: string, name: string) => Promise<unknown | undefined>;\n /** The just-published artifact set (publishPackageDrafts' `published`). */\n published: Array<{ type: string; name: string }>;\n /**\n * The kernel's analytics service, when one is mounted. Widget probes run\n * the SAME `queryDataset` path the dashboard renderer hits — absent\n * service means widgets can't be probed (one aggregate warning, not\n * per-widget noise).\n */\n analytics?: ProbeAnalytics;\n /** Threaded into engine/analytics reads (tenant scoping). */\n organizationId?: string | null;\n}\n\ntype Rec = Record<string, unknown>;\n\nfunction asRec(v: unknown): Rec | undefined {\n return v && typeof v === 'object' && !Array.isArray(v) ? (v as Rec) : undefined;\n}\n\nfunction asArr(v: unknown): unknown[] {\n return Array.isArray(v) ? v : [];\n}\n\n/** Result rows of a queryDataset call, tolerant of {rows}/{data}/array shapes. */\nfunction resultRows(result: unknown): unknown[] {\n if (Array.isArray(result)) return result;\n const r = asRec(result);\n if (!r) return [];\n if (Array.isArray(r.rows)) return r.rows;\n if (Array.isArray(r.data)) return r.data;\n return [];\n}\n\n/** True when the object has at least one row (probe read, isSystem). */\nasync function hasRows(\n engine: ProbeEngine,\n objectName: string,\n organizationId?: string | null,\n): Promise<boolean> {\n const rows = await engine.find(objectName, {\n fields: ['id'],\n limit: 1,\n ...(organizationId ? { where: { organization_id: organizationId } } : {}),\n context: { isSystem: true },\n });\n return Array.isArray(rows) && rows.length > 0;\n}\n\n/**\n * Run the L3 runtime probes over a just-published artifact set:\n *\n * • per published `seed` — its target object must have rows now\n * (`seed_not_applied`: the rows were promised but never materialized);\n * • per published `view` — a limit-1 read through the same engine the\n * renderer uses must not throw (`view_read_failed`);\n * • per published `dashboard` widget — its real dataset selection must\n * execute (`widget_query_failed`) and must not return empty on an object\n * that HAS rows (`empty_query` — the four-layer staging incident class).\n *\n * All probes are reads (limit-1 / single aggregate); a probe crash is\n * reported, never thrown — verification must not break the publish it\n * verifies.\n */\nexport async function runBuildProbes(opts: RunBuildProbesOptions): Promise<BuildProbeReport> {\n const issues: RuntimeBuildIssue[] = [];\n const checked = { seeds: 0, views: 0, widgets: 0 };\n const { engine, getItem, published, analytics, organizationId } = opts;\n\n // Memoized active-item reads (a dashboard and its widgets share datasets).\n const itemCache = new Map<string, unknown | undefined>();\n const readItem = async (type: string, name: string): Promise<unknown | undefined> => {\n const key = `${type} ${name}`;\n if (itemCache.has(key)) return itemCache.get(key);\n let item: unknown | undefined;\n try {\n item = await getItem(type, name);\n } catch {\n item = undefined;\n }\n itemCache.set(key, item);\n return item;\n };\n\n // ── Seeds: rows must exist after publish ────────────────────────────────\n for (const p of published.filter((x) => x.type === 'seed')) {\n const body = asRec(await readItem('seed', p.name));\n const objectName = typeof body?.object === 'string' ? body.object : undefined;\n if (!objectName) continue;\n checked.seeds += 1;\n try {\n if (!(await hasRows(engine, objectName, organizationId))) {\n issues.push({\n layer: 'runtime',\n severity: 'error',\n artifact: { type: 'seed', name: p.name },\n ref: { type: 'object', name: objectName },\n code: 'seed_not_applied',\n message: `Seed \"${p.name}\" was published but object \"${objectName}\" has no rows — the sample data never materialized.`,\n fix: `Check the publish response's seedApplied for the load error, fix the seed rows (field names/types), and republish the seed.`,\n });\n }\n } catch (e) {\n issues.push({\n layer: 'runtime',\n severity: 'error',\n artifact: { type: 'seed', name: p.name },\n ref: { type: 'object', name: objectName },\n code: 'seed_not_applied',\n message: `Seed \"${p.name}\" probe could not read object \"${objectName}\": ${String((e as Error)?.message ?? e)}`,\n });\n }\n }\n\n // ── Views: the renderer's read path must not throw ──────────────────────\n for (const p of published.filter((x) => x.type === 'view')) {\n const body = asRec(await readItem('view', p.name));\n const config = asRec(body?.config);\n const dataObj = asRec(config?.data)?.object;\n const objectName =\n typeof body?.object === 'string' ? body.object\n : typeof dataObj === 'string' ? dataObj\n : undefined;\n if (!objectName) continue;\n checked.views += 1;\n try {\n await engine.find(objectName, {\n fields: ['id'],\n limit: 1,\n ...(organizationId ? { where: { organization_id: organizationId } } : {}),\n context: { isSystem: true },\n });\n } catch (e) {\n issues.push({\n layer: 'runtime',\n severity: 'error',\n artifact: { type: 'view', name: p.name },\n ref: { type: 'object', name: objectName },\n code: 'view_read_failed',\n message: `View \"${p.name}\" cannot read object \"${objectName}\": ${String((e as Error)?.message ?? e)} — it will render as an error for every user.`,\n fix: `Verify object \"${objectName}\" published successfully (its table must exist) and that the view's binding is correct.`,\n });\n }\n }\n\n // ── Dashboard widgets: the real dataset selection must return data ──────\n const dashboards = published.filter((x) => x.type === 'dashboard');\n let widgetsToProbe = 0;\n for (const p of dashboards) {\n const body = asRec(await readItem('dashboard', p.name));\n const widgets = asArr(body?.widgets).map(asRec).filter((w): w is Rec => !!w);\n const datasetBound = widgets.filter((w) => typeof w.dataset === 'string' && w.dataset);\n widgetsToProbe += datasetBound.length;\n if (!analytics || typeof analytics.queryDataset !== 'function') continue;\n\n for (const w of datasetBound) {\n const widgetId = String(w.id ?? w.title ?? '?');\n const dsName = w.dataset as string;\n const dataset = asRec(await readItem('dataset', dsName));\n if (!dataset) continue; // dangling dataset is an L1 (graph) finding, not a runtime one\n checked.widgets += 1;\n\n // The widget's own selection when present, else the dataset's\n // first measure — the same default the renderer falls back to.\n const measures = asArr(w.values).filter((v): v is string => typeof v === 'string' && v.length > 0);\n const firstMeasure = asRec(asArr(dataset.measures)[0])?.name;\n const selection = {\n measures: measures.length ? measures : typeof firstMeasure === 'string' ? [firstMeasure] : [],\n dimensions: [],\n limit: 1,\n };\n if (selection.measures.length === 0) continue; // nothing selectable — schema/graph problem\n\n const objectName = typeof dataset.object === 'string' ? dataset.object : undefined;\n try {\n const result = await analytics.queryDataset(dataset, selection, undefined);\n const rows = resultRows(result);\n if (rows.length === 0 && objectName && (await hasRows(engine, objectName, organizationId))) {\n issues.push({\n layer: 'runtime',\n severity: 'error',\n artifact: { type: 'dashboard', name: p.name },\n ref: { type: 'dataset', name: dsName, member: widgetId },\n code: 'empty_query',\n message: `Dashboard \"${p.name}\" widget \"${widgetId}\" returns NO data from dataset \"${dsName}\" although object \"${objectName}\" has rows — the widget will render empty for every user.`,\n fix: `Run the dataset query directly to see the compiled strategy/SQL; check the dataset's measure/dimension field bindings against object \"${objectName}\".`,\n });\n }\n } catch (e) {\n issues.push({\n layer: 'runtime',\n severity: 'error',\n artifact: { type: 'dashboard', name: p.name },\n ref: { type: 'dataset', name: dsName, member: widgetId },\n code: 'widget_query_failed',\n message: `Dashboard \"${p.name}\" widget \"${widgetId}\" query against dataset \"${dsName}\" failed: ${String((e as Error)?.message ?? e)}`,\n fix: `Fix the dataset definition (or the widget's values/dimensions) so the query compiles, then republish.`,\n });\n }\n }\n }\n\n // Widgets existed but no analytics service was mounted — say so ONCE\n // (silence would read as \"probed and passed\", which it was not).\n if (widgetsToProbe > 0 && (!analytics || typeof analytics.queryDataset !== 'function')) {\n issues.push({\n layer: 'runtime',\n severity: 'warning',\n artifact: { type: 'dashboard', name: dashboards.map((d) => d.name).join(', ') },\n code: 'probes_unavailable',\n message: `${widgetsToProbe} dashboard widget(s) could not be probed: no analytics service is mounted on this kernel.`,\n });\n }\n\n return { issues, checked };\n}\n"],"mappings":"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","names":[]}