# SuperTodo 任务与通知系统 `SuperTodo` 是一个基于 `Gin + PostgreSQL + Redis + Kafka + Vue` 的任务管理与定时通知系统。 当前系统不仅支持基础的任务创建、编辑、完成,还支持通知偏好、通知组、到期提醒、过期提醒、每日摘要、重试与死信队列。 ## 项目概览 系统当前由以下几部分组成: - 后端 API:`Go + Gin` - 前端页面:`Vue 3 + Vite` - 关系型存储:`PostgreSQL` - 会话与缓存:`Redis` - 消息中间件:`Kafka` - 邮件投递:`SMTP` 核心能力包括: - 用户注册、登录、刷新令牌、会话管理 - 任务 CRUD - 用户通知偏好管理 - 通知组管理 - 任务创建、状态变化、即将到期、已过期等事件通知 - 定时调度、异步投递、失败重试、DLQ 死信记录 ## 消息中间件说明 本项目中的消息中间件主要使用 `Kafka`,它不是装饰性组件,而是通知系统可靠性的核心。 ### 为什么要引入消息中间件 如果任务到期、任务状态变化这类业务事件直接在 HTTP 请求里同步发邮件,会有几个明显问题: - 接口响应时间变长,用户操作会被外部邮件服务拖慢 - 邮件服务短暂失败时,业务请求容易被连带失败 - 突发高峰时,大量通知会集中压垮投递链路 - 难以实现统一重试、削峰、幂等和死信补偿 引入 Kafka 后,系统会把“业务处理”和“通知投递”拆成两个阶段: 1. 业务接口先落库并生成通知事件 / 通知任务 2. 通知任务进入 Kafka topic,由后台 worker 异步消费并发送邮件 这样做的结果是: - API 更快返回 - 投递链路与业务链路解耦 - 可以按批次消费,避免瞬时洪峰 - 可以做失败重试与死信记录 - 可以通过幂等键避免重复发送 ### 本项目里的 Kafka 角色 当前用到的 topic 主要有两个: - `todo.tasks` - 用于任务事件输出 - `notification.jobs` - 用于通知任务分发 通知相关链路如下: 1. 用户创建任务或更新任务 2. 系统写入 `notification_events` 3. 规则引擎根据事件类型、通知组、用户偏好生成 `notification_jobs` 4. dispatcher 将可投递任务写入 `notification.jobs` 5. worker 消费消息并发送邮件 6. 发送成功写回 `sent` 7. 临时失败回到 `pending` 并按指数退避重试 8. 超过重试次数或不可重试错误进入 `notification_dlq` ### 当前可靠性机制 通知系统当前已经实现: - 幂等控制:同一事件不会重复生成相同通知任务 - 扫描去重:同一 `task_id + event_type + due_at` 不会被调度器反复重发 - 重试机制:失败任务按退避策略重新投递 - 死信队列:无法恢复的任务进入 DLQ - 状态可观测:支持查看 `pending / sent / dead` ## 系统架构 ### 后端模块 - `cmd/server` - HTTP 服务入口 - `internal/iam` - 登录认证、令牌、会话管理 - `internal/notification` - 通知偏好、通知组、调度器、Kafka dispatcher、worker、SMTP 发送、DLQ 与指标 ### 前端模块 - `web/src/views/TodoView.vue` - 任务列表与编辑 - `web/src/views/UserSettingsView.vue` - 通知偏好设置 - `web/src/views/NotificationGroupsView.vue` - 通知组管理 - `web/src/views/NotificationDlqView.vue` - 死信查看 ## 运行方式 ### 方式一:Docker Compose 启动整套系统 推荐本地联调直接使用容器。 ```bash docker compose up -d ``` 启动后默认端口: - API:`http://localhost:8080` - Kafka UI:`http://localhost:8081` - PostgreSQL:`localhost:5432` - Redis:`localhost:6379` - Kafka:`localhost:29092` 健康检查: ```bash curl http://localhost:8080/api/health ``` ### 方式二:本机运行后端 如果你已经单独启动了 PostgreSQL、Redis、Kafka,也可以直接运行后端: ```bash go run ./cmd/server ``` 常用环境变量: ```bash DATABASE_URL=postgres://todo:todo@localhost:5432/todo?sslmode=disable REDIS_ADDR=localhost:6379 KAFKA_BROKERS=localhost:29092 KAFKA_TOPIC=todo.tasks NOTIFY_ENABLED=true NOTIFY_TOPIC=notification.jobs NOTIFY_DISPATCH_BATCH=200 NOTIFY_SCHED_TICK_SECONDS=60 NOTIFY_MAX_RETRY=5 NOTIFY_BACKOFF_BASE_SECONDS=30 SMTP_HOST=smtp.qq.com SMTP_PORT=465 SMTP_USER=your_mail@example.com SMTP_PASS=your_smtp_password SMTP_FROM=your_mail@example.com SMTP_USE_TLS=true ``` ## 前端运行 ```bash cd web npm install npm run dev ``` 默认访问地址: - 前端开发服务:通常为 `http://localhost:5173` - 前端请求后端 API:`http://localhost:8080/api/v1` ## 主要数据流 通知系统的数据流可以概括为: 1. 业务事件产生 - 如任务创建、任务状态变化、任务即将到期、任务已过期 2. 事件入库 - 写入 `notification_events` 3. 规则判断 - 判断是否需要通知、通知谁、使用哪个模板 4. 偏好过滤 - 过滤订阅状态、语言、时区、免打扰时间 5. 生成通知任务 - 写入 `notification_jobs` 6. 分发到 Kafka - 写入 `notification.jobs` 7. worker 消费并发送邮件 8. 回写状态 - `sent / pending / dead` 9. 失败补偿 - 重试或进入 DLQ ## 常用接口 ### 认证 ```bash curl -X POST http://localhost:8080/api/v1/auth/register \ -H 'Content-Type: application/json' \ -d '{"email":"demo@example.com","password":"secret123","auto_login":true}' ``` ```bash curl -X POST http://localhost:8080/api/v1/auth/login \ -H 'Content-Type: application/json' \ -d '{"email":"demo@example.com","password":"secret123"}' ``` ### 任务 ```bash curl -X POST http://localhost:8080/api/v1/tasks \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -d '{ "title":"学习通知系统", "description":"验证 Kafka 通知链路", "status":"todo", "due_at":"2026-03-10T15:30:00Z", "priority":1, "tags":["demo","notify"], "notify_group_ids":[1] }' ``` ```bash curl http://localhost:8080/api/v1/tasks \ -H 'Authorization: Bearer ' ``` ### 通知偏好 ```bash curl -X PUT http://localhost:8080/api/v1/notifications/prefs \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -d '{ "subscribed":true, "dnd_start":"", "dnd_end":"", "locale":"zh", "timezone":"Asia/Shanghai", "daily_summary_enabled":true, "daily_summary_time":"09:30" }' ``` ### 通知组 ```bash curl -X POST http://localhost:8080/api/v1/notifications/groups \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -d '{ "name":"项目通知组", "emails":["a@example.com","b@example.com"] }' ``` ### 通知指标 ```bash curl http://localhost:8080/api/v1/notifications/metrics \ -H 'Authorization: Bearer ' ``` ## 数据表说明 当前通知系统的关键表包括: - `tasks` - 任务主体,包含 `notify_group_ids` - `user_notification_prefs` - 用户通知偏好 - `notification_groups` - 通知组 - `task_notification_groups` - 任务与通知组关系 - `notification_events` - 通知事件日志 - `notification_jobs` - 通知任务队列 - `notification_attempts` - 每次投递尝试记录 - `notification_dlq` - 死信记录 ## 开发说明 ### 关于 `web/dist` `web/dist/` 已从 Git 移除,并加入 `.gitignore`。 前端构建产物不再直接提交到仓库。 ### 关于通知重复发送 当前代码已经修复“过期任务在每次扫描中重复重发”的问题。 调度器会基于 `task_id + event_type + due_at` 做去重,同一条到期版本只会生成一次对应事件。 ## 相关文档 - [通知系统说明](./doc/notify.md) - [认证模块说明](./doc/iam.md)