refactor: 优化日历状态管理与首页输入框,添加API客户端抽象
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
# Design: Schedule Items API
|
||||
|
||||
**Date:** 2026-02-27
|
||||
**Status:** Approved
|
||||
|
||||
## Overview
|
||||
|
||||
实现日历事项(Schedule Items)的后端 CRUD API,支持用户创建、查询、更新、删除日历事项。
|
||||
|
||||
## Scope
|
||||
|
||||
- 仅后端 API,不涉及前端
|
||||
- 全量 CRUD
|
||||
- 查询按时间范围筛选
|
||||
- 暂不支持重复日程(recurrence_rule 留空)
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### 1. 创建日历事项
|
||||
|
||||
```
|
||||
POST /api/v1/schedule-items
|
||||
```
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"title": "string (1-255 chars, required)",
|
||||
"description": "string? (max 2000 chars)",
|
||||
"start_at": "string (ISO 8601 datetime, required)",
|
||||
"end_at": "string? (ISO 8601 datetime, must be after start_at)",
|
||||
"timezone": "string? (default: UTC)",
|
||||
"metadata": {
|
||||
"color": "#FF6B6B",
|
||||
"location": "会议室A",
|
||||
"notes": "记得带身份证",
|
||||
"attachments": [],
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:** 201 Created
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"title": "string",
|
||||
"description": "string?",
|
||||
"start_at": "string",
|
||||
"end_at": "string?",
|
||||
"timezone": "string",
|
||||
"metadata": {...},
|
||||
"status": "active",
|
||||
"source_type": "manual",
|
||||
"created_at": "string",
|
||||
"updated_at": "string"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 查询日历事项列表
|
||||
|
||||
```
|
||||
GET /api/v1/schedule-items?start_at=2026-02-01&end_at=2026-02-28
|
||||
```
|
||||
|
||||
**Query Parameters:**
|
||||
- `start_at`: ISO 8601 date/datetime(查询范围起始)
|
||||
- `end_at`: ISO 8601 date/datetime(查询范围结束)
|
||||
|
||||
**Response:** 200 OK
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "uuid",
|
||||
"title": "string",
|
||||
"start_at": "string",
|
||||
"end_at": "string?",
|
||||
"timezone": "string",
|
||||
"status": "active"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### 3. 获取单个事项
|
||||
|
||||
```
|
||||
GET /api/v1/schedule-items/{id}
|
||||
```
|
||||
|
||||
**Response:** 200 OK(完整字段,同创建响应)
|
||||
|
||||
### 4. 更新事项
|
||||
|
||||
```
|
||||
PATCH /api/v1/schedule-items/{id}
|
||||
```
|
||||
|
||||
**Request:** 支持 `title`/`description`/`start_at`/`end_at`/`timezone`/`metadata`/`status` 部分更新
|
||||
|
||||
**Response:** 200 OK
|
||||
|
||||
### 5. 删除事项
|
||||
|
||||
```
|
||||
DELETE /api/v1/schedule-items/{id}
|
||||
```
|
||||
|
||||
**Response:** 204 No Content(软删除)
|
||||
|
||||
## Data Models
|
||||
|
||||
### Metadata 结构(Pydantic)
|
||||
|
||||
```python
|
||||
from enum import Enum
|
||||
from pydantic import BaseModel
|
||||
from uuid import UUID
|
||||
|
||||
class AttachmentType(str, Enum):
|
||||
DOCUMENT = "document"
|
||||
REMINDER = "reminder"
|
||||
|
||||
class ScheduleItemMetadataAttachment(BaseModel):
|
||||
name: str
|
||||
type: AttachmentType
|
||||
visible_to: list[UUID] = []
|
||||
# document 类型
|
||||
url: str | None = None
|
||||
note: str | None = None
|
||||
# reminder 类型
|
||||
content: str | None = None
|
||||
|
||||
class ScheduleItemMetadata(BaseModel):
|
||||
color: str | None = None
|
||||
location: str | None = None
|
||||
notes: str | None = None
|
||||
attachments: list[ScheduleItemMetadataAttachment] = []
|
||||
version: int = 1
|
||||
```
|
||||
|
||||
### 数据库模型(已有)
|
||||
|
||||
参见 `backend/src/models/schedule_items.py`:
|
||||
- `id`: UUID
|
||||
- `owner_id`: UUID
|
||||
- `title`: String(255)
|
||||
- `description`: Text
|
||||
- `start_at`: DateTime(timezone=True)
|
||||
- `end_at`: DateTime(timezone=True)
|
||||
- `timezone`: String(50)
|
||||
- `extra_metadata`: JSONB (mapped as "metadata")
|
||||
- `recurrence_rule`: String(255)
|
||||
- `source_type`: Enum (MANUAL/IMPORTED/AGENT_GENERATED)
|
||||
- `status`: Enum (ACTIVE/COMPLETED/CANCELED/ARCHIVED)
|
||||
- `created_by`: UUID
|
||||
|
||||
## Architecture
|
||||
|
||||
遵循项目 `schemas / repository / service / router` 分层模式:
|
||||
|
||||
```
|
||||
backend/src/v1/schedule_items/
|
||||
├── __init__.py
|
||||
├── schemas.py # Pydantic 请求/响应模型
|
||||
├── repository.py # CRUD 操作(无 auth,无 commit)
|
||||
├── service.py # 业务逻辑 + 授权 + 事务边界
|
||||
├── router.py # FastAPI 路由定义
|
||||
└── dependencies.py # DI(如有)
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
- 所有端点需要认证(JWT)
|
||||
- `owner_id` 从 JWT `sub` 提取,不从请求体读取
|
||||
- 用户只能操作自己的日历事项(`owner_id` 过滤)
|
||||
- RLS 已在数据库层启用(防御边界)
|
||||
|
||||
## Error Handling
|
||||
|
||||
使用 RFC 7807 `application/problem+json` 格式:
|
||||
- 400: 请求参数无效
|
||||
- 401: 未认证
|
||||
- 404: 事项不存在或无权限访问
|
||||
- 422: 验证失败
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- 重复日程(recurrence_rule)
|
||||
- 日程订阅与协作(schedule_subscriptions)
|
||||
- 待办事项联动(todos/todo_sources)
|
||||
- 前端实现
|
||||
Reference in New Issue
Block a user