← all branches

feat/select-all

needs attention
faa43ee · incrementalPR #281reviewed 2026-07-09 01:11 UTC1H · 7M · 8L · 5I
The branch
Purpose
Add Gmail-style select-all-matching bulk selection to the Contratos table so batch actions can target the entire filtered set beyond the 25-row page.
Goal
PR #281: feat(contratos): Gmail-style select-all-matching bulk selection
Sub-goals
  • SG-1: New GET /utility-contracts/keys endpoint + domain query (shares buildFullWhere with list)
  • SG-2: Client-side materialized key set with epoch guard + selection lifecycle
  • SG-3: BulkActionBar with persistent batch-result panel (grouped errors, narrow-to-failed, retry)
  • SG-4: Fix pre-existing double-parse z.default() bug (serviceName schema) + regression test
  • SG-5: Codify double-parse and select-all patterns in .claude/rules/
The changes (whole branch)
What
This commit (faa43eeb) adds documentation only — one bullet to api-patterns.md and one section to ui-patterns.md — codifying patterns discovered during implementation. The feature itself was in prior commits reviewed at af91420f.
Why
Persistent pattern capture so the double-parse z.default() hazard and Gmail-style selection architecture are available to future developers.
Areas
.claude/rules+390apps/platform/api+12812apps/platform/BulkActionBar+70698apps/platform/contratos+2664apps/platform/messages+500domains/utility+1471packages/api+1012packages/analytics+110
Blast
21 files, +1510/−118 across platform UI, API, domains, analytics, and .claude/rules. This commit is docs-only (+39/−0).
docs-only-commit rules-pattern-capture
ci· check-runs API not accessible from this tokencoderabbit· no .coderabbit.yaml in repo

Findings · 21

correctness1

medium

Double-parse scope 'internal routes' is ambiguous — applies to all ts-rest handlers with validateInput

.claude/rules/api-patterns.md

Readers interpret 'internal' as /api/internal/*. The hazard fires on any ts-rest handler that re-validates with validateInput after the contract parse.

security4

medium

Keys endpoint docs omit role-floor requirement — any member can enumerate all RPU + address data

.claude/rules/ui-patterns.md

contractNumber (CFE RPU) and serviceName (address) are real-world sensitive identifiers returned up to 500/call. Doc must require the keys route carry the same role floor as the most-privileged action it feeds.

low

Cap bypass via sequential filtered calls

.claude/rules/ui-patterns.md

Cap is a UX rail, not a security ceiling. Doc should acknowledge or call out rate-limiting.

low

Sentinel-union fix may be misapplied to security-sensitive fields

.claude/rules/api-patterns.md

Add caveat for API keys/public IDs: prefer truly optional over present-but-empty sentinel.

info

Epoch guard has dual security property (confused-deputy prevention)

.claude/rules/ui-patterns.md

conventions4

low

PR reference format inconsistency — other bullets use 'PR-5 SG-N' not '#281'

.claude/rules/api-patterns.md

low

'imported by the schema' is misleading — CFE_BATCH_MAX_RECORDS is defined IN the schema file

.claude/rules/ui-patterns.md

low

'product-ux P10' is an opaque reference with no file path

.claude/rules/ui-patterns.md

info

Epoch guard not cross-referenced to Realtime list pages section

.claude/rules/ui-patterns.md

tests6

medium

Epoch guard stale-response discard path has no unit test

apps/platform/src/app/[locale]/(dashboard)/bills/contratos/page.tsx:546

Filter-change-mid-flight → epoch-mismatch → discard is a key invariant with zero coverage. The 5 existing test files skip page orchestration logic.

medium

Truncation-rejection path (total > keys.length → throw) is not tested

apps/platform/src/app/[locale]/(dashboard)/bills/contratos/page.tsx:552

BulkActionBar overCap test covers render-time matchingTotal > cap, not the runtime total > keys.length concurrent-write case.

low

Doc says 'abort' but implementation discards — terminology mismatch

.claude/rules/ui-patterns.md

low

Shared cap constant not verified by a cross-import test

packages/api/src/schemas/cfe-job.schemas.ts

info

Double-parse regression test exists and matches the prescribed pattern

packages/api/src/__tests__/schemas/cfe-job.schemas.test.ts

info

BulkActionBar batch-outcomes coverage is solid

apps/platform/src/app/[locale]/(dashboard)/bills/_components/__tests__/BulkActionBar.test.tsx

improvement6

high

api-patterns double-parse bullet: five actionable points in one run-on sentence

.claude/rules/api-patterns.md

Every adjacent Anti-Patterns bullet uses bold-lead + example + fix structure. Five points crammed into one sentence; split for scannability.

medium

BAT-267 forward reference couples a stable rule doc to a point-in-time backlog ticket

.claude/rules/api-patterns.md

Replace with actionable instruction or drop — tracking tickets in rule files go stale.

medium

selection-lifecycle 'or' clause reads as two alternatives, not bug-vs-guard

.claude/rules/ui-patterns.md

Second clause is the bug the guard prevents. Rephrase: '...discard it — otherwise a mid-flight filter change would silently resurrect a stale selection.'

medium

Keys endpoint contract rules belong in api-patterns.md, not only ui-patterns.md

.claude/rules/ui-patterns.md

A developer writing a new keys endpoint looks in api-patterns.md first and misses count(*) OVER () vs separate count() correctness rule.

low

Row-meta REFRESH rule lacks test reference or observable symptom

.claude/rules/ui-patterns.md

low

Shared-caps bullet too abstract — naming CFE_BATCH_MAX_RECORDS gives a grep target

.claude/rules/ui-patterns.md

History · 3 commits

  1. faa43eeneeds attentionincremental1H · 7M · 8L2026-07-09 01:11current
  2. af91420needs attentionincremental0H · 8M · 10L2026-07-08 23:28
  3. b21721dneeds attentionfull7H · 6M · 8L2026-07-08 19:03