Skip to content

Latest commit

 

History

History
434 lines (334 loc) · 18.4 KB

File metadata and controls

434 lines (334 loc) · 18.4 KB
title Kernel Services Checklist
description Complete inventory of ObjectStack kernel services with protocol methods, implementation status, and development requirements.

Kernel Services Checklist

**This checklist is out of date.** It predates several packages that have since shipped — SQL and MongoDB drivers, automation, realtime, storage, and more (see [Plugins & Packages](/docs/plugins/packages) for the current catalog). Keep it for the protocol-method inventory; treat the per-service status columns as historical until this page is regenerated.

The ObjectStack protocol defines 17 kernel services registered via the CoreServiceName enum. Each service maps to a set of protocol methods (57 total), governed by the ObjectStackProtocol interface.

Key architecture principle: The kernel itself only provides data and metadata (framework). Everything else — including auth and automation — is delivered by plugins. The current @objectstack/objectql package is an example kernel implementation to get the basic API running; production kernels will be rebuilt as new plugins.

**Last Updated**: February 2026
  • ✅ Implemented — 18 protocol methods (kernel-provided)
  • ⚠️ Framework — metadata (in-memory registry, DB persistence pending)
  • 🟡 In Development — auth (plugin structure complete, logic planned)
  • ❌ Plugin Required — 38 protocol methods (to be delivered by plugins)

Architecture Overview

┌─────────────────────────────────────────────────────────┐
│                     Kernel Layer                         │
│  ┌──────────────────┐  ┌──────────────────────────────┐ │
│  │  metadata (⚠️)   │  │  data + analytics (✅)       │ │
│  │  In-memory only   │  │  ObjectQL example kernel     │ │
│  │  DB persistence   │  │  Will be rebuilt as plugins  │ │
│  │  pending          │  │                              │ │
│  └──────────────────┘  └──────────────────────────────┘ │
├─────────────────────────────────────────────────────────┤
│                    Plugin Layer                           │
│  All other services: auth, automation, workflow, ui,     │
│  realtime, notification, ai, i18n, graphql, search,     │
│  file-storage, cache, queue, job                         │
│                                                          │
│  Discovery API reports: enabled/unavailable/degraded     │
│  per service so clients adapt their UI accordingly       │
└─────────────────────────────────────────────────────────┘

Service Overview

# Service Name Criticality Methods Status Provider
1 metadata core 7 ⚠️ Framework Kernel (in-memory)
2 data required 9 ✅ Implemented @objectstack/objectql
3 analytics optional 2 ✅ Implemented @objectstack/objectql
4 auth core 🟡 In Development @objectstack/plugin-auth
5 ui optional 5 ❌ Plugin Required TBD plugin
6 workflow optional 3 ❌ Plugin Required TBD plugin
7 automation optional 1 ❌ Plugin Required TBD plugin
8 realtime optional 6 ❌ Plugin Required TBD plugin
9 notification optional 7 ❌ Plugin Required TBD plugin
10 ai optional 3 ❌ Plugin Required TBD plugin
11 i18n core 3 ✅ Built-in (in-memory fallback) @objectstack/service-i18n
12 file-storage optional ❌ Plugin Required TBD plugin
13 search optional ❌ Plugin Required TBD plugin
14 cache core ✅ Built-in (in-memory fallback) @objectstack/service-cache
15 queue core ✅ Built-in (in-memory fallback) @objectstack/service-queue
16 job core ✅ Built-in (in-memory fallback) @objectstack/service-job
17 graphql optional ❌ Plugin Required TBD plugin
**Criticality Levels** - **required**: System cannot start without this service - **core**: Falls back to in-memory implementation with a warning if missing - **optional**: Feature disabled; API returns `501 Not Implemented` if missing

1. metadata Service ⚠️ Framework

Service Name: metadata · Criticality: core
Implementation: Kernel — SchemaRegistry (in-memory)
Route Mounts: /api/v1/meta, /api/v1, /api/v1/packages

Protocol Methods

Method Signature Status
getDiscovery GetDiscoveryRequest → GetDiscoveryResponse
getMetaTypes GetMetaTypesRequest → GetMetaTypesResponse
getMetaItems GetMetaItemsRequest → GetMetaItemsResponse
getMetaItem GetMetaItemRequest → GetMetaItemResponse
saveMetaItem SaveMetaItemRequest → SaveMetaItemResponse
getMetaItemCached GetMetaItemCachedRequest → GetMetaItemCachedResponse
getUiView GetUiViewRequest → GetUiViewResponse

Current Limitations

The metadata service is a framework — it works with an in-memory SchemaRegistry loaded from YAML/TS config files at startup.

Gap Description Priority
DB Persistence Metadata is only in memory; no save-to-database path exists P0
Multi-instance Sync No mechanism to share metadata changes across instances P1
Migration / Versioning No schema diff or migration tooling P1
Hot Reload Metadata changes require restart P2

Discovery: Per-Service Status

The discovery endpoint returns a services map so clients know what is available:

{
  "services": {
    "metadata": {
      "enabled": true, "status": "degraded",
      "route": "/api/v1/meta", "provider": "kernel",
      "message": "In-memory registry; DB persistence pending"
    },
    "data": {
      "enabled": true, "status": "available",
      "route": "/api/v1/data", "provider": "kernel"
    },
    "auth": {
      "enabled": false, "status": "unavailable",
      "message": "Install an auth plugin to enable"
    }
  }
}

2. data Service ✅ Implemented

Service Name: data · Criticality: required
Implementation: @objectstack/objectqlObjectQL (IDataEngine)
Route Mount: /api/v1/data

`@objectstack/objectql` is an **example kernel implementation** to get the basic data API running. Future production kernels will be developed as separate plugins.

Protocol Methods

Method Signature Status
findData FindDataRequest → FindDataResponse
getData GetDataRequest → GetDataResponse
createData CreateDataRequest → CreateDataResponse
updateData UpdateDataRequest → UpdateDataResponse
deleteData DeleteDataRequest → DeleteDataResponse
batchData BatchDataRequest → BatchDataResponse
createManyData CreateManyDataRequest → CreateManyDataResponse
updateManyData UpdateManyDataRequest → UpdateManyDataResponse
deleteManyData DeleteManyDataRequest → DeleteManyDataResponse

Driver Support

Driver Package CRUD Aggregation Ready
InMemory @objectstack/driver-memory Dev/Test
PostgreSQL TBD
MySQL TBD
MongoDB TBD
SQLite TBD

3. analytics Service ✅ Implemented

Service Name: analytics · Criticality: optional
Implementation: @objectstack/objectql (driver-level capability)
Route Mount: /api/v1/analytics

Protocol Methods

Method Signature Status
analyticsQuery AnalyticsQueryRequest → AnalyticsResultResponse
getAnalyticsMeta GetAnalyticsMetaRequest → AnalyticsMetadataResponse

Features

  • Cube semantic queries: measures / dimensions / filters → ObjectQL aggregation
  • Auto-generated metadata from SchemaRegistry (numeric → sum/avg, date → time dimensions)

4. auth Service 🟡 In Development

Service Name: auth · Criticality: core
Route Mount: /api/v1/auth — only exposed when a plugin registers the auth service

**The kernel does NOT handle auth.** Install an auth plugin to enable authentication. Without it, the discovery response shows `auth: { enabled: false, status: "unavailable" }`.

Plugin Requirements

The auth service covers both authentication (identity) and authorization (permissions). There is no separate permission service in CoreServiceName.

Module Area Description Priority
Identity Provider Authentication JWT issuance/verification, session management P0
User CRUD Authentication Create / read / update / delete users P0
Role Management Authentication Role definitions, role-user associations P0
Permission Engine Authorization Object-level and field-level permissions P0
OAuth2 / OIDC Authentication Third-party login (Google, GitHub, etc.) P1
Sharing Rules Authorization Record-level sharing and visibility P1
Row-Level Security Authorization Automatic query filtering by user context P1
Multi-tenancy Authentication Space / Tenant isolation P1
Territory Management Authorization Data territory assignment and access P2
SCIM Authentication Enterprise user provisioning protocol P2

Spec Files: identity.zod.ts, role.zod.ts, organization.zod.ts, auth-config.zod.ts, tenant.zod.ts


5–7. Business Services ❌ Plugin Required

5. ui Service — 5 methods

listViews, getView, createView, updateView, deleteView
View CRUD, layout engine, action registry, permission filtering.

6. workflow Service — 3 methods

getWorkflowConfig, getWorkflowState, workflowTransition
State machine transitions. Approve/reject are no longer workflow methods — per ADR-0019 they moved to the request-id-based approvals API under /api/v1/approvals.

7. automation Service — 1 method

triggerAutomation
Trigger engine, event triggers from ObjectQL hooks, flow executor, scheduled triggers.


8–11. Communication Services ❌ Plugin Required

8. realtime — 6 methods

realtimeConnect, realtimeDisconnect, realtimeSubscribe, realtimeUnsubscribe, setPresence, getPresence

9. notification — 7 methods

registerDevice, unregisterDevice, getNotificationPreferences, updateNotificationPreferences, listNotifications, markNotificationsRead, markAllNotificationsRead

10. ai — 3 methods

aiNlq, aiSuggest, aiInsights

11. i18n — 3 methods

getLocales, getTranslations, getFieldLabels

Service Name: i18n · Criticality: core
Implementations: @objectstack/service-i18n (production — file-based) · Built-in in-memory fallback · Dev Plugin (in-memory stub)
Route Mount: /api/v1/i18n
Contract: II18nService in @objectstack/spec/contracts

Service Registration

The i18n service is a core built-in service with automatic in-memory fallback. If no plugin registers the service, the kernel automatically injects an in-memory implementation during startup:

Environment Provider Registration
Production I18nServicePlugin File-based FileI18nAdapter loads JSON locale files from disk
Built-in Fallback Kernel In-memory Map-backed stub, auto-injected when no plugin provides i18n
Development DevPlugin In-memory Map-backed stub, supports loadTranslations()
// Production (overrides built-in fallback)
kernel.use(new I18nServicePlugin({ defaultLocale: 'en', localesDir: './i18n' }));

// Development (automatic — DevPlugin registers i18n stub for all 17 core services)
kernel.use(new DevPlugin());

// No plugin required — kernel auto-injects in-memory fallback if none registered
const kernel = new ObjectKernel();
await kernel.bootstrap(); // i18n service available via built-in fallback

Discovery & Handler Consistency

The Discovery API (/api/v1 or /.well-known/objectstack) and the i18n route handler (/api/v1/i18n/*) both use the same async resolution chain to detect i18n availability:

getServiceAsync() → getService() → context.getService() → services Map

This ensures that discovery.services.i18n.status always matches the actual runtime behavior — a service registered via any mechanism (sync Map, async factory, or context) will be reported correctly in both places.

The locale field in the discovery response is populated from the actual i18n service:

  • locale.default — from i18nService.getDefaultLocale() (falls back to 'en')
  • locale.supported — from i18nService.getLocales() (falls back to [default])

AppPlugin Auto-Loading

When an app bundle includes an i18n config and translations array, AppPlugin automatically loads the translation data into the i18n service during the start phase:

export default defineStack({
  manifest: { id: 'com.example.crm', namespace: 'crm' },
  i18n: { defaultLocale: 'en', supportedLocales: ['en', 'zh-CN'] },
  translations: [CrmTranslations],   // TranslationBundle[]
});

AppPlugin will:

  1. Set the default locale via i18nService.setDefaultLocale()
  2. Call i18nService.loadTranslations(locale, data) for each locale in every bundle
  3. Skip gracefully if no i18n service is registered (no errors, just a debug log)

REST API Endpoints

Method Path Description
GET /api/v1/i18n/locales List available locales
GET /api/v1/i18n/translations/:locale Get all translations for a locale
GET /api/v1/i18n/labels/:object/:locale Get translated field labels for an object

12–17. Infrastructure Services

cache, queue, and job are core services: like i18n, the kernel auto-injects an in-memory fallback when no plugin registers them (see CORE_FALLBACK_FACTORIES in packages/core/src/fallbacks/). The optional services (file-storage, search, graphql) stay disabled until a plugin provides them.

Service Description
file-storage Unified upload/download/delete. Drivers: local FS, S3, MinIO.
search Full-text search. Drivers: in-memory, Elasticsearch, Meilisearch.
cache General-purpose cache. In-memory fallback; Redis via @objectstack/service-cache.
queue Message queue. In-memory fallback; BullMQ / Redis via @objectstack/service-queue.
job Scheduled task execution. In-memory fallback; cron-based, concurrency control.
graphql Auto-generate GraphQL schema from Object metadata.

Recommended Development Phases

Phase 1: Foundation (P0)

Plugin Description
plugin-auth Identity engine — JWT, sessions, user CRUD, roles
plugin-ui View CRUD — core low-code capability
plugin-cache General-purpose cache — performance infrastructure
Metadata DB Solve metadata persistence (SchemaRegistry → database)

Phase 2: Business Engine (P1)

Plugin Description
service-automation Flow orchestration, state-machine adjacent execution, approval-node pauses
plugin-automation Triggers + flow orchestration
plugin-i18n Internationalization
plugin-storage File storage (local + S3)
DB drivers PostgreSQL, MySQL, MongoDB, SQLite

Phase 3: Advanced Capabilities (P2)

Plugin Description
plugin-realtime WebSocket / SSE real-time push
plugin-notification Notification engine
plugin-ai NLQ, chat, suggestions, insights
plugin-graphql GraphQL API endpoint
plugin-search Full-text search
plugin-job Scheduled tasks
plugin-queue Message queue

Plugin Implementation Pattern

import type { Plugin } from '@objectstack/core';

let authService: AuthServiceImpl;

export const authPlugin: Plugin = {
  name: 'plugin-auth',

  async init(ctx) {
    // Register the 'auth' CoreServiceName value
    const engine = ctx.getService<IDataEngine>('data');
    authService = new AuthServiceImpl(engine);
    ctx.registerService('auth', authService);
  },

  async start(ctx) {
    const auth = ctx.getService<IAuthService>('auth');
    await auth.onReady();
  },

  // destroy() takes no arguments — capture what you need in module scope
  async destroy() {
    await authService.shutdown();
  },
};

When a plugin registers a service, the discovery endpoint automatically updates:

  • services.auth.enabledtrue, status"available", route"/api/v1/auth"
  • routes.auth"/api/v1/auth" appears in routes
  • features capability flags update accordingly

Next Steps