# Major Feature Update Plan

A comprehensive update adding sub-project tracking granularity, a cross-table R&D summary view, and a data management system (backup/restore/reset).

---

## Proposed Changes

### A — Rename "服务类型预设" → "子项目"

No DB schema changes needed (`service_types` column name stays, only UI text changes).

#### [MODIFY] ClientManage.vue
- Label "服务类型预设" → "子项目预设"
- Dialog field label updated

#### [MODIFY] TimesheetForm.vue
- Label "项目类型" → "子项目"
- Placeholder text updated

---

### B — Statistics display as "项目-子项目"

The `project_type` field in timesheets stores which sub-project was selected. Current stats queries ignore this field. We need to **group by project_type** within each project, and surface "项目名-子项目" combinations.

> [!IMPORTANT]
> This changes **all 3 tab views** (Sales/R&D/Project) to break down by sub-project in charts. Tables remain overview-level, but charts use the sub-project granularity.

#### [MODIFY] server/routes/admin.js
- Update `GET /admin/stats/sales`, `GET /admin/stats/rd`, `GET /admin/stats/project` queries to include sub-project breakdown (join with project_type from timesheets)

#### [MODIFY] client/src/views/admin/Dashboard.vue
- Build chart data as `"项目-子项目"` strings
- Both pie and bar charts use this combined label

---

### C — New Tab: 研发工时汇总 (Matrix)

A cross-table: rows = R&D personnel, columns = "项目-子项目", cells = total hours, plus row/column totals.

#### [NEW] server/routes/admin.js additions
- `GET /admin/summary-matrix?start_date=&end_date=` — returns flat rows with `{user_name, project_label, hours}`
- `GET /admin/export/matrix?start_date=&end_date=` — returns Excel file of the matrix

#### [MODIFY] client/src/api/index.js
- Add `getSummaryMatrix(params)` and `exportMatrixExcel(params)` to `adminApi`

#### [MODIFY] client/src/views/admin/Dashboard.vue
- Add 4th tab "📋 研发工时汇总"
- No charts, just the cross-table with totals row/column
- Date filter + Export button

---

### D — Admin: Clear All Data

#### [NEW] server/routes/admin.js additions
- `POST /admin/reset` — DELETE timesheets, DELETE clients (users preserved)

#### [NEW] client/src/views/admin/DataManage.vue
- New admin page for data management in one place
- Contains: Reset, Backup, Restore sections

#### [MODIFY] router/index.js + Layout.vue
- Add `/data-manage` admin route + menu item "🗄️ 数据管理"

---

### E — Backup / Restore / Auto-backup

#### [MODIFY] server/package.json
- Add `node-cron` dependency

#### [NEW] server/routes/admin.js additions
- `GET /admin/backup/download` — exports JSON `{users, clients, timesheets}`, sent as file download
- `POST /admin/restore` — accepts JSON body, clears and re-populates tables
- `GET /admin/backups` — lists saved auto-backup files (name, size, date)
- `GET /admin/backups/:filename/download` — download a specific auto-backup

#### [MODIFY] server/app.js
- After DB init: start `node-cron` job at `0 3 * * *`
- On trigger: export DB to JSON → save to `server/backups/backup-YYYY-MM-DD.json`
- Purge files in `server/backups/` older than 30 days

#### [MODIFY] client/src/views/admin/DataManage.vue
- **数据备份区**: "立即备份" button → triggers download of backup JSON
- **备份恢复区**: `el-upload` to upload a [.json](file:///c:/Users/chenpeixian/Documents/%E7%BB%9F%E8%AE%A12/server/package.json) backup → calls restore API
- **自动备份列表**: table of auto-backup files with download buttons
- **危险操作区**: "清除所有数据" button (double-confirmation)

---

## Verification Plan

### Backend Tests (manual curl / browser)
- POST client with same name → error
- GET `/admin/summary-matrix` → matrix data returned
- GET `/admin/export/matrix` → Excel file downloads
- POST `/admin/reset` → DB cleared, users remain
- GET `/admin/backup/download` → JSON file with 3 sections
- POST `/admin/restore` with that file → data re-populated
- Auto-backup: verify `server/backups/` gets [.json](file:///c:/Users/chenpeixian/Documents/%E7%BB%9F%E8%AE%A12/server/package.json) files

### Frontend
- Dashboard 4th tab: matrix table renders with totals
- Export matrix → file named correctly
- DataManage page: backup download, restore upload, reset with confirmation
- After restore: page refreshes with restored data
