Skip to content

Commit 7ac69e5

Browse files
authored
Merge pull request #473 from objectstack-ai/copilot/complete-development-roadmap-another-one
2 parents 52cd675 + c764a36 commit 7ac69e5

File tree

39 files changed

+2912
-88
lines changed

39 files changed

+2912
-88
lines changed

MIGRATION_GUIDE.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
# Migration Guide
2+
3+
## Migrating to v3.0.0
4+
5+
This guide covers migrating from `@objectstack/spec` v2.x to v3.0.0 and from `@objectstack/client` v2.x to v3.0.0. These are the upstream dependencies that ObjectUI builds on — if you use ObjectUI with ObjectStack, follow these steps when upgrading.
6+
7+
> **Tip:** The v3.0.0 migration in ObjectUI is complete (see [CHANGELOG.md](./CHANGELOG.md)). This guide helps you migrate your own application code.
8+
9+
---
10+
11+
### Breaking Changes
12+
13+
| Change | v2.x | v3.0.0 |
14+
|--------|------|--------|
15+
| **Namespace rename** | `Hub` | `Cloud` |
16+
| **Plugin definition** | `definePlugin()` | Removed — use `defineStack()` only |
17+
| **Paginated results** | `.value` / `.count` | `.records` / `.total` (+ `.hasMore`) |
18+
| **Metadata API** | `client.meta.getObject(name)` | `client.meta.getItem('object', name)` |
19+
| **New modules** || `contracts`, `integration`, `security`, `studio` |
20+
21+
---
22+
23+
### Step-by-Step Migration
24+
25+
#### 1. Update Dependencies
26+
27+
```bash
28+
# Update all @objectstack packages to v3.0.0
29+
npm install @objectstack/spec@^3.0.0 @objectstack/client@^3.0.0
30+
# or with pnpm
31+
pnpm add @objectstack/spec@^3.0.0 @objectstack/client@^3.0.0
32+
```
33+
34+
#### 2. Replace Hub → Cloud Namespace
35+
36+
Search your codebase for `Hub` namespace references and replace with `Cloud`:
37+
38+
```typescript
39+
// ❌ v2.x
40+
import { Hub } from '@objectstack/spec';
41+
42+
// ✅ v3.0.0
43+
import { Cloud } from '@objectstack/spec';
44+
```
45+
46+
#### 3. Replace definePlugin → defineStack
47+
48+
`definePlugin()` has been removed. Use `defineStack()` for all configuration, including plugins, apps, objects, and dashboards.
49+
50+
```typescript
51+
// ❌ v2.x
52+
import { definePlugin } from '@objectstack/spec';
53+
export default definePlugin({ name: 'my-plugin', objects: [/* ... */] });
54+
55+
// ✅ v3.0.0
56+
import { defineStack } from '@objectstack/spec';
57+
export default defineStack({
58+
manifest: { id: 'my-app', name: 'my_app', version: '1.0.0', type: 'app' },
59+
objects: [/* ... */],
60+
apps: [/* ... */],
61+
});
62+
```
63+
64+
#### 4. Update PaginatedResult Fields
65+
66+
All paginated responses now use `.records` and `.total` instead of `.value` and `.count`. The new `.hasMore` boolean simplifies infinite-scroll patterns.
67+
68+
```typescript
69+
// ❌ v2.x
70+
const result = await client.data.find('accounts', query);
71+
const items = result.value; // array of records
72+
const count = result.count; // total count
73+
74+
// ✅ v3.0.0
75+
const result = await client.data.find('accounts', query);
76+
const items = result.records; // array of records
77+
const count = result.total; // total count
78+
const more = result.hasMore; // boolean — are there more pages?
79+
```
80+
81+
If you have custom data adapters, update all references:
82+
83+
```typescript
84+
// ❌ v2.x adapter
85+
return { data: response.value, total: response.count };
86+
87+
// ✅ v3.0.0 adapter
88+
return { data: response.records, total: response.total };
89+
```
90+
91+
#### 5. Update Metadata API Calls
92+
93+
The `meta.getObject()` convenience method is replaced by the unified `meta.getItem()` API.
94+
95+
```typescript
96+
// ❌ v2.x
97+
const schema = await client.meta.getObject('account');
98+
99+
// ✅ v3.0.0
100+
const schema = await client.meta.getItem('object', 'account');
101+
```
102+
103+
Other metadata patterns:
104+
105+
```typescript
106+
const view = await client.meta.getItem('account', 'views/list'); // view definition
107+
const app = await client.meta.getItem('apps', 'crm'); // app definition
108+
```
109+
110+
---
111+
112+
### API Quick Reference
113+
114+
```typescript
115+
// Hub → Cloud
116+
Hub.*Cloud.*
117+
118+
// definePlugin → defineStack
119+
definePlugin({ ... }) → defineStack({ manifest: { ... }, objects: [...] })
120+
121+
// PaginatedResult
122+
result.valueresult.records
123+
result.countresult.total
124+
/* new */ result.hasMore
125+
126+
// Metadata API
127+
meta.getObject(name) → meta.getItem('object', name)
128+
```
129+
130+
---
131+
132+
### New Features in v3.0.0
133+
134+
#### Contracts Module
135+
136+
Validate plugin contracts and generate manifests for the marketplace:
137+
138+
```typescript
139+
import { validatePluginContract, generateContractManifest } from './contracts';
140+
141+
const result = validatePluginContract({
142+
name: 'my-plugin',
143+
version: '1.0.0',
144+
exports: [{ name: 'GridView', type: 'component' }],
145+
permissions: ['data.read'],
146+
});
147+
// result.valid === true, result.errors === []
148+
```
149+
150+
#### Integration Module
151+
152+
Register external service integrations with event-driven triggers:
153+
154+
```typescript
155+
import { IntegrationManager } from './integration';
156+
157+
const manager = new IntegrationManager();
158+
manager.register('slack-notify', {
159+
provider: 'slack',
160+
enabled: true,
161+
config: { webhookUrl: 'https://hooks.slack.com/...' },
162+
triggers: [{ event: 'record.created' }],
163+
});
164+
```
165+
166+
#### Security Module
167+
168+
CSP headers, audit logging, and field-level data masking:
169+
170+
```typescript
171+
import { SecurityManager } from './security';
172+
173+
const security = new SecurityManager({
174+
csp: { scriptSrc: ["'self'"], connectSrc: ["'self'", 'https://api.example.com'] },
175+
dataMasking: {
176+
rules: [
177+
{ field: 'ssn', strategy: 'partial', visibleChars: 4 },
178+
{ field: 'password', strategy: 'redact' },
179+
],
180+
},
181+
});
182+
const masked = security.maskRecord({ ssn: '123-45-6789', password: 'secret' });
183+
// masked.ssn === '123-*******', masked.password === '[REDACTED]'
184+
```
185+
186+
#### Studio Module
187+
188+
Canvas configuration helpers for visual designers:
189+
190+
```typescript
191+
import { createDefaultCanvasConfig, snapToGrid } from './studio';
192+
193+
const canvas = createDefaultCanvasConfig({ width: 1600, showMinimap: true });
194+
const snapped = snapToGrid(13, 27, 8); // { x: 16, y: 24 }
195+
```
196+
197+
---
198+
199+
### Troubleshooting
200+
201+
#### `definePlugin is not a function`
202+
203+
`definePlugin` was removed in v3.0.0. Replace all usages with `defineStack()`. See [Step 3](#3-replace-defineplugin--definestack) above.
204+
205+
#### `result.value is undefined` in data grids
206+
207+
Paginated results no longer have `.value`. Update to `.records`:
208+
209+
```bash
210+
grep -rn '\.value' --include='*.ts' --include='*.tsx' | grep -i 'result\|response\|paginated'
211+
```
212+
213+
#### `client.meta.getObject is not a function`
214+
215+
The `getObject()` method was replaced by the unified `getItem()` API. See [Step 5](#5-update-metadata-api-calls).
216+
217+
#### TypeScript errors after upgrade
218+
219+
Ensure all `@objectstack/*` packages are on v3.0.0. Mixing v2 and v3 packages causes type conflicts:
220+
221+
```bash
222+
npm ls @objectstack/spec @objectstack/client
223+
```
224+
225+
#### Further Resources
226+
227+
- [CHANGELOG.md](./CHANGELOG.md) — Full list of changes in each release
228+
- [ROADMAP.md](./ROADMAP.md) — Current development priorities
229+
- [SPEC_COMPLIANCE_EVALUATION.md](./SPEC_COMPLIANCE_EVALUATION.md) — Per-package v3.0.0 compliance status
230+
- [OBJECTSTACK_CLIENT_EVALUATION.md](./OBJECTSTACK_CLIENT_EVALUATION.md) — Client SDK evaluation

ROADMAP.md

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -135,23 +135,23 @@ All 4 phases complete across 5 designers (Page, View, DataModel, Process, Report
135135
**Goal:** A developer can go from `git clone` to a running app in under 5 minutes, with discoverable APIs, helpful errors, and complete documentation at every step.
136136

137137
#### P1.1 Zero-Friction Onboarding
138-
- [ ] Create MIGRATION_GUIDE.md at repo root (currently referenced in README but missing)
138+
- [x] Create MIGRATION_GUIDE.md at repo root (currently referenced in README but missing)
139139
- [ ] Streamline `npx create-objectui-app` scaffolding with working Vite + Tailwind templates
140140
- [ ] Ensure `pnpm install && pnpm dev` starts the console with zero additional configuration
141-
- [ ] Add a standalone "Hello World" example (5-file, <50 lines total) demonstrating JSON → UI flow
141+
- [x] Add a standalone "Hello World" example (5-file, <50 lines total) demonstrating JSON → UI flow
142142
- [ ] Provide copy-paste-ready schema examples in the root README for instant gratification
143143

144144
#### P1.2 API Discoverability & JSDoc
145-
- [ ] Add JSDoc comments to all 20+ exported React hooks (`useExpression`, `useActionRunner`, `useViewData`, `useDynamicApp`, `usePerformance`, `useCrudShortcuts`, etc.)
146-
- [ ] Add JSDoc with usage examples to key types in `@object-ui/types` (`SchemaNode`, `FieldMetadata`, `ViewSchema`, `ActionSchema`, etc.)
145+
- [x] Add JSDoc comments to all 20+ exported React hooks (`useExpression`, `useActionRunner`, `useViewData`, `useDynamicApp`, `usePerformance`, `useCrudShortcuts`, etc.)
146+
- [x] Add JSDoc with usage examples to key types in `@object-ui/types` (`SchemaNode`, `FieldMetadata`, `ViewSchema`, `ActionSchema`, etc.)
147147
- [ ] Document all context providers (`ThemeContext`, `AuthContext`, `I18nContext`, `NotificationContext`, `DndContext`) with usage examples
148148
- [ ] Ensure TypeScript autocompletion works smoothly for all schema types via strict discriminated unions
149149

150150
#### P1.3 Error Messages & Debugging
151-
- [ ] Create error code system (`OBJUI-001`, `OBJUI-002`, etc.) with documentation links
152-
- [ ] Improve SchemaErrorBoundary to show actionable fix suggestions in dev mode (e.g., "Missing field 'type'. Did you mean to use a PageSchema?")
153-
- [ ] Replace generic `console.warn()` calls in core with structured error factory
154-
- [ ] Add `OBJECTUI_DEBUG=true` mode with schema resolution tracing and component render timing
151+
- [x] Create error code system (`OBJUI-001`, `OBJUI-002`, etc.) with documentation links
152+
- [x] Improve SchemaErrorBoundary to show actionable fix suggestions in dev mode (e.g., "Missing field 'type'. Did you mean to use a PageSchema?")
153+
- [x] Replace generic `console.warn()` calls in core with structured error factory
154+
- [x] Add `OBJECTUI_DEBUG=true` mode with schema resolution tracing and component render timing
155155
- [ ] Ensure console warnings for deprecated APIs include migration code snippets
156156

157157
#### P1.4 CLI Tooling Polish
@@ -162,16 +162,16 @@ All 4 phases complete across 5 designers (Page, View, DataModel, Process, Report
162162
- [ ] Resolve 8 TODO/FIXME items in CLI code (`doctor.ts`, `dev.ts`, `check.ts`)
163163

164164
#### P1.5 Package READMEs (10 Missing)
165-
- [ ] Add README for `@object-ui/auth` — authentication guards, login/register forms, AuthContext
166-
- [ ] Add README for `@object-ui/tenant` — multi-tenancy support, TenantProvider, branding
167-
- [ ] Add README for `@object-ui/permissions` — RBAC, PermissionGuard, usePermissions hook
168-
- [ ] Add README for `@object-ui/i18n` — 11 locales, RTL support, I18nProvider, formatting utilities
169-
- [ ] Add README for `@object-ui/mobile` — responsive hooks, gesture support, touch optimization
170-
- [ ] Add README for `@object-ui/collaboration` — live cursors, presence, comment threads, conflict resolution
171-
- [ ] Add README for `@object-ui/plugin-ai` — AI form assistance, recommendations, NL query
172-
- [ ] Add README for `@object-ui/plugin-designer` — 5 visual designers (Page, View, DataModel, Process, Report)
173-
- [ ] Add README for `@object-ui/plugin-workflow` — approval processes, workflow designer
174-
- [ ] Add README for `@object-ui/plugin-report` — report builder, viewer, exporter, scheduling
165+
- [x] Add README for `@object-ui/auth` — authentication guards, login/register forms, AuthContext
166+
- [x] Add README for `@object-ui/tenant` — multi-tenancy support, TenantProvider, branding
167+
- [x] Add README for `@object-ui/permissions` — RBAC, PermissionGuard, usePermissions hook
168+
- [x] Add README for `@object-ui/i18n` — 11 locales, RTL support, I18nProvider, formatting utilities
169+
- [x] Add README for `@object-ui/mobile` — responsive hooks, gesture support, touch optimization
170+
- [x] Add README for `@object-ui/collaboration` — live cursors, presence, comment threads, conflict resolution
171+
- [x] Add README for `@object-ui/plugin-ai` — AI form assistance, recommendations, NL query
172+
- [x] Add README for `@object-ui/plugin-designer` — 5 visual designers (Page, View, DataModel, Process, Report)
173+
- [x] Add README for `@object-ui/plugin-workflow` — approval processes, workflow designer
174+
- [x] Add README for `@object-ui/plugin-report` — report builder, viewer, exporter, scheduling
175175

176176
---
177177

@@ -180,10 +180,10 @@ All 4 phases complete across 5 designers (Page, View, DataModel, Process, Report
180180
**Goal:** Every interaction in the Console and rendered UIs is fast, polished, accessible, and works flawlessly in all supported languages.
181181

182182
#### P2.1 Console i18n Completeness
183-
- [ ] Migrate hardcoded strings in `LoadingScreen.tsx` to i18n keys ("ObjectStack Console", "Initializing application...")
184-
- [ ] Migrate hardcoded strings in `KeyboardShortcutsDialog.tsx` to i18n keys
183+
- [x] Migrate hardcoded strings in `LoadingScreen.tsx` to i18n keys ("ObjectStack Console", "Initializing application...")
184+
- [x] Migrate hardcoded strings in `KeyboardShortcutsDialog.tsx` to i18n keys
185185
- [ ] Audit all `apps/console/src/components/` for remaining hardcoded UI strings
186-
- [ ] Remove all Chinese UI strings; enforce English-only with i18n key lookups
186+
- [x] Remove all Chinese UI strings; enforce English-only with i18n key lookups
187187
- [ ] Add locale switcher to Console settings panel
188188

189189
#### P2.2 Console Architecture Cleanup

apps/console/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"@object-ui/example-kitchen-sink": "workspace:*",
3535
"@object-ui/example-todo": "workspace:*",
3636
"@object-ui/fields": "workspace:*",
37+
"@object-ui/i18n": "workspace:*",
3738
"@object-ui/layout": "workspace:*",
3839
"@object-ui/plugin-calendar": "workspace:*",
3940
"@object-ui/plugin-charts": "workspace:*",

apps/console/src/__tests__/KeyboardShortcuts.test.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,34 @@ vi.mock('@object-ui/components', () => ({
1515
DialogDescription: ({ children }: any) => <p>{children}</p>,
1616
}));
1717

18+
// Mock i18n — return the key's last segment as display text
19+
vi.mock('@object-ui/i18n', () => ({
20+
useObjectTranslation: () => ({
21+
t: (key: string) => {
22+
const translations: Record<string, string> = {
23+
'console.shortcuts.title': 'Keyboard Shortcuts',
24+
'console.shortcuts.description': 'Quick reference for all available keyboard shortcuts.',
25+
'console.shortcuts.groups.general': 'General',
26+
'console.shortcuts.groups.navigation': 'Navigation',
27+
'console.shortcuts.groups.dataViews': 'Data Views',
28+
'console.shortcuts.groups.preferences': 'Preferences',
29+
'console.shortcuts.openCommandPalette': 'Open command palette',
30+
'console.shortcuts.showShortcuts': 'Show keyboard shortcuts',
31+
'console.shortcuts.closeDialog': 'Close dialog / panel',
32+
'console.shortcuts.toggleSidebar': 'Toggle sidebar',
33+
'console.shortcuts.focusSearch': 'Focus search',
34+
'console.shortcuts.createRecord': 'Create new record',
35+
'console.shortcuts.refreshData': 'Refresh data',
36+
'console.shortcuts.editRecord': 'Edit selected record',
37+
'console.shortcuts.toggleDarkMode': 'Toggle dark mode',
38+
};
39+
return translations[key] ?? key;
40+
},
41+
language: 'en',
42+
direction: 'ltr',
43+
}),
44+
}));
45+
1846
describe('KeyboardShortcutsDialog', () => {
1947
it('renders without errors', () => {
2048
const { container } = render(<KeyboardShortcutsDialog />);

0 commit comments

Comments
 (0)