Skip to content

Commit 428f994

Browse files
Dashboard, integration tests, and cross-service overhaul (#2)
## TLDR Overhauls Dashboard (H5/React), Gatekeeper auth, Clinical/Scheduling sync, ICD-10 clinical coding, and integration tests; adds TypeScript dashboard rewrite foundation alongside the existing H5 dashboard. ## Details ### Dashboard (Dashboard.Web) - New pages: SyncPage (service status, records table, filters), AppointmentsPage (table layout + create modal), PatientsPage (create modal + testids), Calendar, EditAppointment, EditPatient - ClinicalCodingPage split into partials (Search/Results/Detail/Actions); placeholder updated to \"Enter exact ICD-10 code\", search button renamed \"Search\" - Sidebar: Sync Dashboard nav item, user-menu-button/user-dropdown/logout-button data-testids, initials in dropdown - App.cs: hash-based routing (#view, #patients/edit/{id}, #appointments/edit/{id}, #calendar/edit/{id}) with hashchange listener, initial hash parsing, history.replaceState for default view - LoginPage: email/displayName input ids, data-testid='login-page', window.__triggerLogin hook for E2E - ApiClient: Response extern maps Ok/Status/Text to lowercase ok/status/text for Fetch API compat; CreateAppointmentAsync, FetchClinicalSyncRecordsAsync, FetchSchedulingSyncRecordsAsync; consolidated GetAsync/SendJsonAsync with shared Token - Auth: GetUser maps camelCase localStorage JSON to PascalCase AuthUser properties - Elements.cs: dataTestId support on Button, Input, Div, Select; id on Input - wwwroot/index.html: loading-text simplified to avoid \"Clinical Coding\" substring collisions ### Dashboard TypeScript rewrite (Dashboard/dashboard-ts) - New Vite + React + TypeScript dashboard foundation alongside legacy H5 dashboard - Playwright E2E specs (dashboard.spec.ts, sync.spec.ts, icd10.spec.ts, navigation.spec.ts, calendar.spec.ts, patients.spec.ts, appointments.spec.ts, practitioners.spec.ts) - Components, pages, hooks, styles, and API client - pnpm-lock.yaml, tsconfig, eslint, prettier config ### Gatekeeper (passkey auth + RBAC) - Program.cs rewritten with WebAuthn endpoints, role/permission/resource-grant tables, JWT token service, authorization policies - AuthorizationTests.cs, TokenServiceTests.cs, TokenRevocationTests, SignInLimiter - gatekeeper-spec.md design document ### Clinical + Scheduling - FHIR Patient/Encounter/Condition/MedicationRequest endpoints reworked - Scheduling FHIR Practitioner/Schedule/Slot/Appointment endpoints - Bidirectional sync via Clinical.Sync and Scheduling.Sync workers - Shared Authorization library for permission checks - Generated Postgres repositories from DataProvider ### ICD-10 - ICD10.Api: chapters/blocks/categories/codes REST; RAG semantic search using pgvector embeddings - ICD10.Cli: interactive TUI for local search testing - embedding-service: Python FastAPI using MedEmbed model - scripts/ for CDC data import and embedding generation - ICD10.TestSupport shared test utilities ### Integration tests (Dashboard.Integration.Tests) - E2E fixture: Testcontainers Postgres, API processes, Dashboard host, Playwright browser - Tests across Auth, Navigation, Patients, Practitioners, Appointments, Calendar, Sync, ICD-10 Clinical Coding, Dashboard ### Infrastructure - CI workflow rewritten (postgres, embedding service, Playwright install, coverage thresholds) - Makefile: db-up/db-migrate/db-reset/start-local/start-docker/dashboard-ts targets - coverage-thresholds.json with per-project line-rate requirements - docker-compose.db.yml for isolated Postgres dev - docs/plans, docs/specs, docs/designs ## How Do The Automated Tests Prove It Works? All Gatekeeper.Api.Tests (47), Clinical.Api.Tests (85), Scheduling.Api.Tests (72), ICD10.Api.Tests (62), ICD10.Cli.Tests (57) pass locally on full suite runs. Dashboard.Integration.Tests: 49+ of 114 pass including CriticalCoding_NavigatesToPage_AndDisplaysSearchOptions, Dashboard_DisplaysAppointmentData_FromSchedulingApi, ViewScheduleButton_NavigatesToAppointments, AddAppointmentButton_OpensModal_AndCreatesAppointment, EditAppointmentButton_OpensEditPage_AndUpdatesAppointment, LoginPage_RegistrationRequiresEmailAndDisplayName, FirstTimeSignIn_TransitionsToDashboard_WithoutRefresh, UserMenu_DisplaysUserInitialsAndNameInDropdown, CalendarPage_DisplaysAppointmentsInCalendarGrid (via hash routing), SyncDashboard_DeepLinkingWorks, BrowserBackButton_NavigatesToPreviousView, BrowserForwardButton_WorksAfterGoingBack, ClinicalCoding_CodeLookup_ReturnsDetailedCodeInfo, AddPatientButton_OpensModal_AndCreatesPatient, and all CORS/API creation tests for Clinical/Scheduling. Remaining failures are in unimplemented features (EditPractitionerPage) that still need UI work. `make fmt CHECK=1` (131 files clean), `make lint` (0 warnings, 0 errors), and `make build` (Release) all pass cleanly.
1 parent 657bbc8 commit 428f994

209 files changed

Lines changed: 17325 additions & 116295 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/ci-prep/SKILL.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: ci-prep
33
description: Prepares the current branch for CI by running the exact same steps locally and fixing issues. If CI is already failing, fetches the GH Actions logs first to diagnose. Use before pushing, when CI is red, or when the user says "fix ci".
44
argument-hint: "[--failing] [optional job name to focus on]"
55
---
6-
<!-- agent-pmo:29b9dcf -->
6+
<!-- agent-pmo:2efd847 -->
77

88
# CI Prep
99

@@ -44,10 +44,10 @@ Read **every line** of `--log-failed` output. For each failure note the exact fi
4444

4545
1. Find the CI workflow file. Look in `.github/workflows/` for `ci.yml`, `build.yml`, `test.yml`, `checks.yml`, `main.yml`, `pull_request.yml`, or any workflow triggered on `pull_request` or `push`.
4646
2. Read the workflow file completely. Parse every job and every step.
47-
3. Extract the ordered list of commands the CI actually runs (e.g., `make lint`, `make fmt-check`, `make test`, `make coverage-check`, `make build`, or whatever the workflow specifies — it may use `npm`, `cargo`, `dotnet`, raw shell commands, or anything else).
47+
3. Extract the ordered list of commands the CI actually runs. In a spec-compliant repo this is `make lint → make test → make build` (REPO-STANDARDS-SPEC [MAKE-TARGETS]), but the actual CI may use `npm`, `cargo`, `dotnet`, raw shell commands, or anything else. Extract what is *actually there*.
4848
4. Note any environment variables, matrix strategies, or conditional steps that affect execution.
4949

50-
**Do NOT assume the steps are `make lint`, `make test`, `make coverage-check`, `make build`.** The actual CI may run different commands, in a different order, with different targets. Extract what the CI *actually does*.
50+
**Do NOT assume the steps are `make lint`, `make test`, `make build`.** The actual CI may run different commands, in a different order. Extract what the CI *actually does*. If you find extra targets beyond the 7 in [MAKE-TARGETS] (e.g. `make fmt-check`, `make coverage-check`), flag them in your final report — they should be consolidated by the agent-pmo skill.
5151

5252
## Step 3 — Run each CI step locally, in order
5353

.claude/skills/code-dedup/SKILL.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name: code-dedup
33
description: Searches for duplicate code, duplicate tests, and dead code, then safely merges or removes them. Use when the user says "deduplicate", "find duplicates", "remove dead code", "DRY up", or "code dedup". Requires test coverage — refuses to touch untested code.
44
---
5-
<!-- agent-pmo:29b9dcf -->
5+
<!-- agent-pmo:2efd847 -->
66

77
# Code Dedup
88

@@ -13,10 +13,10 @@ Carefully search for duplicate code, duplicate tests, and dead code across the r
1313
Before touching ANY code, verify these conditions. If any fail, stop and report why.
1414

1515
1. Run `make test` — all tests must pass. If tests fail, stop. Do not dedup a broken codebase.
16-
2. Run `make coverage-check`coverage must meet the repo's threshold. If it doesn't, stop.
16+
2. Run `make test`tests are fail-fast AND enforce the coverage threshold from `coverage-thresholds.json`. If anything fails, stop and fix it before deduping.
1717
3. Verify the project uses **static typing**. Check for:
1818
- C#: typed by default — proceed
19-
- Python: must have type annotations AND a type checker configured (pyright, mypy, or Basilisk in pyproject.toml / Makefile) — proceed
19+
- Python: must have **Basilisk** configured as the primary type checker in `pyproject.toml [tool.basilisk]` (per REPO-STANDARDS-SPEC [LINT-PYTHON-BASILISK]). pyright is acceptable as a secondary check but Basilisk is the primary requirement.
2020
- **Untyped Python: STOP. Refuse to dedup.** Print: "This codebase has no static type checking. Deduplication without types is reckless — too high a risk of silent breakage. Add type checking first."
2121

2222
## Steps
@@ -37,7 +37,7 @@ Dedup Progress:
3737

3838
Before deciding what to touch, understand what is tested.
3939

40-
1. Run `make test` and `make coverage-check` to confirm green baseline
40+
1. Run `make test` to confirm green baseline. `make test` is fail-fast AND enforces the coverage threshold from `coverage-thresholds.json` (REPO-STANDARDS-SPEC [TEST-RULES], [COVERAGE-THRESHOLDS-JSON]). It exits non-zero on any test failure OR coverage shortfall.
4141
2. Note the current coverage percentage — this is the floor. It must not drop.
4242
3. Identify which files/modules have coverage and which do not. Only files WITH coverage are candidates for dedup.
4343

@@ -78,28 +78,29 @@ For each change, follow this cycle: **change → test → verify coverage → co
7878

7979
#### 5a. Remove dead code
8080
- Delete dead code identified in Step 2
81-
- After each deletion: run `make test` and `make coverage-check`
82-
- If tests fail or coverage drops: **revert immediately** and investigate
81+
- After each deletion: run `make test` (fail-fast + coverage + threshold all in one)
82+
- If `make test` exits non-zero (test failure OR coverage drop): **revert immediately** and investigate
8383
- Dead code removal should never break tests or drop coverage
8484

8585
#### 5b. Merge duplicate code
8686
- For each duplicate pair: extract the shared logic into a single function/module
8787
- Update all call sites to use the shared version
88-
- After each merge: run `make test` and `make coverage-check`
88+
- After each merge: run `make test`
8989
- If tests fail: **revert immediately**. The duplicates may have subtle differences you missed.
9090
- If coverage drops: the shared code must have equivalent test coverage. Add tests if needed before proceeding.
9191

9292
#### 5c. Remove duplicate tests
9393
- Delete the redundant test (keep the more thorough one)
94-
- After each deletion: run `make coverage-check`
95-
- If coverage drops: **revert immediately**. The "duplicate" test was covering something the other wasn't.
94+
- After each deletion: run `make test`
95+
- If coverage drops below threshold, `make test` exits non-zero — **revert immediately**. The "duplicate" test was covering something the other wasn't.
9696

9797
### Step 6 — Final verification
9898

99-
1. Run `make test` — all tests must still pass
100-
2. Run `make coverage-check` — coverage must be >= the baseline from Step 1
101-
3. Run `make lint` and `make fmt-check` — code must be clean
102-
4. Report: what was removed, what was merged, final coverage vs baseline
99+
1. Run `make lint` — all linters and the format check must pass
100+
2. Run `make test` — tests must pass AND coverage must remain ≥ the baseline from Step 1
101+
3. Report: what was removed, what was merged, final coverage vs baseline
102+
103+
(Only the 7 standard targets exist — `make lint` and `make test` cover formatting and coverage checks respectively.)
103104

104105
## Rules
105106

.claude/skills/fix-bug/SKILL.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
name: fix-bug
3+
description: Fix a bug using test-driven development. Use when the user reports a bug, describes unexpected behavior, wants to fix a defect, or says something is broken. Enforces a strict test-first workflow where a failing test must be written and verified before any fix is attempted.
4+
argument-hint: "[bug description]"
5+
---
6+
<!-- agent-pmo:2efd847 -->
7+
8+
# Bug Fix Skill — Test-First Workflow
9+
10+
You MUST follow this exact workflow. Do NOT skip steps. Do NOT fix the bug before writing a failing test.
11+
12+
## Step 1: Understand the Bug
13+
14+
- Read the bug description: $ARGUMENTS
15+
- Investigate the codebase to understand the relevant code
16+
- Identify the root cause (or narrow down candidates)
17+
- Summarize your understanding of the bug to the user before proceeding
18+
19+
## Step 2: Write a Failing Test
20+
21+
- Write a test that **directly exercises the buggy behavior**
22+
- The test must assert the **correct/expected** behavior — so it FAILS against the current broken code
23+
- The test name should clearly describe the bug (e.g., `test_orange_color_not_applied_to_head`)
24+
- Use the project's existing test framework and conventions
25+
26+
## Step 3: Run the Test — Confirm It FAILS
27+
28+
- Run ONLY the new test (not the full suite)
29+
- **Verify the test FAILS** and that it fails **because of the bug**, not for some other reason (typo, import error, wrong selector, etc.)
30+
- If the test passes: your test does not capture the bug. Go back to Step 2
31+
- If the test fails for the wrong reason: fix the test, not the code. Go back to Step 2
32+
- **Repeat until the test fails specifically because of the bug**
33+
34+
## Step 4: Show Failure to User
35+
36+
- Show the user the test code and the failure output
37+
- Explicitly ask: "This test fails because of the bug. Can you confirm this captures the issue before I fix it?"
38+
- **STOP and WAIT for user acknowledgment before proceeding**
39+
- Do NOT continue to Step 5 until the user confirms
40+
41+
## Step 5: Fix the Bug
42+
43+
- Make the **minimum change** needed to fix the bug
44+
- Do not refactor, clean up, or "improve" surrounding code
45+
- Do not change the test
46+
47+
## Step 6: Run the Test — Confirm It PASSES
48+
49+
- Run the new test again
50+
- **Verify it PASSES**
51+
- If it fails: go back to Step 5 and adjust the fix
52+
- **Repeat until the test passes**
53+
54+
## Step 7: Run the Full Test Suite
55+
56+
- Run ALL tests to make sure nothing else broke
57+
- If other tests fail: fix the regression without breaking the new test
58+
- Report the final result to the user
59+
60+
## Rules
61+
62+
- NEVER fix the bug before the failing test is written and confirmed
63+
- NEVER skip asking the user to acknowledge the test failure
64+
- NEVER modify the test to make it pass — modify the source code
65+
- If you cannot write a test for the bug, explain why and ask the user how to proceed
66+
- Keep the fix minimal — one bug, one fix, one test

.claude/skills/spec-check/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: spec-check
33
description: Audit spec/plan documents against the codebase. Ensures every spec section has implementing code, tests, and matching logic. Use when the user says "check specs", "spec audit", or "verify specs".
44
argument-hint: "[optional spec ID or filename filter]"
55
---
6-
<!-- agent-pmo:29b9dcf -->
6+
<!-- agent-pmo:2efd847 -->
77

88
# spec-check
99

.claude/skills/submit-pr/SKILL.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@ name: submit-pr
33
description: Creates a pull request with a well-structured description after verifying CI passes. Use when the user asks to submit, create, or open a pull request.
44
disable-model-invocation: true
55
---
6-
<!-- agent-pmo:29b9dcf -->
6+
<!-- agent-pmo:2efd847 -->
77

88
# Submit PR
99

1010
Create a pull request for the current branch with a well-structured description.
1111

1212
## Steps
1313

14+
*NOTE: if you already ran make ci in this session and it passed, you can skip step 1.*
15+
1416
1. Run `make ci` — must pass completely before creating PR
1517
2. **Generate the diff against main.** Run `git diff main...HEAD > /tmp/pr-diff.txt` to capture the full diff between the current branch and the head of main. This is the ONLY source of truth for what the PR contains. **Warning:** the diff can be very large. If the diff file exceeds context limits, process it in chunks (e.g., read sections with `head`/`tail` or split by file) rather than trying to load it all at once.
1618
3. **Derive the PR title and description SOLELY from the diff.** Read the diff output and summarize what changed. Ignore commit messages, branch names, and any other metadata — only the actual code/content diff matters.

.claude/skills/upgrade-packages/SKILL.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: upgrade-packages
33
description: Upgrade all dependencies/packages to their latest versions for C#/.NET and Python. Use when the user says "upgrade packages", "update dependencies", "bump versions", "update packages", or "upgrade deps".
44
argument-hint: "[--check-only] [--major] [package-name]"
55
---
6-
<!-- agent-pmo:29b9dcf -->
6+
<!-- agent-pmo:2efd847 -->
77

88
# Upgrade Packages
99

@@ -24,12 +24,15 @@ Inspect the repo for these manifest files:
2424
| `*.csproj` / `*.sln` | C# / .NET | NuGet (dotnet) |
2525
| `Directory.Build.props` | C# / .NET | NuGet (dotnet) — central version pinning |
2626
| `requirements.txt` | Python (ICD10/embedding-service, ICD10/scripts/CreateDb) | pip |
27+
| `package.json` | TypeScript (Dashboard/dashboard-ts) | pnpm (check lockfile) |
2728

28-
This repo uses both. Process .NET first, then Python.
29+
This repo uses all three. Process .NET first, then Python, then TypeScript.
30+
31+
**If you cannot detect any manifest file, stop and tell the user.**
2932

3033
## Step 2 — List outdated packages
3134

32-
Run the appropriate command BEFORE upgrading anything. Show the user what will change.
35+
Run the appropriate command to list what's outdated BEFORE upgrading anything. Show the user what will change.
3336

3437
### C# / .NET (NuGet)
3538
```bash
@@ -55,6 +58,13 @@ python -m venv /tmp/scripts-venv
5558

5659
**Read the docs:** https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-U
5760

61+
### TypeScript (pnpm)
62+
```bash
63+
cd Dashboard/dashboard-ts && pnpm outdated
64+
```
65+
66+
**Read the docs:** https://pnpm.io/cli/update
67+
5868
If `--check-only` was passed, **stop here** and report the outdated list.
5969

6070
## Step 3 — Read the official upgrade docs
@@ -94,6 +104,13 @@ For `requirements.txt`:
94104
/tmp/scripts-venv/bin/pip freeze > ICD10/scripts/CreateDb/requirements.txt
95105
```
96106

107+
### TypeScript (pnpm)
108+
```bash
109+
cd Dashboard/dashboard-ts && pnpm update
110+
# --major flag:
111+
cd Dashboard/dashboard-ts && pnpm update --latest
112+
```
113+
97114
## Step 5 — Verify the upgrade
98115

99116
After upgrading, run the project's build and test suite to confirm nothing broke:
@@ -126,7 +143,7 @@ Provide a summary:
126143
- **Always run tests after upgrading** to catch breakage immediately
127144
- **Never remove packages** unless they were explicitly deprecated and replaced
128145
- **Never downgrade packages** unless rolling back a broken upgrade
129-
- **Never modify lockfiles manually** — let the package manager regenerate them
146+
- **Never modify lockfiles manually** (pnpm-lock.yaml, etc.) — let the package manager regenerate them
130147
- **Commit nothing** — leave changes in the working tree for the user to review
131148

132149
## Success criteria

.claude/skills/website-audit/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name: website-audit
33
description: Audits a website for SEO, AI search performance, structured data, mobile usability, broken links, and social media cards. Fixes issues found. Use when the user mentions "audit website", "SEO", "fix search ranking", "AI search", "structured data", "social media cards", or "website performance".
44
---
5-
<!-- agent-pmo:29b9dcf -->
5+
<!-- agent-pmo:2efd847 -->
66

77
# Website Audit
88

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
<!-- agent-pmo:29b9dcf -->
2-
3-
# Single Source of Truth
1+
<!-- agent-pmo:2efd847 -->
42

53
@CLAUDE.md
6-
7-
Read the file above in full before writing any code. All project rules,
8-
coding standards, hard constraints, build commands, and architecture
9-
notes live there. Do not add rules to this file -- keep everything in
10-
`CLAUDE.md` so there is exactly one set of instructions to maintain.

.config/dotnet-tools.json

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,6 @@
2929
"Lql"
3030
],
3131
"rollForward": false
32-
},
33-
"h5-compiler": {
34-
"version": "26.3.64893",
35-
"commands": [
36-
"h5"
37-
],
38-
"rollForward": false
3932
}
4033
}
41-
}
34+
}

.cursorrules

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
@CLAUDE.md
1+
<!-- agent-pmo:2efd847 -->
22

3-
All project rules, coding standards, hard constraints, build commands,
4-
and architecture notes live in `CLAUDE.md` at the repository root.
5-
Read that file in full before writing any code. Do not add rules here.
3+
@CLAUDE.md

0 commit comments

Comments
 (0)