You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Daily entry: require grading to reconcile sellable eggs before submit #394
A Daily Entry can be submitted when its grade lines total less than its sellable eggs, including no grade lines at all. For example, a 200-egg entry with no losses and no grading can be submitted successfully.
Impact
Submission freezes the entry and creates egg lots only from grade lines. An ungraded 200-egg submission therefore creates zero stock, leaving recorded production that cannot be sold or reconciled through the intended Phase 1 grades-at-collection flow.
Agreed behaviour
Draft Daily Entries may be incomplete or ungraded.
Save & submit requires grades to equal sellable eggs: totalEggs - crackedEggs - dirtyEggs - discardedEggs.
Zero sellable eggs validly reconcile to zero grade lines.
Adjustments have no draft state, so saving an adjustment requires the same exact reconciliation.
UI and domain/API must enforce the invariant.
Adjust screen
Reshape the adjustment dialog to mirror Daily Entry: adjacent Egg counts and Grading panes, sellable calculation, remaining/day-adds-up status, and the same numeric controls. Retain the prior-adjustment context and required reason.
Acceptance criteria
The Daily Entry submit control is disabled until grading exactly reconciles.
Direct API callers cannot submit an ungraded or partially graded non-zero-sellable entry.
Adjustment save is disabled until grading exactly reconciles, and direct API callers cannot bypass it.
The adjustment dialog uses Daily Entry’s counts/grading visual hierarchy and feedback.
Regression tests cover no grades, partial grades, exact reconciliation, and a zero-sellable day.
Update the Help page and specs/product/GLOSSARY.md in the same change, per AGENTS.md docs-sync rule.
#396 changes the meaning of the #394 reconciliation rule without weakening it:
Drafts remain flexible.
On submit or adjustment, manual grades must exactly equal total - cracked - dirty - discarded.
Cracked and Dirty will have explicit, rename-safe quality-grade identities. When their snapshotted grade is saleable, the counter creates a separate quality lot; when it is not, it remains a loss. Discarded stays a loss.
The default Cracked and Dirty grades are saleable on fresh installs; existing farms and historic entries are not silently reclassified.
Products mapped to those grades carry independently configured default prices; no fixed discount is imposed.
The implementation must also satisfy #395 by updating every non-CI writer and fixture that posts Daily Entries. The documentation PR contains the full design and execution plan.
Activity
mforce commentedon Aug 2, 2026
Design update: saleable quality eggs (#396)
#396 changes the meaning of the #394 reconciliation rule without weakening it:
total - cracked - dirty - discarded.The implementation must also satisfy #395 by updating every non-CI writer and fixture that posts Daily Entries. The documentation PR contains the full design and execution plan.
docs: keep the quality-egg glossary entries with the PR that ships them
fix(help): correct grade-reconciliation copy on the Help page (#394)
docs(agents): require write-contract changes to update the non-CI wri…
docs: close Codex review gaps in the quality-egg reconciliation design
fix(daily-entry): require exact grade reconciliation on submit and ad…
feat(daily-entry): refuse a condition grade named as a manual line (#396
feat(history): adjust modal mirrors the daily-entry two-step form (#403)
feat(reports): report eggs that became stock without being hand-graded (
feat(daily-entry): refuse a condition grade named as a manual line (#396
feat(reports): report eggs that became stock without being hand-graded (
feat(seed): mint and sell condition lots in the demo and simulation f…
feat(eggs): make cracked and dirty eggs sellable stock via condition …
Daily Entry: let grade counts run ahead of the total instead of cappi…
Sales: name the unit at quantity entry — label, live egg-count previe…
fix(auth): attribute every session action to the farm that owns it
feat!: log in by farm code, with per-account email identity (#532) (#564
fix(sim): filter k6 sales bundle to priced products (#394)
feat(sales): require a discount reason when confirming a below-list o…
feat(sales): refuse an over-ceiling confirm from a Sales user (#727) (#…
docs(agents): the Playwright specs have been in CI since 2026-08-08 (#…
fix(dashboard): give recent sales real columns and make both charts r…
fix(dashboard): tell a day with no entry from a day that laid no eggs (…
feat(sim): seed a second farm for the README dashboard capture (#867)