AI Agent and Engineer Build Guide: Desktop Electron EHR
Version: 1.0
Date: 2026-03-31
Audience: Cursor agents and human engineers implementing apps/ehr-desktop (or equivalent).
1. Before writing code
Read in order:
- README.md (this pack’s index)
- SPEC.md and TECHNICAL_REQUIREMENTS.md
- SOLUTION_DESIGN.md
- UI_AND_DESIGN_PARITY.md
- BACKEND_AND_SERVICE_MAP.md
- offline-first/SPEC.md and offline-first/TECHNICAL_REQUIREMENTS.md
- REGIONAL_PROFILE.md and AI_PLATFORM.md for localization and AI guardrails
Platform-wide frontend index: docs/ehr-frontend-specs-index.md.
2. Monorepo placement
| Item | Value |
|---|---|
| Suggested app path | apps/ehr-desktop |
| Workspace | Root pnpm-workspace.yaml already includes apps/* — new app is picked up automatically. |
| Task runner | Follow existing turbo patterns used by other apps/* packages. |
Add the new package with private: true and consistent packageManager/engines as sibling apps.
3. Environment variables (illustrative)
Define in .env.example (never commit secrets):
| Variable | Purpose |
|---|---|
KONG_PUBLIC_BASE_URL | HTTPS origin for Kong (e.g. https://api.example.com) |
OIDC_ISSUER / OIDC_CLIENT_ID | IAM / Keycloak public client configuration |
OIDC_REDIRECT_URI | Custom protocol or http://127.0.0.1 loopback for dev |
Exact names MUST match deployment; align with apps/ehr-web and IAM docs if shared.
3.1 Localization (illustrative)
| Variable / config | Purpose |
|---|---|
DEFAULT_LOCALE | Fallback when tenant/user locale unavailable |
FEATURE_RTL_TEST | CI flag to run Playwright with RTL locale (optional) |
Effective locale SHOULD come from config-resolver / user preference at runtime, not only from env.
3.2 AI (illustrative)
| Variable / config | Purpose |
|---|---|
VITE_AI_CLOUD_ENABLED / feature flag | Gate cloud calls to orchestrator (align with TR-DSK-082) |
VITE_AI_LOCAL_ENABLED | Gate on-device inference IPC (default false) |
Never embed third-party model API keys in the renderer. Cloud AI uses Kong + JWT only (TECHNICAL_REQUIREMENTS.md §10).
4. Security checklist (non-negotiable)
-
nodeIntegration: falseinwebPreferences -
contextIsolation: true -
sandbox: truewhere compatible with chosen DB bridge - Preload-only
contextBridgeAPI; no rawremotemodule - CSP headers on
BrowserWindowHTML - Refresh tokens in OS secure storage, not renderer
localStorage - No
/internal/*URLs from the client (API_PATH_CONVENTIONS.md) - No model vendor secrets in renderer; AI only via Kong orchestrator or controlled local IPC (AI_PLATFORM.md)
5. UI and Berry compliance
- Berry + MUI parity: UI_AND_DESIGN_PARITY.md
- Cursor rule: .cursor/rules/berry-template-requirement.md — treat desktop as the same portal family as
ehr-web; use Berry shell patterns and@ghasi/widgetsfor dashboard bodies.
6. HTTP client
- Use a single axios or fetch wrapper that:
- Injects
Authorization: Bearer <access_token> - Adds
Idempotency-Keyfor mutating requests from outbox - Adds optional
X-Correlation-Id - Handles 401 (refresh or logout), 429 (backoff), structured error
code
- Injects
7. Definition of done (per phase)
Align with IMPLEMENTATION_ROADMAP.md:
| Phase | DoD summary |
|---|---|
| 0 | Build/lint/test green; no secrets in client bundle |
| 1 | Login + tenant + one authenticated GET |
| 2 | Outbox + sync + unit tests |
| 3 | Theme parity checklist + sync banner |
| 4 | At least one vertical slice with E2E smoke |
| 5 | Signed updates + release notes |
8. Testing commands
Follow repo conventions:
pnpm testat root (turbo) once wired- Package-local
test:unit,test:e2emirroringapps/ehr-web/package.jsonpatterns
Minimum coverage expectations: TRACEABILITY_MATRIX.md and TESTING_STANDARDS.md. Include RTL E2E (TR-DSK-063) and, when AI ships, mock orchestrator integration tests for happy-path and offline degradation.
9. Common mistakes to avoid
- Embedding Next.js inside Electron for the main UI — use Vite + React (see TECHNICAL_REQUIREMENTS.md §1).
- Duplicating governance logic — server is authoritative; client guards are UX only.
- Calling NATS from the desktop — forbidden (offline-first SPEC).
- Silent overwrite on sync conflict — always surface per SPEC.md FR-DSK-004.
- Skipping RTL — clinical identifiers and layout must be validated in RTL (FR-DSK-009/010, NFR-DSK-006).
- Bypassing AI governance — no direct vendor SDKs in renderer; follow AI_PLATFORM.md.
10. Pull request expectations
- Link requirements:
FR-DSK-*,TR-DSK-*, and relevantFR-OFF-*/TR-OFF-*when touching sync. - Update BACKEND_AND_SERVICE_MAP.md if offline-write posture changes for a module.
- Screenshots for UI changes (desktop vs
ehr-webside-by-side when possible).