Skip to main content
Version: Current

代码架构

分层​

层位置职责
认证auth.tsProvider、Adapter、JWT、authorized
门禁lib/user-login-gate.ts邮箱白名单
页面app/**/page.tsxServer Component 读库、鉴权、把数据交给 Client
交互*-client.tsx、vote-form.tsxMUI 表单,调用 Server Actions
写入**/actions.ts、*-action.ts权限、校验、事务、revalidatePath
规则lib/campaign-*.ts权重、名簿、规则 JSON
数据lib/neon.ts@neondatabase/serverless 的 neon(url)

投票提交(核心写路径)​

  1. submitCastVote 取 session,拒绝无 id 与 role=admin。
  2. 确认 campaigns.ongoing。
  3. getCampaignVoteWeightForUser 得到应投总票。
  4. 合并同一候选人、校验正整数、合计等于权重、选项属于本场。
  5. 确认存在 (campaign, voter) 选票且尚无分票。
  6. 事务:更新 ballots.weight、清空旧 allocations、插入新行。

UI 壳​

根布局用 Toolpad AppProvider + MUI 红色主题。导航数组在 Server Component 里拼好:普通成员看进行中且自己已参与的场次;admin/moderator 看全部竞选的排名与选票管理。

安全注意​

新增页面或 Action 必须在服务端再查 session 与 ongoing。只改 layout.tsx 不够。结果页目前缺少角色守卫,若要限制公布范围需补校验。