Skip to content

F15: Feed inventory + feed usage #66

Description

@mforce

Part of Phase 1.1 (epic #14). Spec §12.1–12.4, §6 Phase 1.1 list ("Feed inventory and feed usage").

Scope

Inventory foundation (general, feed-first):

  • InventoryItem — name, category (spec enum: feed/supplement/additive/medication/…/other), unit, default cost, active flag. CRUD + list; Version token per AGENTS.md.
  • InventoryLot — receipt of stock: item, received date, quantity received/available, unit cost, optional lot number/expiry. Recording a purchase creates the lot + a purchase movement.
  • InventoryMovement — append-only ledger (BirdMovement pattern: repo seam rejects Update/Remove): purchase / usage / adjustment / discard, quantity delta, optional flock ref, reason. Current stock per item = Σ deltas (or lot quantity_available sum, single source of truth — pick one and enforce).

Feed usage:

  • FeedUsage — date, flock, item, optional lot, quantity, unit, optional note; saving generates a usage movement and decrements lot availability (FIFO by received date when no lot chosen, mirroring egg-lot allocation locking).
  • Estimated cost from lot cost (costing_method lot_cost; other methods later).
  • Optional link to the day's daily entry (daily_entry_id nullable — full daily-entry capture integration can follow later; standalone recording first).

SPA: Feed & Inventory screen — items CRUD, record purchase, record usage, current stock per item, movement history per item. Responsive per #49 patterns.

Out of scope (later slices)

  • Medication/vaccine/withdrawal logic (§13), suppliers, transfers, reconciliation, expiry alerts, average/manual costing, water (separate: see water-usage issue), FCR reports (§19).

Acceptance

  • Purchase 500 kg feed → stock 500; record usage 20 kg for a flock → stock 480, usage movement + cost recorded; lot never goes negative (guarded like EggLot.Allocate, race-tested with Version delta assertions).
  • Usage against a depleted/archived flock blocked consistently with CanRecordProductionOn semantics.

Activity

  1. mforce commented on Jul 18, 2026

    @mforce
    OwnerAuthor

    Scope decision (2026-07-17): purchase corrections land in part 2 (with feed usage), confirmed with the owner.

    Part 1 (PR #68) ships purchases immutable — no lot edit/delete, ledger append-only. Part 2 adds the correction path:

    • POST /inventory/items/{id}/adjustments — signed quantity against a specific lot (or unallocated pool), reason required. Negative adjustment cannot take a lot below what's already been consumed (guarded under the same FOR UPDATE lock as usage).
    • Discard variant for spoiled/written-off stock.
    • A typo'd purchase is corrected by a compensating negative adjustment — original Purchase row and correction both stay visible in the ledger (append-only preserved, spec §12.3).

    Part 2 full scope: FeedUsage records (flock + optional daily-entry link), FIFO lot consumption via InventoryLot.Consume under canonical locking, Usage ledger movements with estimated cost from lot costs, adjustment/discard endpoints as above, flock lifecycle gating, SPA usage + adjustment forms, race tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions