Repository navigation
视图声明 calendar 可视化但缺 calendar 配置块时,平台不报错——直接渲染成一屏错位画面(全部记录堆在今天) #13748
Description
Activity
- addedbugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3
on Aug 31, 2026 分诊 →
domain:spec·needs-user-decision· p2 · bug。这条我保留
needs-user-decision—— 与隔壁 #13751 不同。那条是「请先定级」,定级是分诊的活,我已经答了;这条问的是「平台该不该收下一份写了一半的声明」,那是契约松紧度,触人工地板(公共声明面的 accept 集收窄 + 会打断既有应用的构建),不该由分诊或车道 PM 替你定。锚定。 按我推荐的方向(见下)落点在视图声明 schema,
packages/spec⇒domain:spec(唯一所有者)。⚠️ 若你裁的是「只改界面表现」,落点变成 objectui 的日历呈现层,车道随裁决改挂repo:objectui—— 现在按推荐项挂,不是终局。
四维分析
① 实际业务需求. 现象是真实取证:同一对象下两个视图,一个能用一个渲染出「所有人的假都在同一天」,而工具条上的切换按钮正常显示、正常可点、点了不报错。搭建方没有任何信号知道自己漏了
startDateField。② 项目长远合理性. 本仓已有一条被你自己批过的原则 —— 声明即强制(cloud#1626 裁决的 ③ 轴 rider:一个 schema 合法的值不得是无条件运行时抛错)。这里是同一条原则的另一面:
allowedVisualizations: ['calendar']是一个声明了但兑现不了的能力。按该原则,它应当在声明处被拒,而不是在呈现处被兜底。反过来,如果这里判「宽松默认可接受」,那 #13393 那条postgres枚举的裁决就出现了一个反例,两处口径会不一致 —— 这是我建议同口径处理的主要理由。③ 防 AI 写代码犯错(本案最重). 立单方记下了一个关键事实:这两个视图是同一个 AI agent 依据一句业务需求、在同一批里生成的 —— agent 在一个视图里写全了日历配置,在另一个里只写了
allowedVisualizations。这不是人的疏忽,是本平台主要创作路径的一次典型产出。而平台对这份半成品的回应,是渲染出一屏自信的错误画面:它不像故障,它像数据本身。对一个「按描述长出模块」的平台,静默兜底把 agent 的一次遗漏放大成了「看起来验收通过」。④ 创业阶段不扩散需求. 四个方向的成本差很大:构建期校验是一条 superRefine(视图 schema 里已有同类拒收先例);运行期报错要新错误码 + 文案;界面降级提示要新空态 UI + 文案 + 翻译;「视为可接受的宽松默认」零成本但把缺陷留在线上。最省的恰好也是最早拦下的那个。
建议:构建期拒收 + 界面不再假装。 即 —— 声明面按 ② 收紧(
allowedVisualizations含calendar时必须有calendar:块,缺则带指引地拒收,#5099 那种「拒收并给出补法」的形状);呈现层在拿不到startDateField时 ⛔ 不得把记录堆到今天 —— 那个兜底的产物看起来像真数据,是本单最有害的一环,即使裁决只取界面半边,这一条也应当照做。⚠️ 需要你连带裁一个我不能替你答的问题:收紧 accept 集会让既有的、已经这么写的应用构建失败(hotcrm的all_leave_requests就是一个)。是(a)直接拒收并让存量应用改声明,还是(b)先落一轮 warning、下个 major 再拒?这决定了 Clause-② 的分级与是否需要迁移说明。⚠️ Clause-② 适用于实现卡:路径肢packages/spec/src/**,内容肢 = 收窄公共声明面的 accept 集。实现卡按CONTRACT_REVIEW_TIER派发并申报Clause-②: yes。定级 p2。 无数据损失、无安全后果,且有明确绕法(把配置块写全);不判 p3 是因为 ③ 轴 —— 失败发生在平台自己的主创作路径上,且无声。
邻近单:#13751(同为日历,但主题是导航控件步长,已单独定级 p2 /
repo:objectui)、#13696(同为「声明缺一环则能力不可用」,但那条失败得明显)。立单方的查重结论我认同,均不并卡。
Generated by Claude Code
huangyiirene commented
on Aug 31, 2026 CollaboratorMore actions裁决:定级 bug · p2,方向 A 两头修 —— 实现卡 #13817(spec 半)+ objectui#7029(runtime 半),本卡关(维护者 2026-08-31)
项目总监席 · session
session_01KGtaLpkW1mycWgkbSb3H6t· 决裁批 #19 ⑤维护者原话(逐字):「批 #19 同意」—— 本卡呈报推荐为「A,拆两张实现卡,定级 bug + p2」。
呈报时补齐的机制链(本席两仓实测;卡面只有现象,此为成因)
- spec 不拦:
packages/spec/src/ui/view.zod.ts:945的allowedVisualizations与:1679的calendar:块各自 optional、无交叉校验 ⇒ 写一半的声明原样通过元数据校验; - objectui 臆测:
packages/app-shell/src/views/ObjectView.tsx:2220在缺块时合成配置 ——startDateField: viewDef.calendar?.startDateField || 'due_date'、titleField: … || 'name',即发明字段名(crm_leave_request的真实字段是start_date,不是due_date); - 渲染器静默兜底:
packages/plugin-calendar/src/ObjectCalendar.tsx:445start: startDate ? new Date(startDate) : new Date()⇒ 读不到字段值的记录全部落「今天」; ObjectCalendar.tsx:657本来就有拒绝画面("Calendar configuration required…"),但第 2 层永远合成一个看起来完整的配置,该防线从此路由不可达 —— 不是没有防线,是防线被上游臆测短路。三层单看各自「合理」,叠起来把一个作者错误渲染成一屏可信的假数据。
裁决内容
- spec:
appearance.allowedVisualizationsmay includecalendarwith nocalendar:block — add the cross-field validation (calendar allowed ⇒calendar.startDateFieldrequired) #13817(objectstack,pm:queue· p2 · bug):spec 交叉校验 ——allowedVisualizations含calendar⇒calendar.startDateField必给(只要求承重键;title 有 ADR-0079 兜底链)。条款② YES(收紧 accept 面),带落地前存量普查(数清有多少存量视图正靠due_date臆测碰巧渲染); - objectui#7029(
pm:queue· p2 · bug):摘除臆测默认 —— 缺块 ⇒ 不传 calendar 配置,让既有拒绝画面接住(或禁用切换按钮,实现者择其净者;⛔ 不得再发明字段名); - 两卡独立可落。
状态转移(同笔)
定级
bug+priority:p2已在标签(与分诊同判,读回一致);needs-user-decision摘除;本卡关闭(completed) —— 现象记录完结,工作由两张实现卡承载。附注的一次性prev原地不动照卡面约定不作现象处理;同面导航缺陷 #13751 已另行分级入队,与本裁无涉。
Generated by Claude Code
- spec 不拦:
- added a commit that references this issue
on Sep 1, 2026 - added a commit that references this issue
on Sep 1, 2026
现象
同一个对象
crm_leave_request下的两个视图,都能切到日历呈现,但只有一个真的能用:all_leave_requestsappearance.allowedVisualizations: ['grid','calendar'],没有calendar:配置块(无startDateField/endDateField)LR-00008/LR-00007/ … /+5 more)。翻到下一月则整月全空team_leave_calendarcalendar:配置块(startDateField: 'start_date'/endDateField: 'end_date'/titleField/colorField)关键在于前者没有任何提示:工具条上的 Grid ⇄ Calendar 切换按钮正常显示、正常可点,点下去也不报错——直接渲染出一屏在业务上完全错误的画面(所有人的假看起来都在同一天)。
为什么记下来
声明是不完整的,但不完整没有被任何环节拦下:
allowedVisualizations里写了calendar,但没有配套的日期字段映射,元数据校验放行了;startDateField就把记录都落到当天,而这个兜底的结果看起来像数据本身的样子,不像故障。对一个「按描述长出模块」的平台,这个组合的后果是:一份写了一半的声明,会渲染出一个看起来能用、实际全错的界面,而搭建方没有任何信号知道自己漏了什么。
⚠ 另有一层:这两个视图是同一次 AI agent 依据一句业务需求生成的(同一批产出、同一个视图文件)——即 agent 在一个视图里写全了日历配置、在另一个里只写了
allowedVisualizations。本单不评价 agent 的产出质量,只记录平台在收到这种不完整声明时的行为。复现最小路径
appearance.allowedVisualizations: ['grid','calendar'],不写calendar:块;视图 B:同样允许 calendar,并写全startDateField/endDateField;取证环境
2026-08-31,载体
objectstack-ai/hotcrm,钉@objectstack/* 17.1.0。纯只读实拍,未改数据、未改配置、未改源码。邻近既有单(已查,非重复)