feat: add health data management workspace
This commit is contained in:
@@ -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)));
|
||||
```
|
||||
|
||||
@@ -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."}
|
||||
@@ -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."}
|
||||
76
.trellis/tasks/07-02-care-execution-workspace/prd.md
Normal file
76
.trellis/tasks/07-02-care-execution-workspace/prd.md
Normal 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.
|
||||
26
.trellis/tasks/07-02-care-execution-workspace/task.json
Normal file
26
.trellis/tasks/07-02-care-execution-workspace/task.json
Normal 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": {}
|
||||
}
|
||||
1
.trellis/tasks/07-02-care-service-workspace/check.jsonl
Normal file
1
.trellis/tasks/07-02-care-service-workspace/check.jsonl
Normal 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."}
|
||||
191
.trellis/tasks/07-02-care-service-workspace/design.md
Normal file
191
.trellis/tasks/07-02-care-service-workspace/design.md
Normal 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`
|
||||
@@ -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."}
|
||||
74
.trellis/tasks/07-02-care-service-workspace/implement.md
Normal file
74
.trellis/tasks/07-02-care-service-workspace/implement.md
Normal 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.
|
||||
117
.trellis/tasks/07-02-care-service-workspace/prd.md
Normal file
117
.trellis/tasks/07-02-care-service-workspace/prd.md
Normal 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.
|
||||
26
.trellis/tasks/07-02-care-service-workspace/task.json
Normal file
26
.trellis/tasks/07-02-care-service-workspace/task.json
Normal 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": {}
|
||||
}
|
||||
@@ -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."}
|
||||
@@ -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."}
|
||||
55
.trellis/tasks/07-02-elder-bed-context-optimization/prd.md
Normal file
55
.trellis/tasks/07-02-elder-bed-context-optimization/prd.md
Normal 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.
|
||||
@@ -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": {}
|
||||
}
|
||||
@@ -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."}
|
||||
@@ -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."}
|
||||
65
.trellis/tasks/07-02-emergency-incident-workspace/prd.md
Normal file
65
.trellis/tasks/07-02-emergency-incident-workspace/prd.md
Normal 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.
|
||||
26
.trellis/tasks/07-02-emergency-incident-workspace/task.json
Normal file
26
.trellis/tasks/07-02-emergency-incident-workspace/task.json
Normal 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": {}
|
||||
}
|
||||
@@ -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."}
|
||||
@@ -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."}
|
||||
57
.trellis/tasks/07-02-operations-dashboard-integration/prd.md
Normal file
57
.trellis/tasks/07-02-operations-dashboard-integration/prd.md
Normal 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.
|
||||
@@ -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": {}
|
||||
}
|
||||
@@ -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."}
|
||||
47
.trellis/tasks/07-02-operations-module-roadmap/design.md
Normal file
47
.trellis/tasks/07-02-operations-module-roadmap/design.md
Normal 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.
|
||||
@@ -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."}
|
||||
42
.trellis/tasks/07-02-operations-module-roadmap/implement.md
Normal file
42
.trellis/tasks/07-02-operations-module-roadmap/implement.md
Normal 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.
|
||||
106
.trellis/tasks/07-02-operations-module-roadmap/prd.md
Normal file
106
.trellis/tasks/07-02-operations-module-roadmap/prd.md
Normal 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.
|
||||
32
.trellis/tasks/07-02-operations-module-roadmap/task.json
Normal file
32
.trellis/tasks/07-02-operations-module-roadmap/task.json
Normal 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": {}
|
||||
}
|
||||
Reference in New Issue
Block a user