---
name: dev-issue
description: >
  Run a GitHub issue through its full lifecycle end-to-end: investigate,
  discuss the approach, gather test context (department/data), implement,
  rebuild + local redeploy, verify with Playwright and the database, iterate
  until passing, record any testing-workflow learnings, commit/push, open a
  PR, and loop on review comments until mergeable. Use when asked to "take
  issue #N end to end", "do issue #N fully", "develop and ship issue #N", or
  similar full-cycle requests.
argument-hint: "<issue-number>"
---

# Full Issue Lifecycle (HMIS)

Invoking this skill is the explicit authorization for every commit/push/PR
step below — do not re-ask before each one. Discussion gates (steps 2a
non-repro case and any state-changing step taken there to prove an
*unconfirmed* bug, 3, 4's environment choice only, 14) are the points where
you pause for the user. Everything else in 2a and 4 (which department/record
to use against local test data) is a local-testing-environment choice, not a
product decision — decide it yourself and say what you picked, rather than
pausing.

That 2a gate is narrow and does not extend to step 7. 2a's risk is spending
effort chasing a bug that might not be real; once step 3 has been through
Plan Mode and the user has approved a fix, that risk is gone — exercising
the approved fix in step 7, including any state-changing UI action needed to
set up the scenario (e.g. removing a room, changing a status, editing a
record) against local test data, is the same no-need-to-ask
local-testing-environment judgment call as picking which department/record
to use. Decide it yourself, do it through the real app UI (never raw SQL for
setup — see step 7), and report exactly what you did as evidence. Only ask
first if the action would reach outside local test data (a remote
environment, or anything step 4's environment-choice gate already covers).

This authorization also covers `superpowers:writing-plans`' Execution
Handoff question, if that chain gets invoked anywhere in this flow (e.g.
during step 5): auto-select **option 1, Subagent-Driven** without asking —
do not stop for it as an additional discussion gate.

## 0. Anything you write to GitHub is public

`hmislk/hmis` is a public repo. Before every `gh issue create`,
`gh issue comment`, `gh pr create` or `gh pr comment` in the steps below,
apply
[What May Go Into a GitHub Issue, PR, or Comment](../../../developer_docs/git/github-public-content-policy.md):
no patient/doctor/staff names, production record identifiers (bill/BHT/PHN
numbers, entity IDs), affected-record counts, production schema names, cutover
dates, per-staff statistics, data-fix logs or credentials. Describe the defect
and the local test evidence; keep hospital-specific numbers in `tmp/`. This
applies to the issue body as much as to the PR — including an issue *you* file
mid-run for a bug you found yourself.

## 1. Setup

Run the `start-issue` skill for `$0`: creates the branch from
`origin/development`, sets `persistence.xml` to local JNDI, assigns the
issue, sets the project board status to In Progress.

## 2. Investigate

- Read the issue body and comments (`gh issue view $0 --comments`).
- Explore the relevant code. Use the `Explore` agent for anything spanning
  more than a few files.
- Identify: which entities/services/JSF pages are involved, which existing
  patterns to follow (DTOs, privileges, AJAX), and what's actually broken or
  missing.
- **If the issue is a bug report**, try to pin down the root cause by reading
  code first. Note explicitly whether this succeeded — that decides whether
  step 2a runs.

## 2a. Reproduce the bug (bug issues only)

Skip this step for feature/enhancement issues, and for bug issues where step
2's code reading already found a clear, confirmed root cause.

Run it when the issue is a bug and step 2 left the cause unconfirmed or
unfound:

- Prefer reproducing against existing data first (read-only navigation or
  API `GET`s) — picking which department/record to *read* is the same
  no-need-to-ask judgment call as step 4. If reproduction requires a
  state-changing step (creating, modifying, or deleting a record, or running
  direct SQL), that's a different risk category: confirm with the user
  first (`AskUserQuestion`) before creating a disposable record,
  modifying/deleting an existing record, or running direct SQL — don't
  extend the "don't ask" judgment call to writes. If the user approves a
  disposable record, clean it up in the same session where possible.
- Reproduce live against local Payara — the `playwright-e2e` skill for
  UI-facing bugs, or direct REST calls (per `api-development`) for API-only
  ones.
- Save "before" evidence into the project `tmp/` folder: screenshots for UI
  bugs, request/response bodies for API bugs. Redact patient identifiers,
  credentials, tokens, cookies, and other sensitive fields from any saved
  API body before it leaves `tmp/`.
  - If it reproduces, this evidence proves the bug and becomes the "before"
    half of the before/after comparison published in step 10.
  - If it does **not** reproduce, record that — under the tested
    environment, data, and inputs — the bug did not reproduce; that is not
    proof the bug is absent. Stop here, post the finding to the issue, and
    confirm with the user whether to still proceed (per CLAUDE.md "discuss
    uncertainties") rather than guessing at a fix for a bug you couldn't
    observe.

## 3. Discuss the approach (Plan Mode)

Enter Plan Mode. Present:
- What you found in step 2 (and step 2a's reproduction evidence, for bugs)
- The proposed change (files to touch, approach)
- Anything uncertain (per CLAUDE.md rule "discuss uncertainties")

Exit Plan Mode only once the user approves or adjusts the plan.

## 4. Gather test context

Local Payara / local DB is a testing environment — pick department and
records yourself rather than gating on the user for them:
- **Department**: query the local DB for one that's real and relevant to the
  feature (e.g. Pharmacy, Inward, OPD), and say which one you picked before
  testing.
- **Specific records** to exercise (e.g. an admission ID, bill number, item
  code): query the local DB for existing records that fit the feature and
  use those — report exactly which ones you used (BHT no, bill no, etc.) in
  the PR/issue evidence. Only ask the user if the local DB has no suitable
  record at all (e.g. the feature needs a state nothing local is in) — that
  is a real blocker, not a preference question.
- **Environment**: local Payara (default) unless the issue specifically
  requires testing against a remote env, in which case confirm which one
  with the user (this one *is* a real decision — remote envs carry real
  data/credentials risk that local doesn't). Credentials live outside the
  repo in `C:\Credentials\` — never inlined.

Only the environment choice is a discussion gate here. Department/record
selection against local test data is not — deciding it yourself and moving
straight to step 5 keeps this step from wasting a round-trip on a question
that has no wrong answer in a disposable local DB.

## 5. Develop

Delegate implementation by file type, per CLAUDE.md module rules (DTOs,
JPQL-first, privilege system, AJAX update rules, etc.):
- Java entities/services/DTOs/REST → `java-backend-developer` agent
- XHTML/PrimeFaces views → `jsf-frontend-dev` agent
- Mixed changes: split into per-area tasks and delegate each

Review the diffs from each agent before moving on — don't trust a summary
without checking the actual edits.

## 5a. Regenerate the DDL if the schema changed

If step 5 added or renamed any entity field, or added a new entity/table,
run the `generate-ddl` skill before moving on. This keeps
`tmp/createDDL.jdbc` and the
[Database-Schema-DDL-Generation-Guide](https://github.com/hmislk/hmis/wiki/Database-Schema-DDL-Generation-Guide)
wiki page in sync with the actual schema, so other developers and fresh
installs can pick up the new column/table without hand-writing a migration.
Skip this step entirely if the issue only changed business logic with no
new persisted fields.

## 6. Build and local redeploy ("deploy sos")

Per `playwright-e2e` §0a:

```powershell
$env:JAVA_HOME="C:\Program Files\Eclipse Adoptium\jdk-11.0.23.9-hotspot"
& "D:\Program Files\NetBeans-18\netbeans\java\maven\bin\mvn.cmd" clean package -DskipTests
& "D:\Payara\bin\asadmin.bat" redeploy --name rh "D:\Development\2024\hmis\target\rh-3.0.0.war"
```

Check `D:\Payara\glassfish\domains\domain1\logs\server.log` for deployment
errors before moving on.

## 7. Test with Playwright + verify in DB

Run the `playwright-e2e` skill workflow:
- Login, select the department from step 4
- If verifying the fix requires putting a record into a specific state first
  (e.g. a race-condition fix needs a room removed, a status changed, a second
  record created), do that live through the real app UI yourself — this is
  the same local-testing-environment judgment call as step 4's
  department/record choice, not a fresh discussion gate. (Unlike step 2a,
  which gates state-changing actions because it's proving an *unconfirmed*
  bug, step 7 is exercising a fix the user already approved in step 3.)
  Report exactly what you did (menu path, record IDs, before/after DB state)
  as part of the evidence.
- **Navigate to the page through the menus, never by URL** — HMIS page state is
  set by the `@SessionScoped` navigation method, so a URL-loaded page renders
  against uninitialised state and produces false findings (`playwright-e2e` §2).
  Record the menu path in the issue/PR.
- Exercise the feature using the records chosen in step 4
- **Take screenshots** (`browser_take_screenshot`) into the project `tmp/`
  folder at each meaningful stage (before/after states, confirmation dialogs,
  final result) — per playwright-e2e §0. These double as evidence for the
  issue/PR and wiki in step 10. For bug issues where step 2a ran, capture the
  same view/state it reproduced, so it pairs cleanly as the "after" half of
  that before/after comparison. For API-only bugs, replay the original
  request (the actual parameters, not the redacted evidence artifact)
  against the same confirmed target instead. If that request mutates state,
  reuse a resettable/disposable target or get the user's confirmation again
  before replaying it — don't apply a write twice against real data just to
  capture evidence. Save the response status/body (redacted, same rule as
  step 2a) as the "after" evidence.
- Verify the result in the local DB (credentials: see the
  `local_mysql_credentials.md` memory)

## 8. Iterate

If the test reveals a bug: fix the code (step 5), rebuild/redeploy (step 6),
retest (step 7). Repeat until the flow passes end-to-end.

## 9. Record learnings

If a new Playwright/dev gotcha surfaced, add it to the matching topic file in
`developer_docs/testing/playwright-e2e/`. Number it after the highest § in use,
and list it in the main guide's Contents. Write it as a symptom heading plus
1–3 lines of fix. Leave the story, dates and issue history out; they belong in
the PR. Skip this step if nothing new came up.

## 10. Publish evidence and update the wiki

Follow playwright-e2e
[§8 Publishing screenshot evidence](../../../developer_docs/testing/playwright-e2e-workflow.md#8-publishing-screenshot-evidence)
(and, for bug issues,
[§8a Before/after pairing](../../../developer_docs/testing/playwright-e2e-workflow.md#8a-bug-fixes-pair-before-and-after-evidence)):

1. Review the screenshots from steps 2a and 7 and discard/crop any that
   expose patient data, credentials, or other sensitive information. For API
   evidence, redact patient identifiers, credentials, tokens, cookies, and
   other sensitive fields from the request/response bodies before they leave
   `tmp/`.
2. Copy the durable, non-sensitive screenshots into `../hmis.wiki/images/`.
   Redacted API request/response snippets aren't images — post them as fenced
   code blocks in the issue/PR instead of adding them to the wiki.

3. **Update the wiki page(s) for the feature you changed.** This is a
   required part of the work, not an optional extra — publishing an image
   without wiring it into a page leaves it orphaned, which is why the wiki
   currently has ~600 images but only ~55 pages that reference any.

   a. **Find the page.** Search the sibling wiki repo for the feature by
      name, page title, and menu path:
      ```bash
      cd ../hmis.wiki && ls *.md | grep -iE "<feature|module keyword>"
      grep -ril "<feature name>" *.md | head
      ```
      Wiki pages are named after the user-facing screen
      (e.g. `Inpatient-Nursing-Discharge.md`), so the page usually exists
      even for a narrow bug fix.

   b. **Embed the screenshots** with a relative path, plus a visible caption
      beneath. Markdown alt text is not a rendered caption — it serves screen
      readers, while an italic line under the image is what a sighted reader
      skimming the page actually sees:
      ```markdown
      ![Nursing discharge blocked by pending pharmacy items](images/23222-fixed-discharge-blocked.png)

      *Nursing discharge blocked: the pending pharmacy items are listed and Confirm stays disabled.*
      ```

   c. **Replace outdated images.** If the page already has a screenshot of a
      screen your change altered — or one that simply looks nothing like the
      current UI — replace it rather than appending a second, contradictory
      one. Keeping the wiki current as the UI improves is part of the job.

   d. **Correct any text the change makes wrong.** A page can document
      intended behaviour that never actually worked. `Inpatient-Nursing-Discharge.md`
      described the pending-pharmacy block as working while the check had
      been silently dead since it shipped (issue #23222). If the fix changes
      what a user sees or can do, reconcile the prose with reality — and if
      the page described the behaviour correctly all along, say so in the PR
      so the reviewer knows the page was checked, not skipped.

   e. **If no page exists**, judge which case applies rather than defaulting:
      - The change is user-visible (a screen, a workflow, a report, a
        setting) → **create the page**, following the structure and tone of a
        neighbouring page in the same module.
      - The change is invisible to end users (an internal query fix with no
        behavioural difference, a refactor, a build change) → **no page**;
        the screenshot is evidence for the issue/PR only. Say which you chose
        and why in the PR.

4. Commit and push the wiki from `../hmis.wiki` — both the images and the
   page edits, in one commit.

5. Add a comment (or update the description) on issue `$0` that includes:
   - the evidence — wiki images by raw URL
     (`https://raw.githubusercontent.com/wiki/hmislk/hmis/images/<name>.png`)
     or redacted API snippets as code blocks. For bug issues where step 2a
     ran, label and pair the "before" and "after" evidence. Where step 2a was
     skipped (root cause confirmed by reading code), publish only the step 7
     confirmation, with no comparison implied.
   - **a link to the wiki page(s) you updated**
     (`https://github.com/hmislk/hmis/wiki/<Page-Name>`). The person who
     raised the issue needs to see how the finished feature works, not just
     that a fix landed.

6. Remove the temporary screenshots/evidence from the project `tmp/` folder.

The wiki image URLs **and the wiki page links** are both reused in the PR
description in step 13.

## 11. Pre-push check

Check `src/main/resources/META-INF/persistence.xml` yourself — no skill
needed. If `<jta-data-source>` holds a local JNDI name (e.g. `jdbc/coop`,
`jdbc/ruhunuAudit`) in either persistence unit, note the values (you'll
restore them in step 12) and swap them back to `${JDBC_DATASOURCE}` /
`${JDBC_AUDIT_DATASOURCE}` with `Edit` before staging. If it already reads
placeholders, there's nothing to do here — proceed to commit.

## 12. Commit and push

Stage the intended source/doc files (`git add <files>`), including
`persistence.xml` now that it has placeholders. Commit directly (`git
commit`) with the message format from
[Commit Conventions](../../../developer_docs/git/commit-conventions.md) —
issue number in the closing keyword, Co-Authored-By trailer — then `git
push`. Immediately after the push, restore `persistence.xml` to the local
JNDI names noted in step 11 with `Edit`, leaving that change **unstaged**.

## 13. Create the PR

Target `development`. The PR description should state what was implemented
and summarize the Playwright + DB verification performed in steps 7-8
(concrete enough that a reviewer trusts it was actually tested), and embed
the same wiki-hosted screenshots from step 10 so reviewers can see the
verified behavior without redeploying locally.

It must also **link the wiki page(s) updated in step 10**
(`https://github.com/hmislk/hmis/wiki/<Page-Name>`), under a short
**Documentation** heading. Reviewers check the change against the documented
behaviour, so a PR that alters what users see without showing the
corresponding page edit can't be reviewed properly. If step 10 concluded no
page was needed (internal-only change), say that explicitly instead — an
absent Documentation section reads as forgotten, not as deliberate.

## 14. Review loop (until mergeable)

Repeat, up to **3 cycles**:

1. `gh pr checks <PR#>` — if checks are still pending, `ScheduleWakeup` for
   ~270s and recheck (don't block with `--watch` past a few minutes).
2. If checks fail: investigate the failure, fix, push, go to 1.
3. Once checks pass: run the `review-pr` skill for `<PR#>`.
   - Auto-apply fixes for comments matching `review-pr`'s documented
     false-positive/valid-fix patterns.
   - For genuinely ambiguous comments, pause and ask the user — don't burn a
     cycle guessing.
   - If fixes were applied, push and go to 1.
4. If checks are green and there are no unresolved review comments, stop —
   this cycle is done.

If 3 cycles pass without convergence (flaky CI, unresolved disagreement with
a reviewer, etc.), stop and ask the user how to proceed rather than looping
indefinitely.

## 14a. File what you found along the way

The run is not finished while a defect you noticed but did not fix lives only in chat or `tmp/`. From step 2 onward, keep a **Found along the way** list (in the batch's `tmp/` master plan, or `tmp/<issue>/found.md`). Anything outside the issue's scope goes on that list, not into the PR.

Before Notify:
1. **Confirm each item** against the code, or reproduce it. Drop anything unconfirmed, and say in Notify that you dropped it. A growl you didn't see is not proof of a silent failure.
2. **Search first**: `gh issue list --state all --search "<keywords>"`. If an open issue matches, comment on it. If a closed one fixed the same bug on another page, cite it in the new issue.
3. **File one issue per defect**, following step 0's public-content rules: symptom, cause with `file:line`, steps, expected, fix direction, and honest impact (say so if it is unreachable or low).
4. **List the new issue links** in Notify.

## 15. Notify

Report the PR link, the issue comment from step 10, a short summary of what
changed, and what was verified (including the published screenshots).
If you mention the project board status, re-read it from GitHub first (the `start-issue`
Step 5 read-back query) and quote what it returns. Never report the board status from
memory of an earlier update call. (Issue #24105 was reported as "In Progress" when the
board still showed Backlog.)
Include the issues filed in step 14a.
**Never merge** — that's the user's call.
Once the user says the PRs are merged, run `cleanup-branches`, so merged local and remote branches are deleted and `development` is fast-forwarded and checked out.
