Skip to content

feat: add missing service contract interfaces for all CoreServiceName services#600

Merged
hotlong merged 2 commits into
mainfrom
copilot/evaluate-service-standards
Feb 11, 2026
Merged

feat: add missing service contract interfaces for all CoreServiceName services#600
hotlong merged 2 commits into
mainfrom
copilot/evaluate-service-standards

Conversation

Copilot AI commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

CoreServiceName defines 17 service identifiers but only 6 had contract interfaces. This PR closes the gap by adding the 11 missing contracts.

New contracts

  • IMetadataService — register/get/list/unregister metadata by type, convenience methods for objects (aligned with MetadataFacade)
  • IAuthServicehandleRequest(Request), verify(token), optional logout/getCurrentUser
  • IAutomationServiceexecute(flowName, context), listFlows(), optional register/unregister
  • IGraphQLServiceexecute(GraphQLRequest), optional handleRequest/getSchema
  • IAnalyticsServicequery(AnalyticsQuery), getMeta(), optional generateSql dry-run
  • IRealtimeService — pub/sub with publish(event), subscribe(channel, handler), unsubscribe(id)
  • IJobServiceschedule(name, schedule, handler), cancel, trigger, optional execution history
  • IAIServicechat(messages), complete(prompt), optional embed/listModels
  • II18nServicet(key, locale), loadTranslations, getLocales, optional default locale
  • IUIServicegetView/listViews, optional dashboard CRUD
  • IWorkflowServicetransition(WorkflowTransition), getStatus, optional getHistory

Coverage after this change

CoreServiceName Contract
metadata IMetadataService ✅ new
data IDataEngine (existed)
auth IAuthService ✅ new
cache ICacheService (existed)
search ISearchService (existed)
queue IQueueService (existed)
file-storage IStorageService (existed)
notification INotificationService (existed)
automation IAutomationService ✅ new
graphql IGraphQLService ✅ new
analytics IAnalyticsService ✅ new
realtime IRealtimeService ✅ new
job IJobService ✅ new
ai IAIService ✅ new
i18n II18nService ✅ new
ui IUIService ✅ new
workflow IWorkflowService ✅ new

All contracts follow the established pattern: TypeScript interfaces in src/contracts/ with co-located .test.ts files, exported via barrel. 168 test files / 4312 tests pass.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@vercel

vercel Bot commented Feb 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectstack-play Ready Ready Preview, Comment Feb 11, 2026 3:26am
spec Error Error Feb 11, 2026 3:26am

Request Review

… services

Add 11 new contract interfaces with co-located tests:
- IMetadataService (metadata)
- IAuthService (auth)
- IAutomationService (automation)
- IGraphQLService (graphql)
- IAnalyticsService (analytics)
- IRealtimeService (realtime)
- IJobService (job)
- IAIService (ai)
- II18nService (i18n)
- IUIService (ui)
- IWorkflowService (workflow)

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Evaluate service identifiers against standard specifications feat: add missing service contract interfaces for all CoreServiceName services Feb 11, 2026
Copilot AI requested a review from hotlong February 11, 2026 02:47
@hotlong
hotlong marked this pull request as ready for review February 11, 2026 02:50
Copilot AI review requested due to automatic review settings February 11, 2026 02:50
@hotlong
hotlong merged commit 33646a7 into main Feb 11, 2026
1 of 3 checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the remaining missing CoreServiceName service contract interfaces to @objectstack/spec, completing the set of core service contracts so plugins/adapters can depend on stable, centralized interfaces.

Changes:

  • Introduces 11 new service contract interfaces under packages/spec/src/contracts/ (metadata/auth/automation/graphql/analytics/realtime/job/ai/i18n/ui/workflow).
  • Adds co-located Vitest contract tests for each new interface to validate “minimal vs full” implementations.
  • Updates the contracts barrel export (packages/spec/src/contracts/index.ts) to export the new contracts.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/spec/src/contracts/index.ts Exports the newly added contract modules from the contracts barrel.
packages/spec/src/contracts/metadata-service.ts Defines IMetadataService contract (register/get/list/unregister + object conveniences).
packages/spec/src/contracts/metadata-service.test.ts Contract tests for IMetadataService.
packages/spec/src/contracts/auth-service.ts Defines IAuthService contract and related auth/session types.
packages/spec/src/contracts/auth-service.test.ts Contract tests for IAuthService.
packages/spec/src/contracts/automation-service.ts Defines IAutomationService contract and execution context/result types.
packages/spec/src/contracts/automation-service.test.ts Contract tests for IAutomationService.
packages/spec/src/contracts/graphql-service.ts Defines IGraphQLService contract and GraphQL request/response types.
packages/spec/src/contracts/graphql-service.test.ts Contract tests for IGraphQLService.
packages/spec/src/contracts/analytics-service.ts Defines IAnalyticsService contract and analytics query/result/meta types.
packages/spec/src/contracts/analytics-service.test.ts Contract tests for IAnalyticsService.
packages/spec/src/contracts/realtime-service.ts Defines IRealtimeService pub/sub contract and event/subscription types.
packages/spec/src/contracts/realtime-service.test.ts Contract tests for IRealtimeService.
packages/spec/src/contracts/job-service.ts Defines IJobService contract and job scheduling/execution types.
packages/spec/src/contracts/job-service.test.ts Contract tests for IJobService.
packages/spec/src/contracts/ai-service.ts Defines IAIService contract and chat/completion/options/result types.
packages/spec/src/contracts/ai-service.test.ts Contract tests for IAIService.
packages/spec/src/contracts/i18n-service.ts Defines II18nService translation/locale management contract.
packages/spec/src/contracts/i18n-service.test.ts Contract tests for II18nService.
packages/spec/src/contracts/ui-service.ts Defines IUIService contract for view/dashboard access and optional registration.
packages/spec/src/contracts/ui-service.test.ts Contract tests for IUIService.
packages/spec/src/contracts/workflow-service.ts Defines IWorkflowService contract and workflow transition/status types.
packages/spec/src/contracts/workflow-service.test.ts Contract tests for IWorkflowService.

Comment on lines +61 to +63
* @param packageName - The package name whose items should be removed
*/
unregisterPackage?(packageName: string): void;

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unregisterPackage’s parameter/documentation calls this a packageName, but the underlying registry/facade APIs treat this value as a package identifier (e.g. com.pkg). Renaming the parameter/docs to packageId (and being explicit about the expected format) would avoid confusing it with a human-readable package name.

Suggested change
* @param packageName - The package name whose items should be removed
*/
unregisterPackage?(packageName: string): void;
* @param packageId - The package identifier (e.g. 'com.pkg') whose items should be removed
*/
unregisterPackage?(packageId: string): void;

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +23
export interface JobSchedule {
/** Schedule type */
type: 'cron' | 'interval' | 'once';
/** Cron expression (when type is 'cron') */
expression?: string;

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JobSchedule currently allows invalid combinations (e.g. type: 'cron' without expression, or type: 'interval' without intervalMs). Consider changing this to a discriminated union keyed by type so TypeScript enforces the required fields for each schedule kind.

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +56
export interface IUIService {
/**
* Get a view definition by name
* @param name - View name (snake_case)
* @returns View definition, or undefined if not found
*/
getView(name: string): unknown | undefined;

/**
* List view definitions, optionally filtered by object
* @param object - Optional object name to filter views for
* @returns Array of view definitions
*/
listViews(object?: string): unknown[];

/**
* Get a dashboard definition by name
* @param name - Dashboard name (snake_case)
* @returns Dashboard definition, or undefined if not found
*/
getDashboard?(name: string): unknown | undefined;

/**
* List all dashboard definitions
* @returns Array of dashboard definitions
*/
listDashboards?(): unknown[];

/**
* Register a view definition
* @param name - View name (snake_case)
* @param definition - View definition object
*/
registerView?(name: string, definition: unknown): void;

/**
* Register a dashboard definition
* @param name - Dashboard name (snake_case)
* @param definition - Dashboard definition object
*/
registerDashboard?(name: string, definition: unknown): void;

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getView/listViews returning unknown loses the type-safety available in @objectstack/spec/ui (e.g. View from ui/view.zod and Dashboard from ui/dashboard.zod). Using those exported types (or a small typed alias) would make the contract more useful for consumers and avoid downstream casting.

Suggested change
export interface IUIService {
/**
* Get a view definition by name
* @param name - View name (snake_case)
* @returns View definition, or undefined if not found
*/
getView(name: string): unknown | undefined;
/**
* List view definitions, optionally filtered by object
* @param object - Optional object name to filter views for
* @returns Array of view definitions
*/
listViews(object?: string): unknown[];
/**
* Get a dashboard definition by name
* @param name - Dashboard name (snake_case)
* @returns Dashboard definition, or undefined if not found
*/
getDashboard?(name: string): unknown | undefined;
/**
* List all dashboard definitions
* @returns Array of dashboard definitions
*/
listDashboards?(): unknown[];
/**
* Register a view definition
* @param name - View name (snake_case)
* @param definition - View definition object
*/
registerView?(name: string, definition: unknown): void;
/**
* Register a dashboard definition
* @param name - Dashboard name (snake_case)
* @param definition - Dashboard definition object
*/
registerDashboard?(name: string, definition: unknown): void;
import type { View } from '../ui/view.zod';
import type { Dashboard } from '../ui/dashboard.zod';
export interface IUIService {
/**
* Get a view definition by name
* @param name - View name (snake_case)
* @returns View definition, or undefined if not found
*/
getView(name: string): View | undefined;
/**
* List view definitions, optionally filtered by object
* @param object - Optional object name to filter views for
* @returns Array of view definitions
*/
listViews(object?: string): View[];
/**
* Get a dashboard definition by name
* @param name - Dashboard name (snake_case)
* @returns Dashboard definition, or undefined if not found
*/
getDashboard?(name: string): Dashboard | undefined;
/**
* List all dashboard definitions
* @returns Array of dashboard definitions
*/
listDashboards?(): Dashboard[];
/**
* Register a view definition
* @param name - View name (snake_case)
* @param definition - View definition object
*/
registerView?(name: string, definition: View): void;
/**
* Register a dashboard definition
* @param name - Dashboard name (snake_case)
* @param definition - Dashboard definition object
*/
registerDashboard?(name: string, definition: Dashboard): void;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants