reimburse/docs/admin-guide.md
Claude 7d49759c75
Add user, admin, and developer documentation; expand CLAUDE.md
Creates docs/ with three audience-specific guides:
- docs/user-guide.md: step-by-step form-filling instructions, field
  descriptions, FX rate explanation, receipt handling, troubleshooting
- docs/admin-guide.md: deployment instructions and exhaustive config.yml
  key/value reference with types, defaults, and constraints
- docs/developer-guide.md: architecture overview, full state model, all
  CFG key mappings, PDF engine internals, column positions, four-pass build
  process, common modification checklists, known limitations

Rewrites CLAUDE.md as a dense agent reference covering the same ground
in a compact format: code section line ranges, full config key table with
JS access patterns, validation rules, PDF coordinate system, design
decisions, and modification checklists.

https://claude.ai/code/session_01Dad69NPna53u4hucCYnVNs
2026-05-19 09:50:11 +00:00

8 KiB
Raw Blame History

Administrator Guide — Reimbursement Form

This guide is for the person responsible for deploying and configuring the reimbursement form for their organisation.


Architecture

The application is a static web app — a single HTML file that loads a YAML configuration file at runtime. There is no server-side logic, no database, and no build step.

app/
├── index.html        # Complete application
├── config.yml        # All organisation-specific settings
└── assets/
    └── logo.png      # Optional organisation logo (PNG or JPG)

The browser downloads the two CDN libraries at startup:

  • pdf-lib 1.17.1 — PDF generation
  • js-yaml 4.1.0 — YAML config parsing

Both are loaded from unpkg.com. Users need an internet connection to open the form for the first time; subsequent use within the same browser session does not re-fetch them.


Deployment

  1. Copy the app/ directory to any static web server (Nginx, Caddy, Apache, S3 + CloudFront, GitHub Pages, etc.).
  2. Ensure the server serves .yml files with a valid MIME type. Caddy does this automatically. For Nginx, add:
    types { text/yaml yml; }
    
  3. Access the form at the URL where index.html is served. No path configuration is needed inside the file.

The form works with any URL path. If you deploy at https://intranet.example.org/finance/reimbursement/, no changes to the source are required.


Configuration reference — config.yml

All customisation is done in config.yml. The file is loaded fresh every time the page is opened, so changes take effect immediately without redeploying.

Organisation identity

organization: "Center for Asylum Protection"
logo: yes
logo-maxwidth: 4
Key Type Required Description
organization string Yes Displayed in the form header and on the PDF. Used as a fallback if the logo is disabled or the image file is missing.
logo yes / no Yes Whether to show a logo image. If yes, the app attempts to load assets/logo.png; if that fails, it tries assets/logo.jpg; if that also fails, it falls back to displaying the organization text.
logo-maxwidth number (cm) No Maximum width of the logo in centimetres, applied in both the browser UI and the PDF. Default behaviour is unconstrained. Typical value: 4.

Logo requirements:

  • Format: PNG (preferred) or JPG
  • File must be placed at assets/logo.png (or assets/logo.jpg)
  • The image is scaled to fit within logo-maxwidth cm width and 56 px height (UI) or 50 pt height (PDF), whichever is the binding constraint

PDF page setup

page-size: A4
Key Type Required Description
page-size A4 / letter Yes Paper size for PDF output. A4 = 595.28 × 841.89 pt. letter = 612 × 792 pt.

Typography

font-body: Helvetica
font-heading: Helvetica
font-monospace: Courier
font-size: 10
Key Type Required Description
font-body string Yes Font used for body text in the PDF. Must be one of the standard PDF fonts: Helvetica, Times, or Courier. Custom TTF fonts are not yet supported.
font-heading string Yes Font used for headings and labels in the PDF. Same options as font-body.
font-monospace string Yes Font used for monospaced content. Recommended: Courier.
font-size number (pt) Yes Base font size in points for PDF body text. Headings and labels are scaled relative to this. Typical range: 912.

Note on fonts: The current implementation always uses Helvetica/HelveticaBold/Courier regardless of what font-body, font-heading, and font-monospace are set to. Custom font selection is planned but not yet implemented.

Branding

accent-colour: "#1a3a5c"
Key Type Required Description
accent-colour hex colour string Yes Primary brand colour. Applied as the --accent CSS variable in the browser UI (buttons, borders, headings) and as the heading/divider colour in the PDF. Must be a six-digit hex string including the # prefix.

Form text

intro: ""
footer: "Confidential"
Key Type Required Description
intro string No Optional introductory text shown on the first page of the PDF, above the staff/period/currency fields. Leave empty ("") to omit. Long text wraps automatically.
footer string No Text printed at the bottom of every PDF page. Typical values: "Confidential", "Internal use only", or your organisation's name.

Currency settings

currency-base: USD

currencies:
  - code: USD
    name: United States dollar
  - code: THB
    name: Thai baht
  - code: EUR
    name: Euro
  - code: NOK
    name: Norwegian krone
Key Type Required Description
currency-base ISO 4217 code Yes The default base (reimbursement) currency. Must be present in the currencies list. All amounts on the PDF summary are converted to this currency.
currencies list of {code, name} Yes All currencies available in the per-line currency dropdown. code must be an ISO 4217 three-letter code. name is shown in the dropdown for user reference only.

FX rate convention: rates are expressed as units of the line currency per 1 unit of the base currency (e.g. 34.25 THB per 1 USD). Conversion is base_amount = line_amount / fx_rate.

Adding a currency: append a new {code, name} entry to currencies. No other changes are needed.

Removing a currency: remove its entry. Any existing PDF claims already generated are unaffected.

Accounts

accounts:
  - "1000 - General Operations"
  - "2000 - Travel & Transport"
  - "3000 - Office Supplies"
  - "4000 - Professional Services"
Key Type Required Description
accounts list of strings Yes Dropdown options for the "Account" field on each expense line. Each string is shown verbatim. Typically formatted as "CODE - Description". At least one entry is required.

Selecting an account is mandatory for each line. The account code selected appears verbatim on the generated PDF.

Programs

programs:
  - "General Operations"
  - "Legal Aid Program"
  - "Protection Program"
  - Other
Key Type Required Description
programs list of strings Yes Dropdown options for the "Program" field on each expense line. At least one entry is required.

Special value Other: if the literal string Other is included in the list, selecting it in the form reveals an additional free-text field where the user must type the program name. The PDF will show Other: [typed value]. All other values are shown exactly as written.


Changing configuration

  1. Edit app/config.yml in any text editor.
  2. Save the file and refresh the browser. Changes are live immediately.
  3. Existing downloaded PDFs are not affected.

  1. Prepare a PNG or JPG image of your logo. Transparent background (PNG) works best.
  2. Place the file at app/assets/logo.png (create the assets/ folder if it does not exist).
  3. Set logo: yes in config.yml.
  4. Set logo-maxwidth to the desired maximum width in centimetres.

Troubleshooting

Problem Cause Fix
Form shows "Failed to load: Cannot load config.yml" Server not serving the YAML file, or file missing Check the file path and server MIME type configuration
Logo does not appear File missing or wrong path Place file at assets/logo.png relative to index.html
Accent colour not applied Malformed hex value Use the format "#rrggbb" (six digits, with quotes, with #)
Currency not in dropdown Missing from currencies list Add the {code, name} entry to currencies
currency-base not selectable Code not in currencies list Add it to currencies before using it as currency-base
PDF fonts look wrong Custom font specified Only Helvetica, Times, Courier are currently supported