Skip to content

feat(frontend): adopt backend v0.7.0 cursor API with TanStack Query - #7

Merged
truehazker merged 10 commits into
mainfrom
feature/frontend-v0.6.0-react-query
Jun 20, 2026
Merged

feat(frontend): adopt backend v0.7.0 cursor API with TanStack Query#7
truehazker merged 10 commits into
mainfrom
feature/frontend-v0.6.0-react-query

Conversation

@truehazker

@truehazker truehazker commented Jun 20, 2026

Copy link
Copy Markdown
Owner

Summary

Updates the monorepo template to the tagged backend release v0.7.0 and migrates its frontend to the new API contract, modernising data fetching with TanStack Query.

  • Backend submodule → v0.7.0 (tagged release 007a897). Breaking API changes vs the prior pin: GET /users moved from offset/total to cursor pagination ({ limit, cursor }{ users, nextCursor }); POST /users now returns 409 { message } on email conflict (was 422 string).
  • Frontend migrated to the new contract and rebuilt around @tanstack/react-query:
    • List uses useInfiniteQuery (infiniteQueryOptions in features/users/queries.ts) with a Load more button (fetchNextPage/hasNextPage).
    • Create form handles the 409 { message } error and refreshes the list via queryClient.invalidateQueries.
    • QueryClientProvider added with sane defaults (staleTime, retry, refetchOnWindowFocus).
    • Already-loaded users stay visible on refetch/next-page errors (error shown inline); create-form error announced via role="alert". error.value read with optional chaining.
  • Dependencies upgraded. Added elysia as a direct dep so eden resolves the backend's exact version (dedupe → single elysia@1.4.29), upgraded all frontend deps, and bumped Biome config to 2.5.0.
  • Tooling. tsconfig maps backend src/* so Eden infers the App type; Vitest config merged into vite.config.ts; router ignores *.test.tsx files.

Test plan

  • bunx tsc --noEmit — 0 errors
  • bunx vitest run — 7/7 passing (list, pagination, empty, initial-load error, next-page error, create conflict, submit payload)
  • bunx biome check . — clean
  • bun run build — succeeds, dist/ emitted
  • Manual full-stack run (Docker Postgres + backend + frontend bun run dev): create user, cursor pagination, 409 conflict, list refresh after create
  • Independent reviews: Codex production-readiness audit (ready) + official TanStack Query / Eden docs comparison (patterns idiomatic)

Notes

  • CodeRabbit triage: the submodule is now pinned to the tagged v0.7.0 release (was main HEAD). The Vitest-related comments are not actionable — the scaffolded frontend is intentionally a Vite + React + TanStack Router app; the repo's bun test/"no vite" guidance applies to the create-ely CLI tool, not the generated template (Vitest pre-existed; only the version was bumped).
  • templates.zip is gitignored and regenerated from the pinned submodule at publish time, so only the submodule pointer is committed.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added infinite pagination for the users list with a “Load more” button.
  • Bug Fixes
    • Users list now refreshes after creating a new user by invalidating cached results.
    • Improved user-creation failure messaging and alert semantics.
  • Tests
    • Added Vitest + React Testing Library coverage for /users and /users/new, including pagination and error/empty states.
  • Chores
    • Updated tooling/configuration (React Query defaults, router trailing-slash pathing, schema/version pins, test runner setup) and improved template packaging to exclude unwanted files.

truehazker and others added 3 commits January 4, 2026 19:34
Point the monorepo template's backend submodule at elysia-boilerplate
v0.6.0 (264a2b7). The users API changed in a breaking way: GET /users
moved from offset/total to cursor pagination ({ limit, cursor } ->
{ users, nextCursor }), and POST /users now returns 409 with a { message }
body on email conflict (was 422 with a string).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Migrate the monorepo template frontend to the backend v0.6.0 contract and
upgrade its dependencies.

- Replace offset/total list loading with cursor pagination via TanStack
  Query's useInfiniteQuery (infiniteQueryOptions in features/users/queries.ts);
  "Load more" uses fetchNextPage/hasNextPage.
- Handle the new 409 { message } conflict error in the create form.
- Refresh the list after create with queryClient.invalidateQueries.
- Add QueryClientProvider with sane defaults (staleTime, retry,
  refetchOnWindowFocus).
- Keep already-loaded users visible on refetch/next-page errors, surface the
  error inline, and announce the create-form error via role="alert".
- Add elysia as a direct dependency so eden resolves the backend's version
  (dedupe), upgrade all frontend deps, and bump Biome config to 2.5.0.
- Map backend src/* in tsconfig so Eden can infer the App type; merge the
  Vitest config into vite.config.ts; ignore test files in the router plugin.
- Add component tests: list render, pagination, empty state, initial-load and
  next-page errors, create conflict, and submit payload.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 579027fc-8063-4ccf-9f5f-e80279dcc3fb

📥 Commits

Reviewing files that changed from the base of the PR and between 2177ccf and 692b7e8.

📒 Files selected for processing (3)
  • scripts/prepare.ts
  • templates/monorepo/apps/frontend/src/routes/users/index.tsx
  • templates/monorepo/apps/frontend/src/routes/users/new.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/prepare.ts
  • templates/monorepo/apps/frontend/src/routes/users/new.tsx

📝 Walkthrough

Walkthrough

The monorepo frontend template gains React Query with infinite cursor-based pagination for the users list. A QueryClient is bootstrapped with custom defaults in main.tsx, a new usersQueryOptions module defines the infinite query with pagination, the users list route is refactored from a loader to useInfiniteQuery, the new-user route invalidates the cache on success, Vitest is configured with jsdom, a comprehensive test suite is added, Biome is bumped to 2.5.0, and the template archive build excludes unnecessary directories.

Changes

React Query Infinite Pagination Feature

Layer / File(s) Summary
React Query bootstrap and dependency wiring
templates/monorepo/apps/frontend/package.json, templates/monorepo/apps/frontend/tsconfig.json, templates/monorepo/apps/frontend/src/main.tsx
Bumps frontend dependencies including React Query packages, extends tsconfig with a src/* backend path alias, adds QueryClient/QueryClientProvider imports, instantiates a client with staleTime: 60s, retry: 1, and disabled refetchOnWindowFocus, and wraps RouterProvider inside QueryClientProvider.
Infinite query options and route tree update
templates/monorepo/apps/frontend/src/features/users/queries.ts, templates/monorepo/apps/frontend/src/routeTree.gen.ts
Exports usersQueryOptions using infiniteQueryOptions with a fixed PAGE_SIZE, a cursor-based fetchUsers function, and getNextPageParam deriving pagination from nextCursor. Updates the generated route tree to use /users/ (trailing slash) for the users index route.
Users list route refactored to infinite query
templates/monorepo/apps/frontend/src/routes/users/index.tsx
Replaces loader-based fetching with useInfiniteQuery(usersQueryOptions), flattens data.pages into a users array, adds explicit pending/error/empty conditional rendering, updates the displayed count, and adds a "Load more" button with isFetchingNextPage state and inline error display.
New user route: cache invalidation and error handling
templates/monorepo/apps/frontend/src/routes/users/new.tsx
Adds useQueryClient hook, invalidates usersQueryOptions.queryKey on successful creation, derives the error message from apiError.value?.message with a 'Failed to create user' fallback, and adds role="alert" to the error container.
Vitest configuration and users route test suite
templates/monorepo/apps/frontend/vite.config.ts, templates/monorepo/apps/frontend/src/routes/users/users.test.tsx
Adds vitest/config reference, configures jsdom environment, and adds routeFileIgnorePattern to exclude test files from the router. Adds a test suite covering list initial render, Load More pagination with cursor API calls, empty state, error state, next-page failure retention, 409 conflict display, and create form submission.

Tooling Updates

Layer / File(s) Summary
Biome 2.5.0 upgrade and backend submodule advance
templates/monorepo/apps/frontend/biome.json, templates/monorepo/biome.json, templates/monorepo/package.json, templates/monorepo/apps/backend
Advances the backend submodule commit hash, updates $schema URLs in both biome.json files from 2.3.10 to 2.5.0, and bumps @biomejs/biome devDependency to 2.5.0.

Build Artifact Filtering

Layer / File(s) Summary
Template archive filtering
scripts/prepare.ts
Adds path filtering to the template archive creation to exclude node_modules, dist, .git/, and .env entries.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 Hoppity hop, the queries now stream,
Pages of users unfurl like a dream.
"Load more!" I click with a wiggle of ears,
The cursor scrolls on and new data appears.
Cache invalidated, the list stays in sync—
This bunny approves in the blink of a wink! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: adopting backend v0.7.0's cursor-based pagination API with TanStack Query integration across the frontend.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/frontend-v0.6.0-react-query

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@templates/monorepo/apps/backend`:
- Line 1: The backend submodule in templates/monorepo/apps/backend is pinned to
an incorrect commit (264a2b7b) that contains rate-limiting refactoring changes
dated after the v0.6.0 release. Update the submodule commit reference to
e5094c8e5d8c717d7db9faec54d5ac61af8edeb5, which is the actual v0.6.0 release
tag. This ensures the frontend changes in this PR, which depend on the v0.6.0
API contract including cursor-based pagination and 409 conflict responses, will
work correctly with the backend.

In `@templates/monorepo/apps/frontend/package.json`:
- Line 49: Remove the vitest dependency from devDependencies in the package.json
file (the line containing "vitest": "^4.1.9"). Next, remove or update any vitest
configuration files if they exist (such as vitest.config.ts or vitest
configuration in package.json). Finally, update the test scripts in package.json
to use "bun test" instead of vitest commands, ensuring all test files matching
the pattern **/*.test.{ts,tsx,js,jsx} will be executed using Bun's built-in test
runner as per the coding guidelines.

In `@templates/monorepo/apps/frontend/src/features/users/queries.ts`:
- Around line 10-12: In the error handling block where you check if error
exists, the `error.value.message` access is unsafe because `error.value` is
typed as `unknown`. Replace the direct property access with optional chaining by
changing `error.value.message` to `error.value?.message` to safely handle cases
where the value is undefined, null, or lacks a message property.

In `@templates/monorepo/apps/frontend/src/routes/users/users.test.tsx`:
- Around line 1-20: The test file in users.test.tsx is currently importing test
utilities from vitest (specifically describe, expect, it, vi, afterEach, and
beforeEach) which violates the coding guidelines that require using Bun's
built-in test runner. Replace the vitest import statement with Bun's test API
imports, which provides Jest-compatible functionality. Update all references
from vitest imports to use Bun's test utilities instead, ensuring that vi.mock
and vi.fn calls are replaced with their Bun equivalents for mocking
functionality.

In `@templates/monorepo/apps/frontend/vite.config.ts`:
- Line 6: The vite.config.ts file violates coding guidelines by importing from
'vitest/config' and using Vitest for test configuration instead of bun test.
Replace the import statement that references 'vitest/config' with configuration
appropriate for bun test, and remove or update all Vitest-specific test
configuration in the file (including the sections around lines 28-30) to align
with the guideline requiring bun test for all test files. The entire Vite-based
setup should be reconsidered in favor of using Bun.serve() with HTML imports and
bun build for frontend bundling as specified in the coding guidelines.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c109b415-b260-4e9c-a45a-fa60b5bc98a9

📥 Commits

Reviewing files that changed from the base of the PR and between ea949d7 and 37b191f.

⛔ Files ignored due to path filters (1)
  • templates/monorepo/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • templates/monorepo/apps/backend
  • templates/monorepo/apps/frontend/biome.json
  • templates/monorepo/apps/frontend/package.json
  • templates/monorepo/apps/frontend/src/features/users/queries.ts
  • templates/monorepo/apps/frontend/src/main.tsx
  • templates/monorepo/apps/frontend/src/routeTree.gen.ts
  • templates/monorepo/apps/frontend/src/routes/users/index.tsx
  • templates/monorepo/apps/frontend/src/routes/users/new.tsx
  • templates/monorepo/apps/frontend/src/routes/users/users.test.tsx
  • templates/monorepo/apps/frontend/tsconfig.json
  • templates/monorepo/apps/frontend/vite.config.ts
  • templates/monorepo/biome.json
  • templates/monorepo/package.json

Comment thread templates/monorepo/apps/backend Outdated
Comment thread templates/monorepo/apps/frontend/package.json
Comment thread templates/monorepo/apps/frontend/src/features/users/queries.ts
Comment thread templates/monorepo/apps/frontend/src/routes/users/users.test.tsx
Comment thread templates/monorepo/apps/frontend/vite.config.ts Outdated
truehazker and others added 2 commits June 20, 2026 19:24
Re-pin the backend submodule from main HEAD (264a2b7, an untagged commit one
past v0.6.0) to the tagged v0.7.0 release (007a897). v0.7.0 is identical in
code to the previously pinned commit — only the version bump and changelog
differ — so the frontend contract (cursor pagination, 409 conflict) is
unchanged. Pinning a tagged release instead of a moving main commit keeps the
template reproducible.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Use optional chaining (error.value?.message) in the users query and create
form. Eden's error.value can be absent for some non-2xx responses, so the
?? fallback now applies instead of throwing on a property access.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@truehazker truehazker changed the title feat(frontend): adopt backend v0.6.0 cursor API with TanStack Query feat(frontend): adopt backend v0.7.0 cursor API with TanStack Query Jun 20, 2026
truehazker and others added 4 commits June 20, 2026 20:21
Import defineConfig from 'vite' and add a /// <reference types="vitest/config" />
directive instead of importing defineConfig from 'vitest/config'. This keeps the
single shared config (tests run through the same plugins/aliases as the build)
while the build config imports only from vite — the test-field typing now comes
from a compile-time type reference with no runtime vitest value import. This is
the form documented by Vitest for existing Vite projects.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The prepare script zipped the entire templates/ tree, so running it from a
working copy that had installed template dependencies (or a built frontend, or
a local .env) would bundle those artifacts into the published archive. Add a
filter to addLocalFolder that skips node_modules, dist, .git, and .env, so the
shipped templates.zip is correct and minimal regardless of local state, while
still preserving .gitignore / .env.example files.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Biome (2.3.10 in CI) wraps the long exclusion-regex assignment onto its own line. Apply the formatter so 'biome ci .' passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the singular/plural user-count label with a generic "items"
string in the users list template. Drops the conditional pluralization
in favor of a simpler, reusable label for the monorepo frontend template.

Co-Authored-By: Skrrt Bot <bot@skrrt.sh>
@truehazker

Copy link
Copy Markdown
Owner Author

@coderabbitai is this pr ready to be merged?

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

REPO="truehazker/create-ely"
PR=7

echo "=== PR Status ==="
gh pr view $PR --repo $REPO --json state,mergeable,mergeStateStatus,reviewDecision,checksUrl,title,isDraft,reviews,statusCheckRollup

echo ""
echo "=== Open Review Comments (unresolved) ==="
gh api graphql -F owner="truehazker" -F name="create-ely" -F pr=$PR -f query='
query($owner: String!, $name: String!, $pr: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $pr) {
      reviewThreads(first: 50) {
        nodes {
          isResolved
          isOutdated
          comments(first: 1) {
            nodes {
              author { login }
              body
              path
              line
            }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false and .isOutdated == false) | {path: .comments.nodes[0].path, line: .comments.nodes[0].line, author: .comments.nodes[0].author.login, body: (.comments.nodes[0].body | .[0:100])}'

echo ""
echo "=== CI Checks ==="
gh pr checks $PR --repo $REPO

Length of output: 2033


🏁 Script executed:

#!/bin/bash
set -euo pipefail

REPO="truehazker/create-ely"
PR=7

echo "=== PR Status ==="
gh pr view $PR --repo $REPO --json state,mergeable,mergeStateStatus,reviewDecision,title,isDraft,reviews,statusCheckRollup

echo ""
echo "=== Open Review Comments (unresolved) ==="
gh api graphql -F owner="truehazker" -F name="create-ely" -F pr=$PR -f query='
query($owner: String!, $name: String!, $pr: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $pr) {
      reviewThreads(first: 50) {
        nodes {
          isResolved
          isOutdated
          comments(first: 1) {
            nodes {
              author { login }
              body
              path
              line
            }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false and .isOutdated == false) | {path: .comments.nodes[0].path, line: .comments.nodes[0].line, author: .comments.nodes[0].author.login, body: (.comments.nodes[0].body | .[0:100])}'

echo ""
echo "=== CI Checks ==="
gh pr checks $PR --repo $REPO

Length of output: 10016



@truehazker Here's the current status of #7:

Check Status
Merge conflicts ✅ None
CI — Lint Check ✅ Passing
CI — CodeRabbit ✅ Passing
Unresolved review threads ✅ None
Approving review ❌ Required (blocking merge)

The only blocker is that the branch protection rule requires at least one approving review. Everything else looks good. Would you like me to approve the PR?

The bundled @types/react now flags `React.FormEvent` as deprecated
(TS6385) in favor of event-specific types. The user-create form's
onSubmit handler is typed `SubmitEventHandler`, so switch its parameter
to `React.SubmitEvent<HTMLFormElement>`. `React.ChangeEvent` is not
deprecated and is left unchanged.

Clears the only TS6385 suggestion diagnostic in the scaffold; tsc and
biome remain clean across frontend, backend, and CLI.

Co-Authored-By: Skrrt Bot <bot@skrrt.sh>
@truehazker
truehazker changed the base branch from develop to main June 20, 2026 20:26
@truehazker
truehazker merged commit 8a5c5f3 into main Jun 20, 2026
2 checks passed
@truehazker
truehazker deleted the feature/frontend-v0.6.0-react-query branch June 20, 2026 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant