# ai-data-foundation **Repository Path**: agingai-open/ai-data-foundation ## Basic Information - **Project Name**: ai-data-foundation - **Description**: 数据底座 — 量表/评估/护理历史数据统一存储(PostgreSQL + pgvector),含确定性合成演示数据生成器 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-26 - **Last Updated**: 2026-08-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AI 数据底座 (ai-data-foundation) > AgingAI 平台的个人历史数据统一存储层 — PostgreSQL + pgvector。 ## 核心功能 - **统一存储**:量表、评估结果(含 AI 推理过程)、护理数据、**病史/用药数据**、**AI 护理计划**五类个人历史数据 - **写入 API(同步)**:`POST /api/v1/records`(批量导入用,写入成功即落库,支持断点续传) - **写入 API(异步)**:`POST /api/v1/records/async`(实时写入用,受理即返回 job_id,后台落库;`submit_job` 内独立 commit,确保后台 execute 跨 session 可见——T-H 修复)+ `GET /api/v1/jobs/{job_id}` 状态查询 - **查询 API**:`GET /api/v1/records`(趋势 / 回溯) - **AI 护理计划(T-AA)**:`GET /api/v1/care-plan-ai`(护士端待办列表,按状态/指派过滤)+ `PATCH /api/v1/care-plan-ai/{plan_id}`(assign/accept/complete/dismiss 状态机流转) - **案例检索**:`POST /api/v1/cases/search`(按风险标签 + 人口学特征匹配相似历史案例) - **批量导出**:`GET /api/v1/export`(供 ai-training 取训练数据) ## 快速开始 ```bash python3.11 -m venv venv && source venv/bin/activate pip install -r requirements.txt cp .env.example .env docker compose up -d # 启动 PostgreSQL (pgvector) uvicorn app.main:app --port 8005 --reload ``` 健康检查:`GET http://localhost:8005/health` ## 技术栈 Python 3.11 · FastAPI · PostgreSQL 16 + pgvector · SQLAlchemy 2.0 async · asyncpg ## 数据模型 | 表 | 内容 | |----|------| | `scale_records` | 量表数据(MMSE / MoCA / GDS / SARC-F 等) | | `evaluation_records` | AI 评估结果 + 推理过程(支持审计/回溯/校准) | | `nursing_records` | 护理措施 / 计划(外部养老系统导入) | | `medical_history_records` | 病史/用药数据(慢病诊断 / 既往病史 / 用药记录 / 过敏史) | | `care_plan_ai_records` | **AI 护理计划**(评估→护理计划自动链,T-AA):状态机四态 + 指派护士 + 评估溯源(session_id / based_on_evaluation_ids),与 nursing 历史导入物理分表 | | `async_write_jobs` | 异步写入任务(受理→后台落库,payload 存档供重放/重启恢复) | 明细字段统一用 JSONB 存储(灵活且可索引查询)。 ## API 接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/health` | 健康检查 | | POST | `/api/v1/records` | 写入记录(同步,支持 scale/evaluation/nursing/medical_history/care_plan_ai) | | POST | `/api/v1/records/async` | 写入记录(异步,返回 job_id) | | GET | `/api/v1/jobs/{job_id}` | 查询异步写入状态 | | GET | `/api/v1/records` | 查询记录列表(按 elderly_id / record_type 过滤) | | GET | `/api/v1/export` | 批量导出(按 record_type) | | POST | `/api/v1/cases/search` | **案例检索** — 按风险标签+人口学特征匹配历史案例 | | GET | `/api/v1/care-plan-ai` | **AI 护理计划待办列表** — 按状态/指派护士/老人过滤分页(T-AA) | | PATCH | `/api/v1/care-plan-ai/{plan_id}` | **AI 护理计划状态流转** — assign/accept/complete/dismiss(状态机校验,非法迁移 409) | ### AI 护理计划 API(care_plan_ai,T-AA) `record_type=care_plan_ai` 由 ai-recommendation 在评估会话完成后生成写入(ADR-002 §九),落 `care_plan_ai_records` 独立表(与 nursing 历史导入物理分表),带任务语义:四态状态机 + 指派护士(portal 用户 id,ADR-005 只存 id 不存姓名)。 **写入**:与其它记录类型共用 `POST /api/v1/records`(同步)/ `POST /api/v1/records/async`(异步,推荐 recommendation 侧使用)。payload 校验:`recommendations` 必须为非空列表;`plan_id`(幂等键,recommendation 生成)、`session_id`(兜底 `trigger.session_id`)、`based_on_evaluation_ids` 提取为结构化列;落库初始态恒为 `pending`。 **待办列表**:`GET /api/v1/care-plan-ai?status=pending&assigned_nurse_id=&elderly_id=&page=1&page_size=20`(created_at 倒序分页,供护士端跨老人待办查询)。 **状态流转**:`PATCH /api/v1/care-plan-ai/{plan_id}`,body `{"action": "assign|accept|complete|dismiss", "assigned_nurse_id": "...", "note": "..."}`: | action | 合法当前态 | 副作用 | |--------|-----------|--------| | assign | pending | 写 assigned_nurse_id / assigned_at(允许改派;须带 assigned_nurse_id,否则 422) | | accept | pending 且已指派 | status=accepted,写 accepted_at | | complete | accepted | status=done,写 completed_at | | dismiss | pending / accepted | status=dismissed(留痕不物理删),note 追加到 payload.dismiss_note | 非法迁移与并发冲突(单行乐观锁:UPDATE WHERE status=期望值)返回 **409**;计划不存在 404。 ```mermaid stateDiagram-v2 [*] --> pending : 生成落库 pending --> pending : assign(指派/改派) pending --> accepted : accept(须已指派) accepted --> done : complete pending --> dismissed : dismiss accepted --> dismissed : dismiss ``` ### 案例检索 API `POST /api/v1/cases/search` 接受风险标签和可选的人口学特征,从历史护理数据中检索相似案例。 **请求示例:** ```json { "risk_labels": ["跌倒(康复评估确认)", "营养不良"], "elderly_profile": {"age": 78, "gender": "男", "care_level": 2}, "top_k": 5 } ``` **响应示例:** ```json { "code": 0, "message": "success", "data": { "cases": [ { "elderly_id": "12345", "similarity_score": 0.85, "matched_risks": ["跌倒(康复评估确认)"], "demographic_match": {"age": 75, "gender": "男", "care_level": 2}, "nursing_measures": [{"type": "护理", "label": "防跌倒措施", "source_type": "评估"}], "risk_detail": {"risk_label": "跌倒(康复评估确认)", "eval_result": "...", "opinion": "..."} } ], "total_matched": 23 } } ``` **相似度计算**:年龄 ±10 岁内匹配(权重 0.3)+ 性别精确匹配(0.3)+ 护理等级精确匹配(0.4)。 **查询逻辑**: 1. 在 `nursing_records` 表中按 `measures->'risk_label'` JSONB 字段匹配风险标签 2. 去重获得候选老人,按人口学计算相似度 3. 聚合每位老人的护理措施和风险详情 4. 按相似度降序返回 top-K ## 测试数据填充(seed) `scripts/seed_test_data.py` 生成覆盖 nurse-web / admin-web 主要页面的演示数据,与设计稿对齐: - **8 位老人**:`E001-E008`,每位含档案(`E001` API 兼容 ID + `measures.档案编号` `ELD-2026-XXXX` 展示用、疾病标签、认知/情绪/健康基线)、护理计划、评估报告 - **护理记录/位**:7 条风险点(高2/中3/低2,含依据+触发措施)、4 个基础服务包、28 条照顾措施(医疗/康复/护理/营养/社工 5 大类) - **评估/位**:3 次评估(2026.05/06/07),component_scores 8 维(cognitive/memory/fluency/emotion/affect/health/physical/frailty),趋势有语义(下降/稳定/改善) - **病史/位**:3 种慢性病(诊断日期/严重程度/治疗方案)、4 种用药(品牌/剂量/频率/依从性%)、7 条既往事件、过敏史 ```bash cd ai-data-foundation && source venv/bin/activate python scripts/seed_test_data.py # 幂等填充(按 seed_key 跳过已 seed 的老人) python scripts/seed_test_data.py --reset # 清空旧 seed 数据(含 E001-E008 残留评估)后重新填充 ``` > 幂等性基于 nursing `measures.seed_key` 判断;`--reset` 直连 PG 仅删除 `source='seed'` 记录及 `E001-E008` 的残留评估,不影响 `care_plan_import` / `collection` 真实导入数据。 ## 合成演示数据生成(generate_demo_data) `scripts/generate_demo_data.py` 是**确定性合成数据生成器**(脱敏安全设计):100 老人 / 万条级评估与护理记录,三档画像 40/40/20(healthy/moderate/crisis),姓名由百家姓加权池 + 出生年代用字池合成并做黑名单碰撞校验,标识符全部为安全占位格式(`DEMO-E0001` 内部 ID、`160` 虚拟号段手机),**不包含任何真实人员信息**。同 seed 同参数输出 byte-identical。 **生成 → 导入 → 验证** 三步: ```bash cd ai-data-foundation && source venv/bin/activate # 1) 生成(--blacklist 传入私有姓名黑名单文件,每行一个;省略时碰撞校验机制仍生效) python scripts/generate_demo_data.py \ --seed 42 --elderly-count 100 --records-target 10000 \ --format sql --out demo_data.sql \ --fixtures <父仓>/tests/integration/data \ --blacklist name_blacklist.txt # 2) 导入(SQL 直连 PG;或 --format api 产 JSONL 走 POST /api/v1/records) docker compose up -d psql "$DATABASE_URL" -f demo_data.sql # 幂等:BEGIN + DELETE source='demo' + INSERT # 3) 验证 pytest tests/test_generate_demo_data.py -v # 确定性/分布/黑名单/标识符安全 psql "$DATABASE_URL" -c "SELECT count(*) FROM evaluation_records WHERE source='demo';" ``` 要点: - **记录覆盖**:基础档案(`elderly_profile`)、六维评估(frailty/nutrition/cognitive/mobility/chronic/medication + comprehensive + 语音元数据)、护理历史(风险/基础包/措施)、病史用药(慢病/用药/既往/过敏)、量表(MMSE/MNA-SF/GDS/SARC-F),schema 对齐 `app/models/db.py` 四张核心表 - **`--fixtures