# PHIS Health Record Upsert Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Convert one PHIS health-record task into a validated CHIS JKDA write request, then provide a reusable query-first upsert application service. **Architecture:** `source` owns the PHIS JSON contract and strips credentials, `mapping` performs pure PHIS-to-CHIS conversion, `contract` owns the JKDA write shape, and `pipeline` orchestrates query/create/update through injected interfaces. HTTP exposure and persistent retry/report stores remain in T-204 and Phase 3. **Tech Stack:** Go 1.24 standard library, existing `contract`/`mapping`/`osi` packages, table-driven tests. --- ### Task 1: T-212 PHIS DTO and source identity **Files:** - Create: `source/health_record.go` - Create: `source/health_record_test.go` - Create: `source/testdata/health_record.json` - Create: `docs/decisions/001-phis-health-record-source-key.md` - [ ] Write failing tests that decode the PHIS envelope, retain `archId/businessId/empiId/phrId`, expose only doctor ID/name, and reject a missing `archId`. - [ ] Run `go test ./source -count=1` and verify failure because the package/API does not exist. - [ ] Implement the DTO and `DecodeHealthRecordTask`; use `archId` as the health-record source key and retain `businessId` only for tracing. - [ ] Run `go test ./source -count=1` and verify pass. - [ ] Record the source-key evidence and compatibility decision in the ADR. ### Task 2: T-212 complete mapping and write contract **Files:** - Modify: `contract/jkda.go` - Modify: `contract/jkda_test.go` - Modify: `mapping/health_record.go` - Modify: `mapping/health_record_test.go` - Modify: `mapping/health_record_baseline_test.go` - Modify: `mapping/checkid.go` - [ ] Write failing contract/mapping tests for all PHIS direct fields, `adressNumber` to `addressNumber`, stable checkId across `updateTime`, past-history nodes, four history arrays, conditional `familyMiddle`, required/date/length/code validation, and per-record `operateUser`. - [ ] Run targeted `go test ./contract ./mapping -count=1` and verify expected failures. - [ ] Expand only fields supplied by PHIS and implement pure conversion helpers; normalize multi-select separators and preserve explicit no-history codes. - [ ] Run targeted tests until green, then run `go test ./contract ./mapping -count=1`. ### Task 3: T-212 per-record operation context **Files:** - Modify: `osi/jkda.go` - Modify: `osi/jkda_test.go` - Modify: `cache/dictionary.go` - Modify: `cache/dictionary_test.go` - [ ] Write failing tests proving a mapped doctor ID survives as `manageInfo.operateUser`, while `DSFMC/operateUnit` still come from trusted client config; add doctor-ID membership validation to dictionary snapshots. - [ ] Run targeted tests and verify expected failures. - [ ] Implement minimal request-context merge and dictionary membership lookup. - [ ] Run `go test ./cache ./osi ./mapping -count=1` and verify pass. ### Task 4: Complete and commit T-212 **Files:** - Modify: `tasks.md` - Modify: `progress.md` - Modify: `docs/current-state.md` - Modify: `docs/04-字段与接口映射.md` - [ ] Update mapping documentation, mark T-212 DONE, append RED/GREEN/full validation evidence, and set T-213 as next. - [ ] Run `gofmt`, `go test ./...`, `go build ./...`, and `git diff --check`. - [ ] Commit T-212 as one logical commit. ### Task 5: T-213 query-first upsert service **Files:** - Create: `pipeline/health_record_upsert.go` - Create: `pipeline/health_record_upsert_test.go` - [ ] Write failing tests for zero-result create, one-result update, multiple/cross-unit/inactive manual review, query failure without create fallback, create/update failure classification, idempotent skip, and PHIS/report events. - [ ] Run `go test ./pipeline -count=1` and verify expected failure because the service does not exist. - [ ] Implement `HealthRecordUpsertService` with injected OSI, converter, idempotency, report, and PHIS status interfaces; keep persistence and retry scheduling out of scope. - [ ] Run `go test ./pipeline -count=1` and then `go test ./...`. ### Task 6: Complete and commit T-213 **Files:** - Modify: `tasks.md` - Modify: `progress.md` - Modify: `docs/current-state.md` - Modify: `docs/03-目标架构设计.md` - [ ] Document the reusable application-service boundary and mark T-213 DONE; leave T-204 TODO and T-215 BLOCKED. - [ ] Run `gofmt`, `go test ./...`, `go build ./...`, and `git diff --check`. - [ ] Commit T-213 as a second logical commit.