蓝色舞台灯光下,彩纸飘落在演唱会观众上方:PassNow 活动页面的横幅图。

案例研究 PassNow

从活动页面到入场口,一张手机上的票。

客户
PassNow
类型
票务平台
角色
产品与全栈开发
年份
2026

一个活动票务销售与管理平台:面向购票者的公开目录和结账流程,面向主办方、推广员和管理员的后台,以及离线也能继续工作的检票扫描器。同一套代码同时发布为网页、PWA 和 Android 应用。

一张票会经过许多人之手:付款的购票者、需要查看销售情况的主办方、拿佣金的推广员、守在入口的工作人员。任何一环都可能成为薄弱点,而一张能被复制或重复扫描的票毫无价值。

把所有规则放在服务器端,把门票当作机密对待。前端从不接触数据库;由 API 决定谁可以查看、销售、提现或放行,并且每张票只能使用一次,即使入口处没有网络也是如此。

实际构建了什么

  1. 01

    Next.js 16 前端只与 REST API 通信;NestJS 11 后端基于 Prisma 和 PostgreSQL,是唯一持有数据库连接地址的进程:25 个模块、48 个数据模型,使用短时效 JWT 以及存放在 HTTP-only Cookie 中、可轮换和吊销的刷新令牌。

  2. 02

    四步结账流程,通过 Canvi 支持 PIX、信用卡和借记卡。卡号和 CVV 直接发送给支付服务商,PassNow 只保存卡组织和末四位。票据令牌以加盐(pepper)的 SHA-256 哈希存储,并另存一份 AES-256-GCM 加密副本用于授权展示;未注册的购票者凭访问密钥打开自己的票。

  3. 03

    同一张票不可能入场两次:首次扫描是在事务内执行的条件更新,操作员必须属于该活动的主办组织,每次入场都写入审计日志。离线时,扫描记录排队存入 IndexedDB,稍后同步,冲突会被标记出来。

  4. 04

    组织内角色(所有者、管理员、财务、市场、检票、客服)、推广员与提现,以及管理后台。Google 登录仅对购票者开放。同一应用以带更新提示的 PWA 形式发布,也通过 Capacitor 打包为 Android APK。

技术

  • Next.js
  • TypeScript
  • React
  • Tailwind CSS
  • NestJS
  • Prisma
  • PostgreSQL
  • Zod
  • Capacitor
  • Docker

1.0.0 版本于 2026 年 6 月发布,提供 PWA 和已签名的 Android APK。截图来自在本地运行、使用演示种子数据的构建。

下一个项目PC Control CenterPersonal project · 桌面应用与远程代理