init
This commit is contained in:
commit
db0af18b91
2 files changed
+175
No files matched your search
@@ -0,0 +1,76 @@
|
||||
# AGENTS.md
|
||||
|
||||
## 项目定位
|
||||
|
||||
这是一个 ASP.NET Core 选举与投票信息系统。它包含在线匿名投票、线下纸质票计票与复核、混合结果汇总、公开实时看板和 CMS。实现必须优先保证选民资格、投票唯一性、选票匿名性、计票可追溯性和权限范围隔离。
|
||||
|
||||
## 设计与实现原则
|
||||
|
||||
- 保持变更小而完整;一个功能必须覆盖授权、验证、数据迁移、可操作界面、审计与正常/异常路径。
|
||||
- 优先采用成熟组件与框架能力,不重复自建认证、权限、任务调度、富文本、实时推送、图表和对象存储基础设施。
|
||||
- 核心选举规则、计票规则、资格判断和审计边界必须在服务端实现,不能仅依赖前端限制。
|
||||
- 所有读取、统计、导出和写操作先施加组织范围与活动权限,再进行筛选、分页和聚合。
|
||||
- 默认在线投票为匿名;任何改变为实名投票的需求都需要明确的产品与合规确认。
|
||||
|
||||
## 强制安全边界
|
||||
|
||||
- 绝不在常规业务模型、日志、导出或公开接口中建立“选民身份 -> 匿名选票内容”的可查询关联。
|
||||
- 已投状态只用于防重复投票;其数据模型与匿名选票模型分离。
|
||||
- 通过数据库唯一约束、服务端事务和并发控制保证每名合格选民每项活动最多投一次。
|
||||
- 投票资格必须在服务端重新验证:用户状态、活动状态、时间窗口、资格快照、投票方式与选择规则。
|
||||
- 投票开始后,选民范围、候选人和关键规则应冻结;例外变更必须经过受控审核并记录审计。
|
||||
- 线上与线下混合模式默认互斥:线下签到和线上已投状态必须交叉校验。
|
||||
- 已确认的线下计票不可原地修改。任何修正必须创建新版本并记录原因、操作者、复核人与时间。
|
||||
- 未复核的线下录入数据不得计入最终结果,也不得出现在对外公开接口。
|
||||
- 对外实时页面默认仅公开参与率;候选人实时得票必须由活动级公开策略显式开启。
|
||||
- 公开 API、日志和错误消息不得泄露选民身份信息、联系方式、内部审计记录或未公开计票数据。
|
||||
|
||||
## 建议模块
|
||||
|
||||
- `Identity`:认证、用户、角色、权限。
|
||||
- `Organization`:组织层级、成员归属、范围授权。
|
||||
- `Election`:活动、候选人、资格规则、状态机与结果规则。
|
||||
- `Voting`:线上资格验证、匿名选票、已投状态和投票回执。
|
||||
- `OfflineCounting`:场次、签到、票箱、双人录入、差异复核、监票确认与封存。
|
||||
- `Results`:线上/线下已确认结果汇总、审核、发布、归档。
|
||||
- `Cms`:文章、公告、政策、媒体、版本、审核和发布。
|
||||
- `PublicBoard`:对外只读看板、公开策略、SignalR 推送与缓存。
|
||||
- `Audit`:不可抵赖的关键操作记录与查询。
|
||||
|
||||
## 技术约定
|
||||
|
||||
- 后端:ASP.NET Core Web API、EF Core、PostgreSQL、OpenAPI。
|
||||
- 优先按需使用 ABP Framework 提供的身份、权限、审计、设置与模块化能力。
|
||||
- 认证优先使用 OpenIddict 或 Keycloak;不要自行发明不兼容的令牌协议。
|
||||
- SignalR 用于实时状态推送;Hangfire 处理定时发布、自动开关活动、提醒和归档。
|
||||
- Redis 用于缓存、限流和短期协调,不能作为选票或审计事实的唯一持久化来源。
|
||||
- MinIO/S3 用于候选人照片、附件和线下计票凭证;文件访问必须有授权策略。
|
||||
- 管理端建议 Vue 3 + Element Plus;公开 CMS/看板建议 Nuxt 3;富文本使用 CKEditor 5 或 TinyMCE;图表使用 ECharts。
|
||||
|
||||
## 数据与迁移
|
||||
|
||||
- 每个新增持久化实体必须同时提供 EF Core 配置、数据库迁移、索引、约束与测试数据策略。
|
||||
- 对 `ElectionId + VoterId` 等防重字段建立数据库唯一索引;不要只依赖应用层先查后写。
|
||||
- 金额/票数/统计字段必须使用适当整型或 decimal 类型,禁止浮点计算票数。
|
||||
- 所有时间使用 UTC 持久化,并在展示层转换为活动配置时区。
|
||||
- 禁止在迁移中无条件删除业务数据;有破坏性迁移须先说明影响并取得明确授权。
|
||||
|
||||
## API 与前端
|
||||
|
||||
- 管理 API、选民 API 与公开 API 分开路由、授权策略和响应模型;不要把后台 DTO 直接返回给公开页面。
|
||||
- 写接口要求明确的资源授权、参数验证、幂等/并发策略和审计记录。
|
||||
- 列表接口必须分页;导出必须遵守同一范围授权,不得绕过筛选或泄露跨组织数据。
|
||||
- 前端提示不代替后端校验。对异常状态应提供可理解的错误码和可恢复指引。
|
||||
- 公共看板的数据最小化:只返回活动公开策略允许的数据,并明确标注数据更新时间与统计口径。
|
||||
|
||||
## 测试与验证
|
||||
|
||||
- 每项核心规则至少覆盖:正常路径、权限越权、重复操作、并发冲突、时间边界和异常恢复。
|
||||
- 必测场景:重复线上投票、线上线下重复参与、无资格访问、候选人数选择越界、线下双录不一致、未确认线下数据泄露、公开策略切换和结果发布。
|
||||
- 构建成功仅证明编译;涉及迁移、实时推送、公开页面或部署时,要分别说明已验证和未验证的边界。
|
||||
- 不要执行破坏性 git 命令或删除用户现有文件,除非用户明确授权。
|
||||
|
||||
## 文档要求
|
||||
|
||||
- 变更涉及选举规则、数据模型、权限、公开口径或部署时,同步更新相关设计文档和操作说明。
|
||||
- 对有产品决策影响的默认值(匿名/实名、实时票数公开、线下双录、平票规则)必须明确记录,不能静默假设。
|
||||
@@ -0,0 +1,99 @@
|
||||
# 选举与投票信息系统 - 实施清单
|
||||
|
||||
## 项目目标
|
||||
|
||||
建设一个面向组织内部选举的 ASP.NET Core 系统,统一支持在线匿名投票、线下纸质票计票、混合汇总、公开内容发布与实时公开看板。系统应确保资格受控、投票唯一、选票匿名、计票可复核、结果可审计。
|
||||
|
||||
## 技术基线
|
||||
|
||||
- 后端:ASP.NET Core Web API、EF Core、OpenAPI(Scalar 或 Swagger)
|
||||
- 业务基础设施:ABP Framework(按需采用其身份、权限、审计和模块化能力)
|
||||
- 数据库:PostgreSQL(首选;SQL Server 为可支持替代)
|
||||
- 身份认证:OpenIddict 或 Keycloak,采用 OpenID Connect / OAuth 2.0
|
||||
- 实时与任务:SignalR、Hangfire、Redis
|
||||
- 文件:MinIO 或 S3 兼容对象存储
|
||||
- 管理端:Vue 3 + Element Plus;公开站点:Nuxt 3(优先)
|
||||
- 编辑与可视化:CKEditor 5 或 TinyMCE、ECharts、ClosedXML
|
||||
- 可观测性:Serilog + Seq 或 OpenSearch
|
||||
|
||||
## 业务规则(实现前必须确认)
|
||||
|
||||
- [ ] 明确选民身份认证来源:本地账号、统一身份认证或两者并行。
|
||||
- [ ] 明确是否存在实名投票;默认在线投票为匿名投票。
|
||||
- [ ] 明确线上、线下混合投票时,是否允许同一选民跨渠道投票;默认不允许。
|
||||
- [ ] 明确线下票是否必须双人独立录入和监票确认;建议必须。
|
||||
- [ ] 明确结果公开策略:默认实时公开参与率,截止前不公开候选人实时得票。
|
||||
- [ ] 明确票数相同、无效票、弃权票、候选人退出和补选的规则。
|
||||
- [ ] 明确组织层级、管理员授权范围与数据保留期限。
|
||||
|
||||
## 第一阶段:项目骨架与基础能力
|
||||
|
||||
- [ ] 创建解决方案与模块边界:Identity、Organization、Election、Voting、OfflineCounting、Cms、PublicBoard、Audit。
|
||||
- [ ] 配置 PostgreSQL、EF Core 迁移、开发环境配置与健康检查。
|
||||
- [ ] 接入身份认证,建立用户、角色、权限和组织范围授权。
|
||||
- [ ] 建立统一 API 错误格式、参数校验、分页、排序和筛选规范。
|
||||
- [ ] 接入 Serilog、审计日志与敏感字段脱敏。
|
||||
- [ ] 配置 Redis、Hangfire、对象存储和本地开发替代实现。
|
||||
- [ ] 建立单元测试、集成测试和权限越权测试基础设施。
|
||||
|
||||
## 第二阶段:组织、选民与候选人
|
||||
|
||||
- [ ] 组织架构:组织、部门、班级等层级与成员归属。
|
||||
- [ ] 用户和选民资料:导入、停用、有效状态、组织范围查询。
|
||||
- [ ] 选民资格规则:按组织、名单、身份属性或人工审核确定。
|
||||
- [ ] 候选人管理:提名、自荐、资格材料、审核、撤回、取消资格和公示。
|
||||
- [ ] 提供 Excel 批量导入/导出,导入须预校验并返回逐行错误。
|
||||
|
||||
## 第三阶段:选举活动与在线投票
|
||||
|
||||
- [ ] 活动状态机:草稿、待发布、公示中、投票中、已截止、计票中、已发布、已归档。
|
||||
- [ ] 配置活动类型:单选、多选、多席位、赞成/反对/弃权。
|
||||
- [ ] 配置时间窗口、选民范围、候选人范围、最少/最多选择数、平票和当选规则。
|
||||
- [ ] 创建选民资格快照;投票开始前完成冻结,冻结后的变更必须走受控流程。
|
||||
- [ ] 实现在线投票资格校验、时间校验、规则校验、限流和防重复投票。
|
||||
- [ ] 分离“投票资格/已投状态”和“匿名选票”存储;常规查询不得反向关联。
|
||||
- [ ] 通过数据库唯一约束、事务和并发控制保障每个活动每名选民只能完成一次投票。
|
||||
- [ ] 实现投票回执,仅证明投票完成,不透露选票内容。
|
||||
- [ ] 覆盖:越权、重复提交、截止边界、并发投票、非法候选人和异常恢复测试。
|
||||
|
||||
## 第四阶段:线下投票与计票复核
|
||||
|
||||
- [ ] 管理线下场次:地点、时间、票箱/票站、工作人员、监票员。
|
||||
- [ ] 实现线下签到或名单核验,与线上已投状态交叉校验。
|
||||
- [ ] 支持按候选人录入有效票、无效票和弃权票。
|
||||
- [ ] 支持双人独立计票录入,自动比对并将差异送入复核。
|
||||
- [ ] 实现计票批次、复核、监票确认、封存附件与更正版本记录。
|
||||
- [ ] 已确认线下计票不得原地修改;更正必须保留前版本、原因、审核人与时间。
|
||||
- [ ] 仅将“已确认”的线下票纳入活动最终汇总。
|
||||
|
||||
## 第五阶段:结果、公开看板与 CMS
|
||||
|
||||
- [ ] 按规则汇总线上有效票与已确认线下票,生成候选人得票、有效/无效/弃权统计及当选名单。
|
||||
- [ ] 建立结果审核、监票确认、发布和归档流程。
|
||||
- [ ] SignalR 推送公开看板数据,断线后使用受控轮询兜底。
|
||||
- [ ] 公开看板显示活动状态、参与人数、参与率、数据更新时间和公开规则说明。
|
||||
- [ ] 候选人实时票数、排名和图表只在活动明确开启后公开;不得公开未确认线下结果。
|
||||
- [ ] CMS:栏目、文章、公告、政策、操作指南、候选人公示、结果公告、媒体库与附件。
|
||||
- [ ] CMS 支持草稿、审核、发布、下线、定时发布、版本历史、回滚、分类、标签、SEO。
|
||||
- [ ] 建立 CMS 内容与选举活动、公开看板、结果公告之间的关联。
|
||||
|
||||
## 第六阶段:安全、运维与交付
|
||||
|
||||
- [ ] 实现全量审计:配置、名单、审核、投票状态、线下计票、结果发布和 CMS 发布。
|
||||
- [ ] 审计日志中不得存储线上匿名选票与选民身份的可查询关联。
|
||||
- [ ] 配置接口限流、防自动化滥用、CSRF 策略(如采用 Cookie 会话)与安全响应头。
|
||||
- [ ] 制定备份、恢复、归档和日志保留策略。
|
||||
- [ ] 容器化部署:API、前端、PostgreSQL、Redis、MinIO、反向代理。
|
||||
- [ ] 建立 CI:格式检查、编译、单元测试、集成测试、数据库迁移验证与镜像构建。
|
||||
- [ ] 编写管理员、监票员、线下计票员、CMS 编辑与选民操作手册。
|
||||
|
||||
## 验收场景
|
||||
|
||||
- [ ] 无资格选民不能查看或提交目标活动的选票。
|
||||
- [ ] 同一选民无法在线重复投票,也无法在线上与线下重复参与。
|
||||
- [ ] 管理员可查看参与状态,但无法从正常业务查询获知匿名选民投给谁。
|
||||
- [ ] 两份线下独立计票不一致时,结果不能进入最终汇总。
|
||||
- [ ] 未审核/未确认的线下票不出现在对外公开看板或最终结果中。
|
||||
- [ ] 实时公开数据严格遵守活动的公开策略,且不会泄露个人投票信息。
|
||||
- [ ] 活动截止、结果确认、发布、撤销发布等关键动作均可审计追溯。
|
||||
- [ ] CMS 内容经过审核后可公开发布,历史版本可追溯和恢复。
|
||||
Reference in new issue
Block a user