Aller au contenu

@platform/schema

Location: modules/platform/schema/
Dependencies: @platform/core, @platform/socket

Overview

@platform/schema is the schema and pub/sub layer of the platform. It is built on Zod and provides:

  • A schema factory (CSchema, CEnum, CType, PString, PNumber, …) for defining typed, metadata-rich schemas.
  • Reactive subscription infrastructureSubscriptionContext, ServerPubService, ServerSubService, useSubscription.
  • Form generation — React components that render and validate forms from a Zod schema at runtime.
  • Layout componentsEntityBrowser, EntityEditor, EntityForm, EntityNavigator for full CRUD UIs.
  • Shared entity typesSchema, Property, PubDefinition, ServiceDefinition, SubscriptionStatus, Enum, I18nString.

Contexts

Context Entry point Contents
client src/client/index.ts Form/display components, layout components, SubscriptionContext, hooks
server src/server/index.ts SchemaServerModule, ServerPubService, ServerSubService
common src/common/index.ts Zod re-export (z), SchemaFactory, entities, enums, services, interfaces

Common API

Zod Re-export

@platform/schema/common re-exports the entire Zod library as z:

import { z } from '@platform/schema/common'
const PersonSchema = z.object({ name: z.string() })

Schema Factory

import { CSchema, CEnum, CType, PString, PNumber, PBoolean, PDate, PEmail, PEnum, PSchema, PI18nString } from '@platform/schema/common'

All schemas are built using these helpers. They wrap Zod types and attach metadata used for UI rendering and i18n.

Export Wraps Description
CSchema(shape, meta) z.object Create a Zod object schema with namespace, name, and optional render metadata
CEnum(values, meta) z.enum Create a Zod enum with metadata
CType(type, options) any Zod type Wrap a Zod type with optional, multiple, and PropertyMeta
PString(options?) z.string String property
PEmail(options?) z.email Email string property
PNumber(options?) z.number Number property
PBoolean(options?) z.boolean Boolean property
PDate(options?) z.coerce.date Date property
PEnum(enum, options?) Zod enum Enum property
PSchema(schema, options?) Zod object Nested object property
PI18nString(options?) I18nStringSchema Bilingual { fr, en } property

CTypeOptions:

Option Type Description
optional? boolean Wraps the type in z.optional(...)
multiple? boolean Wraps the type in z.array(...)

SchemaMeta (passed as second arg to CSchema):

Field Type Description
namespace string Logical grouping (e.g., 'doc', 'security')
name string Schema name (e.g., 'User')
render? (entity, meta, lang) => string Function to render a human-readable label for an instance

Schema Entities

import { Schema, Property, PubDefinition, ServiceDefinition, SubscriptionStatus, Enum, I18nString } from '@platform/schema/common'
Export Description
Schema / SchemaSchema Type and Zod schema for schema descriptors
Property / PropertySchema Type and Zod schema for property descriptors
PropertyMeta / PropertyMetaSchema Optional metadata for properties (female, vowel for i18n)
PubDefinition / PubDefinitionSchema Publication definition — name, optional default types for params/output
ServiceDefinition / ServiceDefinitionSchema Service/method descriptor
MethodDefinition / FeatureDefinition Method and feature descriptor types
SubscriptionStatus / SubscriptionStatusSchema Live subscription state (id, definition, params, socketId)
Enum / EnumSchema Enum descriptor with values array
I18nString / I18nStringSchema Bilingual string { en: string; fr: string }

Services

import { CommonSchemaService, CommonDraftService, CommonErrorService } from '@platform/schema/common'
Export Description
CommonSchemaService Schema introspection helpers (field type detection, label resolution)
CommonDraftService Create and manage draft objects before saving
CommonErrorService Normalize and format Zod validation errors
SchemaFactory (see above) — CSchema, CType, etc.

Interfaces

Export Description
IServerSubService Contract for the subscription service (subscribe/unsubscribe/updateParams)

Publications

Export Description
ServicesDefinition PubDefinition for the list of registered services
SubscriptionStatusesDefinition PubDefinition for the list of active subscriptions

Enums

Export Description
Gender Gender enum
Language Supported UI language enum
Weekday Weekday enum

Server API

import { SchemaServerModule, ServerPubService, ServerSubService } from '@platform/schema/server'
Export Description
SchemaServerModule Registers built-in publications (ServicesDefinition, SubscriptionStatusesDefinition) on startup
ServerPubService Registry for server-side publications — publish({ definition, subscribe, updateParams? }) and get(name)
ServerSubService Socket-aware subscription handler — implements IServerSubService and registers it with ServerService

Defining a Publication

import { ServerPubService } from '@platform/schema/server'
import { MyPublication } from './myPublications'

ServerPubService.publish({
  definition: MyPublication,
  subscribe: async (params, callback, subscriptionId) => {
    const data = await fetchData(params)
    callback(data)
    return {
      value: data,
      cleanup: () => { /* unsubscribe logic */ }
    }
  }
})

Client API

Subscription Infrastructure

import { SubscriptionContext, useSubscription, useSubscriptionContext } from '@platform/schema/client'
Export Description
SubscriptionContext React context provider — manages active subscriptions, listens for pubSubMessage socket events
useSubscriptionContext Hook to access subscribe/unsubscribe/updateParams actions
useSubscription(definition, params, callback) Subscribe to a publication; calls callback(subscriptionId, value) on each push

Form Components

import { SchemaForm, SchemaControl, FormContext } from '@platform/schema/client'
Export Description
SchemaForm Complete auto-generated form from a Zod schema
SchemaControls Renders all controls for a schema
SchemaControl Single schema-aware input control
FormContext React context providing schema, draft, and submit state
SubFormContext Nested form context for composite schemas
SubmitButton Submit button wired to FormContext
AddButton Button to add an item in an array field
DeleteButton Button to delete an item in an array field
FieldExists Conditional rendering based on field presence
ForEach Iterates over array fields
DraftEditor Full draft editor with form and controls

Layout Components

import { EntityBrowser, EntityEditor, EntityForm, EntityNavigator } from '@platform/schema/client'
Export Description
EntityNavigator List/search/select panel for a collection of entities
EntityBrowser Split-pane layout combining EntityNavigator with a detail view
EntityEditor Editor shell with tabs for nested object properties and save/cancel
EntityForm Schema-driven field form (renders all fields, supports column layout)

Display Components

Export Description
EntityLabel Renders a human-readable label for an entity using the schema's render function
FieldDisplayValue Renders a single field value as text
FieldLabel Renders a localized field label
PropertyTable Table of property name/value pairs
SchemaTable Table showing all fields defined in a schema
DraftJson Displays the raw JSON of the current draft

Hooks

Export Description
useEntityLabel(schema, entity) Returns the rendered label for an entity
useCoreControlProps Derives base control props from a schema field
useCoreColumnProps Derives column definition props from a schema field
useSubscription (see above)

i18n

Export Description
LangButton Language toggle button

Usage Example

// Define a Zod schema with metadata
import { CSchema, PString, PNumber } from '@platform/schema/common'

export const PersonSchema = CSchema(
  {
    name: PString(),
    age: PNumber({ optional: true })
  },
  {
    namespace: 'people',
    name: 'Person',
    render: (person) => person.name
  }
)

// Render an auto-generated form
import { SchemaForm } from '@platform/schema/client'

function PersonForm() {
  return (
    <SchemaForm
      schema={PersonSchema}
      value={{ name: '' }}
      onSubmit={(value) => console.log(value)}
    />
  )
}

// Publish data from the server
import { ServerPubService } from '@platform/schema/server'

ServerPubService.publish({
  definition: { name: 'people.all' },
  subscribe: async (_params, callback) => {
    const people = await PersonRepository.findAll()
    callback(people)
    return { value: people }
  }
})

// Subscribe from the client
import { useSubscription } from '@platform/schema/client'

function PersonList() {
  const [people, setPeople] = useState([])
  useSubscription({ name: 'people.all' }, undefined, (_, value) => setPeople(value))
  return <ul>{people.map(p => <li key={p.name}>{p.name}</li>)}</ul>
}