Sanity Challenge 第二赛道提交
这是 Sanity Challenge 第二赛道:Vibe-Code Something Strange 的参赛作品
我构建了什么
GrantQuest —— 奖学金搜寻,但形式是一个 RPG 任务日志。
每项奖学金都是一个任务。资格要求是你逐一通过的关卡。材料是你收集的库存物品。截止日期是不在乎你感受的倒计时。通过关卡可获得 XP,你的任务日志会像战役日志一样追踪每一次申请。
但真正让它超越主题设定的转折点在于:奖学金数据会腐烂。截止日期会变,项目会停办,金额每年都会更新——而互联网上一半的奖学金网站都在悄悄给你提供去年的信息。因此 GrantQuest 中的每个任务都带有一个新鲜度徽章:FRESH(30 天内已验证且截止日期仍未到)或 NEEDS RE-VERIFICATION。数据的可信度被建模为数据,而不是凭感觉。
25 项真实奖学金。真实的截止日期。真实的钱。无需登录,无需注册——打开即可开始你的探险。
这是为像我这样被 40 个打开的标签页淹没、试图弄清楚自己是否有资格申请任何东西的学生准备的。
演示
在这里体验:https://grantquest.tech
视频演示(60 秒):
网站内还内置了一个 30 秒的引导游览——点击主视觉区的“Take the 30-second tour”,它会带你走完整个流程。
代码
https://github.com/mateir0/grandquest
我的构建过程
我用 OpenCode 运行 Muse Spark 来构建这个项目,一次一个提示词,总共十五个提示词。计划很简单:任务面板、任务详情页、资格引擎、带 XP 的任务日志,以及 Studio 中的新鲜度验证工作流。然后是扩展目标:派生新鲜度徽章、官方 Workflows API、截止日期清扫 Function、App SDK 面板,以及为评委准备的引导游览。
以下就是出问题的地方,因为这才是有趣的部分:
那次部署让所有东西都 404 了。我的 Next.js 应用从 web/ 上一层的文件夹里导入了共享逻辑。在我机器上运行得完美无缺。Vercel 却让整个站点 404 了,因为 Vercel 只上传 web/ 目录,而我的导入指向了在上层并不存在的文件。这个教训现在深深刻在我脑子里:在 Vercel 上的 Next.js 应用里,永远不要从 web/ 上层导入。我把文件复制进了 web/lib/,重新部署,搞定。
被我过度复杂化的新鲜度规则。我的第一版说,如果一个 quest 的截止日期在 60 天内,它就过期了。然后我盯着它看,意识到:那是倒计时的职责,不是新鲜度徽章的职责。新鲜度回答的是“这份数据是否仍然属实?”紧迫性回答的是“截止日期是否临近?”两个不同的问题,两个不同的 UI 元素。我把规则简化为:30 天内验证过 且 截止日期未过 = FRESH。其他一切都被标记。代码变短了,概念变清晰了,这通常是你完工的信号。
ERSU 事件——我最喜欢的一次失败。我的数据集里有一条意大利奖学金(ERSU Messina)的测试记录,数据有一半是猜的。偷懒的做法是直接给它盖上已验证的章然后继续——谁会去查呢,对吧?但我没有,而是去读了真正的官方 bando,用意大利语,来自 ersumessina.it,把每一个猜测的字段都换成了真实数字:真实金额(fuori sede 为 €7,171.11)、真实的 ISEE 门槛、真实的日期。现在它正确地显示 NEEDS RE-VERIFICATION,因为申请早在 8 月就截止了。一个诚实的红色徽章胜过撒谎的绿色徽章。那条记录就是整个应用哲学浓缩在一张卡片里。
Vanier 的剧情反转。在提交前研究要新增的 10 个奖学金时,我发现 Vanier Canada Graduate Scholarship——地球上最著名的奖学金之一——已正式停办。“不再接受申请”,就写在政府网站上。于是我把它换成了它真正的继任者,Canada Graduate Research Scholarship–Doctoral。新鲜度系统之所以存在,正是因为这类事情:脚下的地面在移动,却没人告诉你。
笨拙的导览。回看时,第一版引导式评审导览感觉卡顿。你知道那种感觉——有点不对劲,然后就再也无法忽视。我重建了动画方案,直到它变得流畅。
泄露的 token。最后一次安全扫描发现,一个已提交的 .env.example 里竟然有一个真实的 Sanity 写入 token。我把它清理成占位符,吊销了该 token,并轮换了一个新的。(旧的仍在 git 历史里,但它已经失效,所以无所谓。)
我超越 Studio 的地方:
Workflows(官方 API):每个任务都通过真正的 Workflows 引擎从 unverified → underReview → verified——不是状态下拉菜单,而是实际的工作流转换。全部 25 个任务都是通过真实转换驱动的。
Functions:一个定时 Function 每天扫描。任何已过截止日期、或验证时间超过 30 天的任务都会被自动标记——并带有每次扫描的不可变审计日志。
App SDK:Quest Master's Board,一个用于处理验证队列的仪表盘应用。
Sanity 项目详情
项目 ID:aitdwcxh · 数据集:production
公开数据集——你可以自行查询:
https://aitdwcxh.api.sanity.io/v2024-01-01/data/query/production?query=*%5B_type%3D%3D%22quest%22%5D
Schema 亮点:任务带有结构化的资格门槛(不是散文——而是带有要求的实际类型化数据)、作为库存物品的文档、截止日期、奖励金额,以及验证工作流状态机。门槛是数据而不是文本,这正是关键所在——它让应用能够计算你的资格,而不只是展示一大段文字。