Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 133 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,133 @@
# timeflow
# Timeflow

**让时间真正流动起来的智能日程与目标助手。**

Timeflow 面向需要同时管理日程、待办与长期目标的个人用户,把「记下要做什么」升级为「帮你安排、拆解、调整与复盘」。你可以用文字、语音或图片表达意图;系统理解后给出可执行的安排,并在计划偏离时帮助你重新排程。

> 当前仓库处于架构骨架与基础设施阶段:API、数据库迁移、质量门禁与 Agent / 业务目录边界已就绪,核心业务能力将按模块逐步落地。

---

## 产品定位

传统待办工具擅长记录,却很少帮你回答更难的问题:

- 这件事该插在今天的哪一段空档?
- 一个模糊目标如何拆成可执行步骤?
- 突发冲突出现时,整周计划如何最小代价地重排?
- 执行一段时间后,该如何复盘并改进下一次安排?

Timeflow 的目标是成为**时间决策的协同方**:不只存事项,还参与调度、拆解、重排与反馈闭环,让计划跟着真实生活持续流动。

---

## 核心能力

| 能力 | 说明 |
| --- | --- |
| 日程与待办调度 | 创建、调整日程与待办,结合已有安排给出可落地的时间建议 |
| 任务拆解 | 将模糊目标拆成可执行的子任务与阶段性计划 |
| 智能重排 | 在冲突、延期或优先级变化时,重新规划后续时间线 |
| 执行反馈 | 记录完成情况与偏差,为后续调度提供依据 |
| 周期复盘 | 对目标与时间使用进行回顾,沉淀可复用的改进建议 |
| 多模态输入 | 支持文字、语音(ASR)与图片(OCR)表达意图 |
| 日程视图 | 按时间展示日程、待办与目标任务,支持确认后的统一查看与操作 |

消息提醒等端侧能力由移动端负责;后端聚焦理解、规划与事实数据管理。

---

## 目标架构(概览)

Timeflow 的 Agent 协作采用「主入口 + 专项能力」的职责划分,并与非 Agent 业务边界并存。下图展示各模块的职责与协作关系:

```text
用户(Android App)
主 Agent(唯一对话 / 编排入口)
├── 日程待办 Agent
├── 任务拆解 Agent
├── 重排 Agent
├── 复盘 Agent
└── 反馈 Agent
公共事实数据 / 用户画像 / 对象存储
```

- **主 Agent(目标职责)**:对外提供唯一 Agent HTTP 入口,负责理解意图、追问补全、确认写操作与结果编排。
- **专项 Agent(目标职责)**:作为进程内能力包,专注各自领域推理,不直接对外暴露接口、不直接落库。
- **Basic 业务**:身份、用户画像、OCR / ASR、用量管理等非对话型产品能力。
- **Common 能力**:公共数据读写、LLM 调用、任务画像、对象存储与系统日志等横切支撑。

详细目录说明见 [docs/project-structure.md](docs/project-structure.md)。

---

## 技术栈

| 层级 | 选型 |
| --- | --- |
| 移动端 | Expo React Native(目标平台 **Android**)+ TypeScript |
| API | FastAPI + SQLAlchemy + Alembic |
| 数据 | PostgreSQL 16 |
| 工程 | uv(后端) / npm(前端),Docker Compose 本地栈 |

运行时版本基线:Node.js `>=20.20.2 <21`、Python `>=3.11,<3.12`(Docker 使用 `3.11.15`)、uv `0.11.28`、PostgreSQL `16.4`。依赖约定见 [docs/dependency-management.md](docs/dependency-management.md)。

---

## 快速开始

```bash
# 1. 环境文件
cp .env.example .env
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env

# 2. 安装依赖
npm --prefix frontend ci
(cd backend && uv sync --locked --all-groups)

# 3. 启动 PostgreSQL + API(容器会先执行 alembic upgrade head)
docker compose up --build
```

- API 健康检查:<http://127.0.0.1:8000/api/v1/health>
- 仅启动移动端:`npm --prefix frontend run start`(Android:`npm --prefix frontend run android`)
- 仅本地启动 API:`cd backend && uv run alembic upgrade head && uv run uvicorn timeapp.main:app --reload`
- Android 模拟器默认通过 `10.0.2.2` 访问宿主机 API;真机请将 `EXPO_PUBLIC_API_URL` 改为开发机局域网 IP

更多后端说明见 [backend/README.md](backend/README.md)。

---

## 质量与协作

```bash
bash scripts/check-all.sh # 全量
bash scripts/check-all.sh backend # 仅后端
bash scripts/check-all.sh frontend # 仅前端
```

数据库迁移验证只在显式设置 `TIMEAPP_CHECK_DATABASE_URL` 时执行,并且数据库名必须以 `_test` 或 `_check` 结尾。脚本不会对应用使用的 `TIMEAPP_DATABASE_URL` 执行迁移;一旦提供检查数据库地址,配置、连接或迁移错误都会使门禁失败。

开发规范与硬性约束见 [docs/skills/dev-standards/SKILL.md](docs/skills/dev-standards/SKILL.md)。提交信息遵循 [Conventional Commits](https://www.conventionalcommits.org/zh-hans/v1.0.0/)。

---

## 文档索引

| 文档 | 内容 |
| --- | --- |
| [docs/project-structure.md](docs/project-structure.md) | 仓库目录与模块边界 |
| [docs/dependency-management.md](docs/dependency-management.md) | 依赖与锁文件规则 |
| [docs/skills/dev-standards/SKILL.md](docs/skills/dev-standards/SKILL.md) | 开发规范 |
| [docs/skills/git-hooks/SKILL.md](docs/skills/git-hooks/SKILL.md) | Git Hooks 启用指引 |
| [backend/README.md](backend/README.md) | API 本地启动与迁移 |

---

Timeflow —— 让计划跟随生活流动,而不是让生活迁就一份过时的清单。
38 changes: 38 additions & 0 deletions docs/dependency-management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# 依赖管理

## 运行时基线

| 范围 | 工具 | 版本基线 | 权威来源 |
| --- | --- | --- | --- |
| 前端运行时 | Node.js | `>=20.20.2 <21` | `frontend/package.json`(`engines`) |
| 前端包管理器 | npm | 10.8.2 | `frontend/package.json`(`engines` / `packageManager`) |
| 后端运行时 | Python | `>=3.11,<3.12`(Docker:3.11.15) | `backend/pyproject.toml`(版本范围)与 `backend/Dockerfile`(精确版本) |
| 后端包管理器 | uv | 0.11.28 | `backend/Dockerfile` |
| 开发数据库 | PostgreSQL | 16.4 | `docker-compose.yml` |

## 允许的命令

- 前端依赖:`npm --prefix frontend ci`
- 后端依赖:`cd backend && uv sync --locked --all-groups`
- 官方门禁:`bash scripts/check-all.sh`(或带 `backend` / `frontend` 参数);显式设置 `TIMEAPP_CHECK_DATABASE_URL` 后,后端还会执行 `alembic upgrade head` + `alembic check`
- 前端质量与安全:`npm --prefix frontend run check` 与 `npm --prefix frontend audit --audit-level=moderate`
- 后端质量:`cd backend && uv run ruff check . && uv run ruff format --check . && uv run mypy && uv run pytest && uv run alembic history`
- 数据库迁移:`cd backend && uv run alembic upgrade head`;模型变更后 `uv run alembic revision --autogenerate -m "..."`

开发环境禁止使用 yarn、pnpm、`pip install`、Poetry,或再引入第二套锁文件;`backend/Dockerfile` 仅使用 pip 安装固定版本的 uv 作为构建引导。

数据库迁移检查不得复用应用的 `TIMEAPP_DATABASE_URL`。检查数据库必须通过 `TIMEAPP_CHECK_DATABASE_URL` 显式提供,名称以 `_test` 或 `_check` 结尾,并且只用于可随时重建的数据;配置、连接或迁移失败会直接终止门禁。未设置时脚本会明确警告迁移检查未运行。

## 锁文件规则

- 修改 `frontend/package.json` 后必须提交 `frontend/package-lock.json`
- 修改 `backend/pyproject.toml` 后必须提交 `backend/uv.lock`
- 安装与质量检查使用 `npm ci` 和 `uv sync --locked`,二者不得改写锁文件
- 运行时依赖与开发依赖保持在各自声明的分区中

## 更新流程

1. 只改对应 manifest 里的一处依赖声明。
2. 只重新生成该包管理器的锁文件。
3. 跑对应端的质量检查与安全审计(优先 `bash scripts/check-all.sh`)。
4. 若改了 Expo 相关依赖,提交前跑 Expo Doctor 与 Android export。
39 changes: 39 additions & 0 deletions docs/project-structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# 项目结构

```text
timeflow/
├── .env.example # Docker Compose 开发默认值
├── backend/
│ ├── Dockerfile
│ ├── docker-entrypoint.sh # 启动前执行 alembic upgrade head
│ ├── alembic.ini # Alembic 配置(连接串来自 Settings)
│ ├── alembic/ # 迁移环境与 versions/
│ ├── pyproject.toml
│ ├── uv.lock
│ ├── README.md
│ ├── src/timeapp/
│ │ ├── agents/ # 主 Agent 与五个子 Agent 的空目录边界
│ │ ├── api/ # HTTP 路由聚合与健康检查
│ │ ├── basic/ # 手动业务、用户画像与 OCR/ASR 边界
│ │ ├── common/ # 数据、LLM、任务画像、对象存储与日志边界
│ │ └── core/ # 配置与数据库基础设施
│ └── tests/
├── docs/
│ ├── project-structure.md
│ ├── dependency-management.md
│ └── skills/ # 开发规范与 git hooks 指引
│ ├── dev-standards/
│ └── git-hooks/
├── frontend/
│ ├── .env.example # Android 模拟器 API 基址
│ ├── package.json
│ ├── package-lock.json
│ └── src/
│ ├── api/
│ ├── constants/
│ └── screens/
├── docker-compose.yml # API 与 PostgreSQL 开发栈
└── scripts/check-all.sh # 官方完工门禁
```

`agents/` 及其主 Agent、五个子 Agent 目录保留为空(仅 `__init__.py`),实现文件将在数据库和接口设计完成后添加。`common/` 负责共享数据、LLM、任务画像、对象存储和系统日志;`basic/` 负责非 Agent 产品边界。消息推送由前端实现。
142 changes: 142 additions & 0 deletions docs/skills/dev-standards/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
name: dev-standards
description: Timeflow 项目的开发规范与硬性约束。在本仓库中编写、修改、重构任何代码(backend FastAPI 或 frontend Expo RN)之前必须先阅读并遵守。涵盖架构分层、API 设计、数据库、前端结构、命名、注释语言、测试与安全底线,以及 AI 禁止行为清单。
---

# Timeflow 开发规范

本文件是本仓库的最高开发约束。与本文件冲突的实现一律不允许产出。
改完代码后必须运行检查(见「完工门禁」),检查不过不算完成。

## 项目概览

- `backend/`:FastAPI + SQLAlchemy + Alembic,Python `>=3.11,<3.12`,包管理用 **uv**(开发环境禁止 pip install / poetry)
- `frontend/`:Expo React Native + TypeScript strict,**目标平台为 Android**,包管理用 **npm**(禁止 yarn / pnpm),本地运行用 `npm --prefix frontend run android`
- 后端包名 `timeapp`,src 布局:`backend/src/timeapp/`

## 完工门禁(每次改完代码必须执行)

```bash
# 只改了后端
bash scripts/check-all.sh backend
# 只改了前端
bash scripts/check-all.sh frontend
# 都改了
bash scripts/check-all.sh
```

门禁内容:后端 `ruff check` + `ruff format --check` + `mypy`(strict)+ `pytest` + `alembic history`;显式设置 `TIMEAPP_CHECK_DATABASE_URL` 后,再对该检查数据库执行 `alembic upgrade head` + `alembic check`;前端 `eslint` + `prettier --check` + `tsc --noEmit` + `npm audit --audit-level=moderate`。
任何一项失败都必须修复后重跑,直到全绿。禁止用 `# noqa`、`# type: ignore`、`eslint-disable` 掩盖问题(确有必要时必须写明原因并在回复中向用户说明)。

迁移检查禁止使用应用的 `TIMEAPP_DATABASE_URL`,只能显式提供数据库名以 `_test` 或 `_check` 结尾的 `TIMEAPP_CHECK_DATABASE_URL`。该数据库必须是可随时重建的本地或测试数据库;一旦提供,配置、连接和迁移错误都必须使门禁失败。未提供时必须明确报告迁移检查未运行。

## 后端架构(强制分层)

后端按 Agent 边界组织,禁止把业务写进 `api/`、`core/` 或 `main.py`:

```text
src/timeapp/
├── agents/ # 主 Agent 与五个子 Agent 的目录边界,当前仅含空 __init__.py
│ ├── main_agent/
│ ├── schedule_todo_agent/
│ ├── task_breakdown_agent/
│ ├── replanning_agent/
│ ├── review_agent/
│ └── feedback_agent/
├── basic/ # 非 Agent 产品边界(手动业务、用户画像、OCR/ASR 等)
│ └── <domain>/ # router / schemas / service / models(按需)
├── common/ # 跨 Agent 共享能力
│ ├── data/ # 公共事实数据读写(专项 Agent 禁止直接调用)
│ ├── llm/ # 统一模型调用与提示词管理
│ ├── task_profile/ # 任务级画像
│ ├── object_storage/ # 图片与音频对象存储
│ └── system_logs/ # 系统日志与业务审计
├── api/ # 路由聚合、health、dependencies
└── core/ # Settings、DB engine / session / Base
```

- Agent 调用协议和实现文件尚未确定;新增 Agent 逻辑必须依据 Wiki 设计,通过独立功能提交实现
- 目标架构中只有 `main_agent` 暴露 Agent HTTP 入口;专项 Agent 是进程内能力包,不直接读写数据库、不追问、不执行 `db_action`
- 对外 HTTP 路由必须在 `api/router.py` 中注册:`api_router.include_router(...)`
- 横切能力(认证、DB 会话)统一放 `api/dependencies.py`,业务包内禁止自建
- 配置只能通过 `core/config.py` 的 `Settings` 读取,禁止在业务代码里直接 `os.environ`
- `basic/<domain>/` 内部分层:`router` 只做 HTTP 编排,`service` 禁止出现 FastAPI 对象;包之间只允许调用对方 `service`,禁止跨包 import `router` / `models`
- ORM 模型放 `basic/<domain>/models.py` 或经 `common/data/` 统一出口;专项 Agent 目录禁止出现 `models.py` 与数据库导入

## API 设计

- 路径用 kebab-case,与现有前缀保持一致;资源用复数名词,禁止动词路径(`POST /todos`,不是 `/create-todo`)
- 请求/响应必须定义 Pydantic 模型并声明 `response_model`,禁止返回裸 dict
- 状态码:创建 201、删除 204、404/409 等错误用 `HTTPException` 抛出,`detail` 用英文
- 分页列表统一 query 参数 `limit`(默认 20,上限 100)+ `offset`

## 数据库

- 公共 `Base`、engine、session 放 `core/db.py`;迁移脚本放 `backend/alembic/versions/`
- 表名 snake_case 复数(`todos`、`goal_plans`);所有表必须有 `id`、`created_at`、`updated_at`
- 任何模型变更必须生成 Alembic 迁移(`cd backend && uv run alembic revision --autogenerate -m "..."`),禁止手改历史迁移、禁止 `Base.metadata.create_all` 用于生产路径
- 应用迁移:`cd backend && uv run alembic upgrade head`
- 查询写在 service / `common/data` 层,禁止在 router 里直接操作 session

## 前端结构(Expo RN)

新代码按以下目录组织(目录不存在时按需创建):

```text
frontend/src/
├── screens/ # 页面级组件,PascalCase:HomeScreen.tsx
├── components/ # 可复用组件,PascalCase:TodoCard.tsx
├── hooks/ # 自定义 hook,camelCase:useTodos.ts
├── api/ # 后端 API 封装,统一 fetch 客户端
├── types/ # 共享 TS 类型
└── constants/ # 颜色、间距等设计常量
```

- 一律函数组件 + hooks,禁止 class 组件;组件 props 必须有显式 TS 类型
- 样式用 `StyleSheet.create`,禁止大段内联样式对象;颜色/间距取自 `constants/`
- 禁止 `any`(确需未知类型用 `unknown` 再收窄);tsconfig strict 不得关闭
- 调用后端必须经过 `src/api/` 封装层,组件内禁止直接写 fetch/URL

### Android 适配(目标平台)

- 一切 UI 与交互以 Android 为准验收,禁止引入 iOS-only API(如 `ActionSheetIOS`)
- 阴影用 `elevation`,禁止只写 iOS 的 `shadow*` 系列样式
- 必须处理 Android 物理返回键的页面退出逻辑(`BackHandler` 或导航库默认行为)
- 系统权限(通知、麦克风、相册等)在 `app.json` 的 `android.permissions` 中声明,并在代码中运行时请求
- 刘海屏/状态栏适配用 `SafeAreaView`/safe-area 方案,不写死状态栏高度

## 命名与语言

- Python:模块/函数/变量 snake_case,类 PascalCase;TS:变量/函数 camelCase,组件/类型 PascalCase
- 注释和 docstring 用**中文**;标识符、日志、错误信息、commit scope 用**英文**
- 只写解释「为什么」的注释,禁止复述代码行为的废话注释

## 测试(硬性要求)

- 新增或修改业务逻辑(service 层、非空壳 router、工具函数)必须同步补/改 pytest 测试,放 `backend/tests/test_<模块>.py`
- API 测试用 `fastapi.testclient.TestClient`,覆盖正常路径 + 至少一个错误路径
- 改完必须实际运行 `cd backend && uv run pytest` 并通过;禁止提交只为凑数、无断言的测试

## 安全底线

- 密钥、token、连接串只能走环境变量(`TIMEAPP_` 前缀)+ `.env`(已 gitignore),新增变量必须同步更新 `.env.example`(放占位值)
- 禁止把 `.env`、真实密钥、用户数据写进代码、测试、文档
- SQL 只能通过 ORM / 绑定参数,禁止字符串拼接 SQL
- 禁止 `print` 调试(ruff T20 会拦截);日志不得输出密码、token、个人敏感信息
- 后端禁止吞异常(裸 `except: pass`);对外错误信息不暴露堆栈和内部路径

## AI 禁止行为清单

1. 禁止未经用户同意引入新依赖、新框架、新服务(改 `backend/pyproject.toml` / `frontend/package.json` 依赖前必须先说明理由并征得同意)
2. 禁止修改与当前任务无关的代码、重排无关 import、顺手重构
3. 禁止留 TODO 空壳函数、`pass` 占位实现交差;做不完就明确告诉用户哪部分没做
4. 禁止降低门禁:不得删除/放宽 ruff、mypy、eslint、tsconfig 的现有配置
5. 未经用户明确授权,禁止执行 git init、commit、push、merge 或创建 PR;用户明确授权后,只能在授权范围内操作。启用 hooks 时按 `git-hooks` skill 写 `.git/hooks/` 下的三个文件
6. 禁止编造不存在的 API、库用法;不确定就先查证
7. 禁止跳过「完工门禁」就宣称任务完成

## Commit 规范(供用户参考,hooks 强制)

提交信息请遵循 Conventional Commits 规范,详见 <https://www.conventionalcommits.org/zh-hans/v1.0.0/>。
格式 `type(scope)?: 描述`,type 限 feat/fix/docs/style/refactor/perf/test/build/ci/chore/revert,scope 可选且使用英文模块名,描述可中文,标题 ≤ 72 字符。示例:`feat(scheduling): 新增待办创建接口`。
启用拦截:用户提出需求后,按 `docs/skills/git-hooks/SKILL.md` 创建 hooks(pre-commit 检查改动端、commit-msg 校验格式、pre-push 全量检查)。
Loading