feat: add health data management workspace

This commit is contained in:
2026-07-03 00:25:11 -07:00
parent dc034b6d85
commit 41807ff557
53 changed files with 7367 additions and 3 deletions

View File

@@ -180,3 +180,93 @@ if (!floor) {
}
await database.insert(rooms).values({ organizationId, floorId: floor.id, name, code });
```
## Scenario: Health Admin Data Management
### 1. Scope / Trigger
- Trigger: adding or changing health profile, vital record, chronic condition, or health anomaly review behavior.
- Applies because health data is persisted in Drizzle tables and rendered through a settings management page, not fabricated in the operational `/app/health` placeholder.
### 2. Signatures
- `GET /api/health/admin`
- `PUT /api/health/profiles/[elderId]`
- `POST /api/health/vitals`
- `POST /api/health/chronic-conditions`
- `PATCH /api/health/reviews/[id]`
- `listHealthAdminData(organizationId: string): Promise<HealthAdminData>`
- Mutations return either the domain DTO or `{ success: false; reason: string; status: number }`.
### 3. Contracts
- Health APIs must call `requirePermission` before reading or mutating:
- reads use `health:read`
- mutations use `health:manage`
- All health rows are scoped by `organizationId`.
- Elder-owned health mutations must validate the elder exists in the active organization.
- `GET /api/health/admin` returns `{ success: true; reason: string; data: HealthAdminData }`; client refresh code must read `result.data`.
- Mutation success responses follow the standard shape:
- profile: `{ success: true; reason: string; profile }`
- vital: `{ success: true; reason: string; vital; review? }`
- chronic condition: `{ success: true; reason: string; condition }`
- review: `{ success: true; reason: string; review }`
- Mutations must write audit logs after successful persistence.
### 4. Validation & Error Matrix
- Missing active organization -> `400` with a Chinese reason instructing the user to select an organization.
- Missing `elderId` for vital/condition -> `400`.
- Invalid date/source/status/numeric field -> `400`.
- Elder not found or belongs to another organization -> `404` / `老人档案不存在`.
- Review not found or belongs to another organization -> `404` / `异常复核记录不存在`.
- Missing permission -> `403` from `requirePermission`; route must not call domain helpers.
- Insert/update returning no row -> `500` mutation failure.
### 5. Good/Base/Bad Cases
- Good: keep `/app/settings/health` as the backend management surface and leave `/app/health` operational until real operational data exists.
- Good: return the admin payload under a `data` key so route output and client refresh types match.
- Good: seed demo health rows only inside the default workspace seeding transaction and tie them to real seeded elders.
- Base: anomaly review rows may be created automatically from MVP vital thresholds.
- Bad: render UI-only health records or counters on static module pages.
- Bad: hide mutation buttons in the UI without enforcing `health:manage` in the Route Handler.
- Bad: update reviews by `id` alone without also filtering by active `organizationId`.
### 6. Tests Required
- `pnpm test` with API assertions for each health route.
- Route tests must cover at least: happy path, permission denial, missing active organization, invalid input, and missing/cross-organization IDs.
- `pnpm db:generate` after schema changes, then review the generated SQL for only additive health enum/table/index/FK changes.
- `pnpm lint`, `pnpm type-check`, and `pnpm build`.
### 7. Wrong vs Correct
#### Wrong
```ts
const data = await listHealthAdminData(organizationId);
return jsonSuccess("健康数据已加载", data);
```
#### Correct
```ts
const data = await listHealthAdminData(organizationId);
return jsonSuccess("健康数据已加载", { data });
```
#### Wrong
```ts
await database.update(healthAnomalyReviews).set({ status }).where(eq(healthAnomalyReviews.id, id));
```
#### Correct
```ts
await database
.update(healthAnomalyReviews)
.set({ status, updatedAt: new Date() })
.where(and(eq(healthAnomalyReviews.id, id), eq(healthAnomalyReviews.organizationId, organizationId)));
```

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1,76 @@
# 护理服务执行工作台
## Goal
Replace the current `护理服务` placeholder with a real daily care execution workspace. The MVP unit is a persisted care task / service execution record, not a care-plan generation engine.
## Confirmed Facts
- `/app/care` currently renders `ModulePage` only.
- `/app/{organizationSlug}/care` delegates to the unscoped care page.
- Existing elder, bed, and admission data are persisted in Drizzle.
- Navigation already exposes `护理服务` under the operation group.
- Historical product direction includes care tasks, dispatch,巡检打卡, service records, and service evaluation.
## Requirements
- Add Drizzle-backed care execution records scoped by organization.
- Care records should link to a real elder where applicable.
- Care records should support at least:
- title/name
- care type
- priority
- status
- scheduled time or due time
- assignee label or executor label
- execution notes
- completed time
- Replace `/app/care` and `/app/{organizationSlug}/care` with a real workspace.
- The workspace should show summary metrics, filters, and a dense care task table/list.
- Operators must be able to filter by status, priority, care type, and elder/search terms.
- Authorized operators can mark care items as in progress and completed.
- Completion must persist notes and completion timestamp.
- Mutations must record audit logs.
- Default workspace seed data must include representative care examples covering multiple statuses and care types.
## Permissions
- Prefer explicit care permissions if adding new permissions is practical:
- `care:read`
- `care:manage`
- If scope needs to stay smaller, reuse existing `elder:update` temporarily only if documented in the design.
- Server-side permissions are required for all mutation APIs.
## Acceptance Criteria
- [ ] `/app/care` no longer renders the generic placeholder.
- [ ] `/app/{organizationSlug}/care` renders the same real care workspace.
- [ ] Care records are loaded from Drizzle and scoped to the active organization.
- [ ] Default seeded workspace includes care tasks tied to seeded elders.
- [ ] The UI shows pending, in-progress, completed, and overdue/high-priority examples.
- [ ] Authorized users can move a care item to in-progress and completed from the UI.
- [ ] Completed care items persist execution notes and completion time.
- [ ] Unauthorized mutation attempts return structured failures.
- [ ] Care mutations write audit log entries.
- [ ] `pnpm db:generate` is run if schema changes are made.
- [ ] `pnpm lint` passes.
- [ ] `pnpm type-check` passes.
- [ ] `pnpm build` passes.
## Dependencies
- Can start after or parallel with health management because it primarily depends on existing elder/admission data.
- Dashboard integration should wait until this task is complete.
## Out Of Scope
- Care plan template management.
- Automatic recurring task generation.
- Service billing or pricing.
- Family notifications.
- Mobile QR/NFC check-in.
- AI care recommendations.
## Open Questions
- None currently blocking planning.

View File

@@ -0,0 +1,26 @@
{
"id": "care-execution-workspace",
"name": "care-execution-workspace",
"title": "护理服务执行工作台",
"description": "",
"status": "planning",
"dev_type": null,
"scope": null,
"package": null,
"priority": "P2",
"creator": "TalexDreamSoul",
"assignee": "TalexDreamSoul",
"createdAt": "2026-07-02",
"completedAt": null,
"branch": null,
"base_branch": "main",
"worktree_path": null,
"commit": null,
"pr_url": null,
"subtasks": [],
"children": [],
"parent": "07-02-operations-module-roadmap",
"relatedFiles": [],
"notes": "",
"meta": {}
}

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1,191 @@
# Health Care Admin Page Design
## Summary
Add a dedicated management route under `/settings/health` for persisted elder health data. This keeps operational navigation (`/health`) separate from backend data administration, matching the user's direction to split the management surface into its own page.
## Route Boundary
- Unscoped route: `app/(app)/app/settings/health/page.tsx`
- Scoped route: `app/(app)/app/[organizationSlug]/settings/health/page.tsx`
- Optional redirect source: none in MVP. `/app/health` stays independent.
- Navigation: add a management item under `管理系统`.
- Breadcrumbs: add `"/settings/health": "健康数据管理"`.
The page should follow existing settings pages:
1. Server Component loads `getCurrentAuthContext()`.
2. Redirect unauthenticated users to `/login`.
3. Redirect users without `health:read` back to a safe workspace route.
4. Load persisted initial data through server helpers.
5. Render a focused Client Component for filtering and mutation UI.
## Data Model
All tables use `organizationId` for tenant scope and `createdAt` / `updatedAt` timestamps.
### `health_profiles`
- `id`
- `organizationId`
- `elderId`
- `allergyNotes`
- `medicalHistory`
- `medicationNotes`
- `careRestrictions`
- `emergencyNotes`
- `createdAt`
- `updatedAt`
Constraint: unique `(organizationId, elderId)` so each elder has one admin health profile.
### `vital_records`
- `id`
- `organizationId`
- `elderId`
- `recordedAt`
- `source`: `manual | device | import`
- `systolicBp`
- `diastolicBp`
- `heartRate`
- `temperatureTenths`
- `spo2`
- `bloodGlucoseTenths`
- `weightTenths`
- `notes`
- `createdByAccountId`
- `createdAt`
- `updatedAt`
Integer tenths avoid PostgreSQL numeric string handling for MVP decimal values.
### `chronic_conditions`
- `id`
- `organizationId`
- `elderId`
- `name`
- `status`: `active | controlled | resolved`
- `diagnosedAt`
- `treatmentNotes`
- `followUpNotes`
- `createdAt`
- `updatedAt`
### `health_anomaly_reviews`
- `id`
- `organizationId`
- `elderId`
- `vitalRecordId`
- `severity`: `info | warning | critical`
- `status`: `pending | reviewed | resolved`
- `title`
- `description`
- `reviewedByAccountId`
- `reviewedAt`
- `resolutionNotes`
- `createdAt`
- `updatedAt`
`vitalRecordId` is nullable so reviews can also be created directly against an elder health concern.
## Server Helpers
Create `modules/health/`:
- `modules/health/types.ts`
- shared enum values, labels, API DTO types, and validators.
- `modules/health/server/operations.ts`
- `listHealthAdminData(organizationId: string)`
- `upsertHealthProfile(...)`
- `createVitalRecord(...)`
- `createChronicCondition(...)`
- `updateHealthReview(...)`
- `modules/health/components/HealthAdminClient.tsx`
- client-side tabs, filters, dialogs/forms, optimistic-free refresh.
Server reads should batch queries by organization and join elders once. Avoid per-elder database calls.
## API Design
MVP route handlers:
- `GET /api/health/admin`
- permission: `health:read`
- returns metrics, elders, profiles, recent vitals, chronic conditions, reviews.
- `PUT /api/health/profiles/[elderId]`
- permission: `health:manage`
- validates elder belongs to active organization.
- upserts one profile.
- `POST /api/health/vitals`
- permission: `health:manage`
- validates elder belongs to active organization.
- creates vital record.
- may create a pending review if values exceed MVP thresholds.
- `POST /api/health/chronic-conditions`
- permission: `health:manage`
- validates elder belongs to active organization.
- creates chronic condition.
- `PATCH /api/health/reviews/[id]`
- permission: `health:manage`
- validates review belongs to active organization.
- updates status and review metadata.
All responses use `ApiResult`.
## Permission Design
Update `modules/core/types.ts` and `modules/core/server/permissions.ts`:
- Add `health:read`
- Add `health:manage`
- Add permission definitions in category `健康`
- Grant defaults:
- `org_admin`: read/manage
- `manager`: read/manage
- `caregiver`: read/manage unless user chooses stricter admin-only behavior
- `viewer`: read
This avoids overloading `elder:update` for a separate health management page.
## UI Design
The page should look like an internal management console:
- Header: `健康数据管理`, short description, manage badge if allowed.
- Metrics: elders with profiles, vitals today, active chronic conditions, pending reviews.
- Tabs:
- `健康档案`: elder list with profile completeness and edit dialog.
- `生命体征`: recent vitals table and add-vital dialog.
- `慢病记录`: condition table and add-condition dialog.
- `异常复核`: pending/reviewed/resolved queue with review action.
- Filters: elder search, status/severity select, source select where useful.
Keep tables and cards dense; no landing-page composition.
## Compatibility And Rollback
- Existing `/app/health` remains unchanged in MVP, limiting frontend blast radius.
- New tables are additive; rollback is dropping the generated health tables/enums and removing nav/API/page files.
- Existing seed file has uncommitted work. Implementation must read and preserve user changes in `modules/core/server/default-workspace-data.ts` before adding health seed rows.
## Validation
Required:
- `pnpm db:generate`
- Review generated SQL in `drizzle/`
- `pnpm lint`
- `pnpm type-check`
- `pnpm build`
Manual checks:
- login as authorized user and open `/app/{slug}/settings/health`
- create/update a health profile
- create a vital record
- create or review an abnormal item
- verify reload persists records
- verify mutation with insufficient permission returns `403`

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1,74 @@
# Implementation Plan
## 1. Align Task Metadata
- Update task title/description if needed so the Trellis task reflects `健康数据管理` instead of care-service workspace wording.
- Keep the existing task directory unless a rename is explicitly requested.
## 2. Schema And Migration
- Add health enums and tables in `modules/core/server/schema.ts`.
- Add indexes/unique constraints:
- profile unique `(organizationId, elderId)`
- recent vital lookups by `(organizationId, elderId, recordedAt)`
- review queues by `(organizationId, status, severity)`
- Run `pnpm db:generate`.
- Review generated migration SQL.
## 3. Types And Permissions
- Add `health:read` and `health:manage` to `modules/core/types.ts`.
- Add permission definitions and default role grants in `modules/core/server/permissions.ts`.
- Add health DTOs, labels, validators, and formatting helpers in `modules/health/types.ts`.
## 4. Server Operations
- Create `modules/health/server/operations.ts`.
- Implement batched list helper for the admin page.
- Implement mutation helpers for:
- profile upsert
- vital create
- chronic condition create
- review status update
- Ensure all helpers require an organization ID and validate elder/review ownership.
## 5. API Routes
- Add `/api/health/admin`.
- Add `/api/health/profiles/[elderId]`.
- Add `/api/health/vitals`.
- Add `/api/health/chronic-conditions`.
- Add `/api/health/reviews/[id]`.
- Use `requirePermission`, structured `jsonSuccess` / `jsonFailure`, and audit logs.
## 6. Admin Page UI
- Add `app/(app)/app/settings/health/page.tsx`.
- Add `app/(app)/app/[organizationSlug]/settings/health/page.tsx` delegating to the unscoped route pattern.
- Add `modules/health/components/HealthAdminClient.tsx`.
- Use existing UI adapters for buttons, cards, dialogs, inputs, selects, tables, and badges.
- Add management nav and breadcrumbs.
## 7. Default Workspace Data
- Carefully inspect current uncommitted `modules/core/server/default-workspace-data.ts`.
- Add health seed records only if compatible with existing default seed flow.
- Tie seed records to seeded elders and organization.
## 8. Verification
- Run `pnpm lint`.
- Run `pnpm type-check`.
- Run `pnpm build`.
- If a database is available, run `pnpm db:migrate` and manually test:
- scoped management page loads.
- health profile upsert persists.
- vital record create persists.
- abnormal review update persists.
- insufficient permission returns `403`.
## Rollback Points
- Before migration generation: schema changes can be removed directly.
- After migration generation: remove generated migration files and schema changes together.
- After UI/API addition: remove `modules/health`, health API routes, settings health pages, nav/breadcrumb additions, and health permissions.

View File

@@ -0,0 +1,117 @@
# Health Care Admin Page
## Goal
Build a separate backend management page for health care data instead of turning the existing operational `健康照护` module into a management surface. The first usable slice should let authorized staff manage real persisted health profiles, vital signs, chronic conditions, and abnormal-review records for elders in the active organization.
## Background And Confirmed Facts
- The current `健康照护` operational route renders the generic placeholder only: `app/(app)/app/health/page.tsx`.
- The scoped `健康照护` route delegates to the unscoped placeholder: `app/(app)/app/[organizationSlug]/health/page.tsx`.
- The placeholder contract explicitly forbids fabricated operational records until real Drizzle-backed data exists: `.trellis/spec/frontend/components.md`.
- The sidebar already has a separate `管理系统` group for backend management pages: `modules/shared/lib/navigation.ts`.
- Existing management routes live under `/settings/...` and have scoped mirrors under `/app/[organizationSlug]/settings/...`.
- Breadcrumbs already treat `/settings/...` as the management area: `modules/shared/components/AppBreadcrumbs.tsx`.
- The current Drizzle schema includes organizations, elders, rooms, beds, admissions, audit logs, incidents, permissions, roles, and sessions, but no health profile, vital sign, chronic condition, or health review tables: `modules/core/server/schema.ts`.
- Existing persisted feature pages load data in Server Components and pass initial records into Client Components, for example `app/(app)/app/elders/page.tsx` and `app/(app)/app/beds/page.tsx`.
- The user explicitly clarified that this should be a separate backend management page, split from the current operational health page.
## Requirements
### Route And Navigation
- Add a new backend management route under the management area.
- Recommended route: `/app/settings/health` with scoped mirror `/app/{organizationSlug}/settings/health`.
- Add a `管理系统` navigation item labeled `健康数据管理`.
- Keep the existing `/app/health` operational page separate from this management page for this task.
- Breadcrumbs must show the new route under `工作台 > 管理系统 > 健康数据管理`.
### Data Model And Persistence
- Add Drizzle-backed tables for the health-care admin MVP.
- Health data must be scoped by `organizationId`.
- Health data that belongs to an elder must reference a real elder in the same organization.
- Minimum persisted domains:
- health profile: allergy notes, medical history, medication notes, restrictions, emergency health note.
- vital sign record: recorded time, source, blood pressure, heart rate, temperature, SpO2, blood glucose, weight, notes.
- chronic condition: condition name, status, diagnosed date or note, treatment/follow-up notes.
- abnormal review: severity, status, source vital record or elder, reviewer, reviewed time, handling notes.
- Generated migrations must stay coherent with `modules/core/server/schema.ts`.
- New mutations must use Drizzle queries or transactions through server boundaries, not legacy write helpers.
### Permissions
- Add explicit health permissions unless implementation review finds an existing permission is a better fit:
- `health:read`
- `health:manage`
- The new management navigation item should require `health:read`.
- Mutations should require `health:manage`.
- Default role seeding should grant sensible permissions:
- platform admin: all permissions through the existing all-permissions pattern.
- organization admin and manager: read/manage.
- caregiver: read/manage for health records if the product treats caregivers as health-data operators.
- viewer: read only.
### API And Server Boundaries
- Add health-specific Route Handlers under `/api/health/...`.
- All health APIs must call `requirePermission`.
- All APIs must validate active organization presence before reading or mutating organization-scoped data.
- Invalid or cross-organization IDs must return structured failures.
- Mutations must record audit logs for create/update/review actions.
- API responses must follow the existing `{ success, reason, ... }` shape.
### Admin UI
- The new page must be dense and operational, not a hero or marketing page.
- The first screen should show summary metrics and data management controls.
- Expected tabs or sections:
- 健康档案
- 生命体征
- 慢病记录
- 异常复核
- The page should support filtering by elder, status/severity, and search terms where useful.
- Authorized users should be able to create or update health records from the UI.
- Users without manage permission may view records but must not see working mutation paths.
- Use project UI adapters from `components/ui/*`.
- Do not fabricate UI-only health records.
### Default Workspace Data
- If seeded workspace data is used for first-run development/demo, it must create real persisted health records tied to real seeded elders.
- Seed records should cover normal vitals, abnormal vitals, chronic conditions, and at least one pending abnormal review.
## Acceptance Criteria
- [ ] `/app/settings/health` renders a real backend health management page.
- [ ] `/app/{organizationSlug}/settings/health` renders the same management page in the active workspace.
- [ ] The new management page is reachable from the `管理系统` navigation group.
- [ ] Existing `/app/health` remains separate from the backend management page.
- [ ] Health admin data is loaded from Drizzle-backed tables and scoped to the active organization.
- [ ] Health profiles, vital signs, chronic conditions, and abnormal reviews have persisted list views.
- [ ] Authorized users can create or update at least the MVP health records from the UI.
- [ ] Users without `health:manage` cannot mutate health records through the API.
- [ ] Health mutations write audit log entries.
- [ ] Invalid input and cross-organization references return structured failure responses.
- [ ] Seeded examples, if added, are real database rows tied to seeded elders.
- [ ] `pnpm db:generate` is run after schema changes and generated SQL is reviewed.
- [ ] `pnpm lint` passes.
- [ ] `pnpm type-check` passes.
- [ ] `pnpm build` passes.
## Out Of Scope
- Replacing the existing operational `/app/health` placeholder with a full clinical dashboard.
- Device telemetry integration.
- External medical system integration.
- AI-generated health recommendations.
- Complex clinical decision support.
- Full recurring measurement schedule engine.
- Family app notifications.
- Billing, pricing, or insurance flows.
- Replacing Route Handlers with oRPC.
- Replacing the current authentication/session implementation.
## Open Questions
- None currently blocking planning.

View File

@@ -0,0 +1,26 @@
{
"id": "care-service-workspace",
"name": "care-service-workspace",
"title": "新增健康照护后台管理页",
"description": "新增独立的健康数据管理后台页面,与现有运营健康照护入口分开。",
"status": "in_progress",
"dev_type": null,
"scope": null,
"package": null,
"priority": "P2",
"creator": "TalexDreamSoul",
"assignee": "TalexDreamSoul",
"createdAt": "2026-07-02",
"completedAt": null,
"branch": null,
"base_branch": "main",
"worktree_path": null,
"commit": null,
"pr_url": null,
"subtasks": [],
"children": [],
"parent": "07-02-operations-module-roadmap",
"relatedFiles": [],
"notes": "",
"meta": {}
}

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1,55 @@
# 老人床位联动优化
## Goal
Improve the existing elder and bed workspaces so operators can see relevant cross-module context without leaving the workflow: current admission, bed, recent care tasks, health abnormal records, and safety incidents.
## Confirmed Facts
- `老人档案` already supports persisted elder CRUD.
- `床位房间` already supports persisted room, bed, admission, transfer, and discharge workflows.
- Elder rows already show current active bed labels from admissions.
- Bed rows already show current elder names where occupied.
- Health, care, and emergency modules will add additional context after their child tasks.
## Requirements
- Add cross-module context to elder and bed surfaces only after the relevant underlying persisted data exists.
- Elder detail/edit surfaces should expose concise recent context:
- current bed/admission state
- recent care execution records
- recent health abnormalities or latest vital summary
- open safety/emergency incidents tied to the elder when available
- Bed workspace should expose concise current occupant context:
- elder status and care level
- active/recent care tasks for the occupant
- open safety/emergency incidents for the bed/occupant when available
- The UI should remain dense and operational; avoid nested cards or large explanatory blocks.
- Cross-module data must be read-only context unless the user is in that module's own workflow.
- Server data loading should stay scoped by active organization.
## Acceptance Criteria
- [ ] Elder pages show current bed/admission context from persisted data.
- [ ] Elder pages show recent health/care/emergency context once those records exist.
- [ ] Bed workspace shows current occupant context without requiring manual lookup.
- [ ] Cross-module context does not fabricate records when a module has no data.
- [ ] Unauthorized users do not see context that they lack permission to read.
- [ ] Existing elder CRUD and bed/admission workflows still work.
- [ ] `pnpm lint` passes.
- [ ] `pnpm type-check` passes.
- [ ] `pnpm build` passes.
## Dependencies
- Should run after health data management, care execution workspace, and emergency incident workspace have shipped basic persisted data.
## Out Of Scope
- Moving all workflows into a single giant elder detail page.
- Editing health/care/emergency records from elder or bed context panels.
- Replacing existing elder or bed workspace architecture.
## Open Questions
- None currently blocking planning.

View File

@@ -0,0 +1,26 @@
{
"id": "elder-bed-context-optimization",
"name": "elder-bed-context-optimization",
"title": "老人床位联动优化",
"description": "",
"status": "planning",
"dev_type": null,
"scope": null,
"package": null,
"priority": "P2",
"creator": "TalexDreamSoul",
"assignee": "TalexDreamSoul",
"createdAt": "2026-07-02",
"completedAt": null,
"branch": null,
"base_branch": "main",
"worktree_path": null,
"commit": null,
"pr_url": null,
"subtasks": [],
"children": [],
"parent": "07-02-operations-module-roadmap",
"relatedFiles": [],
"notes": "",
"meta": {}
}

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1,65 @@
# 安全应急事件工作台
## Goal
Replace the current `安全应急` placeholder with a real emergency and safety event workspace. The MVP should let operators view, triage, update, and close persisted incidents inside the active organization.
## Confirmed Facts
- `/app/emergency` currently renders `ModulePage` only.
- `/app/{organizationSlug}/emergency` delegates to the unscoped emergency page.
- `systemIncidents` already exists in the Drizzle schema and supports severity, status, title, description, source, acknowledgement, resolution, and organization scoping.
- `app/api/system/incidents/[id]/route.ts` already supports incident status updates with audit logs.
- Settings status pages already use incident status actions.
## Requirements
- Replace `/app/emergency` and `/app/{organizationSlug}/emergency` with a real emergency workspace.
- Use existing persisted incident data as the starting model unless implementation analysis proves a separate emergency table is required.
- Show summary metrics by severity and status.
- Show an operational incident list/table with search and status/severity filters.
- Support status transitions for open, acknowledged, resolved, and closed events.
- Support creating a manual emergency/safety event if practical in the MVP.
- Link incidents to organization and optionally to elder/bed context in a future-compatible way.
- Mutations must record audit logs.
- Default workspace seed data must include representative safety/emergency events.
## Permissions
- Use existing `incident:read` for viewing.
- Use existing `incident:manage` for create/update/status transitions.
- Server-side permissions are required for all mutation APIs.
## Acceptance Criteria
- [ ] `/app/emergency` no longer renders the generic placeholder.
- [ ] `/app/{organizationSlug}/emergency` renders the same real emergency workspace.
- [ ] Emergency events are loaded from Drizzle and scoped to the active organization.
- [ ] The workspace shows severity/status metrics and a searchable event list.
- [ ] Authorized users can transition event status from the UI.
- [ ] Event status updates persist and survive reload.
- [ ] Authorized users can create a manual safety/emergency event if included in MVP implementation.
- [ ] Unauthorized mutation attempts return structured failures.
- [ ] Emergency mutations write audit log entries.
- [ ] Default seeded workspace includes safety/emergency events.
- [ ] `pnpm lint` passes.
- [ ] `pnpm type-check` passes.
- [ ] `pnpm build` passes.
## Dependencies
- Can start independently because `systemIncidents` already exists.
- Elder/bed context optimization may later add richer links from incidents to elders or beds.
- Dashboard integration should wait until this task is complete.
## Out Of Scope
- Device telemetry ingestion.
- Real-time alarm channels.
- SMS, phone, or push notification delivery.
- Dispatch routing engine.
- Post-incident regulatory reporting.
## Open Questions
- None currently blocking planning.

View File

@@ -0,0 +1,26 @@
{
"id": "emergency-incident-workspace",
"name": "emergency-incident-workspace",
"title": "安全应急事件工作台",
"description": "",
"status": "planning",
"dev_type": null,
"scope": null,
"package": null,
"priority": "P2",
"creator": "TalexDreamSoul",
"assignee": "TalexDreamSoul",
"createdAt": "2026-07-02",
"completedAt": null,
"branch": null,
"base_branch": "main",
"worktree_path": null,
"commit": null,
"pr_url": null,
"subtasks": [],
"children": [],
"parent": "07-02-operations-module-roadmap",
"relatedFiles": [],
"notes": "",
"meta": {}
}

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1,57 @@
# 运营看板整合优化
## Goal
Upgrade the existing operation dashboard into a cross-module summary after health, care, emergency, elder, bed, and admission data are available. The dashboard should summarize and route operators to work, not become a CRUD surface.
## Confirmed Facts
- The dashboard already uses real persisted elders, beds, admissions, and incidents.
- The dashboard currently does not include dedicated health or care-service metrics because those data sources do not exist yet.
- Recharts is already installed and the dashboard already uses a data-backed bed occupancy chart.
## Requirements
- Keep the dashboard as a Server Component data-loading surface with presentational components.
- Add health metrics after health data management exists:
- recent abnormal vital signs
- pending abnormal reviews
- chronic-condition coverage or counts where useful
- Add care metrics after care execution exists:
- today's care tasks
- pending/in-progress/completed care counts
- overdue/high-priority care count
- Add emergency metrics after emergency workspace exists:
- open safety events
- critical events
- recent resolved/closed events where useful
- Keep existing elder, bed, and admission summaries working.
- Use data-backed charts only; do not add fake visualization rows.
- Link dashboard items to the appropriate operational module route where practical.
## Acceptance Criteria
- [ ] Dashboard still loads persisted elder, bed, admission, and incident data.
- [ ] Dashboard includes persisted health summaries after health data is available.
- [ ] Dashboard includes persisted care execution summaries after care data is available.
- [ ] Dashboard includes persisted safety/emergency summaries after emergency data is available.
- [ ] Charts and tables are data-backed.
- [ ] Dashboard links route users into the relevant module instead of duplicating full workflows.
- [ ] `pnpm lint` passes.
- [ ] `pnpm type-check` passes.
- [ ] `pnpm build` passes.
## Dependencies
- Should run after health data management, care execution workspace, and emergency incident workspace are implemented.
- Should run after elder/bed context optimization if dashboard links depend on new detail surfaces.
## Out Of Scope
- Creating or editing records directly from the dashboard.
- Adding fake summary cards before backing data exists.
- Replacing the dashboard with a marketing landing page.
## Open Questions
- None currently blocking planning.

View File

@@ -0,0 +1,26 @@
{
"id": "operations-dashboard-integration",
"name": "operations-dashboard-integration",
"title": "运营看板整合优化",
"description": "",
"status": "planning",
"dev_type": null,
"scope": null,
"package": null,
"priority": "P2",
"creator": "TalexDreamSoul",
"assignee": "TalexDreamSoul",
"createdAt": "2026-07-02",
"completedAt": null,
"branch": null,
"base_branch": "main",
"worktree_path": null,
"commit": null,
"pr_url": null,
"subtasks": [],
"children": [],
"parent": "07-02-operations-module-roadmap",
"relatedFiles": [],
"notes": "",
"meta": {}
}

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1,47 @@
# Operations Module Roadmap Design
## Boundary
This parent task is a coordination artifact. It should not directly implement schema, API, or UI changes unless a later requirement explicitly adds parent-level integration work.
Implementation belongs to child tasks:
- `07-02-care-service-workspace`: health data management page.
- `07-02-care-execution-workspace`: care execution workspace.
- `07-02-emergency-incident-workspace`: emergency event workspace.
- `07-02-elder-bed-context-optimization`: cross-module context on elder and bed workflows.
- `07-02-operations-dashboard-integration`: final dashboard summaries.
## Dependency Shape
The modules should be delivered in foundation-to-summary order:
1. Health data management creates health records.
2. Care execution creates care task/service records.
3. Emergency workspace operationalizes incident records.
4. Elder/bed context reads the new health/care/emergency records.
5. Dashboard integration summarizes all persisted data.
## Shared Technical Contracts
- Drizzle schema remains the persistence source of truth.
- New tables are additive migrations.
- Organization scoping is mandatory.
- Elder-linked records validate same-organization ownership.
- API responses use `{ success, reason, ... }`.
- Route handlers call `requirePermission`.
- Mutations record audit logs.
- Default workspace data creates real rows, not UI-only fixtures.
## UI Contract
- Operational pages should use dense work-focused layouts.
- Backend management pages belong under `管理系统`.
- Existing `/app/health` remains separate from backend `健康数据管理`.
- `护理服务` is daily execution work, not health data management.
- `安全应急` is event triage and closure.
- `运营看板` summarizes and routes; it is not a CRUD surface.
## Rollback
Rollback should happen per child task. Parent rollback means unlinking or archiving the roadmap task; child migrations and source changes must be reverted in their own rollback plans.

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1,42 @@
# Implementation Plan
## Execution Order
1. Start and implement `07-02-care-service-workspace` (`新增健康照护后台管理页`).
2. Start and implement `07-02-care-execution-workspace` (`护理服务执行工作台`).
3. Start and implement `07-02-emergency-incident-workspace` (`安全应急事件工作台`).
4. Start and implement `07-02-elder-bed-context-optimization` (`老人床位联动优化`).
5. Start and implement `07-02-operations-dashboard-integration` (`运营看板整合优化`).
6. Review parent acceptance criteria after all children are complete.
## Per-Child Gate
Before starting each child:
- Read its `prd.md`.
- For complex children, add or refresh `design.md` and `implement.md`.
- Load `trellis-before-dev` and relevant backend/frontend/shared specs.
Before finishing each child:
- Run `pnpm lint`.
- Run `pnpm type-check`.
- Run `pnpm build`.
- Run `pnpm db:generate` and review SQL when schema changes are made.
- Confirm default workspace seed data is real persisted data when seed examples are added.
## Parent Completion Gate
The parent task is complete only after:
- Each child task is completed or explicitly moved out of scope by the user.
- The dashboard reflects completed module data.
- Existing elder, bed, admission, auth, settings, and audit workflows still pass validation.
- Final `pnpm lint`, `pnpm type-check`, and `pnpm build` pass.
## Risk Notes
- Schema migrations across multiple children can conflict if implemented out of order.
- Default seed file already has active edits; every child that touches it must read it before editing.
- Permission additions must keep role seeding idempotent.
- Dashboard integration should not start before the data sources exist.

View File

@@ -0,0 +1,106 @@
# 运营模块完善总计划
## Goal
Turn the six operation-side sidebar entries into a coherent persisted operating system for the pension workspace:
1. 运营看板
2. 老人档案
3. 床位房间
4. 健康照护
5. 护理服务
6. 安全应急
The work should be delivered as separate, independently verifiable child tasks, then integrated back into the dashboard. This parent task owns scope, ordering, and cross-module acceptance criteria. Implementation should happen in child tasks.
## Confirmed Facts
- `运营看板` already renders real Drizzle-backed elders, beds, admissions, and incidents data.
- `老人档案` already supports real persisted elder CRUD.
- `床位房间` already has a real bed/admission workspace backed by rooms, beds, elders, and admissions.
- `健康照护`, `护理服务`, and `安全应急` currently render placeholders or are not complete operational modules.
- The current Drizzle schema has core operational tables but no dedicated health or care-service tables yet.
- `systemIncidents` already provides a useful base for safety/emergency event state flow.
- Static module pages must not fabricate operational data before a real persisted source exists.
- The user wants all of these operation modules planned and completed, not only the currently selected sidebar item.
## Task Map
### Child 1: 新增健康照护后台管理页
- Path: `.trellis/tasks/07-02-care-service-workspace`
- Note: The slug is historical, but the task title and artifacts now describe the health data management page.
- Scope: Add backend management page for health profiles, vital signs, chronic conditions, and abnormal reviews.
- Dependency: None. This can be implemented first because it creates the health data foundation.
### Child 2: 护理服务执行工作台
- Path: `.trellis/tasks/07-02-care-execution-workspace`
- Scope: Add care task/service execution records, status flow, completion notes, and seeded examples.
- Dependency: Can use existing elder/admission data. Does not depend on health admin unless a care item links to abnormal health reviews later.
### Child 3: 安全应急事件工作台
- Path: `.trellis/tasks/07-02-emergency-incident-workspace`
- Scope: Replace the placeholder with an emergency event workspace using and extending persisted incident data.
- Dependency: Can build on `systemIncidents` and existing incident status actions.
### Child 4: 老人床位联动优化
- Path: `.trellis/tasks/07-02-elder-bed-context-optimization`
- Scope: Improve elder and bed screens so operators can see linked health, care, admission, and incident context where available.
- Dependency: Should run after health/care/emergency have at least basic persisted data.
### Child 5: 运营看板整合优化
- Path: `.trellis/tasks/07-02-operations-dashboard-integration`
- Scope: Integrate health, care, emergency, elder, bed, and admission summaries into the dashboard.
- Dependency: Should run after the relevant child data surfaces exist.
## Delivery Order
1. Health data management page.
2. Care execution workspace.
3. Emergency event workspace.
4. Elder/bed cross-module context improvements.
5. Dashboard integration.
This order creates data foundations first, then links records to existing operator workflows, then summarizes everything in the dashboard.
## Cross-Module Requirements
- All new operational records must be Drizzle/PostgreSQL backed.
- New data must be scoped by active organization.
- New data tied to elders must reference real elders in the same organization.
- Default workspace seed data must create real persisted rows, not UI-only demo objects.
- All API responses must follow `{ success, reason, ... }`.
- Permission checks must happen on the server.
- Mutations must record audit logs.
- Navigation labels should remain clear:
- `健康照护` remains the operational health entry.
- backend health management can live under `管理系统` as `健康数据管理`.
- `护理服务` remains daily service execution.
- `安全应急` remains event response and closure.
- The app must not show hero/marketing-style module introductions for operational pages.
## Acceptance Criteria
- [ ] Each child task has its own PRD and implementation scope.
- [ ] Health, care, and emergency modules no longer rely on fabricated UI-only data.
- [ ] Existing elder and bed workflows remain functional after new modules are added.
- [ ] Default workspace seed data covers elders, beds, health, care, and incidents once all child tasks are complete.
- [ ] Dashboard metrics include the new persisted health/care/emergency data after integration.
- [ ] `pnpm lint` passes for each implementation child.
- [ ] `pnpm type-check` passes for each implementation child.
- [ ] `pnpm build` passes before the parent task is considered complete.
## Out Of Scope
- Doing all child tasks in a single implementation pass.
- Replacing Route Handlers with oRPC.
- Replacing current auth/session implementation.
- Billing, family app notifications, device telemetry integrations, and AI recommendations unless created as separate future tasks.
## Open Questions
- None blocking the plan. Implementation should start with Child 1 unless the user explicitly changes priority.

View File

@@ -0,0 +1,32 @@
{
"id": "operations-module-roadmap",
"name": "operations-module-roadmap",
"title": "运营模块完善总计划",
"description": "",
"status": "planning",
"dev_type": null,
"scope": null,
"package": null,
"priority": "P2",
"creator": "TalexDreamSoul",
"assignee": "TalexDreamSoul",
"createdAt": "2026-07-02",
"completedAt": null,
"branch": null,
"base_branch": "main",
"worktree_path": null,
"commit": null,
"pr_url": null,
"subtasks": [],
"children": [
"07-02-care-service-workspace",
"07-02-emergency-incident-workspace",
"07-02-elder-bed-context-optimization",
"07-02-care-execution-workspace",
"07-02-operations-dashboard-integration"
],
"parent": null,
"relatedFiles": [],
"notes": "",
"meta": {}
}