有人已经在B桌订好了《车票之旅》。然后B桌不能用了。把游戏挪到C桌听起来很容易,但那张桌子上已经挂着一个真实的人,他的预订必须活过这次修改。
INKSHIFT就是为这类变化而做的。它把一个游戏夜、工作坊或社团聚会的计划,变成一张共享的报名页。上传一张照片,或者直接输入计划,确认场次,然后把邀请链接发出去。参与者不需要注册账号,就能订下一个位置。
![]()
当计划发生变化时,组织者要拿修改提案和已经报名的人一起核对。可以修正识别结果,检查受影响的预订,再批准这次移动。参与者在新地点保留原来的位置。
Sanity给这个聚会带来连续性:Content Lake存储相互关联的场次和报名,Workflows记录每一次计划审核,App SDK订阅共享日程。预订属于一个场次,而场次的位置可以改变。
演示
43秒的演示视频跟着一个准备好的游戏夜计划走完一次改桌流程。
你也可以自己试一遍同样的路径:选择“Try a sample”,打开它的参与者邀请链接;加入《车票之旅》,然后回到组织者工作区;选择“Use the crossed-out example”,查看移动到C桌的提案;批准它,再重新打开参与者页面。
组织者的审核界面里,已经有一个预订挂在那里。审核会指出这次移动,以及跟着它一起走的报名记录。在允许批准之前,INKSHIFT会检查C桌是否有足够的座位,以及整个场次期间是否可用。
批准之后,参与者原有的预订会出现在“Your places”下面,地点是C桌。他们不需要重新报名。
视频和截图使用的是带标签的准备样本,读数固定。截图展示的是一条保存下来的演示报名和一次已应用的审核。另外的照片识别检查,用的是渲染出来的打印表格。
Sanity如何让预订保持挂接
在Content Lake里,空间、场次和报名各自有独立的身份。一条报名指向一个场次,场次指向它所在的空间。
移动《车票之旅》,改的是它的空间引用。场次ID保持不变,所以报名仍然属于它。这些关系可以在Sanity schema里查看。
应用里还有一个实时内容检查器。移动之后,它显示session-1-1在C桌,已订1/4个位置。
App SDK从Content Lake读取这份公开日程和它的预订计数。参与者姓名、上传的照片和组织者访问数据,留在需要授权的服务器路由后面。Sanity的写入令牌也留在服务器上。
一次修改,有审核,也有决定
被编辑的计划会变成一份保存下来的提案。Sanity Workflows把它跟踪过Reading、Review,最后落到Applied或Discarded,组织者可以回到某次审核,看看发生了什么。
这里有个时间差问题:组织者审核移动的时候,可能有人正好加入。一份原本符合早先预订的提案,可能已经不再合适。
所以在应用之前,服务器会检查事件和提案的修订版本,重新计算约束。如果事件变了,组织者必须重新核对。一旦批准,计划、关联记录和公开日程会在一次Content Lake事务里一起保存。
App SDK订阅公开日程的版本。有变化时,组织者工作区会通过授权的服务器路由刷新它的私有数据。Workflows记录审核进度,服务器检查权限并验证这次移动。
代码
INKSHIFT使用Next.js和React、Sanity Content Lake、App SDK和Workflows。照片识别通过Hugging Face Inference Providers使用Qwen3-VL。验证记录覆盖预订保留、并发变化、访问恢复和私有数据检查。
我的构建过程
INKSHIFT用了两个AI原生工具来构建:Codex负责第一次搭建和收尾,Claude Code在中间做了一次升级。每一步都跑在真实的Sanity项目上,所以下面每条说法都来自一次测试运行或一次实时检查。
想法最初是一条粘贴进来的笔记:“一份手写计划变成一个能用的多人应用。然后你改了那张纸,应用理解了变化,却没有丢掉人们已经做过的事。”
之后的提示词都很短:“go on it's for dev.to challenge”,然后是“anything works also if that does not fit the hackathon let me know and switch over to another project”。Codex在写代码前读了Path Two的规则,回答说它符合,因为Sanity会承载整个产品所依赖的模型。
第一次修正:桌子不是场次。最初的模型把每个游戏绑到它的桌子上。把《车票之旅》从B桌移到C桌,会替换掉场次并丢掉它的预订——这正是这个产品要防止的失败。空间、场次和报名变成了各自独立的记录,带稳定的ID,一条报名指向它的场次。后面的大部分工作,都从那个决定而来。
同一天我们定了第二条规则:照片里缺失的区域是不确定,不是删除的证据,它要进入审核。
模型卡住的地方
视觉提供方拒绝了schema。通过Hugging Face路由的Qwen3-VL不接受边界框格式。Codex把每个框改写成固定长度的数字数组,修好了它。
识别器删掉了一个已订游戏。在编辑后计划的第二张照片上,识别器判定《车票之旅》不见了。审核阻止了批准,直到我把它匹配回原来的场次。批准之后,预订出现在C桌。那次运行就是审核必须存在、而非可选的原因。
schema部署被拒绝了。Sanity为这个项目配置的令牌……
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.