|
| 1 | +# Scope |
| 2 | + |
| 3 | +This document is the **single source of truth** for what this package does and |
| 4 | +why. The README explains *how to use* it; this file defines *what it must do*. |
| 5 | +Every feature below has an ID. Every feature ID must be covered by at least one |
| 6 | +test (enforced by `tests/test_scope_coverage.py`). Do not add, change, or remove |
| 7 | +a feature here without updating the tests — that is how current behaviour is |
| 8 | +guaranteed across future changes. |
| 9 | + |
| 10 | +## Purpose |
| 11 | + |
| 12 | +`claude-code-commons` is the small, **vendor-agnostic, standard-library-only** |
| 13 | +toolkit shared by Claude routine repos. It owns the generic helpers every routine |
| 14 | +tends to re-implement — environment lookup, tolerant number parsing, currency |
| 15 | +symbols, remote-path building and a run-log line — with **no third-party |
| 16 | +dependency**, so any routine can install it without dragging in a web client or a |
| 17 | +spreadsheet engine. Vendor-specific toolkits (e.g. a WooCommerce REST client) |
| 18 | +build on top of it. |
| 19 | + |
| 20 | +## Why it exists |
| 21 | + |
| 22 | +Every routine needs the same handful of helpers. Copying them into each repo lets |
| 23 | +the copies drift — a fix made in one is missed in the others. One tiny, |
| 24 | +dependency-free package, versioned and tested in isolation, removes that hazard |
| 25 | +and keeps the heavier vendor toolkits thin: they import the core and add only |
| 26 | +their vendor-specific parts. |
| 27 | + |
| 28 | +## Features (acceptance criteria) |
| 29 | + |
| 30 | +Each feature is testable. The ID in brackets is referenced by tests via |
| 31 | +`@pytest.mark.feature("F-00X")`. |
| 32 | + |
| 33 | +- **[F-001] Environment helpers with project-prefix fallback.** `env_required(key, |
| 34 | + *, prefix="")` and `env_opt(key, default, *, prefix="")` — with `env_get` as a |
| 35 | + convenience alias of `env_opt` — resolve a variable by trying `<prefix>_<key>` |
| 36 | + first and falling back to the unprefixed `<key>` (plain `<key>` with no prefix, |
| 37 | + backward compatible). `env_required` aborts with a clear `SystemExit` naming the |
| 38 | + variable when neither form is set; `env_opt`/`env_get` return `default`. This |
| 39 | + lets a family of routines share one environment: shared values set once |
| 40 | + unprefixed, per-routine values set prefixed so they never collide. |
| 41 | + |
| 42 | +- **[F-002] Tolerant number parsing.** `parse_num()` accepts comma **thousands** |
| 43 | + separators (`"1,234"` → `1234.0`), plain numbers and numeric strings, and |
| 44 | + returns `0.0` for `None`, `""` or unparseable input — it never raises. A comma |
| 45 | + is always a thousands separator (dot-decimal domain); comma-**decimal** locale |
| 46 | + input (`"1,5"` → `15.0`, not `1.5`) is out of scope and handled by per-routine |
| 47 | + locale parsers. |
| 48 | + |
| 49 | +- **[F-003] Remote-path builder.** `build_remote_path(base, folder, filename)` |
| 50 | + joins an optional base directory, an optional sub-folder and a filename into one |
| 51 | + absolute, slash-normalised path. Lets a family share one base |
| 52 | + (`DROPBOX_PATH`) while each writes into its own `<PREFIX>_DROPBOX_FOLDER` |
| 53 | + sub-folder: base `/Reports` + folder `Stock` → `/Reports/Stock/<filename>`. An |
| 54 | + empty/None folder drops the file straight into `base`; an empty/None base falls |
| 55 | + back to the root — so an unset folder reproduces the previous single-directory |
| 56 | + behaviour (backward compatible). |
| 57 | + |
| 58 | +- **[F-004] Currency symbols.** `currency_symbol(code)` maps a 3-letter currency |
| 59 | + code to a display symbol (case-insensitive), falling back to the upper-cased |
| 60 | + code itself for unmapped currencies. |
| 61 | + |
| 62 | +- **[F-005] Timestamped run log.** `log(msg)` prints a flushed `[HH:MM:SS] msg` |
| 63 | + line to stdout — the shared run-log format the routines use. |
| 64 | + |
| 65 | +## Out of scope |
| 66 | + |
| 67 | +Anything vendor-specific (a WooCommerce/Shopify/… client, shop meta keys); |
| 68 | +network access of any kind (this package makes no network calls); spreadsheet or |
| 69 | +file I/O; currency *conversion* (only symbol labelling); and locale-aware |
| 70 | +comma-decimal parsing. Vendor toolkits and the routines themselves own those. If a |
| 71 | +new generic, dependency-free helper is ever needed, add a feature ID here first, |
| 72 | +then a test, then the code. |
0 commit comments