You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2-7Lines changed: 2 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
- **`@objectstack/service-tenant` — system objects now actually register** — `createTenantPlugin()` previously declared its control-plane schemas (`sys_project`, `sys_project_credential`, `sys_project_member`, `sys_package`, `sys_package_version`, `sys_package_installation`, `sys_tenant_database`) via a top-level `objects: [...]` field on the kernel plugin object. The kernel only consumes `plugin.objects` for **nested** plugins inside a parent manifest (`packages/objectql/src/engine.ts` → `registerPlugin()`), so plugins added via `kernel.use(plugin)` had to use the `manifest` service (as `AuthPlugin`/`SecurityPlugin`/`SetupPlugin` already do). The result was that `sys__project` etc. were never registered with `SchemaRegistry`, so `ObjectQL.getDriver('sys__project')` could not match the `namespace: 'sys' → turso` `datasourceMapping` rule (the lookup returned `undefined` and skipped past the namespace check), silently routing every control-plane write to the default driver — typically the in-memory driver. On Vercel each lambda instance has its own memory, so `POST /api/v1/cloud/projects` "succeeded" with HTTP 202 but the row evaporated on cold start, causing the subsequent `GET /api/v1/cloud/projects/:id` to return 404 even though the user/organization writes (registered through the proper path by `AuthPlugin`) were correctly persisted in Turso. The plugin now registers the same set of objects via `ctx.getService('manifest').register({ id: 'com.objectstack.tenant', namespace: 'sys', objects: [...] })` and throws if the manifest service is unavailable, fail-fast instead of silent data loss. Also affected: package install/upgrade endpoints, project credential rotation, project membership reads.
12
12
13
13
### Changed
14
+
-**Platform object definitions consolidated in `@objectstack/platform-objects`** — Removed the now-redundant `@objectstack/objectos` package. Metadata-layer objects (`SysObject`, `SysView`, `SysAgent`, `SysTool`, `SysFlow`) are registered directly from `@objectstack/platform-objects/metadata`, and plugin/service packages no longer re-export platform objects through compatibility `objects` facades.
14
15
-**`examples/app-crm` — showcase `fieldGroups` MVP** — The CRM reference example (`Account`, `Contact`, `Opportunity`, `Lead`) now demonstrates the new `fieldGroups` protocol end to end. Each object declares logical groups (e.g., *Basic Information*, *Financials*, *Contact Information*, *Ownership & Status*, *System*) and every field opts in via `group: '<key>'`. No business logic changed — only field-layout metadata — so existing validations, workflows, indexes, and state machines are unaffected. Useful as a reference when designing multi-group forms and detail pages.
15
16
16
17
### Added
@@ -21,21 +22,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
21
22
- Supported migrations at this layer: add / rename / delete / reorder groups (by editing the `fieldGroups` array) and assigning an existing field to a group (by editing `Field.group`). Explicit per-field in-group ordering is deferred to a future iteration.
22
23
- New `ObjectFieldGroup` / `ObjectFieldGroupInput` type exports alongside the schema.
23
24
- Tests: 12 new round-trip cases in `packages/spec/src/data/object.test.ts` covering minimal/full-group parsing, required fields, snake_case key validation, declaration-order preservation, duplicate-key rejection, `Field.group` referencing, and `ObjectSchema.create()` integration.
24
-
### Fixed
25
-
- **Doubly-prefixed FQN for `@objectstack/objectos` system objects** — The ObjectOS-layer object definitions (`SysObject`, `SysView`, `SysAgent`, `SysTool`, `SysFlow`, `SysMetadata`) were being registered with fully-qualified names like `sys__sys_object`, `sys__sys_view`, `sys__sys_metadata`, because each object hard-coded a `sys_` prefix into its `name` **and** its manifest was registered under `namespace: 'sys'`, causing `SchemaRegistry.computeFQN(namespace, name)` to apply the prefix twice. The object `name` values are now the unprefixed short form (`object`, `view`, `agent`, `tool`, `flow`, `metadata`), producing the correct FQNs (`sys__object`, `sys__view`, `sys__agent`, `sys__tool`, `sys__flow`). `SysMetadata` (which would collide with the canonical `sys__metadata` owned by `@objectstack/metadata`) is now exported separately and excluded from the auto-registered `SystemObjects` catalog to avoid ownership conflicts; consumers that need it can still import it directly. See `packages/objectos/src/objects/*.ts` and `packages/objectos/src/registry.ts`.
26
-
27
25
### Added
28
26
-**Environment-per-database multi-tenancy (`service-tenant` v4.1)** — Refactored the multi-tenant architecture from "per-organization database" to **per-environment database** high-isolation, with a hard split between Control Plane (environment registry / addressing / credentials / RBAC) and Data Plane (one physical database per environment). See [`docs/adr/0002-environment-database-isolation.md`](docs/adr/0002-environment-database-isolation.md) for the full rationale and trade-offs.
29
27
-**Zod protocol schemas** (`packages/spec/src/cloud/environment.zod.ts`): `EnvironmentSchema`, `EnvironmentDatabaseSchema`, `DatabaseCredentialSchema`, `EnvironmentMemberSchema`, `EnvironmentTypeSchema`, `EnvironmentStatusSchema`, `EnvironmentRoleSchema`, `DatabaseCredentialStatusSchema`, `ProvisionEnvironmentRequest/ResponseSchema`, `ProvisionOrganizationRequest/ResponseSchema`. `TenantDatabaseSchema` is now marked `@deprecated`.
30
28
-**Control-plane objects** (`packages/services/service-tenant/src/objects/`): `sys_environment` (UNIQUE `(organization_id, slug)`), `sys_environment_database` (UNIQUE `environment_id` — exactly one DB per environment), `sys_database_credential` (rotatable, encrypted, with `active` / `rotating` / `revoked` lifecycle), `sys_environment_member` (UNIQUE `(environment_id, user_id)`, owner / admin / maker / reader / guest). Every field carries `.describe()` metadata and every uniqueness constraint is explicit.
31
29
-**`EnvironmentProvisioningService`** (`packages/services/service-tenant/src/environment-provisioning.ts`): `provisionOrganization()` bootstraps a new org with a default environment and DB in one call; `provisionEnvironment()` allocates any subsequent dev / test / sandbox / preview environment; `rotateCredential()` mints a new `active` credential and revokes the previous one. Pluggable `EnvironmentDatabaseAdapter` (initial `turso`; `libsql` / `sqlite` / `postgres` drop in without core changes) and `SecretEncryptor` hooks.
32
-
-**Tenant plugin wiring**: `createTenantPlugin()` now registers all four new control-plane objects out of the box, plus `sys_tenant_database` as a v4.x shim (opt out via `registerLegacyTenantDatabase: false`).
30
+
-**Tenant plugin wiring**: `createTenantPlugin()` now registers the current control-plane objects directly from `@objectstack/platform-objects/tenant`.
33
31
-**v4 → v5 migration skeleton** (`packages/services/service-tenant/migrations/v4-to-v5-env-migration.ts`): idempotent, non-destructive, re-encrypts credentials with the current KMS key, reuses existing physical DBs as each org's new `prod` environment DB — no data movement required.
34
32
-**Tests**: 22 new schema round-trip tests in `packages/spec/src/cloud/environment.test.ts`, 10 new provisioning tests in `packages/services/service-tenant/src/environment-provisioning.test.ts` covering organization bootstrap, environment creation, default-environment invariants, adapter routing, credential rotation, and encryption hooks.
35
33
36
-
### Deprecated
37
-
-**`TenantDatabaseSchema` / `sys_tenant_database`** — Superseded by the environment-per-database model above. The schema and object remain registered in v4.x as a deprecation shim; both will be removed in **v5.0**. Consumers should migrate by running `migrateV4ToV5Environments()` before upgrading to v5.0.
38
-
39
34
### Changed
40
35
-**Polished `examples/app-crm` dashboards** — Rewrote `executive`, `sales`, and `service` dashboards and added a new unified `crm` overview dashboard, modeled after the reference implementation at [objectstack-ai/objectui/examples/crm](https://github.com/objectstack-ai/objectui/tree/main/examples/crm/src/dashboards). The dashboards now use the framework's first-class metadata fields instead of ad-hoc hex strings stuffed into `options.color`:
41
36
- Semantic `colorVariant` tokens (`success`/`warning`/`danger`/`blue`/`teal`/`purple`/`orange`) replace raw hex codes
0 commit comments