# todosApi **Repository Path**: linjunbin0101/todos ## Basic Information - **Project Name**: todosApi - **Description**: 哈哈哈哈哈哈哈哈哈哈哈哈 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-23 - **Last Updated**: 2026-02-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Todo List Application ## 项目概述 本项目是一个基于 Fastify 框架和 MongoDB 数据库的待办事项(Todo)管理应用程序。用户可以通过手机号注册账号,并管理属于自己的待办事项列表。每个待办事项可以设置到期时间和提醒时间。 ## 技术栈 - **后端框架**: Fastify - **数据库**: MongoDB - **ODM (对象文档映射)**: Mongoose - **代码规范检查**: ESLint (4 空格缩进) - **运行时环境**: Node.js - **HTTP 协议**: RESTful API - **环境变量管理**: dotenv - **热更新**: Nodemon - **请求验证**: Fastify 内置 AJV - **CORS 支持**: @fastify/cors - **健康检查**: 内置健康检查端点 - **全局错误处理**: 统一错误响应格式 - **MongoDB 连接池**: 优化数据库连接性能 - **环境变量验证**: 确保必要的环境变量存在 - **非 root 运行**: 提高 Docker 容器安全性 - **多阶段构建**: 优化 Docker 镜像大小 - **密码加密**: bcrypt 用于安全存储用户密码 ## 项目结构 ```text todo/ ├── index.js # 应用程序入口文件 ├── package.json # 项目依赖和脚本配置 ├── eslint.config.mjs # ESLint 配置文件 ├── .env # 环境变量配置 ├── .gitignore # Git 忽略文件配置 ├── Dockerfile # Docker 构建文件 ├── docker-compose.yml # Docker Compose 配置文件 ├── deploy.sh # 一键部署脚本 ├── models/ # 数据模型目录 │ ├── User.js # 用户模型 │ └── Todo.js # 待办事项模型 ├── routes/ # 路由目录 │ ├── userRoutes.js # 用户相关路由 │ └── todoRoutes.js # 待办事项相关路由 ├── middleware/ # 中间件目录 │ └── authMiddleware.js # 身份验证中间件 ├── utils/ # 工具函数目录 │ └── responseHandler.js # 统一响应格式处理 └── scripts/ # 脚本目录 ├── addUser.js # 添加用户脚本 └── bump-version.js # 版本号更新脚本 ``` ## 安装和运行 详细的部署说明请参考 [DEPLOYMENT.md](DEPLOYMENT.md) 文件,包含: - **传统方式部署**:Node.js + MongoDB - **Docker 部署**: - 一键部署脚本(推荐) - Docker Compose 手动部署 - Dockerfile 手动部署 - **Docker 配置文件说明** - **监控和维护** - **常见问题排查** - **安全建议** ### 快速启动(开发模式) ```bash # 克隆项目 git clone https://gitee.com/linjunbin0101/todos.git cd todos # 安装依赖 npm install # 配置环境变量 cp .env.example .env || echo "MONGODB_URI=mongodb://localhost:27017/todo-list\nPORT=724" > .env # 启动开发服务器 npm run dev ``` 应用启动后,可通过 `http://localhost:724` 访问 ## 数据库设计 ### Collections #### 1. users 集合 | 字段名 | 类型 | 约束 | 说明 | | ------ | ---- | ---- | ---- | | _id | ObjectId | PRIMARY KEY | 用户唯一标识符 | | phone | String | Required, Unique | 用户手机号 | | password | String | Required | 加密后的用户密码 | | created_at | Date | Required | 创建时间 | | updated_at | Date | Required | 更新时间 | #### 2. todos 集合 | 字段名 | 类型 | 约束 | 说明 | | ------ | ---- | ---- | ---- | | _id | ObjectId | PRIMARY KEY | 待办事项唯一标识符 | | user_id | ObjectId | Required, Ref | 关联到 users 集合 | | title | String | Required | 待办事项标题 | | description | String | Optional | 待办事项描述 | | completed | Boolean | Required, Default: false | 是否已完成 | | due_date | Date | Optional | 到期时间 | | reminder_time | Date | Optional | 提醒时间 | | created_at | Date | Required | 创建时间 | | updated_at | Date | Required | 更新时间 | ### 关系 - users 集合与 todos 集合之间是一对多关系 - 一个用户可以拥有多个待办事项 - 一个待办事项必须属于且仅属于一个用户 ## API 接口文档 ### 响应格式 所有 API 响应均遵循统一格式: #### 成功响应 ```json { "code": 0, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "", "data": { /* 实际返回的数据 */ } } } ``` #### 失败响应 ```json { "code": -1, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "错误信息", "data": {} } } ``` ### 用户相关接口 #### 1. 用户注册 - **URL**: `/api/users/register` - **Method**: `POST` - **Request Body**: ```json { "phone": "13800138000", "password": "123456" } ``` - **Response**: ```json { "code": 0, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "", "data": { "user_id": "60d5ec49e4b0b8b8b8b8b8b8", "phone": "13800138000", "created_at": "2023-06-25T00:00:00.000Z", "updated_at": "2023-06-25T00:00:00.000Z" } } } ``` #### 2. 检查手机号是否存在 - **URL**: `/api/users/check-phone` - **Method**: `GET` - **Query Parameters**: - `phone`: 手机号,必填,格式为中国大陆手机号 - `password`: 密码,必填,最小长度为 6 个字符 - **Response**: **当手机号存在且密码正确时:** ```json { "code": 0, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "", "data": { "phone": "13643035136", "user_id": "60d5ec49e4b0b8b8b8b8b8b8", "created_at": "2023-06-25T00:00:00.000Z", "updated_at": "2023-06-25T00:00:00.000Z" } } } ``` **当手机号不存在时:** ```json { "code": -1, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "User with this phone number does not exist", "data": {} } } ``` **当密码不正确时:** ```json { "code": -1, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "Invalid password", "data": {} } } ``` **状态码**: - `200`: 手机号存在且密码正确,返回用户信息 - `401`: 密码不正确 - `404`: 手机号不存在 - `400`: 请求参数错误(手机号格式不正确或密码长度不足) - `500`: 服务器内部错误 ### 健康检查接口 #### 健康检查 - **URL**: `/health` - **Method**: `GET` - **Response**: **成功时:** ```json { "code": 0, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "", "data": { "message": "Todo API is running with hot reload support!", "dbStatus": "connected" } } } ``` **失败时:** ```json { "code": -1, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "Health check failed", "data": {} } } ``` **dbStatus 说明:** - `disconnected` (0) - 未连接 - `connected` (1) - 已连接 - `connecting` (2) - 连接中 - `disconnecting` (3) - 断开连接中 - `unknown` - 未知状态 ### 待办事项相关接口 > 所有待办事项接口均需在请求头中提供 `user_id` 字段 #### 1. 获取所有待办事项 - **URL**: `/api/todos` - **Method**: `GET` - **Headers**: `{ "user_id": "60d5ec49e4b0b8b8b8b8b8b8" }` - **Query Parameters**: - `page` (可选): 页码,默认值为 1,最小值为 1 - `limit` (可选): 每页数量,默认值为 10,最小值为 1,最大值为 100 - **Response**: ```json { "code": 0, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "", "data": { "todos": [ { "_id": "60d5ec49e4b0b8b8b8b8b8b9", "user_id": "60d5ec49e4b0b8b8b8b8b8b8", "title": "Buy groceries", "description": "Milk, eggs, bread", "completed": false, "due_date": "2023-06-26T00:00:00.000Z", "reminder_time": null, "created_at": "2023-06-25T00:00:00.000Z", "updated_at": "2023-06-25T00:00:00.000Z" } ], "pagination": { "page": 1, "limit": 10, "total": 100, "totalPages": 10, "hasNext": true, "hasPrev": false } } } } ``` #### 2. 创建待办事项 - **URL**: `/api/todos` - **Method**: `POST` - **Headers**: `{ "user_id": "60d5ec49e4b0b8b8b8b8b8b8" }` - **Request Body**: ```json { "title": "Buy groceries", "description": "Milk, eggs, bread", "due_date": "2023-06-26T00:00:00.000Z", "reminder_time": null } ``` - **Response**: ```json { "code": 0, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "", "data": { "_id": "60d5ec49e4b0b8b8b8b8b8b9", "user_id": "60d5ec49e4b0b8b8b8b8b8b8", "title": "Buy groceries", "description": "Milk, eggs, bread", "completed": false, "due_date": "2023-06-26T00:00:00.000Z", "reminder_time": null, "created_at": "2023-06-25T00:00:00.000Z", "updated_at": "2023-06-25T00:00:00.000Z" } } } ``` #### 3. 获取单个待办事项 - **URL**: `/api/todos/:id` - **Method**: `GET` - **Headers**: `{ "user_id": "60d5ec49e4b0b8b8b8b8b8b8" }` - **Response**: ```json { "code": 0, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "", "data": { "_id": "60d5ec49e4b0b8b8b8b8b8b9", "user_id": "60d5ec49e4b0b8b8b8b8b8b8", "title": "Buy groceries", "description": "Milk, eggs, bread", "completed": false, "due_date": "2023-06-26T00:00:00.000Z", "reminder_time": null, "created_at": "2023-06-25T00:00:00.000Z", "updated_at": "2023-06-25T00:00:00.000Z" } } } ``` #### 4. 更新待办事项 - **URL**: `/api/todos/:id` - **Method**: `PUT` - **Headers**: `{ "user_id": "60d5ec49e4b0b8b8b8b8b8b8" }` - **Request Body**: ```json { "title": "Buy groceries and fruits", "completed": true } ``` - **Response**: ```json { "code": 0, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "", "data": { "_id": "60d5ec49e4b0b8b8b8b8b8b9", "user_id": "60d5ec49e4b0b8b8b8b8b8b8", "title": "Buy groceries and fruits", "description": "Milk, eggs, bread", "completed": true, "due_date": "2023-06-26T00:00:00.000Z", "reminder_time": null, "created_at": "2023-06-25T00:00:00.000Z", "updated_at": "2023-06-25T01:00:00.000Z" } } } ``` #### 5. 删除待办事项 - **URL**: `/api/todos/:id` - **Method**: `DELETE` - **Headers**: `{ "user_id": "60d5ec49e4b0b8b8b8b8b8b8" }` - **Response**: ```json { "code": 0, "timestamp": "2025-01-01T00:00:00.000Z", "result": { "error": "", "data": { "_id": "60d5ec49e4b0b8b8b8b8b8b9", "user_id": "60d5ec49e4b0b8b8b8b8b8b8", "title": "Buy groceries and fruits", "description": "Milk, eggs, bread", "completed": true, "due_date": "2023-06-26T00:00:00.000Z", "reminder_time": null, "created_at": "2023-06-25T00:00:00.000Z", "updated_at": "2023-06-25T01:00:00.000Z" } } } ``` ## 开发规范 - **代码缩进**: 4 空格 - **代码检查**: ESLint - **命名规范**: - 文件和目录名: 小驼峰式(camelCase) - 变量和函数名: 小驼峰式(camelCase) - 类名: 大驼峰式(PascalCase) - **API 设计**: RESTful API 规范 - **响应格式**: 统一响应格式 - **请求验证**: 使用 Fastify 内置 AJV 验证 - **分页规范**: 支持 `page` 和 `limit` 查询参数,返回包含总数和分页信息的响应 ## 请求验证 ### 验证规则 #### 用户注册 - `phone`: 手机号格式验证,正则表达式:`^1[3-9]\d{9}$` - `password`: 字符串,必填,最小长度 6 #### 手机号检查 - `phone`: 手机号格式验证,正则表达式:`^1[3-9]\d{9}$` - `password`: 字符串,必填,最小长度 6 #### 待办事项列表 - `page`: 整数,最小值 1,默认值 1 - `limit`: 整数,最小值 1,最大值 100,默认值 10 #### 创建待办事项 - `title`: 字符串,必填,最小长度 1,最大长度 200 - `description`: 字符串,可选,最大长度 1000 - `due_date`: 字符串,可选,ISO 日期时间格式 - `reminder_time`: 字符串,可选,ISO 日期时间格式 #### 更新待办事项 - `id`: MongoDB ObjectID 格式验证 - `title`: 字符串,可选,最小长度 1,最大长度 200 - `description`: 字符串,可选,最大长度 1000 - `completed`: 布尔值,可选 - `due_date`: 字符串,可选,ISO 日期时间格式 - `reminder_time`: 字符串,可选,ISO 日期时间格式 #### 删除待办事项 - `id`: MongoDB ObjectID 格式验证 ## 脚本命令 | 命令 | 描述 | | ---- | ---- | | `npm run start` | 启动生产服务器 | | `npm run dev` | 启动开发服务器(带热更新) | | `npm run lint` | 运行 ESLint 检查 | | `npm run lint:fix` | 自动修复 ESLint 错误 | | `npm run version:patch` | 更新 patch 版本号 (1.0.0 -> 1.0.1) | | `npm run version:minor` | 更新 minor 版本号 (1.0.0 -> 1.1.0) | | `npm run version:major` | 更新 major 版本号 (1.0.0 -> 2.0.0) | ## 版本管理 手动更新版本号: ```bash # 修复 Bug,更新 patch 版本 (1.0.0 -> 1.0.1) npm run version:patch # 添加新功能,更新 minor 版本 (1.0.0 -> 1.1.0) npm run version:minor # 重大改动,更新 major 版本 (1.0.0 -> 2.0.0) npm run version:major ``` 更新版本号后,记得提交更改: ```bash git add package.json git commit -m "chore: bump version to x.x.x" ``` ## 后续优化建议 1. **实现 JWT 身份验证** 2. **实现数据缓存** 3. **添加单元测试和集成测试** 4. **实现 CI/CD 流水线** 5. **添加 API 文档自动生成** 6. **实现监控和告警系统** 7. **添加数据备份和恢复功能** 8. **实现限流和熔断机制** ## 许可证 ISC