chore: remove AGENTS.md from tracking, gitignore Claude doc files

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
祀梦
2026-05-17 14:43:04 +08:00
parent 58559064d2
commit 1047bcece9
2 changed files with 4 additions and 86 deletions

4
.gitignore vendored
View File

@@ -72,3 +72,7 @@ check_*.py
# Environment variables
.env
.env.*
# Claude Code
CLAUDE.md
AGENTS.md

View File

@@ -1,86 +0,0 @@
# AGENTS.md
## Project overview
- Full-stack todo app: **Vue 3 + Element Plus** (WebUI/) + **FastAPI + SQLAlchemy** (api/)
- **Python 3.10+, Node 18+**; SQLite database
- Single `master` branch (4 commits total), no CI/CD
## Quick commands
```powershell
# Install Python deps (required before first run)
pip install -r requirements.txt
# Full-stack one-shot (builds frontend, then starts backend on :23994)
python main.py
# Frontend dev only (hot-reload on :5173, proxies /api → :23994)
cd WebUI; npm run dev
# Backend only
cd api; uvicorn app.main:app --host 0.0.0.0 --port 23994
# Type-check frontend (noEmit; uses project references tsconfig)
cd WebUI; npm run typecheck
```
**Build order matters:** `python main.py` automatically compiles WebUI (`npm install` + `npm run build`), copies `WebUI/dist/``api/webui/`, then starts uvicorn. It checks timestamps to skip rebuilds when frontend is unchanged.
**Import path:** `main.py` injects `api/` into `sys.path` (no `os.chdir`). Backend imports resolve relative to `api/` — e.g. `from app.config import ...`, not `from api.app.config import ...`.
**Port conflict:** `main.py` will auto-kill any process already listening on port 23994 before starting. If you have another instance running, it will be terminated without warning.
## Architecture
### Backend (`api/app/`)
- **Config is hardcoded** in `api/app/config.py` — no `.env`, no `os.getenv()`. Port `23994`, CORS origins `["http://localhost:5173", "http://localhost:23994"]`. Note: `pydantic-settings` is in `requirements.txt` but unused.
- **SQLite path** is computed relative to `api/` via `__file__` — safe regardless of cwd. `connect_args={"check_same_thread": False}` for FastAPI async compatibility.
- **`database.py:init_db()`** auto-creates tables on startup (`create_all`) and auto-adds missing columns via `ALTER TABLE ADD COLUMN` (no Alembic). Columns that are non-nullable with no default are skipped.
- **UserSettings is a singleton**: always id=1, auto-created on first `GET`. `set_default_password()` auto-initializes password to `"elysia"` on first access if `password_hash` is empty.
- **Habit checkins for the same day** accumulate count (not new rows), enforced by a `(habit_id, checkin_date)` unique constraint. Cancelling reduces count; deleting when count ≤ 0 removes the row.
- **Anniversaries** have computed fields (`next_date`, `days_until`, `year_count`) calculated at request time, not stored in DB. The calculation functions live in the router layer (not models), because they depend on `date.today()`.
- **`task_tags` M2M table** is defined in `models/tag.py` (not `models/task.py`). Tags only support create/delete (no update).
- **Update schemas** use `clearable_fields` + `exclude_unset=True` to distinguish "field not sent" from "field sent as null". For non-clearable fields, `None` means "don't change"; for clearable fields, `None` means "clear it". See `schemas/task.py:TaskUpdate`, `schemas/habit.py:HabitUpdate`, `schemas/anniversary.py:AnniversaryUpdate`.
- **JWT authentication** — `utils/auth.py` handles JWT (HS256, key: `"elysia-todo-secret-key-change-in-production"`, 24h expiry). Middleware in `main.py` validates tokens for all `/api/*` routes except `/api/auth/*` and `/health`. Default password: `elysia`. Login via `POST /api/auth/login`. Token key in localStorage: `elysia_auth_token`. **Middleware only validates the token; it does NOT inject user info into `request.state`.** Routes needing user data must call `get_current_user(request)` manually.
- **Different cascade delete strategies:**
- `Category`: refuses deletion if tasks are linked (400)
- `HabitGroup`: sets linked habits' `group_id` to NULL
- `AnniversaryCategory`: sets linked anniversaries' `category_id` to NULL
### Router registration quirks
- **`/health` MUST be registered before `/{full_path:path}`** in `main.py:114` — otherwise SPA fallback intercepts health checks and returns `index.html`.
- **habits router** (`routers/habits.py`) is an empty-shell router that combines 3 sub-routers via `include_router`: habit-groups (`/api/habit-groups`), habits (`/api/habits`), and checkins (`/api/habits/{habit_id}/checkins`).
- **anniversaries router** uses `prefix="/api"` (not `/api/anniversaries`). Its internal paths are `/anniversaries`, `/anniversary-categories`, etc.
### Frontend (`WebUI/`)
- Vue Router uses `createWebHistory()` (HTML5 history mode) — **requires the backend SPA fallback** (`/{full_path:path}``index.html`).
- Vite dev proxy forwards `/api``http://localhost:23994`.
- `@` alias maps to `src/`.
- 8 Pinia stores: `auth`, `task`, `category`, `tag`, `habit`, `anniversary`, `userSettings`, `ui`. The `ui` store manages dialog visibility, editing state, sidebar collapse, and global loading (no API calls).
- Element Plus icons registered globally in `main.ts` — use `<Edit />`, `<Delete />` etc. in templates without imports.
- Element Plus uses Chinese locale (`zh-cn`).
- **Vite 7.x + TypeScript 5.9** with `erasableSyntaxOnly: true` and project references.
- **Frontend task filtering is entirely client-side.** `fetchTasks()` loads all tasks once; filtering, sorting, and pinyin search run in computed getters. No server-side filtering for tasks.
- **Pinyin search** via `pinyin-pro` (`utils/pinyin.ts`) — supports Chinese character search by pinyin initials or full pinyin.
- **Token key `elysia_auth_token` is hardcoded in 3 separate files** (`router/index.ts`, `api/request.ts`, `stores/useAuthStore.ts`). If you rename it, update all 3.
- **401 response triggers a hard page redirect** (`window.location.href = '/login'`) in the axios interceptor, which reloads the SPA entirely. This differs from the router guard's in-app redirect (`return { path: '/login' }`).
- `sass` is a runtime `dependency` (not `devDependency`) in `package.json` — intentional.
### Docker
- `Dockerfile` copies pre-built `api/webui/` — you must build frontend before `docker build`.
- Docker CMD is an inline `python -c` one-liner that injects `api/` into `sys.path` and starts uvicorn. No separate entrypoint script.
- `docker-compose.yml` mounts `api/data/` and `api/logs/` for persistence; `api/webui/` is read-only.
## Testing quirks
- No test framework or test files currently in the repo.
- No test coverage for tasks, habits, anniversaries, or tags.
## What's missing (agents should not assume)
- No linter, formatter, pre-commit hooks, or CI/CD
- No `.env` or environment variable loading
- No database migrations framework (Alembic)
## Additional notes
- Swagger UI at `/docs` when backend is running.
- `python-multipart` in `requirements.txt` is required for FastAPI to parse form data (not optional).
- `pydantic-settings` is installed but unused — config is hardcoded.