Skip to content

Five screens silently truncate the flock list at 100, ordered by name #509

Description

@mforce

What happens

GET /flocks returns the first 100 flocks ordered by name (DefaultPageSize = 100, MaxPageSize = 500 in src/Cluckwork.Api/Endpoints/Flocks/FlockEndpoints.cs:17-18; OrderBy(f => f.Name).ThenBy(f => f.Id) then Skip/Take in FlockRepository.ListAsync).

Five screens call listFlocks() without a limit and render the result straight into a control with no paging:

Screen Call Archived counted?
DailyEntryPage.tsx:124, :401 listFlocks() no
HistoryPage.tsx:121 listFlocks({ includeArchived: true }) yes
FeedPage.tsx:96 listFlocks({ includeArchived: true }) yes
WaterPage.tsx:101 listFlocks({ includeArchived: true }) yes
UsersPage.tsx:166 listFlocks() no

Three others already raise it to the maximum, which is what makes this look like an oversight rather than a decision:

  • FlocksPage.tsx:93 — limit: 500
  • ExpensesPage.tsx:158 — limit: 500
  • Dashboard.tsx:48 — limit: MAX_PAGE (500)

Why it matters

A farm with more than 100 flocks (or more than 100 including archived, on the three screens that ask for those) cannot record a daily entry for the flocks that fall outside the first page. The affected flock is simply absent from the dropdown — no message, no "showing 100 of N", nothing to distinguish it from a flock that does not exist.

Which flocks disappear is alphabetical, not recent-or-old, so it will not look like a paging problem to whoever hits it. A farm that names flocks Barn A…/Barn B… loses the end of the alphabet.

The includeArchived: true screens are the more likely to bite first: archived flocks accumulate permanently and are never cleaned up, so the 100 fills with history.

How this surfaced

Not from a farm — from the E2E suite. manager.spec.ts creates a flock per run named E2E …; they cluster alphabetically and the newest sorts last, so it is the first one truncated. After ~100 accumulated runs the spec could no longer find the flock it had just created, and the failure read as a bare Expected 1, Received 0 on an unrelated-looking assertion. PR #504 added a diagnostic message pointing at reset.sh; this issue is the product half, which that PR deliberately did not touch.

Options

  1. Pass limit: 500 on the five screens, matching the three that already do. Smallest change, consistent with existing practice, still a silent cliff at 500.
  2. Make the cliff visible — if the response fills the page, say so next to the control ("showing the first 100 flocks"). Cheap, and turns a silent wrong answer into a visible limitation.
  3. Make the pickers searchable/paged. Correct, and considerably more work; probably only worth it if a real farm approaches these numbers.

1 + 2 together seem like the honest minimum: it removes the realistic case and stops the remaining one being silent.

Not verified

I have not confirmed what a real farm's flock count looks like, so I cannot say whether 100 is close to reachable in practice or purely theoretical. If it is theoretical, option 2 alone may be enough. The mechanism above is read from the code and confirmed by the E2E failure; the impact estimate is not measured.

Implementation order

This issue is not a separate implementation step. Its picker defects are covered by #512.

  1. Implement Page truncated customer and movement tables with the shared usePagedList hook #511 first: adopt the existing usePagedList hook for the truncated customer and movement tables/ledgers.
  2. Implement Add a reusable searchable paged entity picker for flock and customer selectors #512 second: add and adopt the reusable searchable paged entity picker.
  3. The Add a reusable searchable paged entity picker for flock and customer selectors #512 implementation PR should close both Add a reusable searchable paged entity picker for flock and customer selectors #512 and this issue.

Do not land the temporary limit: 500 workaround from the options above as an intermediate step unless this order is explicitly reprioritized; #512 replaces that workaround with full reachability.

Related issues

Simulation coverage

The durable regression fixture for this defect belongs to #512, not to a separate implementation here. #512 must extend the simulation seed beyond the flock page boundary and exercise a deterministic late-sorting flock through the real picker. The fixture must update the simulation manifest's exact expected counts/fingerprint and remain idempotent and fail-closed.

Activity

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

    area:frontendReact/Vite web clientepic-1.5severity:p2Defect: user-visible wrong behaviour, no data loss

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions