# CLAUDE.md

## What this is

`reportgen` is a small Ruby CLI that pulls client account data from the Finch API and
renders/delivers periodic reports to clients. It runs as a scheduled job (cron on the ops
box); there is no server component.

## Module map

- `bin/reportgen` — CLI entry point; dispatches to the classes in `lib/reportgen/`.
- `lib/reportgen/client.rb` — Finch OAuth client (token fetch + caching).
- `lib/reportgen/fetcher.rb` — pulls account/transaction records from the Finch API.
- `lib/reportgen/formatter.rb` — date/number formatting helpers.
- `lib/reportgen/renderer.rb` — renders the report view (HTML) from fetched records.
- `lib/reportgen/charts.rb` — builds the charts embedded in a rendered report.
- `lib/reportgen/exporter.rb` — CSV export of a report's underlying data.
- `lib/reportgen/export_writer.rb` — newer CSV writer used by the exporter's next iteration.
- `lib/reportgen/delivery.rb` — packages a rendered report and sends it to the client.

## Running

```
ruby bin/reportgen generate --client initech --month 2026-06
ruby bin/reportgen deliver --client initech --month 2026-06
```

## Style

Plain Ruby, no framework. Two-space indent, `frozen_string_literal: true` at the top of
every file, one class per file under `lib/reportgen/`.

## Architecture decisions

Architecture decisions for this project are recorded in `docs/adr/`.

## Cross-project memory

Durable knowledge that is not about this repo goes to the SecondBrain vault via
`/os-vault:write` — not into this repo, and not into auto-memory.

- **When** you discover during a task that a tool, API, or service behaves differently from
  what its docs or config claim (advertised X, actually Y) → that discrepancy is evergreen
  vault knowledge. Run `/os-vault:write` before you consider the task complete.
- **When** the user states a client-specific requirement, standard, or standing preference →
  record it with `/os-vault:write` (scope: client). An ADR records how *this repo's code*
  implements it; the client's requirement itself is client knowledge and an ADR does **not**
  satisfy this rule — the vault note is still required.
- Mechanical rule: **before your final reply on any task**, check whether either of the above
  occurred this session; if yes, the task is not complete until the vault note is written.
- Ephemeral material stays out of the vault: task status, in-progress refactor state,
  project-local quirks, and anything this repo's docs or ADRs already record.
