|
| 1 | +# ObjectStack Console — Next Steps |
| 2 | + |
| 3 | +> Generated: 2026-02-07 |
| 4 | +> Previous: DEVELOPMENT_PLAN.md (10 phases — all complete ✅) |
| 5 | +
|
| 6 | +## Audit Summary |
| 7 | + |
| 8 | +After completing the initial 10 phases, a deep audit revealed these **architectural gaps**: |
| 9 | + |
| 10 | +| # | Finding | Impact | |
| 11 | +|---|---------|--------| |
| 12 | +| A | Console `ObjectView` is 400+ lines of hand-wired logic; the official `plugin-view/ObjectView` (410 lines) is registered but unused | High — duplicated CRUD, no SDUI | |
| 13 | +| B | `useExpression` not used anywhere — `visible` fields do simple `=== false` checks instead of expression evaluation | High — conditional rendering broken | |
| 14 | +| C | `ContactList.tsx` + `types.ts` are hardcoded legacy components (`client.data.find` directly), unused by current routing | Medium — dead code | |
| 15 | +| D | `plugin-view/ObjectView` registration passes `dataSource={null}` — broken unless overridden | Medium — blocks adoption | |
| 16 | +| E | Two competing `ActionSchema` interfaces (`crud.ts` vs `ui-action.ts`) — spec v0.7.1 version is orphaned | High — type confusion | |
| 17 | +| F | `ActionRunner.execute()` takes `any` — no typed action dispatch, no toast/redirect/dialog handling | Medium — action system is incomplete | |
| 18 | +| G | `DataSource` interface has no `getView`/`getApp` — can't fetch UI definitions from server | High — blocks server-driven UI | |
| 19 | +| H | `AppShell` has no branding props — `useBranding` hook works around this at app level | Low — works, not ideal | |
| 20 | +| I | `ThemeProvider` import is at bottom of App.tsx (below component definitions) | Low — code smell | |
| 21 | +| J | No console app documentation in `content/docs/` | Medium — DDD violation | |
| 22 | + |
| 23 | +--- |
| 24 | + |
| 25 | +## Phase 11: Dead Code Cleanup 🧹 (Quick — 30 min) |
| 26 | + |
| 27 | +| Task | Description | Files | |
| 28 | +|------|-------------|-------| |
| 29 | +| 11.1 | Delete `ContactList.tsx` — legacy, unused, violates SDUI pattern | `src/components/ContactList.tsx` | |
| 30 | +| 11.2 | Delete `types.ts` — `Contact` interface is unused (only by ContactList) | `src/types.ts` | |
| 31 | +| 11.3 | Move `ThemeProvider` import to top of App.tsx (code organization) | `src/App.tsx` | |
| 32 | +| 11.4 | Extract `RecordDetailView` from App.tsx into its own file | `src/App.tsx` → `src/components/RecordDetailView.tsx` | |
| 33 | +| 11.5 | Gate MSW console.logs behind `import.meta.env.DEV` | `src/mocks/browser.ts` | |
| 34 | + |
| 35 | +**Estimate:** 30 minutes |
| 36 | + |
| 37 | +--- |
| 38 | + |
| 39 | +## Phase 12: Expression Engine Integration 🧮 (High — 1 day) |
| 40 | + |
| 41 | +**Goal:** Make `visible`, `disabled`, `hidden` expressions actually work. |
| 42 | + |
| 43 | +| Task | Description | Files | |
| 44 | +|------|-------------|-------| |
| 45 | +| 12.1 | Import `useExpression` from `@object-ui/react` | Multiple components | |
| 46 | +| 12.2 | Replace `item.visible === false` with `useExpression(item.visible)` in `AppSidebar` | `src/components/AppSidebar.tsx` | |
| 47 | +| 12.3 | Add `hidden` expression evaluation in `ObjectView` for conditional fields | `src/components/ObjectView.tsx` | |
| 48 | +| 12.4 | Add expression context provider with `{ user, app, data }` at app root | `src/App.tsx` | |
| 49 | +| 12.5 | Add `visibleOn` support for navigation items per `@objectstack/spec` | `src/components/AppSidebar.tsx` | |
| 50 | + |
| 51 | +**Estimate:** 1 day |
| 52 | + |
| 53 | +--- |
| 54 | + |
| 55 | +## Phase 13: Consolidate to Plugin ObjectView 🏗️ (Critical — 2-3 days) |
| 56 | + |
| 57 | +**Goal:** Replace the 400-line hand-wired `ObjectView` in console with the official `plugin-view/ObjectView`. This is the single most impactful refactor — it makes the console truly Server-Driven. |
| 58 | + |
| 59 | +| Task | Description | Files | |
| 60 | +|------|-------------|-------| |
| 61 | +| 13.1 | Fix `plugin-view/ObjectView` registration to receive `dataSource` from `SchemaRendererProvider` context | `packages/plugin-view/src/index.tsx` | |
| 62 | +| 13.2 | Wire `FilterUI` + `SortUI` into `plugin-view/ObjectView` (replace TODO placeholder) | `packages/plugin-view/src/ObjectView.tsx` | |
| 63 | +| 13.3 | Add `ViewSwitcher` to `plugin-view/ObjectView` for multi-view support | `packages/plugin-view/src/ObjectView.tsx` | |
| 64 | +| 13.4 | Replace console's hand-wired `ObjectView` with `SchemaRenderer` rendering `object-view` type | `apps/console/src/components/ObjectView.tsx` | |
| 65 | +| 13.5 | Keep console-specific toolbar additions (MetadataInspector, branding) as wrapper | `apps/console/src/components/ObjectView.tsx` | |
| 66 | +| 13.6 | Ensure the CRUD Dialog uses the action system (`useObjectActions`) | `packages/plugin-view/src/ObjectView.tsx` | |
| 67 | + |
| 68 | +**Why:** Currently the console duplicates 80% of what `plugin-view/ObjectView` already does. The plugin version has proper CRUD modals, search, schema fetching — but it's not used. |
| 69 | + |
| 70 | +**Estimate:** 2-3 days |
| 71 | + |
| 72 | +--- |
| 73 | + |
| 74 | +## Phase 14: DataSource Metadata API 📡 (Critical — 1-2 days) |
| 75 | + |
| 76 | +**Goal:** Add `getView`, `getApp` methods to the DataSource interface so the console can fetch UI definitions from the server instead of using static config. |
| 77 | + |
| 78 | +| Task | Description | Files | |
| 79 | +|------|-------------|-------| |
| 80 | +| 14.1 | Add `getView(objectName, viewId)` to `DataSource` interface | `packages/types/src/data-source.ts` | |
| 81 | +| 14.2 | Add `getApp(appId)` to `DataSource` interface | `packages/types/src/data-source.ts` | |
| 82 | +| 14.3 | Implement `getView` / `getApp` in `ObjectStackAdapter` | `packages/data-objectstack/src/index.ts` | |
| 83 | +| 14.4 | Fallback to static config when server doesn't provide UI metadata | `apps/console/src/App.tsx` | |
| 84 | +| 14.5 | Add caching for view/app metadata in adapter | `packages/data-objectstack/src/index.ts` | |
| 85 | + |
| 86 | +**Estimate:** 1-2 days |
| 87 | + |
| 88 | +--- |
| 89 | + |
| 90 | +## Phase 15: Action System Completion 🎯 (Medium — 2 days) |
| 91 | + |
| 92 | +**Goal:** Unify the two ActionSchema types and make ActionRunner production-ready. |
| 93 | + |
| 94 | +| Task | Description | Files | |
| 95 | +|------|-------------|-------| |
| 96 | +| 15.1 | Deprecate `crud.ts` ActionSchema; make `ui-action.ts` the canonical one | `packages/types/src/index.ts` | |
| 97 | +| 15.2 | Type `ActionRunner.execute()` with `ActionSchema` instead of `any` | `packages/core/src/actions/ActionRunner.ts` | |
| 98 | +| 15.3 | Add `toast` action handler (integrate with Sonner/Toast from Shadcn) | `packages/core/src/actions/ActionRunner.ts` | |
| 99 | +| 15.4 | Add `dialog` action handler (open confirmation via Shadcn AlertDialog) | New: `packages/react/src/hooks/useActionDialog.ts` | |
| 100 | +| 15.5 | Add `redirect` result handling in `useActionRunner` | `packages/react/src/hooks/useActionRunner.ts` | |
| 101 | +| 15.6 | Wire action buttons into ObjectView toolbar from config | `apps/console/src/components/ObjectView.tsx` | |
| 102 | + |
| 103 | +**Estimate:** 2 days |
| 104 | + |
| 105 | +--- |
| 106 | + |
| 107 | +## Phase 16: App Shell Branding 🎨 (Medium — 1 day) |
| 108 | + |
| 109 | +**Goal:** Move branding from the console's `useBranding` hook into the `@object-ui/layout` AppShell so all apps get it for free. |
| 110 | + |
| 111 | +| Task | Description | Files | |
| 112 | +|------|-------------|-------| |
| 113 | +| 16.1 | Add `branding` prop to `AppShell` (logo, primaryColor, title) | `packages/layout/src/AppShell.tsx` | |
| 114 | +| 16.2 | Apply CSS custom properties inside AppShell (move logic from useBranding) | `packages/layout/src/AppShell.tsx` | |
| 115 | +| 16.3 | Console's `useBranding` becomes a thin wrapper over AppShell's built-in | `apps/console/src/hooks/useBranding.ts` | |
| 116 | +| 16.4 | Update `ConsoleLayout` to pass `activeApp.branding` to AppShell | `apps/console/src/components/ConsoleLayout.tsx` | |
| 117 | + |
| 118 | +**Estimate:** 1 day |
| 119 | + |
| 120 | +--- |
| 121 | + |
| 122 | +## Phase 17: Console Documentation 📚 (Medium — 1 day) |
| 123 | + |
| 124 | +**Goal:** Per Rule #2 (Documentation Driven Development), create console app docs. |
| 125 | + |
| 126 | +| Task | Description | Files | |
| 127 | +|------|-------------|-------| |
| 128 | +| 17.1 | Create getting-started guide for running the console | `content/docs/guide/console.md` | |
| 129 | +| 17.2 | Document the console architecture (data flow, routing, MSW mock) | `content/docs/guide/console-architecture.md` | |
| 130 | +| 17.3 | Add JSDoc headers to all console components | `apps/console/src/components/*.tsx` | |
| 131 | +| 17.4 | Update root `README.md` with console quickstart section | `apps/console/README.md` | |
| 132 | + |
| 133 | +**Estimate:** 1 day |
| 134 | + |
| 135 | +--- |
| 136 | + |
| 137 | +## Phase 18: Test Coverage 🧪 (Ongoing) |
| 138 | + |
| 139 | +**Goal:** The 20 existing test files need to be audited — some may be broken after all the refactoring. |
| 140 | + |
| 141 | +| Task | Description | Files | |
| 142 | +|------|-------------|-------| |
| 143 | +| 18.1 | Run all existing tests and fix failures | `vitest` | |
| 144 | +| 18.2 | Add test for `CommandPalette` keyboard shortcut | `src/__tests__/CommandPalette.test.tsx` | |
| 145 | +| 18.3 | Add test for `ErrorBoundary` recovery | `src/__tests__/ErrorBoundary.test.tsx` | |
| 146 | +| 18.4 | Add test for `useBranding` CSS variable injection | `src/__tests__/useBranding.test.tsx` | |
| 147 | +| 18.5 | Add test for `useObjectActions` handlers | `src/__tests__/useObjectActions.test.tsx` | |
| 148 | + |
| 149 | +**Estimate:** 1-2 days |
| 150 | + |
| 151 | +--- |
| 152 | + |
| 153 | +## Execution Order |
| 154 | + |
| 155 | +``` |
| 156 | +Phase 11 (cleanup) → 30 min ← Quick Win, remove dead code |
| 157 | +Phase 12 (expressions) → 1 day ← Unblock conditional UI |
| 158 | +Phase 13 (plugin OV) → 2-3 days← THE key refactor — true SDUI |
| 159 | +Phase 14 (metadata API) → 1-2 days← Server-driven data |
| 160 | +Phase 15 (action system) → 2 days ← Type safety + toast/dialog |
| 161 | +Phase 16 (app shell) → 1 day ← Package-level branding |
| 162 | +Phase 17 (docs) → 1 day ← DDD compliance |
| 163 | +Phase 18 (tests) → 1-2 days← Quality gate |
| 164 | +``` |
| 165 | + |
| 166 | +**Total: ~10 days for Phases 11-18** |
| 167 | + |
| 168 | +--- |
| 169 | + |
| 170 | +## Priority Matrix |
| 171 | + |
| 172 | +| Priority | Phase | Reason | |
| 173 | +|----------|-------|--------| |
| 174 | +| 🔴 Critical | Phase 13 | Eliminates 400 lines of duplication, makes console truly SDUI | |
| 175 | +| 🔴 Critical | Phase 14 | Unblocks server-driven metadata; without it, console is static-config-only | |
| 176 | +| 🟡 High | Phase 12 | Expression engine is the core of SDUI conditional rendering | |
| 177 | +| 🟡 High | Phase 15 | Action system type safety affects every interactive component | |
| 178 | +| 🟢 Medium | Phase 11 | Dead code is confusing but harmless | |
| 179 | +| 🟢 Medium | Phase 16 | useBranding works, just not in the ideal package | |
| 180 | +| 🟢 Medium | Phase 17 | Missing docs slow down contributors | |
| 181 | +| 🔵 Low | Phase 18 | Tests can be added incrementally | |
0 commit comments