Skip to content

Commit d62fbe4

Browse files
Copilothotlong
andcommitted
docs: add package publishing documentation to metadata-service.mdx, README.md, and ROADMAP.md
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 8741749 commit d62fbe4

3 files changed

Lines changed: 87 additions & 0 deletions

File tree

ROADMAP.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ business/custom objects, aligning with industry best practices (e.g., ServiceNow
398398
- [x] **In-Memory Driver** — Full CRUD, bulk ops, transactions, aggregation pipeline (Mingo), streaming
399399
- [x] **In-Memory Driver Persistence** — File-system (Node.js) and localStorage (Browser) persistence adapters with auto-save, custom adapter support
400400
- [x] **Metadata Service** — CRUD, query, bulk ops, overlay system, dependency tracking, import/export, file watching
401+
- [x] **Metadata Package Publishing**`publishPackage`, `revertPackage`, `getPublished` for atomic package-level metadata publishing with version snapshots
401402
- [x] **Serializers** — JSON, YAML, TypeScript format support
402403
- [x] **Loaders** — Memory, Filesystem, Remote (HTTP) loaders
403404
- [x] **REST API** — Auto-generated CRUD/Metadata/Batch/Discovery endpoints
@@ -452,6 +453,7 @@ business/custom objects, aligning with industry best practices (e.g., ServiceNow
452453
- User overlay persistence across sessions
453454
- Multi-instance metadata synchronization
454455
- Production-grade metadata storage
456+
- Package-level metadata publishing (publishPackage / revertPackage / getPublished)
455457

456458
### Phase 4b: Infrastructure Service Upgrades (P1 — Weeks 3-4)
457459

content/docs/guides/contracts/metadata-service.mdx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,59 @@ const filteredViews = views.filter(view => {
352352
return !v.requiredPermission || userPermissions.includes(v.requiredPermission);
353353
});
354354
```
355+
356+
---
357+
358+
## Package Publishing
359+
360+
ObjectStack uses **package-level publishing** to ensure metadata consistency. All metadata items within a package are published atomically — either everything goes live, or nothing does.
361+
362+
### publishPackage
363+
364+
Publishes all metadata items in a package:
365+
1. Validates all items (optional)
366+
2. Snapshots each item's definition into `publishedDefinition`
367+
3. Increments the package version
368+
4. Sets all items to `active` state
369+
370+
```typescript
371+
const result = await metadataService.publishPackage('com.acme.crm', {
372+
publishedBy: 'admin-user',
373+
validate: true, // default: true
374+
changeNote: 'Added opportunity fields',
375+
});
376+
377+
console.log(result.success); // true
378+
console.log(result.version); // 2
379+
console.log(result.itemsPublished); // 5
380+
console.log(result.publishedAt); // "2025-06-01T12:00:00Z"
381+
```
382+
383+
### revertPackage
384+
385+
Reverts all metadata items in a package to their last published state. Discards any unpublished changes.
386+
387+
```typescript
388+
await metadataService.revertPackage('com.acme.crm');
389+
// All items restored to their publishedDefinition snapshots
390+
```
391+
392+
### getPublished
393+
394+
Returns the published version of a metadata item (for runtime/end-user serving). Falls back to the current definition if the item has never been published.
395+
396+
```typescript
397+
// End user sees the published version
398+
const published = await metadataService.getPublished('object', 'opportunity');
399+
400+
// Designer sees the draft version (via regular get)
401+
const draft = await metadataService.get('object', 'opportunity');
402+
```
403+
404+
### REST Endpoints
405+
406+
| Method | Path | Description |
407+
|:---|:---|:---|
408+
| `POST` | `/packages/:id/publish` | Publish a package |
409+
| `POST` | `/packages/:id/revert` | Revert a package to last published state |
410+
| `GET` | `/metadata/:type/:name/published` | Get published version of a metadata item |

packages/metadata/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ The `MetadataManager` is the main orchestrator. It provides:
8686
- **Core CRUD**: `register`, `get`, `list`, `unregister`, `exists`, `listNames`
8787
- **Convenience**: `getObject`, `listObjects`
8888
- **Package Management**: `unregisterPackage` — unload all metadata from a package
89+
- **Package Publishing**: `publishPackage`, `revertPackage`, `getPublished` — atomic package-level metadata publishing
8990
- **Query / Search**: `query` with filtering, pagination, sorting by type/scope/state/tags
9091
- **Bulk Operations**: `bulkRegister`, `bulkUnregister` with error handling
9192
- **Import / Export**: `exportMetadata`, `importMetadata` with conflict resolution (skip/overwrite/merge)
@@ -201,6 +202,34 @@ const plugin = MetadataPlugin({
201202
kernel.use(plugin);
202203
```
203204

205+
## Package Publishing
206+
207+
ObjectStack supports **package-level metadata publishing** — all metadata items within a package are published atomically.
208+
209+
### Publish a Package
210+
211+
```typescript
212+
const result = await manager.publishPackage('com.acme.crm', {
213+
publishedBy: 'admin',
214+
validate: true,
215+
});
216+
// result: { success: true, version: 2, itemsPublished: 5, publishedAt: '...' }
217+
```
218+
219+
### Revert to Last Published State
220+
221+
```typescript
222+
await manager.revertPackage('com.acme.crm');
223+
// All items restored to their publishedDefinition snapshots
224+
```
225+
226+
### Get Published Version (Runtime Serving)
227+
228+
```typescript
229+
const published = await manager.getPublished('object', 'opportunity');
230+
// Returns publishedDefinition if exists, else current definition
231+
```
232+
204233
## Package Structure
205234

206235
```

0 commit comments

Comments
 (0)