Skip to content

Commit e8330d4

Browse files
Copilothotlong
andauthored
fix: address PR review — type-safe protocol access, narrower error handling, canonical app type in tests
Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/0c3ad9ed-acb5-48f4-a9c5-c81bde62ed87 Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 5d4f207 commit e8330d4

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

packages/objectql/src/plugin.integration.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ describe('ObjectQLPlugin - Metadata Service Integration', () => {
838838
return [
839839
{
840840
id: '1',
841-
type: 'app',
841+
type: 'apps',
842842
name: 'custom_crm',
843843
state: 'active',
844844
metadata: JSON.stringify({ name: 'custom_crm', label: 'Custom CRM' }),
@@ -888,7 +888,7 @@ describe('ObjectQLPlugin - Metadata Service Integration', () => {
888888

889889
// Assert — items should be restored into the registry
890890
const registry = (kernel.getService('objectql') as any).registry;
891-
expect(registry.getItem('app', 'custom_crm')).toEqual({
891+
expect(registry.getAllApps()).toContainEqual({
892892
name: 'custom_crm',
893893
label: 'Custom CRM',
894894
});

packages/objectql/src/plugin.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,25 @@ import { Plugin, PluginContext } from '@objectstack/core';
66

77
export type { Plugin, PluginContext };
88

9+
/**
10+
* Protocol extension for DB-based metadata hydration.
11+
* `loadMetaFromDb` is implemented by ObjectStackProtocolImplementation but
12+
* is NOT (yet) part of the canonical ObjectStackProtocol wire-contract in
13+
* `@objectstack/spec`, since it is a server-side bootstrap concern only.
14+
*/
15+
interface ProtocolWithDbRestore {
16+
loadMetaFromDb(): Promise<{ loaded: number; errors: number }>;
17+
}
18+
19+
/** Type guard — checks whether the service exposes `loadMetaFromDb`. */
20+
function hasLoadMetaFromDb(service: unknown): service is ProtocolWithDbRestore {
21+
return (
22+
typeof service === 'object' &&
23+
service !== null &&
24+
typeof (service as Record<string, unknown>)['loadMetaFromDb'] === 'function'
25+
);
26+
}
27+
928
export class ObjectQLPlugin implements Plugin {
1029
name = 'com.objectstack.engine.objectql';
1130
type = 'objectql';
@@ -352,13 +371,24 @@ export class ObjectQLPlugin implements Plugin {
352371
* - The underlying driver/table does not exist yet (first-run scenario).
353372
*/
354373
private async restoreMetadataFromDb(ctx: PluginContext): Promise<void> {
374+
// Phase 1: Resolve protocol service (separate from DB I/O for clearer diagnostics)
375+
let protocol: ProtocolWithDbRestore;
355376
try {
356-
const protocol = ctx.getService('protocol') as any;
357-
if (!protocol || typeof protocol.loadMetaFromDb !== 'function') {
377+
const service = ctx.getService('protocol');
378+
if (!service || !hasLoadMetaFromDb(service)) {
358379
ctx.logger.debug('Protocol service does not support loadMetaFromDb, skipping DB restore');
359380
return;
360381
}
382+
protocol = service;
383+
} catch (e: unknown) {
384+
ctx.logger.debug('Protocol service unavailable, skipping DB restore', {
385+
error: e instanceof Error ? e.message : String(e),
386+
});
387+
return;
388+
}
361389

390+
// Phase 2: DB hydration
391+
try {
362392
const { loaded, errors } = await protocol.loadMetaFromDb();
363393

364394
if (loaded > 0 || errors > 0) {
@@ -368,7 +398,7 @@ export class ObjectQLPlugin implements Plugin {
368398
}
369399
} catch (e: unknown) {
370400
// Non-fatal: first-run or in-memory driver may not have sys_metadata yet
371-
ctx.logger.debug('DB metadata restore skipped (non-fatal)', {
401+
ctx.logger.debug('DB metadata restore failed (non-fatal)', {
372402
error: e instanceof Error ? e.message : String(e),
373403
});
374404
}

0 commit comments

Comments
 (0)