# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What this is

Phase 1 of the SMWC clinical hour log: a browser-only web app replacing the paper "On-Site Weekly Hour Log" (Appendix E, CN599 Internship I). The product brief is `~/PersonalProjects/SmwcServices/smwc-requirements.md`; read it before changing behaviour. No server, no accounts: data lives in `localStorage` and in exported JSON/CSV backups. It does **not** call the SmwcServices User microservice; the brief rules out accounts for phase 1.

`Main.dc.html`, `Entry.dc.html` and `PrintLog.dc.html` are the design mockups (dashboard, log a week, printable form). They are references, not part of the app, and need a `support.js` runtime that is not in this repo. The app reproduces their tokens and layouts; when changing the look, match them.

## Commands

```bash
npm test                          # node --test tests/  (no dependencies; Node is at /opt/homebrew/bin)
node --test --test-name-pattern="supervision" tests/   # one test
npm run serve                     # python3 -m http.server 8080; ES modules do not load from file://
```

No build step and no packages: plain HTML, CSS and ES modules.

## Architecture

- `js/config.js`: every requirement number (120 direct, 300 total, 1 / 1.5 hr weekly supervision), the form's wording, and the export format/version. Phase 2 (.NET MAUI) copies this, so keep it plain data.
- `js/model.js`: all pure logic (dates, totals, Total Clock formula, supervision shortfalls, validation, biweekly periods, backup reminder, JSON/CSV export and import). No DOM or storage, so everything here is covered by `tests/model.test.mjs`. Put new rules here, not in `app.js`.
- `js/store.js`: the whole state in one `localStorage` key (`smwc-hour-log/v1`). `update()` clones, applies and persists, and returns false (keeping the old state) when the browser refuses to save.
- `js/app.js`: a hash router (`#/`, `#/entry[/<id>]`, `#/print[/<periodStart>|/all]`, `#/settings`) and the screens, rendered as template strings. Every user string goes through `esc()`.
- `js/signature-pad.js`: Pointer Events canvas; exports a PNG trimmed to the ink.

Rules the code relies on:

- `weekDate` is always the **Monday** of its week (`weekStart`), ISO `YYYY-MM-DD`, handled as a local calendar date. One entry per week.
- Hours are numbers in 0.25 steps, never negative. `totalClockHours` is never stored; it is recomputed (Direct + Indirect, plus supervision if the per-user setting is on).
- A row is signed when it has a signature image, a supervisor name and a signed date. Signed rows are read-only until the signature is cleared.
- Biweekly periods are consecutive two-week pairs counted from the first logged week. Printing a period marks it exported (`exportedPeriods`).
- The JSON export (`format: "smwc-hour-log"`, `version`) is the contract with the phase 2 app. Bump `exportVersion` and keep `fromExport` reading old versions when the shape changes. Import accepts signatures only as inline `data:image` URLs.
- Never add fields for client names or anything that identifies a client; the app holds hours only.

## Style

Tabs, Allman braces, no braces on single-statement `if`/`else`, matching the sibling PHP projects.
