Files
election-system/TODO.md
T
2026-09-11 19:38:43 +08:00

104 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 选举与投票信息系统 - 实施清单
## 项目目标
建设一个面向组织内部选举的 ASP.NET Core 系统,统一支持在线匿名投票、线下纸质票计票、混合汇总、公开内容发布与实时公开看板。系统应确保资格受控、投票唯一、选票匿名、计票可复核、结果可审计。
## 技术基线
- 后端:ASP.NET Core Web API、EF Core、OpenAPI(Scalar 或 Swagger)
- 业务基础设施:ABP Framework(按需采用其身份、权限、审计和模块化能力)
- 数据库:MySql(首选;SQL Server 为可支持替代)
- 身份认证:OpenIddict 或 Keycloak,采用 OpenID Connect / OAuth 2.0
- 实时与任务:SignalR、Hangfire、Redis
- 文件:MinIO 或 S3 兼容对象存储
- 管理端:Vue 3 + Element Plus;公开站点:Nuxt 3(优先;当前基础实现为 Razor Pages 服务端渲染)
- 编辑与可视化:CKEditor 5 或 TinyMCE、ECharts、ClosedXML
- 可观测性:Serilog + Seq 或 OpenSearch
## 业务规则(实现前必须确认)
- [ ] 明确选民身份认证来源:本地账号、统一身份认证或两者并行。
- [ ] 明确是否存在实名投票;默认在线投票为匿名投票。
- [ ] 明确线上、线下混合投票时,是否允许同一选民跨渠道投票;默认不允许。
- [ ] 明确线下票是否必须双人独立录入和监票确认;建议必须。
- [ ] 明确结果公开策略:默认实时公开参与率,截止前不公开候选人实时得票。
- [ ] 明确票数相同、无效票、弃权票、候选人退出和补选的规则。
- [ ] 明确组织层级、管理员授权范围与数据保留期限。
## 第一阶段:项目骨架与基础能力
- [x] 创建解决方案与模块边界:Identity、Organization、Election、Voting、OfflineCounting、Cms、PublicBoard、Audit。
- [x] 配置 MySQL、EF Core 初始迁移、开发环境配置与健康检查。
- [x] 内置身份认证:ASP.NET Core Identity 本地用户、密码策略、锁定、安全 Cookie、首个系统管理员初始化,以及地域角色范围授权。
- [x] 建立统一 API 错误格式和分页响应模型;参数校验、排序和筛选随首个业务列表接口落地。
- [x] 建立基础审计拦截器;Serilog 与敏感字段脱敏随身份及业务字段接入时配置。
- [ ] 配置 Redis、Hangfire、对象存储和本地开发替代实现。
- [x] 建立单元测试基础设施;集成测试和权限越权测试随受保护 API 接入。
## 第二阶段:组织、选民与候选人
- [x] 行政区划目录:省、市、区县、镇街、村社区五级;省市区镇采用受控 AreaCity 数据版本,村社区采用本地确认目录。
- [x] 地域角色与范围:省、市、区、镇、村管理员的下级覆盖;计票员、监督员与具体计票所分配。
- [x] 用户和选民资料:导入预校验/确认、停用、有效状态、地域范围查询。
- [ ] 选民资格规则:按组织、名单、身份属性或人工审核确定。
- [x] 候选人管理:提名、自荐、服务端资格状态转换、撤回、取消资格和公示;资格材料文件待对象存储阶段接入。
- [x] 提供 Excel 批量导入,导入预校验并返回逐行错误;导出将在管理端与授权下载审计接入时实施。
- [x] 管理端基础资料页面:使用 Razor Pages + Blazor Interactive Server 提供地域、选民、候选人、角色、计票所与导入操作,不引入独立 SPA。
## 第三阶段:选举活动与在线投票
- [ ] 活动状态机:草稿、待发布、公示中、投票中、已截止、计票中、已发布、已归档。
- [ ] 配置活动类型:单选、多选、多席位、赞成/反对/弃权。
- [ ] 配置时间窗口、选民范围、候选人范围、最少/最多选择数、平票和当选规则。
- [ ] 创建选民资格快照;投票开始前完成冻结,冻结后的变更必须走受控流程。
- [ ] 实现在线投票资格校验、时间校验、规则校验、限流和防重复投票。
- [ ] 分离“投票资格/已投状态”和“匿名选票”存储;常规查询不得反向关联。
- [ ] 通过数据库唯一约束、事务和并发控制保障每个活动每名选民只能完成一次投票。
- [ ] 实现投票回执,仅证明投票完成,不透露选票内容。
- [ ] 覆盖:越权、重复提交、截止边界、并发投票、非法候选人和异常恢复测试。
## 第四阶段:线下投票与计票复核
- [x] 管理线下计票批次:按已分配计票所、工作人员、监督员及活动截止时间控制;地点/票箱信息沿用计票所资料。
- [ ] 实现线下签到或名单核验,与线上已投状态交叉校验。
- [x] 支持按候选人/议案选项录入有效票、无效票、弃权票和缺投数。
- [x] 支持双人独立计票录入,自动比对并将差异送入复核。
- [x] 实现计票批次、复核、监票确认与更正版本记录;封存附件待对象存储阶段接入。
- [ ] 已确认线下计票不得原地修改;更正必须保留前版本、原因、审核人与时间。
- [x] 仅将“已确认”的线下票纳入活动最终汇总。
## 第五阶段:结果、公开看板与 CMS
- [x] 按活动规则汇总已确认线下票,生成候选人/议案选项得票、有效/无效/弃权/缺投统计及当选名单;线上投票接入后复用同一结果服务。
- [ ] 建立结果审核、监票确认、发布和归档流程。
- [x] SignalR 推送已确认线下计票的公开看板数据;断线后使用公开结果接口受控轮询兜底。
- [x] 公开看板显示活动状态、参与人数、数据更新时间和公开规则说明;`/results` 以受控轮询刷新。
- [x] 候选人实时票数只在活动明确开启后公开;接口与 SignalR 推送共用公开策略,且不会公开未确认线下结果。
- [x] CMS 公开信息基础:建立八类固定内容定义(选举公告、规则与政策、候选人公示、选民指南、结果公告、常见问题、资料下载、历史归档)及只读公开内容契约。
- [x] 公开信息前端:提供八类内容的首页最新发布区、直接栏目菜单入口、目录/详情页、发布内容空状态与服务不可用提示;采用响应式中性政务信息风格。
- [ ] CMS:栏目、文章、公告、政策、操作指南、候选人公示、结果公告、媒体库与附件。
- [ ] CMS 支持草稿、审核、发布、下线、定时发布、版本历史、回滚、分类、标签、SEO。
- [ ] 建立 CMS 内容与选举活动、公开看板、结果公告之间的关联。
## 第六阶段:安全、运维与交付
- [ ] 实现全量审计:配置、名单、审核、投票状态、线下计票、结果发布和 CMS 发布。
- [ ] 审计日志中不得存储线上匿名选票与选民身份的可查询关联。
- [ ] 配置接口限流、防自动化滥用、CSRF 策略(如采用 Cookie 会话)与安全响应头。
- [ ] 制定备份、恢复、归档和日志保留策略。
- [ ] 容器化部署:API、前端、PostgreSQL、Redis、MinIO、反向代理。
- [ ] 建立 CI:格式检查、编译、单元测试、集成测试、数据库迁移验证与镜像构建。
- [ ] 编写管理员、监票员、线下计票员、CMS 编辑与选民操作手册。
## 验收场景
- [ ] 无资格选民不能查看或提交目标活动的选票。
- [ ] 同一选民无法在线重复投票,也无法在线上与线下重复参与。
- [ ] 管理员可查看参与状态,但无法从正常业务查询获知匿名选民投给谁。
- [ ] 两份线下独立计票不一致时,结果不能进入最终汇总。
- [ ] 未审核/未确认的线下票不出现在对外公开看板或最终结果中。
- [ ] 实时公开数据严格遵守活动的公开策略,且不会泄露个人投票信息。
- [ ] 活动截止、结果确认、发布、撤销发布等关键动作均可审计追溯。
- [ ] CMS 内容经过审核后可公开发布,历史版本可追溯和恢复。