From 2c0151ed5be7f1287d0a843333d1c8ebe3de401e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 03:10:51 +0000 Subject: [PATCH 1/2] Initial plan From 5b4759aadb818feea63406ff2b9b7bce36c431c8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 03:18:03 +0000 Subject: [PATCH 2/2] Add Airtable Interface gap analysis design document and update ROADMAP - Create docs/design/airtable-interface-gap-analysis.md with detailed comparison of ObjectStack UI Protocol vs Airtable Interfaces - Add UI Protocol Enhancement roadmap items to Phase 8 (8.1) - Update versioning plan with UI protocol work in v3.2-v4.1 - Add design document reference to Related Documents section Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- ROADMAP.md | 54 +- .../design/airtable-interface-gap-analysis.md | 662 ++++++++++++++++++ 2 files changed, 707 insertions(+), 9 deletions(-) create mode 100644 docs/design/airtable-interface-gap-analysis.md diff --git a/ROADMAP.md b/ROADMAP.md index 0c1189af6..fa47a0efc 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,6 +1,6 @@ # ObjectStack Protocol — Road Map -> **Last Updated:** 2026-02-15 +> **Last Updated:** 2026-02-16 > **Current Version:** v3.0.2 > **Status:** Protocol Specification Complete · Runtime Implementation In Progress @@ -352,7 +352,41 @@ The following renames are planned for packages that implement core service contr > **Goal:** Build the ecosystem for community and enterprise adoption. -### 8.1 Studio IDE +### 8.1 UI Protocol Enhancement — Airtable Interface Parity + +> See [Airtable Interface Gap Analysis](docs/design/airtable-interface-gap-analysis.md) for the full evaluation. + +#### Phase A: Interface Foundation (v3.2) + +- [ ] `InterfaceSchema` — Self-contained, shareable, multi-page application surface (`src/ui/interface.zod.ts`) +- [ ] `RecordReviewConfigSchema` — Sequential record review/approval page type with navigation and actions +- [ ] Content elements — `element:text`, `element:number`, `element:image`, `element:divider` as `PageComponentType` extensions +- [ ] Per-element data binding — `dataSource` property on `PageComponentInstanceSchema` for multi-object pages +- [ ] Element props — `ElementTextPropsSchema`, `ElementNumberPropsSchema`, `ElementImagePropsSchema` + +#### Phase B: Element Library & Builder (v3.3) + +- [ ] Interactive elements — `element:button`, `element:filter`, `element:form`, `element:record_picker` +- [ ] `BlankPageLayoutSchema` — Free-form canvas composition with grid-based positioning +- [ ] Record picker variable binding — `PageVariableSchema` integration with `element:record_picker` +- [ ] Studio Interface Builder — Drag-and-drop element placement UI + +#### Phase C: Sharing, Embedding & Permissions (v4.0) + +- [ ] `SharingConfigSchema` — Public link, password, domain restriction, expiration (`src/ui/sharing.zod.ts`) +- [ ] `EmbedConfigSchema` — iframe embedding with origin restrictions and display options +- [ ] Per-interface role assignment — `assignedRoles` on `InterfaceSchema` +- [ ] Public form sharing — `sharing` property on `FormViewSchema` +- [ ] Design-time user impersonation — `previewAs` option for interface preview + +#### Phase D: Advanced Interface Features (v4.1) + +- [ ] Interface templates and duplication +- [ ] Interface versioning — draft → published → archived lifecycle +- [ ] Real-time collaborative interface editing +- [ ] Interface analytics — page views, element interactions, user engagement + +### 8.2 Studio IDE - [x] Object Designer Protocol — field editor, relationship mapper, ER diagram, object manager schemas defined (`studio/object-designer.zod.ts`) - [ ] Object Designer Runtime — visual field editor with inline editing, drag-reorder, type-aware property panels @@ -360,6 +394,7 @@ The following renames are planned for packages that implement core service contr - [ ] ER Diagram — interactive entity-relationship diagram with force/hierarchy/grid layouts, minimap, zoom, export (PNG/SVG) - [ ] Object Manager — unified object list with search, filter, card/table/tree views, quick preview, statistics - [ ] View Builder — drag-and-drop list/form/dashboard designers +- [ ] Interface Builder — drag-and-drop interface designer with element palette (see [Gap Analysis](docs/design/airtable-interface-gap-analysis.md)) - [ ] Flow Builder — visual automation flow editor - [ ] Security Console — permission matrix, RLS policy editor - [ ] AI Playground — agent testing, NLQ sandbox @@ -367,21 +402,21 @@ The following renames are planned for packages that implement core service contr > See [`apps/studio/ROADMAP.md`](apps/studio/ROADMAP.md) for detailed Studio phases. -### 8.2 Developer Experience +### 8.3 Developer Experience - [ ] VS Code Extension — full IntelliSense, diagnostics, and code actions for `.object.ts`, `.view.ts` - [ ] `create-objectstack` scaffolding — templates for app, plugin, driver, adapter - [ ] Documentation site — interactive tutorials, API playground - [ ] CLI enhancements — `objectstack migrate`, `objectstack deploy` -### 8.3 Marketplace & Cloud +### 8.4 Marketplace & Cloud - [ ] Plugin marketplace — publish, discover, install community plugins - [ ] App store — pre-built applications (CRM, HRM, Project Management) - [ ] Developer portal — API keys, usage metrics, billing - [ ] Managed cloud offering — ObjectStack-as-a-Service -### 8.4 Example Applications +### 8.5 Example Applications - [x] **app-todo** — Beginner reference (objects, actions, flows, dashboards, reports, i18n) ✅ - [x] **app-crm** — Enterprise reference (10 objects, 5 AI agents, 4 RAG pipelines, security profiles) ✅ @@ -486,10 +521,10 @@ The following renames are planned for packages that implement core service contr |:---|:---|:---| | **v3.0** | ✅ Shipped | Protocol specification complete, core runtime stable | | **v3.1** | Q2 2026 | Essential services (`service-cache`, `service-queue`, `service-job`, `service-storage`), PostgreSQL driver, Turso/libSQL core driver ([design](docs/design/driver-turso.md)) | -| **v3.2** | Q3 2026 | Communication services (`service-realtime`, `service-graphql`, `service-i18n`, `service-notification`), Turso embedded replica & edge sync | -| **v3.3** | Q4 2026 | Business logic services (`service-automation`, `service-workflow`, `service-search`), Turso multi-tenancy (database-per-tenant) | -| **v4.0** | Q1 2027 | Zod v4 migration, `plugin-auth` → `service-auth` rename, JSON Schema output, OpenAPI generation, AI services, multi-tenancy, Turso vector search & FTS5 integration | -| **v4.1** | Q2 2027 | Studio IDE general availability, marketplace launch | +| **v3.2** | Q3 2026 | Communication services (`service-realtime`, `service-graphql`, `service-i18n`, `service-notification`), Turso embedded replica & edge sync, UI Protocol Enhancement Phase A (`InterfaceSchema`, `RecordReviewConfig`, content elements) — see [gap analysis](docs/design/airtable-interface-gap-analysis.md) | +| **v3.3** | Q4 2026 | Business logic services (`service-automation`, `service-workflow`, `service-search`), Turso multi-tenancy (database-per-tenant), UI Protocol Enhancement Phase B (interactive elements, blank page layout, Interface Builder) | +| **v4.0** | Q1 2027 | Zod v4 migration, `plugin-auth` → `service-auth` rename, JSON Schema output, OpenAPI generation, AI services, multi-tenancy, Turso vector search & FTS5 integration, UI Protocol Enhancement Phase C (sharing, embedding, per-interface permissions) | +| **v4.1** | Q2 2027 | Studio IDE general availability, marketplace launch, UI Protocol Enhancement Phase D (templates, versioning, collaborative editing) | | **v5.0** | 2027+ | Managed cloud, app store, global ecosystem | --- @@ -500,6 +535,7 @@ The following renames are planned for packages that implement core service contr |:---|:---| | [`ARCHITECTURE.md`](ARCHITECTURE.md) | Microkernel design, package structure, three-layer protocol stack | | [`docs/design/driver-turso.md`](docs/design/driver-turso.md) | Turso/libSQL driver design document — architecture impact, capabilities, implementation phases | +| [`docs/design/airtable-interface-gap-analysis.md`](docs/design/airtable-interface-gap-analysis.md) | Airtable Interface gap analysis — UI protocol comparison, schema proposals, implementation roadmap | | [`apps/studio/ROADMAP.md`](apps/studio/ROADMAP.md) | Studio IDE development phases (v2.1 → v3.0) | | [`docs/DX_ROADMAP.md`](docs/DX_ROADMAP.md) | Developer experience improvements | | [`RELEASE_NOTES.md`](RELEASE_NOTES.md) | Version history and changelog | diff --git a/docs/design/airtable-interface-gap-analysis.md b/docs/design/airtable-interface-gap-analysis.md new file mode 100644 index 000000000..74a12281c --- /dev/null +++ b/docs/design/airtable-interface-gap-analysis.md @@ -0,0 +1,662 @@ +# Design Document: Airtable Interface Gap Analysis — ObjectStack UI Protocol Evaluation + +> **Author:** ObjectStack Core Team +> **Created:** 2026-02-16 +> **Status:** Proposal +> **Target Version:** v3.2 – v4.0 + +--- + +## Table of Contents + +- [1. Executive Summary](#1-executive-summary) +- [2. Airtable Interfaces Overview](#2-airtable-interfaces-overview) + - [2.1 Page Types](#21-page-types) + - [2.2 Interface Elements](#22-interface-elements) + - [2.3 Design Philosophy](#23-design-philosophy) +- [3. Feature Comparison Matrix](#3-feature-comparison-matrix) + - [3.1 Page Types & Layouts](#31-page-types--layouts) + - [3.2 View Types (Data Visualization)](#32-view-types-data-visualization) + - [3.3 Interface Elements](#33-interface-elements) + - [3.4 Interaction & Permissions](#34-interaction--permissions) + - [3.5 Sharing & Distribution](#35-sharing--distribution) +- [4. Gap Analysis — What ObjectStack Is Missing](#4-gap-analysis--what-objectstack-is-missing) + - [4.1 Critical Gaps (P0)](#41-critical-gaps-p0) + - [4.2 Important Gaps (P1)](#42-important-gaps-p1) + - [4.3 Nice-to-Have Gaps (P2)](#43-nice-to-have-gaps-p2) +- [5. ObjectStack Advantages Over Airtable](#5-objectstack-advantages-over-airtable) +- [6. Schema Improvement Proposals](#6-schema-improvement-proposals) + - [6.1 Interface Schema (New)](#61-interface-schema-new) + - [6.2 Interface Page Schema (New)](#62-interface-page-schema-new) + - [6.3 Interface Element Schema (New)](#63-interface-element-schema-new) + - [6.4 View Schema Enhancements](#64-view-schema-enhancements) + - [6.5 Sharing & Embedding Schema (New)](#65-sharing--embedding-schema-new) +- [7. Implementation Road Map](#7-implementation-road-map) + - [7.1 Phase A: Interface Foundation (v3.2)](#71-phase-a-interface-foundation-v32) + - [7.2 Phase B: Element Library & Builder (v3.3)](#72-phase-b-element-library--builder-v33) + - [7.3 Phase C: Sharing, Embedding & Permissions (v4.0)](#73-phase-c-sharing-embedding--permissions-v40) + - [7.4 Phase D: Advanced Interface Features (v4.1)](#74-phase-d-advanced-interface-features-v41) +- [8. Risk Analysis](#8-risk-analysis) +- [9. Decision Log](#9-decision-log) +- [10. References](#10-references) + +--- + +## 1. Executive Summary + +This document evaluates the gap between ObjectStack's current UI Protocol (`packages/spec/src/ui/`) and +**Airtable Interfaces** — the industry-leading no-code interface builder for data-centric applications. + +**Key Finding:** ObjectStack already possesses a **technically richer** schema foundation than Airtable +(45+ chart types, Gantt/Map views, full theme system, offline support, AI components, drag-and-drop). +However, it lacks Airtable's **"Interface" abstraction** — the concept of a self-contained, shareable, +role-specific application surface that stitches together multiple views, elements, and actions into a +cohesive experience. + +The core gap is **not** in individual component capabilities, but in the **composition layer** that +ties them together — specifically: + +| Area | Airtable | ObjectStack | +|:---|:---|:---| +| **Interface as a first-class entity** | ✅ Multi-page app per base | 🟡 App + Page exist separately | +| **Drag-and-drop element canvas** | ✅ Free-form element placement | 🟡 Region-based composition | +| **Record Review workflow** | ✅ Built-in record-by-record review | ❌ Not modeled | +| **Element-level data binding** | ✅ Each element binds to any table/view | 🟡 Page-level object binding | +| **Shareable interface URLs** | ✅ Public/private share links | ❌ Not modeled | +| **Interface-level permissions** | ✅ Per-interface user access | 🟡 App-level permissions only | +| **Embeddable interfaces** | ✅ iframe embed codes | ❌ Not modeled | + +This document proposes specific schema additions and a phased roadmap to close these gaps while +preserving ObjectStack's superior extensibility and enterprise capabilities. + +--- + +## 2. Airtable Interfaces Overview + +### 2.1 Page Types + +Airtable Interfaces organize data presentations into **page types** — pre-configured layouts +optimized for specific workflows: + +| Page Type | Purpose | Key Elements | +|:---|:---|:---| +| **Dashboard** | KPI summary, executive overview | Charts, numbers, text, buttons | +| **Grid** | Spreadsheet-like data management | Sortable/filterable table with inline editing | +| **List** | Record list with quick actions | Compact record cards, status indicators | +| **Gallery** | Visual browsing (images/cards) | Large cards with cover images | +| **Kanban** | Status-based workflow boards | Drag-and-drop columns | +| **Calendar** | Date-based scheduling | Monthly/weekly event display | +| **Timeline** | Gantt-like project timelines | Date range bars on a timeline axis | +| **Form** | Data collection and entry | Custom form fields with validation | +| **Record Detail** | Single record deep-dive | All fields, linked records, comments | +| **Record Review** | Sequential record review/approval | Record flipper, approval actions | +| **Overview** | Landing/navigation hub | Links, instructions, bookmarks | +| **Blank** | Free-form canvas | Any combination of elements | + +### 2.2 Interface Elements + +Each page can contain **elements** — modular UI building blocks: + +| Element | Description | +|:---|:---| +| **Grid** | Embedded data table (read-only or editable) | +| **Chart** | Bar, line, pie, donut visualizations | +| **Number** | Single metric/aggregate (count, sum, avg) | +| **Text** | Static text, headers, instructions (Markdown) | +| **Button** | Trigger actions (update record, open URL, run automation) | +| **Filter** | User-interactive filter controls | +| **Divider** | Visual separator between sections | +| **Form** | Inline data entry form | +| **Record Detail** | Selected record's field values | +| **Record List** | Compact list of records from any table | +| **Image** | Static image or attachment preview | +| **Link/Bookmark** | Navigation link to another page or external URL | + +### 2.3 Design Philosophy + +Airtable's approach is characterized by: + +1. **Data-first composition** — Every element is bound to a data source (table + view + filter) +2. **Role-specific surfaces** — Same data, different interfaces for different stakeholders +3. **Zero-code building** — Drag-and-drop, no configuration files +4. **Progressive disclosure** — Simple defaults, advanced options on demand +5. **Shareable artifacts** — Interfaces are independently shareable/embeddable +6. **Record-centric workflow** — Review, approve, and edit records inline + +--- + +## 3. Feature Comparison Matrix + +### 3.1 Page Types & Layouts + +| Page Type | Airtable | ObjectStack | Gap | +|:---|:---:|:---:|:---| +| Dashboard | ✅ | ✅ `DashboardSchema` | Parity — ObjectStack has richer widget/chart options | +| Grid/Table | ✅ | ✅ `ListViewSchema` (type: grid) | Parity | +| Kanban Board | ✅ | ✅ `ListViewSchema` (type: kanban) | Parity | +| Gallery | ✅ | ✅ `ListViewSchema` (type: gallery) | Parity | +| Calendar | ✅ | ✅ `ListViewSchema` (type: calendar) | Parity | +| Timeline | ✅ | ✅ `ListViewSchema` (type: timeline) | Parity | +| Form | ✅ | ✅ `FormViewSchema` | ObjectStack has more form types (wizard, split, drawer) | +| Record Detail | ✅ | ✅ `PageSchema` (type: record) | ObjectStack has component-based region model | +| Record Review | ✅ | ❌ | **GAP** — No sequential review/approval page type | +| Overview/Landing | ✅ | ✅ `PageSchema` (type: home) | Parity — ObjectStack uses component regions | +| Blank/Free-form | ✅ | 🟡 `PageSchema` (type: utility) | Partial — region-based, not free-form canvas | +| Gantt | ❌ | ✅ `ListViewSchema` (type: gantt) | **ObjectStack advantage** | +| Map | ❌ | ✅ `ListViewSchema` (type: map) | **ObjectStack advantage** | + +### 3.2 View Types (Data Visualization) + +| View Feature | Airtable | ObjectStack | Gap | +|:---|:---:|:---:|:---| +| Grid with inline editing | ✅ | ✅ `inlineEdit` | Parity | +| Column pinning | ✅ | ✅ `pinned: left/right` | Parity | +| Row grouping (multi-level) | ✅ (1 level) | ✅ (3 levels) | **ObjectStack advantage** | +| Column summaries | ✅ | ✅ `summary` (6 aggregates) | Parity | +| Row coloring | ✅ | ✅ `RowColorConfigSchema` | Parity | +| Row height density | ✅ | ✅ (5 levels) | **ObjectStack advantage** (5 vs 4) | +| Quick filters | ✅ | ✅ `quickFilters` | Parity | +| Virtual scrolling | ❌ | ✅ | **ObjectStack advantage** | +| Export (CSV/XLSX/PDF/JSON) | 🟡 (CSV only) | ✅ (4 formats) | **ObjectStack advantage** | +| Personal/collaborative views | ✅ | ✅ `ViewSharingSchema` | Parity | +| View locking | ✅ | ✅ `lockedBy` | Parity | +| Conditional formatting | 🟡 (record coloring) | ✅ `conditionalFormatting` | **ObjectStack advantage** | + +### 3.3 Interface Elements + +| Element | Airtable | ObjectStack | Gap | +|:---|:---:|:---:|:---| +| Chart widget | ✅ (4 types) | ✅ (45+ types) | **ObjectStack advantage** | +| Number/Metric | ✅ | ✅ `DashboardWidgetSchema` (metric) | Parity | +| Static text/Markdown | ✅ | 🟡 `PageHeaderProps` | **GAP** — No standalone text element | +| Button/Action | ✅ | ✅ `ActionSchema` | Parity | +| Filter control | ✅ | ✅ `quickFilters`, `GlobalFilterSchema` | Parity | +| Divider/Separator | ✅ | ❌ | **GAP** — No divider element | +| Image element | ✅ | ❌ | **GAP** — No standalone image element | +| Record picker/selector | ✅ | ❌ | **GAP** — No record picker element | +| Linked record list | ✅ | ✅ `RecordRelatedListProps` | Parity | +| Inline form | ✅ | 🟡 `FormViewSchema` (standalone) | Partial — form is a full view, not an embeddable element | +| Bookmark/Link | ✅ | 🟡 `UrlNavItemSchema` | Partial — navigation only, not in-page element | +| Cover image/Branding | ✅ | ✅ `AppBrandingSchema` | Parity | + +### 3.4 Interaction & Permissions + +| Feature | Airtable | ObjectStack | Gap | +|:---|:---:|:---:|:---| +| Per-interface user access | ✅ | 🟡 `requiredPermissions` (app-level) | **GAP** — No per-interface/page-level sharing | +| Conditional field visibility | ✅ (Business/Enterprise) | ✅ `visibleOn` in FormView | Parity | +| Element group visibility | ✅ | 🟡 Component visibility in Page | Partial | +| Record-level commenting | ✅ | ✅ `record:chatter` component | Parity | +| Activity feed | ✅ | ✅ `record:activity` component | Parity | +| Record approval workflow | ✅ | 🟡 `WorkflowSchema` (separate system) | Partial — exists but not integrated into UI | +| Drag-and-drop record reorder | ✅ | ✅ `DnDSchema` | Parity | +| Button → Automation trigger | ✅ | ✅ `ActionSchema` (type: flow) | Parity | +| Button → Record update | ✅ | ✅ `ActionSchema` (type: script) | Parity | +| Button → URL navigation | ✅ | ✅ `ActionSchema` (type: url) | Parity | + +### 3.5 Sharing & Distribution + +| Feature | Airtable | ObjectStack | Gap | +|:---|:---:|:---:|:---| +| Public share link | ✅ | ❌ | **GAP** — No share link generation | +| Password-protected share | ✅ | ❌ | **GAP** | +| Email domain restriction | ✅ | ❌ | **GAP** | +| Embeddable iframe | ✅ | ❌ | **GAP** — No embed configuration | +| Share with specific users | ✅ | 🟡 `requiredPermissions` | Partial — permission-based, not user-list-based | +| Share with edit/view-only | ✅ | ❌ | **GAP** — No access level on share | +| Shareable form (public) | ✅ | ❌ | **GAP** | +| Preview as another user | ✅ | ❌ | **GAP** | + +--- + +## 4. Gap Analysis — What ObjectStack Is Missing + +### 4.1 Critical Gaps (P0) + +#### G1: Interface as a First-Class Entity + +**Problem:** Airtable treats an "Interface" as a top-level entity — a multi-page, shareable +application bound to a data base. ObjectStack has `AppSchema` and `PageSchema` separately but +lacks the **intermediate "Interface"** concept that bundles pages into a shareable, role-specific +surface. + +**Impact:** Cannot model the Airtable use case: "Marketing team sees Dashboard + Gallery, Sales +team sees Kanban + Record Review, External clients see Form + Overview". + +**Proposed Solution:** Introduce `InterfaceSchema` — a self-contained, shareable application +surface containing ordered pages, branding, and access controls. + +#### G2: Record Review Page Type + +**Problem:** Airtable's "Record Review" page enables sequential record-by-record review with +approval/rejection actions. ObjectStack has no equivalent page type — the closest is +`PageSchema` (type: record) which shows a single record. + +**Impact:** Cannot model approval queues, content review workflows, or data QA processes +natively in the UI protocol. + +**Proposed Solution:** Add `recordReview` type to `PageSchema` or introduce a +`RecordReviewConfigSchema` with record navigation, approval actions, and filter criteria. + +#### G3: Standalone Interface Elements + +**Problem:** Airtable allows placing **standalone elements** (text, number, divider, image, +button) freely on any page. ObjectStack's `PageSchema` uses a **region → component** model +which is more structured but doesn't include simple content elements. + +**Impact:** Cannot create rich informational pages with mixed content (text + metrics + charts + +dividers) as flexibly as Airtable. + +**Proposed Solution:** Extend `PageComponentType` to include content elements: +`element:text`, `element:number`, `element:image`, `element:divider`, `element:button`, +`element:filter`. + +### 4.2 Important Gaps (P1) + +#### G4: Sharing & Embedding Configuration + +**Problem:** ObjectStack has no schema for generating share links, configuring embed codes, +or controlling public access to interfaces/views/forms. + +**Impact:** Cannot model the common Airtable pattern of sharing a dashboard with stakeholders +or embedding a form in an external website. + +**Proposed Solution:** Introduce `SharingSchema` with share type (public link, password, domain +restriction, embed), access level (view/comment/edit), and expiration. + +#### G5: Per-Element Data Binding + +**Problem:** In Airtable, each element (grid, chart, number) can independently bind to a +different table and view. In ObjectStack, `PageSchema` binds to a single `object` at the page +level, and components operate within that context. + +**Impact:** Cannot create pages that combine data from multiple objects (e.g., a dashboard page +with a "Projects" grid alongside a "Tasks" kanban and a "Team" gallery). + +**Proposed Solution:** Add `dataSource` property to individual page components, allowing +per-element object/view binding that overrides the page-level context. + +#### G6: Inline Form Element + +**Problem:** Airtable can embed a form element within any page. ObjectStack treats `FormView` +as a standalone view type, not an embeddable page component. + +**Impact:** Cannot create pages that combine informational content with data entry (e.g., +"Overview page with embedded quick-add form"). + +**Proposed Solution:** Add `element:form` to `PageComponentType` with props for target object, +visible fields, and submission action. + +### 4.3 Nice-to-Have Gaps (P2) + +#### G7: User Impersonation Preview + +**Problem:** Airtable allows interface builders to preview the interface "as another user" to +verify role-based visibility. ObjectStack has no equivalent in its protocol. + +**Proposed Solution:** Add `previewAs` option to `InterfaceSchema` or `PageSchema` for design-time +impersonation support in Studio. + +#### G8: Interface Templates & Duplication + +**Problem:** Airtable allows duplicating interface pages and using templates. ObjectStack's +`AppSchema` doesn't model template inheritance or duplication. + +**Proposed Solution:** Add `template` field to `InterfaceSchema` referencing a base template, +and support `clone` operations in Studio. + +#### G9: Record Picker Element + +**Problem:** Airtable has a "Record Picker" element that lets users select a record from a +dropdown to populate context for other elements on the page. ObjectStack has no equivalent +standalone element. + +**Proposed Solution:** Add `element:recordPicker` to `PageComponentType` with props for source +object, display field, filter criteria, and variable binding. + +--- + +## 5. ObjectStack Advantages Over Airtable + +ObjectStack's UI Protocol already **exceeds Airtable** in several significant areas: + +| Capability | Airtable | ObjectStack | +|:---|:---:|:---:| +| Chart types | 4 (bar, line, pie, donut) | 45+ (including sankey, treemap, heatmap, radar, waterfall, candlestick) | +| Gantt view | ❌ | ✅ with dependencies and progress tracking | +| Map view | ❌ | ✅ with clustering and zoom | +| Form types | 1 (simple) | 6 (simple, tabbed, wizard, split, drawer, modal) | +| Theme system | ❌ (fixed branding) | ✅ Full design system (colors, typography, spacing, shadows, animations) | +| Offline support | ❌ | ✅ Cache strategies, sync queuing, conflict resolution | +| Custom widgets | ❌ (limited extensions) | ✅ NPM, Module Federation, inline code | +| AI components | ❌ | ✅ Chat window, suggestions, agent integration | +| Keyboard shortcuts | Limited | ✅ Full keyboard navigation, focus management, shortcuts | +| Touch/gesture support | Basic | ✅ Swipe, pinch, long-press, haptic feedback | +| Drag-and-drop protocol | Basic (kanban) | ✅ Full DnD with constraints, drop zones, sortable lists | +| Responsive design | Basic | ✅ 6 breakpoints, per-component columns, visibility rules | +| Animation/transitions | ❌ | ✅ Page transitions, component animations, easing functions | +| Internationalization | ❌ | ✅ Full i18n with plurals, number/date formatting | +| Multi-level grouping | 1 level | 3 levels with independent sort | +| Export formats | CSV | CSV, XLSX, PDF, JSON | +| Report types | ❌ | 4 (tabular, summary, matrix, joined) | +| Notification system | ❌ | ✅ Toast, snackbar, banner, alert, inline | + +--- + +## 6. Schema Improvement Proposals + +### 6.1 Interface Schema (New) + +A new `InterfaceSchema` to represent the Airtable "Interface" concept — a self-contained, +shareable, multi-page application surface: + +```typescript +// Proposed: src/ui/interface.zod.ts + +export const InterfaceSchema = z.object({ + name: z.string().regex(/^[a-z_][a-z0-9_]*$/) + .describe('Machine name (snake_case)'), + label: z.string() + .describe('Display name'), + description: z.string().optional() + .describe('Purpose description'), + object: z.string().optional() + .describe('Primary object binding (snake_case)'), + pages: z.array(InterfacePageSchema) + .describe('Ordered list of pages in this interface'), + homePageId: z.string().optional() + .describe('Default landing page ID'), + branding: InterfaceBrandingSchema.optional() + .describe('Visual branding overrides'), + sharing: SharingConfigSchema.optional() + .describe('Sharing and access configuration'), + assignedRoles: z.array(z.string()).optional() + .describe('Roles that can access this interface'), + isDefault: z.boolean().optional() + .describe('Whether this is the default interface for the object'), +}); +``` + +### 6.2 Interface Page Schema (New) + +Extends the existing `PageSchema` with Airtable-inspired page types: + +```typescript +// Proposed additions to PageSchema types + +export const InterfacePageTypeSchema = z.enum([ + 'dashboard', // KPI summary with charts/metrics + 'grid', // Spreadsheet-like data table + 'list', // Record list with quick actions + 'gallery', // Card-based visual browsing + 'kanban', // Status-based board + 'calendar', // Date-based scheduling + 'timeline', // Gantt-like project timeline + 'form', // Data entry form + 'record_detail', // Single record deep-dive + 'record_review', // Sequential record review/approval (NEW) + 'overview', // Landing/navigation hub + 'blank', // Free-form canvas +]); + +export const RecordReviewConfigSchema = z.object({ + object: z.string().describe('Target object for review'), + filter: z.any().optional().describe('Filter criteria for review queue'), + sort: z.array(SortItemSchema).optional().describe('Sort order for review queue'), + displayFields: z.array(z.string()).optional() + .describe('Fields to display on the review page'), + actions: z.array(z.object({ + label: z.string().describe('Action button label'), + type: z.enum(['approve', 'reject', 'skip', 'custom']) + .describe('Action type'), + field: z.string().optional() + .describe('Field to update on action'), + value: z.any().optional() + .describe('Value to set on action'), + nextRecord: z.boolean().optional().default(true) + .describe('Auto-advance to next record after action'), + })).describe('Review actions'), + navigation: z.enum(['sequential', 'random', 'filtered']) + .optional().default('sequential') + .describe('Record navigation mode'), + showProgress: z.boolean().optional().default(true) + .describe('Show review progress indicator'), +}); +``` + +### 6.3 Interface Element Schema (New) + +Extends `PageComponentType` with standalone interface elements: + +```typescript +// Proposed additions to PageComponentType + +// Content elements (new) +'element:text' // Static text / Markdown block +'element:number' // Single metric / aggregate value +'element:image' // Static image or dynamic attachment +'element:divider' // Visual horizontal separator +'element:button' // Standalone action button +'element:filter' // User-interactive filter control +'element:form' // Inline embedded form +'element:record_picker' // Record selector dropdown + +// Props for new elements +export const ElementTextPropsSchema = z.object({ + content: z.string().describe('Text or Markdown content'), + variant: z.enum(['heading', 'subheading', 'body', 'caption']) + .optional().default('body'), + align: z.enum(['left', 'center', 'right']).optional().default('left'), +}); + +export const ElementNumberPropsSchema = z.object({ + object: z.string().describe('Source object'), + field: z.string().optional().describe('Field to aggregate'), + aggregate: z.enum(['count', 'sum', 'avg', 'min', 'max']) + .describe('Aggregation function'), + filter: z.any().optional().describe('Filter criteria'), + format: z.enum(['number', 'currency', 'percent']).optional(), + prefix: z.string().optional(), + suffix: z.string().optional(), +}); + +export const ElementImagePropsSchema = z.object({ + src: z.string().describe('Image URL or attachment field'), + alt: z.string().optional().describe('Alt text'), + fit: z.enum(['cover', 'contain', 'fill']).optional().default('cover'), + height: z.number().optional().describe('Fixed height in pixels'), +}); + +export const ElementRecordPickerPropsSchema = z.object({ + object: z.string().describe('Source object for record selection'), + displayField: z.string().describe('Field to display in dropdown'), + filter: z.any().optional().describe('Filter criteria'), + placeholder: z.string().optional(), + variable: z.string().describe('Page variable to bind selected record ID'), +}); + +export const ElementFormPropsSchema = z.object({ + object: z.string().describe('Target object for form submission'), + fields: z.array(z.string()).optional() + .describe('Specific fields to include'), + submitLabel: z.string().optional().default('Submit'), + successMessage: z.string().optional(), + resetAfterSubmit: z.boolean().optional().default(true), +}); +``` + +### 6.4 View Schema Enhancements + +Proposed enhancements to existing `ListViewSchema`: + +```typescript +// Per-element data source binding (for multi-object pages) +export const ElementDataSourceSchema = z.object({ + object: z.string().describe('Object to query'), + view: z.string().optional().describe('Named view to apply'), + filter: z.any().optional().describe('Additional filter criteria'), + sort: z.array(SortItemSchema).optional(), + limit: z.number().optional().describe('Max records to display'), +}); + +// Add to page component instances: +// dataSource: ElementDataSourceSchema.optional() +// .describe('Per-element data binding, overrides page-level object context') +``` + +### 6.5 Sharing & Embedding Schema (New) + +```typescript +// Proposed: additions to src/ui/app.zod.ts or new src/ui/sharing.zod.ts + +export const ShareAccessLevelSchema = z.enum([ + 'view', // Read-only access + 'comment', // Can view and comment + 'edit', // Can view, comment, and edit records +]); + +export const ShareTypeSchema = z.enum([ + 'private', // Only assigned users/roles + 'link', // Anyone with the link + 'password', // Link + password required + 'domain', // Restricted to email domain + 'embed', // Embeddable in external sites +]); + +export const SharingConfigSchema = z.object({ + enabled: z.boolean().default(false) + .describe('Whether sharing is active'), + type: ShareTypeSchema + .describe('Share access method'), + accessLevel: ShareAccessLevelSchema.optional().default('view') + .describe('What shared users can do'), + password: z.string().optional() + .describe('Password for password-protected shares'), + allowedDomains: z.array(z.string()).optional() + .describe('Allowed email domains for domain-restricted shares'), + expiresAt: z.string().optional() + .describe('ISO 8601 expiration date for the share link'), + allowDownload: z.boolean().optional().default(false) + .describe('Whether shared users can export/download data'), + showBranding: z.boolean().optional().default(true) + .describe('Whether to show ObjectStack branding on shared views'), +}); + +export const EmbedConfigSchema = z.object({ + enabled: z.boolean().default(false) + .describe('Whether embedding is allowed'), + allowedOrigins: z.array(z.string()).optional() + .describe('Allowed parent origins for iframe embedding'), + width: z.string().optional().default('100%') + .describe('Embed width (CSS value)'), + height: z.string().optional().default('600px') + .describe('Embed height (CSS value)'), + hideNavigation: z.boolean().optional().default(false) + .describe('Hide interface navigation in embedded mode'), + hideToolbar: z.boolean().optional().default(false) + .describe('Hide toolbar controls in embedded mode'), +}); +``` + +--- + +## 7. Implementation Road Map + +### 7.1 Phase A: Interface Foundation (v3.2 — Q3 2026) + +> **Goal:** Establish the "Interface" abstraction as a first-class protocol entity. + +- [ ] Define `InterfaceSchema` in `src/ui/interface.zod.ts` +- [ ] Add `RecordReviewConfigSchema` to `PageSchema` types +- [ ] Add content elements to `PageComponentType` (`element:text`, `element:number`, `element:image`, `element:divider`) +- [ ] Add `ElementTextPropsSchema`, `ElementNumberPropsSchema`, `ElementImagePropsSchema` to component props +- [ ] Add `dataSource` property to `PageComponentInstanceSchema` for per-element data binding +- [ ] Write comprehensive tests for all new schemas +- [ ] Update `src/ui/index.ts` exports +- [ ] Generate JSON Schema for new types + +**Estimated effort:** 2–3 weeks + +### 7.2 Phase B: Element Library & Builder (v3.3 — Q4 2026) + +> **Goal:** Complete the element library and enable free-form page composition. + +- [ ] Add interactive elements: `element:button`, `element:filter`, `element:form`, `element:record_picker` +- [ ] Add `ElementFormPropsSchema`, `ElementRecordPickerPropsSchema`, `ElementButtonPropsSchema`, `ElementFilterPropsSchema` +- [ ] Define `BlankPageLayoutSchema` for free-form canvas composition (grid-based positioning) +- [ ] Add `PageVariableSchema` integration with `element:record_picker` (variable binding) +- [ ] Add `RecordReviewConfigSchema` with approval actions, navigation modes, and progress indicators +- [ ] Implement Studio Interface Builder UI (drag-and-drop element placement) +- [ ] Write integration tests for multi-element page composition + +**Estimated effort:** 4–6 weeks + +### 7.3 Phase C: Sharing, Embedding & Permissions (v4.0 — Q1 2027) + +> **Goal:** Enable Airtable-level sharing and access control for interfaces. + +- [ ] Define `SharingConfigSchema` in `src/ui/sharing.zod.ts` +- [ ] Define `EmbedConfigSchema` for iframe embedding configuration +- [ ] Add `sharing` property to `InterfaceSchema` and `FormViewSchema` (public forms) +- [ ] Add per-interface role assignment (`assignedRoles`) +- [ ] Implement share link generation in runtime (service layer) +- [ ] Implement embed code generation with origin restrictions +- [ ] Add `previewAs` option for design-time user impersonation +- [ ] Security audit for shared/embedded interface access control +- [ ] Write permission and sharing tests + +**Estimated effort:** 4–6 weeks + +### 7.4 Phase D: Advanced Interface Features (v4.1 — Q2 2027) + +> **Goal:** Polish and advanced capabilities matching or exceeding Airtable. + +- [ ] Interface templates and duplication +- [ ] Interface versioning (draft → published → archived lifecycle) +- [ ] Multi-table dashboard pages (cross-object data binding) +- [ ] Real-time collaborative interface editing (multiple builders) +- [ ] Interface analytics (page views, element interactions, user engagement) +- [ ] Mobile-optimized interface rendering with responsive element layout +- [ ] A/B testing support for interface variants + +**Estimated effort:** 8–12 weeks + +--- + +## 8. Risk Analysis + +| Risk | Impact | Probability | Mitigation | +|:---|:---:|:---:|:---| +| **Schema bloat** — Adding too many element types increases spec complexity | Medium | Medium | Use discriminated unions; keep element props minimal; provide sensible defaults | +| **Backward compatibility** — New `InterfaceSchema` may conflict with existing `AppSchema` | High | Low | `InterfaceSchema` is additive; `AppSchema` remains as the top-level navigation container; `InterfaceSchema` lives within or alongside `AppSchema` | +| **Security of shared interfaces** — Public share links expose data | High | Medium | Default to read-only; require explicit opt-in; enforce row-level security on shared views; origin restrictions for embeds | +| **Performance of multi-source pages** — Pages binding to multiple objects create N+1 query patterns | Medium | High | Implement query batching in runtime; add `limit` to `ElementDataSourceSchema`; use caching service | +| **Scope creep** — Attempting to replicate all Airtable features at once | High | Medium | Phased approach; prioritize schema definitions first (spec repo), defer runtime to service implementations | + +--- + +## 9. Decision Log + +| # | Decision | Rationale | Date | +|:---:|:---|:---|:---| +| 1 | Introduce `InterfaceSchema` as separate from `AppSchema` | `AppSchema` is the navigation container; `InterfaceSchema` is a shareable, role-specific surface. They serve different architectural purposes. An App can contain multiple Interfaces. | 2026-02-16 | +| 2 | Add elements as `PageComponentType` extensions, not a separate system | Reuses existing region → component model; avoids a parallel composition system; maintains consistency | 2026-02-16 | +| 3 | Phase sharing/embedding to v4.0 | Requires security infrastructure (RLS, share tokens, origin validation) that depends on service implementations in v3.x | 2026-02-16 | +| 4 | Keep `RecordReviewConfig` as part of `PageSchema` rather than a new view type | Record Review is a page layout pattern, not a data visualization (view). It combines record display with workflow actions. | 2026-02-16 | +| 5 | Support per-element `dataSource` instead of page-level-only binding | Critical for dashboards and overview pages that aggregate data from multiple objects | 2026-02-16 | + +--- + +## 10. References + +| Source | URL | +|:---|:---| +| Airtable Interface Designer Docs | https://support.airtable.com/docs/interface-layouts | +| Airtable Record Detail Layout | https://support.airtable.com/docs/airtable-interface-layout-record-detail | +| Airtable Dynamic Filtering | https://support.airtable.com/docs/dynamic-filtering-in-linked-record-fields | +| Airtable Legacy Interface Elements | https://support.airtable.com/docs/legacy-interface-designer-functionality | +| ObjectStack UI Protocol | `packages/spec/src/ui/` | +| ObjectStack Page Schema | `packages/spec/src/ui/page.zod.ts` | +| ObjectStack View Schema | `packages/spec/src/ui/view.zod.ts` | +| ObjectStack Dashboard Schema | `packages/spec/src/ui/dashboard.zod.ts` | +| ObjectStack App Schema | `packages/spec/src/ui/app.zod.ts` |