Skip to content

Make user-data template filters and pagination match HaveAPI #241

Description

@Kerrycek

Priority

P2 — searching can fail against the real API and pagination can repeat rows or open a false terminal page.

Problem

The shared user-data template list at /app/profile/user-data and /admin/users/:id/user-data does not match VpsUserData::Index:

  • WebUI sends vps_user_data[q], but the upstream Index declares and applies only user and format plus the inherited limit and from_id controls.
  • WebUI derives Next with cursorFromDescendingPage (the minimum visible ID), while upstream with_pagination is ascending and its resource spec requires every returned ID to be greater than from_id.
  • WebUI requests exactly the visible limit and treats every full page as non-terminal, so an exact final page exposes a false Next action.
  • The current Playwright mock invents server-side q, sorts descending, and ignores the real cursor/limit contract, masking all three defects.

At origin/main commit 23c71925c9d7ec314534201396ade99bd904c936, the affected code is src/components/user/UserDataTemplatesPanel.tsx, src/lib/api/vpsUserData.ts, and e2e/specs/app/profile_user_data.spec.ts. The authoritative contract is in upstream api/lib/vpsadmin/api/resources/vps_user_data.rb and api/spec/api/resources/vps_user_data_spec.rb.

Legacy UI purpose is preserved: list templates for the signed-in owner or exact administrator-selected user, filter by the supported user scope, and manage create/edit/deploy/delete actions. It never sends a label-search parameter.

Required frontend resolution

  1. Send only supported Index parameters to HaveAPI.
  2. Preserve label/#ID search without inventing q, using a bounded ascending client-side scan that retains exact user and format scope and fails explicitly if completeness cannot be established.
  3. Request one lookahead match, render only the selected page size, and derive continuation from the greatest valid visible ID.
  4. Rebuild forward edges from fresh data, hide stale descendants, and recover safely if deleting a template empties a cursor page.
  5. Keep URL filter/history state, member/admin scope, responsive behavior, and all existing mutations unchanged.
  6. Replace the permissive mock with the real id > from_id, ascending, bounded contract.

Acceptance criteria

  • No request contains vps_user_data[q].
  • Label and #ID search can find a match beyond the first raw API batch while retaining user/format scope.
  • Traversing pages returns no repeated visible IDs under the documented ascending contract.
  • Lookahead rows never leak into the table or local search.
  • An exact terminal page has Next disabled.
  • Member and administrator user routes are covered on desktop and mobile.
  • Tests perform no live mutation.

Residual upstream risk

VpsUserData::Index does not explicitly order by ID even though its cursor predicate and spec are ascending. The frontend will use the only cursor compatible with id > from_id; the broader deterministic-order guarantee remains an upstream concern tracked in #189.

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

    ai-prCodex opened a pull requestbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions