Provider Directory Service — User Stories
Service: provider-directory-service Story prefix: PROVDIR-US Last updated: 2026-04-17
Stories
PROVDIR-US-001 — Create practitioner with multi-script names
| Field | Value |
|---|---|
| Issue type | Story |
| Summary | Create a practitioner profile supporting ps/fa-AF/ar + Latin names |
| Epic link | PROVDIR-EPIC-01 |
| Status | To Do |
| Priority | Must |
| Story points | 5 |
| Labels | service:provider-directory-service, type:backend, slice:S0 |
| FR references | FR-PROVDIR-001 |
| Legacy FR refs | FR-PROV-001, FR-PROV-007 |
User story: As a credentialing admin, I want to register a clinician with local-script and Latin names, so downstream workflows can display the correct variant.
Acceptance criteria:
- Given I POST with at least one
officialname, then 201 +provider_directory.practitioner.created.v1published. - Given no
officialname, then 422. - Given duplicate identifier under same authority, then 409
IDENTIFIER_CONFLICT.
Technical notes: Endpoint POST /api/v1/practitioners; validate against terminology-service for specialties.
DoD: Unit + integration + OpenAPI + Pact + event schema + telemetry + coverage.
PROVDIR-US-002 — Update and version practitioner
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-01 |
| Priority | Must |
| Story points | 3 |
| FR references | FR-PROVDIR-002 |
| Legacy FR refs | FR-PROV-001 |
User story: As an admin, I want to update names, telecoms, and specialties with optimistic locking.
Acceptance criteria: If-Match mismatch → 409 VERSION_MISMATCH; no partial writes.
PROVDIR-US-003 — Suspend / reinstate / deactivate
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-01 |
| Priority | Must |
| Story points | 3 |
| FR references | FR-PROVDIR-003 |
| Legacy FR refs | BR-PROV-002 |
User story: As an admin, I want suspension (temporary) and deactivation (permanent) separate lifecycles.
Acceptance criteria: suspended practitioner not selectable; deactivated cannot be reinstated without admin override; events emitted.
PROVDIR-US-004 — Link practitioner to identity user
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-01 |
| Priority | Should |
| Story points | 2 |
| FR references | FR-PROVDIR-005 |
User story: As an admin, I want to link a practitioner to an identity user so their login maps to their clinical profile.
Acceptance criteria: userId unique per tenant; emits practitioner.updated.
PROVDIR-US-005 — Add credential with issuer & expiry
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-02 |
| Priority | Must |
| Story points | 3 |
| FR references | FR-PROVDIR-006 |
| Legacy FR refs | FR-PROV-003 |
User story: As credentialing, I want to record a license with number, issuing authority, and expiry so downstream privilege gating works.
Acceptance criteria: uniqueness per (authority, number); expiry required for license; event emitted.
PROVDIR-US-006 — Nightly expiry scan with 60/30/7-day notifications
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-02 |
| Priority | Must |
| Story points | 5 |
| FR references | FR-PROVDIR-007 |
| Legacy FR refs | FR-PROV-003 |
User story: As the platform, I want to emit reminders 60/30/7 days before expiry to practitioner + admin.
Acceptance criteria: idempotent emission (one event per tick per credential); communication-service receives; audit trail.
PROVDIR-US-007 — Auto-demote roles on credential revoke/expire
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-02 |
| Priority | Must |
| Story points | 5 |
| FR references | FR-PROVDIR-008 |
| Legacy FR refs | BR-PROV-001 |
User story: As clinical safety, when a required license is revoked, any role requiring it is ended automatically.
Acceptance criteria: cascade within same transaction; role.revoked.v1 emitted; audit captures reason.
PROVDIR-US-008 — Revoke credential with audited reason
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-02 |
| Priority | Must |
| Story points | 3 |
| FR references | FR-PROVDIR-009 |
| Legacy FR refs | FR-PROV-003 |
User story: As compliance, I want to revoke a credential with a reason captured in audit.
Acceptance criteria: 200 + credential.revoked.v1; audit event with actor + reason.
PROVDIR-US-009 — Assign role with required-credential check
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-03 |
| Priority | Must |
| Story points | 5 |
| FR references | FR-PROVDIR-011 |
| Legacy FR refs | BR-PROV-001 |
User story: As admin, I want to assign a role, but the system must block if required credentials are missing.
Acceptance criteria: missing credential → 422 CREDENTIAL_REQUIRED with details.missing.
PROVDIR-US-010 — Privilege check endpoint (hot path)
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-03 |
| Priority | Must |
| Story points | 5 |
| FR references | FR-PROVDIR-012 |
| Legacy FR refs | FR-PROV-002 |
User story: As orders/lab/radiology services, I want /internal/practitioners/:id/privileges?nodeId= with p99 ≤ 30ms.
Acceptance criteria: cache hit ≥ 90%; fallback ≤ 80ms.
PROVDIR-US-011 — End role with period.end
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-03 |
| Priority | Must |
| Story points | 2 |
| FR references | FR-PROVDIR-013 |
User story: As admin, I want to end a role with a specific date.
Acceptance criteria: future-dated ends allowed; role.revoked.v1 emitted.
PROVDIR-US-012 — Cross-script fuzzy search
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-04 |
| Priority | Must |
| Story points | 5 |
| FR references | FR-PROVDIR-014 |
| Legacy FR refs | FR-PROV-004, FR-PROV-007 |
User story: As a scheduler, I search "Ahmad" and find "احمد" and vice-versa.
Acceptance criteria: OpenSearch ICU analyser; integration test covers both directions.
PROVDIR-US-013 — Search by specialty with filters
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-04 |
| Priority | Should |
| Story points | 3 |
| FR references | FR-PROVDIR-014 |
| Legacy FR refs | FR-PROV-004 |
User story: As a scheduler, I want to filter by specialty code + active status + node.
Acceptance criteria: response p95 ≤ 500ms; pagination stable.
PROVDIR-US-014 — Register service endpoint
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-05 |
| Priority | Should |
| Story points | 3 |
| FR references | FR-PROVDIR-015 |
| Legacy FR refs | FR-PROV-005 |
User story: As interop admin, I register an external partner's FHIR/HL7 endpoint.
Acceptance criteria: TLS-required URL validated; auth-method captured.
PROVDIR-US-015 — Periodic endpoint health
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-05 |
| Priority | Should |
| Story points | 3 |
| FR references | FR-PROVDIR-017 |
User story: As ops, I want endpoints probed every 5 min and health transitions emitted.
Acceptance criteria: on outage, state moves to error within 15 min; event emitted.
PROVDIR-US-016 — FHIR Practitioner R4 CRUD
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-06 |
| Priority | Must |
| Story points | 5 |
| FR references | FR-PROVDIR-018 |
| Legacy FR refs | SPEC §6 |
User story: As interop partners, I want standard FHIR Practitioner with search params.
Acceptance criteria: name/identifier/specialty/active supported; roundtrip test green.
PROVDIR-US-017 — FHIR PractitionerRole with scope
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-06 |
| Priority | Must |
| Story points | 3 |
| FR references | FR-PROVDIR-018 |
| Legacy FR refs | SPEC §6 |
User story: As interop, I need PractitionerRole with organization/location references.
Acceptance criteria: references resolvable; HL7 v2 PV1/ORC mapping documented.
PROVDIR-US-018 — SLO dashboards + alerts
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-07 |
| Priority | Must |
| Story points | 3 |
| FR references | NFR-PROVDIR-001..004 |
User story: As SRE, I want dashboards for the 5 SLIs and 5 alerts wired.
Acceptance criteria: alerts fire in drills; runbooks linked.
PROVDIR-US-019 — Chaos drill: OpenSearch + NATS outage
| Field | Value |
|---|---|
| Epic link | PROVDIR-EPIC-07 |
| Priority | Should |
| Story points | 5 |
| FR references | NFR-PROVDIR-CHAOS |
User story: As SRE, I verify resilience when search or events degrade.
Acceptance criteria: DB fallback search works; outbox drains; no data loss.