From e3f73048a756b92a1a291f5242712fb3a1ea8abe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=A5=80=E6=A2=A6?= <3501646051@qq.com>
Date: Sun, 17 May 2026 12:59:52 +0800
Subject: [PATCH] refactor: remove all asset/account functionality (models,
schemas, routers, store, views, components, tests, docs)
---
AGENTS.md | 16 +-
README.md | 12 +-
WebUI/src/App.vue | 4 +-
WebUI/src/api/accounts.ts | 64 -
WebUI/src/api/types.ts | 89 --
WebUI/src/components/AccountDialog.vue | 361 ------
WebUI/src/components/AccountHistoryDialog.vue | 235 ----
WebUI/src/components/AppHeader.vue | 8 -
WebUI/src/components/BalanceDialog.vue | 185 ---
WebUI/src/components/InstallmentDialog.vue | 272 ----
WebUI/src/router/index.ts | 6 -
WebUI/src/stores/useAccountStore.ts | 208 ---
WebUI/src/stores/useUIStore.ts | 4 +-
WebUI/src/views/AssetPage.vue | 1134 -----------------
api/app/database.py | 2 +-
api/app/models/__init__.py | 2 -
api/app/models/account.py | 61 -
api/app/routers/__init__.py | 3 +-
api/app/routers/accounts.py | 490 -------
api/app/schemas/account.py | 141 --
tests/test_accounts.py | 618 ---------
21 files changed, 11 insertions(+), 3904 deletions(-)
delete mode 100644 WebUI/src/api/accounts.ts
delete mode 100644 WebUI/src/components/AccountDialog.vue
delete mode 100644 WebUI/src/components/AccountHistoryDialog.vue
delete mode 100644 WebUI/src/components/BalanceDialog.vue
delete mode 100644 WebUI/src/components/InstallmentDialog.vue
delete mode 100644 WebUI/src/stores/useAccountStore.ts
delete mode 100644 WebUI/src/views/AssetPage.vue
delete mode 100644 api/app/models/account.py
delete mode 100644 api/app/routers/accounts.py
delete mode 100644 api/app/schemas/account.py
delete mode 100644 tests/test_accounts.py
diff --git a/AGENTS.md b/AGENTS.md
index e1c5318..d2e4220 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -22,9 +22,6 @@ 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
-
-# Run the one hand-written test (backend must be running on :23994)
-python tests/test_accounts.py
```
**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.
@@ -40,9 +37,8 @@ python tests/test_accounts.py
- **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.
-- **Account balance changes** auto-create `AccountHistory` records in `update_balance()`. You cannot directly modify balance via `PUT /api/accounts/{id}` — balance is replaced via `POST /api/accounts/{id}/balance`.
- **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 / DebtInstallments** have computed fields (`next_date`, `days_until`, `year_count` / `remaining_periods`) calculated at request time, not stored in DB. The calculation functions live in the router layer (not models), because they depend on `date.today()`.
+- **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.
@@ -50,18 +46,17 @@ python tests/test_accounts.py
- `Category`: refuses deletion if tasks are linked (400)
- `HabitGroup`: sets linked habits' `group_id` to NULL
- `AnniversaryCategory`: sets linked anniversaries' `category_id` to NULL
- - `FinancialAccount`: full cascade delete (removes linked history + installments)
### 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 and accounts routers** BOTH use `prefix="/api"` (not `/api/anniversaries` or `/api/accounts`). Their internal paths are `/anniversaries`, `/anniversary-categories`, `/accounts`, `/debt-installments`, etc. They coexist because internal paths don't overlap — but be careful adding new routes; the first `include_router` match wins.
+- **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/`.
-- 9 Pinia stores: `auth`, `task`, `category`, `tag`, `habit`, `anniversary`, `account`, `userSettings`, `ui`. The `ui` store manages dialog visibility, editing state, sidebar collapse, and global loading (no API calls).
+- 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 ``, `` etc. in templates without imports.
- Element Plus uses Chinese locale (`zh-cn`).
- **Vite 7.x + TypeScript 5.9** with `erasableSyntaxOnly: true` and project references.
@@ -77,10 +72,7 @@ python tests/test_accounts.py
- `docker-compose.yml` mounts `api/data/` and `api/logs/` for persistence; `api/webui/` is read-only.
## Testing quirks
-- Only one test file: `tests/test_accounts.py` — **hand-written, no framework** (not pytest). It counts pass/fail manually and uses `requests` directly against `localhost:23994`.
-- Backend must be running before executing tests.
-- **The test permanently mutates the database** — Section 15 deliberately leaves test data in place for UI display. Run it on a disposable database copy or reset manually if you need a clean state.
-- **The test sends no auth headers** and will fail with 401 if JWT auth is enforced. You must first `POST /api/auth/login` with `{"password": "elysia"}` to get a token, then include `Authorization: Bearer ` in requests, or temporarily comment out the auth middleware for testing.
+- 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)
diff --git a/README.md b/README.md
index e22501f..fa94627 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Elysia ToDo - 爱莉希雅待办事项
-一款全栈个人信息管理应用,集待办任务、习惯打卡、纪念日提醒、资产总览于一体。
+一款全栈个人信息管理应用,集待办任务、习惯打卡、纪念日提醒于一体。
## 功能概览
@@ -20,12 +20,6 @@
- 支持农历/公历日期
- 倒计时提醒,不错过重要日子
-### 资产总览
-- 财务账户管理(现金、银行卡、电子钱包等)
-- 收支记录与历史查询
-- 分期还款跟踪
-- 资产汇总统计
-
### 系统功能
- 偏好设置(站点名称、默认视图等)
- 可折叠侧边栏
@@ -130,7 +124,6 @@ npm run dev
| 标签 | `/api/tags` | 标签 CRUD |
| 习惯 | `/api/habits` | 习惯、习惯组、打卡记录 |
| 纪念日 | `/api/anniversaries` | 纪念日、纪念日分类 |
-| 资产 | `/api/accounts` | 账户、交易记录、分期还款 |
| 设置 | `/api/user-settings` | 用户偏好设置 |
| 健康检查 | `/health` | 服务状态检查 |
@@ -143,9 +136,6 @@ Category ──< Task >── Tag
AnniversaryCategory ──< Anniversary
-FinancialAccount ──< AccountHistory
- ──< DebtInstallment
-
UserSettings (单例)
```
diff --git a/WebUI/src/App.vue b/WebUI/src/App.vue
index a96e3fb..4a430e1 100644
--- a/WebUI/src/App.vue
+++ b/WebUI/src/App.vue
@@ -24,7 +24,7 @@ const authStore = useAuthStore()
// 路由变化时同步 currentView
watch(() => route.meta.view, (view) => {
if (view) {
- uiStore.setCurrentView(view as 'list' | 'calendar' | 'quadrant' | 'profile' | 'settings' | 'habits' | 'anniversaries' | 'assets')
+ uiStore.setCurrentView(view as 'list' | 'calendar' | 'quadrant' | 'profile' | 'settings' | 'habits' | 'anniversaries')
}
}, { immediate: true })
@@ -89,7 +89,7 @@ onMounted(async () => {
-