From 34493e0a9210d831ec700e20841cce2c496cdf33 Mon Sep 17 00:00:00 2001 From: mforce <> Date: Thu, 16 Jul 2026 15:36:23 -0700 Subject: [PATCH] Docs: glossary of key domain concepts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit specs/product/GLOSSARY.md defines the domain language in one place — flock lifecycle (active/depleted/archived, backfill rules), the bird ledger (mortality vs cull vs adjustment, append-only corrections), daily entry states and what submit generates, grades and saleability, egg lots / FIFO allocation / withdrawal restrictions, order lifecycle, money-as-minor-units, and the cross-cutting concepts (tenancy, idempotency keys, Version tokens, operational dates). Linked from README (Specs & roadmap) and AGENTS.md (phase context) so both humans and agents find it before renaming or modeling anything. --- AGENTS.md | 2 + README.md | 4 +- specs/product/GLOSSARY.md | 130 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 specs/product/GLOSSARY.md diff --git a/AGENTS.md b/AGENTS.md index 55590c2b1..f84f4dcc9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -69,4 +69,6 @@ slow) — CI is the authority. Skip once with `--no-verify`. **Phase 1.0 (MVP) is shipped** — epic #13 closed. The egg loop runs end-to-end from the SPA: daily entry (by grade) → submit → egg lots → stock → customer → sales order → FIFO allocation → stock decremented. Single-farm login (multi-tenant infra present but dormant), customers without payments, draft orders cancellable/editable. +Domain terms (flock lifecycle, daily entry states, egg lots, grades, culls, FIFO allocation) are defined in `specs/product/GLOSSARY.md` — read it before renaming or modeling anything. + Current phase: **Phase 1.1** (epic #14, `specs/product/specs.md` §6) — RBAC UI, product catalog / egg-grade management, inventory movement ledger, feed/water/mortality, expenses, payments, dashboard, reports, audit UI, exports, i18n infrastructure (#45; English-only, translations land in 1.5). Known deferred item with an issue: farm-local timezone boundaries (#35). Work is tracked as GitHub issues (epics + slices). diff --git a/README.md b/README.md index c3d78af63..533f4da53 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,9 @@ Flock classification is extensible: `species` (chicken, duck, quail…), `produc ## Specs & roadmap -The canonical product and technical specification — data model, business rules, transaction boundaries, KPI formulas, and the **phase plan (Phase 1.0 MVP through Phase 5)** — lives in [`specs/product/specs.md`](specs/product/specs.md). Work is tracked as GitHub issues (epics + slices). +The canonical product and technical specification — data model, business rules, transaction boundaries, KPI formulas, and the **phase plan (Phase 1.0 MVP through Phase 5)** — lives in [`specs/product/specs.md`](specs/product/specs.md). New to the domain? Start with the +[**glossary of key concepts**](specs/product/GLOSSARY.md) — flocks, daily entries, egg lots, +culls, FIFO allocation, and friends. Work is tracked as GitHub issues (epics + slices). ## Contributing / agents diff --git a/specs/product/GLOSSARY.md b/specs/product/GLOSSARY.md new file mode 100644 index 000000000..dc29f7ec7 --- /dev/null +++ b/specs/product/GLOSSARY.md @@ -0,0 +1,130 @@ +# Cluckwork glossary — key concepts + +Domain concepts as the app uses them. For the full requirements see +[specs.md](./specs.md); for architecture see +[../technical/tech_spec.md](../technical/tech_spec.md). + +## Birds & flocks + +**Flock** — a group of birds managed as one unit, defined by breed and +*placement date* (the day the birds were placed in the house). Everything else +— production, mortality, sales — hangs off a flock. + +**Placement date** — when the flock entered its house. Age (shown in weeks) +counts from here; laying performance is judged against age. + +**Initial count** — birds placed on day one. Never changes with deaths; the +*bird ledger* accounts for those. + +**Current birds** — `initial count − Σ bird movements`. Computed from the +ledger, never stored. + +**Bird movement** — one row in the append-only bird ledger. Types: + +- **Mortality** — birds that died on their own. Generated automatically when a + daily entry is submitted; never entered by hand (that would double-count). +- **Cull** — birds deliberately removed alive: spent hens sold at end-of-lay, + sick birds removed to protect the flock, poor layers. Always positive. +- **Adjustment** — count correction after a recount. May be negative (adds + birds back). Corrections are always *new* rows — ledger rows are never + edited or deleted. + +**Spent hen** — a hen past her productive laying period (typically ~72–80 +weeks); usually culled and sold for meat. + +**Flock lifecycle** — `Active → Depleted → Archived` (archive is also allowed +straight from Active for mistake-created flocks): + +- **Active** — laying; accepts daily entries and movements for any date. +- **Depleted** — birds are gone. Still visible in lists and history. Accepts + *backfill* only: entries/movements dated on or before the depletion date + (the final laying days are often entered late). +- **Archived** — hidden bookkeeping. Gone from pickers and the dashboard, + visible on the Flocks screen behind a toggle; accepts nothing new. Historic + data keeps rendering its name. + +## Production + +**Daily entry** — one flock's production record for one operational day: total +eggs, loss counts (cracked / dirty / discarded), mortality count, and the +graded breakdown of sellable eggs. One entry per flock per day (natural key). + +**Daily entry lifecycle** — `Draft → Submitted → Locked`: + +- **Draft** — editable; re-saving the same flock+date updates it in place. + Nothing downstream exists yet. +- **Submitted** — the day is frozen. Submitting *generates* the downstream + facts atomically: one **egg lot** per grade line, and a **mortality + movement** if the count is > 0. Corrections after this need a manager + adjustment (future slice). +- **Locked** — closed to any change (period close; future use). + +**Sellable cap** — graded quantities must fit in +`total − cracked − dirty − discarded`. You cannot grade more eggs than +survived the day. + +## Grading & stock + +**Egg grade** — a per-farm grading bucket (spec §9.1). The seeded defaults are +sizes (Small/Medium/Large/Jumbo), qualities (Seconds/Cracked/Dirty/Soft +Shell), and custom buckets (Discarded/Internal Use), but the catalog is fully +user-managed. `gradeType` (Size/Quality/Custom) records which axis a bucket +is on and is immutable after creation. + +**Saleable** — grades flagged saleable can receive graded production and be +sold on orders. Non-saleable grades are bookkeeping buckets — losses are +captured by the daily entry's counters, not grade lines. Names are unique per +farm, case-insensitively. + +**Deactivated grade** — removed from capture and order pickers; existing +stock keeps selling until the lots drain, and history keeps resolving the +name. Grades are never hard-deleted (historic rows reference them forever). + +**Egg lot** — a batch of sellable eggs: flock + production date + grade + +quantity. Created only by submitting a daily entry. Stock is the sum of lots' +available quantities per grade. + +**FIFO allocation** — confirming a sale draws eggs from the *oldest* lots of +that grade first, under a pessimistic row lock so two sales can never +allocate the same physical eggs. + +**Withdrawal restriction** — a lot flagged `RestrictedUntil` a date (bird +medication withholding periods). Restricted quantities show in stock but are +blocked from sale until the date passes. + +## Sales + +**Customer** — name + phone required; email/address/note optional. No +payments/balances yet (later 1.1 slice). + +**Sales order lifecycle** — `Draft → Confirmed` (or `Draft → Cancelled`): +drafts are fully editable (add/edit/remove lines, cancel); **confirming** +allocates stock FIFO and is the point of no return for inventory. + +**Money** — stored as integer *minor units* plus a currency code snapshotted +from the account onto each order (JPY has 0 decimals, USD 2 — the snapshot +records that too). Totals are recalculated from lines on every mutation, +never incrementally patched. + +## Cross-cutting + +**Account** — the tenant. Every row carries `AccountId`; the API enforces +isolation with EF global query filters. Single-farm login today, multi-tenant +infrastructure dormant. + +**Farm / House** — physical hierarchy. Present as ids from day one, but real +Farm/House management arrives with later phases; the MVP runs on one seeded +farm and house. + +**Idempotency key** — every write request carries an `Idempotency-Key` +header. Retrying the same key replays the original response instead of +repeating the write — the safety net for flaky barn connectivity and the +backbone of the future offline mode (#50). + +**Version (concurrency token)** — every mutable aggregate carries a `Version` +that each mutation bumps. Two concurrent edits: first save wins, second gets +a 409 and retries against fresh state. Append-only aggregates (bird +movements) don't need one. + +**Operational day** — dates are farm-local calendar dates. For the MVP, +browser-local ≈ farm-local; true farm timezones are #35.