Location: modules/platform/doc/
Dependencies: @platform/core, @platform/socket, @platform/schema
Overview
@platform/doc is the reactive document store of the platform. It abstracts MongoDB operations behind a clean, schema-driven API and propagates changes to all connected clients in real time through the socket layer.
Key responsibilities:
- CRUD operations — create, read, update, and delete documents in MongoDB.
- Reactive subscriptions — clients subscribe to queries; the server pushes live updates via @platform/schema's pub/sub layer.
- Schema integration — every collection is defined with a DSchema (Zod-based schema with doc metadata) from @platform/schema.
- React hooks — useDoc and useDocs provide ergonomic reactive data access in components.
- Crud routes — docCrudRoute generates a full React Router route tree (browser + form + editor) for a collection.
Contexts
| Context |
Entry point |
Contents |
client |
src/client/index.ts |
React hooks, context providers, display components, layout, crud route |
server |
src/server/index.ts |
ServerDocService, ServerCrudService, ServerMongoService, Cursor |
common |
src/common/index.ts |
Doc, DSchema, PRef, interfaces, publications, CommonDocService |
Common API
import { Doc, DocSchema, DSchema, PRef, CommonDocService } from '@platform/doc/common'
| Export |
Description |
Doc |
Base document type — { _id: string } |
DocSchema |
Zod schema for the base Doc — { _id: PString() } with namespace 'doc' |
TDoc |
TypeScript type alias for typeof DocSchema |
DSchema(shape, meta) |
Creates a Zod schema extending DocSchema and registers it with CommonDocService. Use for all document schemas. |
PRef(schema, options?) |
Creates a property whose value is a reference (string _id) to another document schema |
CommonDocService |
Shared utilities for document manipulation, schema registry |
interfaces |
TypeScript interfaces for CRUD and subscription contracts |
publications |
Named publication definitions |
Defining a Document Schema
import { DSchema } from '@platform/doc/common'
import { PString, PNumber } from '@platform/schema/common'
export const NoteSchema = DSchema(
{
title: PString(),
content: PString({ optional: true }),
order: PNumber({ optional: true })
},
{
namespace: 'notes',
name: 'Note',
render: (note) => note.title
}
)
export type Note = z.infer<typeof NoteSchema>
Document References
import { PRef } from '@platform/doc/common'
import { UserSchema } from '@platform/security/common'
const CommentSchema = DSchema(
{
text: PString(),
author: PRef(UserSchema) // stores the user's _id
},
{ namespace: 'comments', name: 'Comment', render: (c) => c.text }
)
Server API
import {
ServerDocService,
ServerCrudService,
ServerMongoService,
Cursor
} from '@platform/doc/server'
| Export |
Description |
ServerMongoService |
Manages the MongoDB connection and exposes the native Db object |
ServerDocService |
High-level document service — wraps ServerMongoService with schema-aware helpers |
ServerCrudService |
Generic CRUD service base class — extend it to expose create/read/update/delete operations for a collection |
Cursor |
MongoDB cursor wrapper with pagination and filtering utilities |
Defining a Collection Service
import { ServerCrudService } from '@platform/doc/server'
import { NoteSchema } from './NoteSchema'
export class NoteService extends ServerCrudService<typeof NoteSchema> {
collectionName = 'notes'
schema = NoteSchema
}
Client API
Hooks
import { useDoc, useDocs, useDocSubscription, useDocAutocomplete, useSubscriptionDocs } from '@platform/doc/client'
| Export |
Description |
useDoc(type, id) |
Subscribes to a single document by type and _id; returns the live document or undefined |
useDocs(type, query?) |
Subscribes to a collection query; returns a live array of matching documents |
useDocSubscription(publication, params) |
Low-level hook for custom publication subscriptions |
useDocAutocomplete(schema, query) |
Returns a filtered list of documents for use in autocomplete controls |
useSubscriptionDocs(publication, params) |
Subscribes to a publication that returns a list of documents |
Context Providers
| Export |
Description |
DocContext |
React context that must wrap the component tree; connects to the server doc subscription |
useDocContext |
Hook to access the DocContext state and actions |
useDocDataState |
Internal hook for raw document data state |
useDocSubscriptionState |
Internal hook for subscription lifecycle state |
Display Components
import { DocDisplayValue, DocSchemaTable } from '@platform/doc/client'
| Export |
Description |
DocDisplayValue |
Renders a document field value using schema-derived formatting |
DocSchemaTable |
Renders a property table for a document based on its schema |
| Export |
Description |
DocRefStringControl |
Form control for selecting a referenced document by _id |
DocSchemaControl |
Schema-aware form control bound to a document field |
DocControl |
General-purpose document form control |
Layouts
| Export |
Description |
DocForm |
Full form layout for a document, combining EntityEditor + SchemaForm |
Crud Route Factory
import { docCrudRoute } from '@platform/doc/client'
docCrudRoute(path, schema, publication) generates a complete React Router RouteObject tree for a collection:
/<path> → DocBrowserRoute (list + search)
/<path>/:id → DocFormRoute (load doc into form context)
/<path>/:id/ → DocEditorRoute (entity editor with tabs)
/<path>/:id/ → EntityForm (index: main fields)
/<path>/:id/<child> → child routes (one route per nested object field)
import { docCrudRoute } from '@platform/doc/client'
import { NoteSchema } from '@platform/notes/common'
import { NotesPublication } from '@platform/notes/common'
const notesRoute = docCrudRoute('/notes', NoteSchema, NotesPublication)
Route Utilities
| Export |
Description |
AppRoute |
Route wrapper type helpers (AppRouteParams, ModelComponentProps, RouteToModel, ModelToView) |
Usage Example
// Common — define a document schema
import { DSchema } from '@platform/doc/common'
import { PString } from '@platform/schema/common'
export const NoteSchema = DSchema(
{ title: PString() },
{ namespace: 'notes', name: 'Note', render: (n) => n.title }
)
// Server — expose a CRUD service
import { ServerCrudService } from '@platform/doc/server'
export class NoteService extends ServerCrudService<typeof NoteSchema> {
collectionName = 'notes'
schema = NoteSchema
}
// Client — consume live data
import { useDocs } from '@platform/doc/client'
function NoteList() {
const notes = useDocs('Note')
return <ul>{notes.map(n => <li key={n._id}>{n.title}</li>)}</ul>
}