Skip to content

feat: unified Navigation protocol with Area support and new nav item types#736

Merged
hotlong merged 2 commits into
mainfrom
copilot/unify-navigation-protocol
Feb 19, 2026
Merged

feat: unified Navigation protocol with Area support and new nav item types#736
hotlong merged 2 commits into
mainfrom
copilot/unify-navigation-protocol

Conversation

Copilot AI commented Feb 19, 2026

Copy link
Copy Markdown
Contributor

NavigationItem had limited type coverage (object/dashboard/page/url/group) and lacked per-item ordering, badges, and permissions. No support for Salesforce-style Area partitioning for enterprise apps with multiple business domains.

BaseNavItemSchema enhancements

  • order — sort position within same level
  • badge — string or number notification indicator
  • requiredPermissions — per-item access control

New navigation item types

  • ReportNavItemSchema (type: 'report') — targets a named report
  • ActionNavItemSchema (type: 'action') — triggers a named action with optional params

NavigationAreaSchema

Business domain partitioning (à la Salesforce App Areas). Each area owns an independent navigation tree with its own visibility/permissions.

AppSchema

Added optional areas: NavigationArea[]. Coexists with existing navigation[] for backward compat.

const app = defineApp({
  name: 'enterprise_crm',
  label: 'Enterprise CRM',
  areas: [
    {
      id: 'area_sales', label: 'Sales', icon: 'briefcase', order: 1,
      navigation: [
        { id: 'nav_leads', type: 'object', label: 'Leads', objectName: 'lead', badge: 12 },
        { id: 'nav_report', type: 'report', label: 'Pipeline', reportName: 'pipeline_overview' },
        { id: 'nav_new_lead', type: 'action', label: 'New Lead', actionDef: { actionName: 'create_lead' } },
      ],
    },
    {
      id: 'area_settings', label: 'Settings', icon: 'settings', order: 99,
      requiredPermissions: ['admin.access'],
      navigation: [
        { id: 'nav_users', type: 'object', label: 'Users', objectName: 'user' },
      ],
    },
  ],
});

All fields are optional additive — zero breaking changes to existing configs. 20 new tests added, full suite passes (5770/5770). ROADMAP updated.

Original prompt

This section details on the original issue you should resolve

<issue_title>统一 Navigation 协议,支持 Area/分区、系统对象管理和 Spec 级配置</issue_title>
<issue_description># 🎯 协议升级:App Navigation 统一与 Area/对象管理支持

背景

当前 ObjectStack 在 "App" 和 "导航" 协议上,存在多模型并行和難以系统对象化管理的问题(如 MenuItem、NavigationItem 两套并存)。主流低代码体系(Salesforce、Power Apps)普遍采用 Area(分区)、对象化与 JSON Schema 导航协议统一管理所有应用与导航。随着 Console/PC 端大幅企业增强,需要 Spec 协议层做支撑。


改动要求

1. 统一 NavigationItem 为唯一导航协议

  • 删除/废弃 MenuItem/多余历史协议,NavigationItem 成为唯一 source of truth。
  • 字段支持:type、label、icon、order、badge、children、visible、requiredPermissions、(objectName|dashboardName|pageName|reportName|url|target|actionDef)、areaId(归属分区)。
  • 表达式与权限一致可控。

2. 增加 Area/NavigationArea 支持

  • areas?: NavigationArea[] 分区,每个分区/业务域可定义独立 NavigationItem[] 树。

3. 规范所有协议为 Spec/Schema 驱动

  • 明确以 Zod Schema 为唯一入口,所有类型通过 z.infer 推导。
  • 命名规范:JS/TS 配置 camelCase,数据值 snake_case
  • 与 objectstack-ai/objectui、console、cli 完全对齐

4. 影响范围与兼容性说明

  • packages/spec/src/ui/app.zod.ts、view.zod.ts 等需要同步更新
  • 变动为 breaking change,建议增加 deprecate 声明并短期向后兼容
  • 建议文档附升级迁移指导方案

建议 Roadmap

  • 设计与评审统一 NavigationItem/Area 协议草案
  • 更新 Zod Schema 与主类型定义
  • CLI/Console/PC 框架适配新版 schema
  • 保留临时 transform 处理现有 menu 到 navigation 数据
  • 更新测试、Spec 文档、migration guide

开发与合入标准:规范性 PR + test + roadmap 更新
</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercel Bot commented Feb 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectstack-play Error Error Feb 19, 2026 0:51am
spec Error Error Feb 19, 2026 0:51am

Request Review

… enhanced BaseNavItem fields

- Add order, badge, requiredPermissions to BaseNavItemSchema
- Add ReportNavItemSchema (type: 'report')
- Add ActionNavItemSchema (type: 'action')
- Add NavigationAreaSchema for business domain partitioning
- Add areas field to AppSchema
- Update NavigationItemSchema union with new types
- Export new types: NavigationArea, ReportNavItem, ActionNavItem
- Add comprehensive tests (20 new test cases)
- Update ROADMAP.md with navigation unification milestone

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Unify navigation protocol to support Area and object management feat: unified Navigation protocol with Area support and new nav item types Feb 19, 2026
Copilot AI requested a review from hotlong February 19, 2026 12:47
@hotlong
hotlong marked this pull request as ready for review February 19, 2026 12:55
Copilot AI review requested due to automatic review settings February 19, 2026 12:55
@hotlong
hotlong merged commit efe7b06 into main Feb 19, 2026
1 of 3 checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the UI App navigation protocol in packages/spec to support enterprise-scale navigation via Areas, and adds new navigation item capabilities (ordering, badges, permissions) plus new item types (report/action), while keeping backward compatibility with existing navigation[] configs.

Changes:

  • Enhanced BaseNavItemSchema with order, badge, and requiredPermissions.
  • Added new ReportNavItemSchema and ActionNavItemSchema, and introduced NavigationAreaSchema with AppSchema.areas?: NavigationArea[].
  • Added comprehensive tests covering new fields/types/areas; updated ROADMAP to document the unified navigation protocol.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
packages/spec/src/ui/app.zod.ts Adds new nav item fields, new nav item types (report/action), and Area partitioning via NavigationAreaSchema + AppSchema.areas.
packages/spec/src/ui/app.test.ts Adds validation tests for the new fields, new item types, and app configs using areas.
ROADMAP.md Documents the unified navigation protocol additions in the UI Protocol deliverables list.

Comment on lines 131 to +135
DashboardNavItemSchema,
PageNavItemSchema,
UrlNavItemSchema,
ReportNavItemSchema,
ActionNavItemSchema,

Copilot AI Feb 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NavigationItemSchema is still declared as z.ZodType<any>, which makes z.infer<typeof NavigationItemSchema> (and the exported NavigationItem type) evaluate to any, eliminating type-safety for consumers. Since this union is being extended with new item types, consider introducing an explicit recursive NavigationItem TS union type and typing the schema as z.ZodType<NavigationItem> (casting the z.lazy(...) result if needed).

Copilot uses AI. Check for mistakes.
*/
export const ReportNavItemSchema = BaseNavItemSchema.extend({
type: z.literal('report'),
reportName: z.string().describe('Target report name'),

Copilot AI Feb 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReportSchema.name is validated as a snake_case identifier, but ReportNavItemSchema.reportName currently accepts any string. To prevent invalid references (and catch typos early), consider using SnakeCaseIdentifierSchema (or the same regex) for reportName in this new nav item type.

Suggested change
reportName: z.string().describe('Target report name'),
reportName: SnakeCaseIdentifierSchema.describe('Target report machine name (lowercase snake_case)'),

Copilot uses AI. Check for mistakes.
export const ActionNavItemSchema = BaseNavItemSchema.extend({
type: z.literal('action'),
actionDef: z.object({
actionName: z.string().describe('Action machine name to execute'),

Copilot AI Feb 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ActionSchema.name is constrained to snake_case via SnakeCaseIdentifierSchema, but ActionNavItemSchema.actionDef.actionName currently accepts any string. Since this is a new reference field, consider validating actionName with SnakeCaseIdentifierSchema (or reusing the Action schema identifier rules) to avoid configs that can never resolve to a real action.

Suggested change
actionName: z.string().describe('Action machine name to execute'),
actionName: SnakeCaseIdentifierSchema.describe('Action machine name to execute (lowercase snake_case)'),

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

统一 Navigation 协议,支持 Area/分区、系统对象管理和 Spec 级配置

3 participants