chore: prove backend supports mobile clients + unblock CI#8
Merged
jeanpaulsio merged 2 commits intomainfrom Apr 13, 2026
Merged
chore: prove backend supports mobile clients + unblock CI#8jeanpaulsio merged 2 commits intomainfrom
jeanpaulsio merged 2 commits intomainfrom
Conversation
- Add integration test that walks register → verify → login → Bearer call
→ refresh → Bearer call with no cookies, asserting no Set-Cookie headers
appear. Locks in the contract that the backend works for React Native /
native mobile clients, not just the Vike frontend.
- Document the client-agnostic contract in CLAUDE.md + README: backend
returns tokens in the response body, clients choose their own storage
(cookies for web SSR, SecureStore/Keychain for mobile).
- Fix CI workflow: POSTGRES_DB had literal {{APP_SLUG_UNDERSCORE}}
placeholder which GitHub Actions interpreted as expression syntax and
failed to parse. Replaced with stable 'starter_test' name and removed
ci.yml from setup.sh's substitution list.
- Fix pre-existing test_list_requires_auth assertion: HTTPBearer returns
401 for missing auth (correct HTTP semantics), not 403.
- Zustand cleanup: README claimed a Zustand auth store and a stores/
directory that don't exist. Codebase has always used React Query.
- Drive-by: ruff format fix on config.py that main had drifted on while
CI was broken.
Three issues were preventing CI from going green on the template itself
(user projects post-setup.sh were fine):
- pyproject.toml used `{{APP_SLUG}}-server` as the project name, which
isn't a valid PEP 508 identifier, so `pip install -e .` failed on CI.
Switched to a static default (`fastapi-vike-starter-server`) and moved
the slug rewrite into setup.sh.
- package-lock.json was out of sync with package.json after Sentry was
added in da77914. Regenerated.
- Prettier errors and one unused `user` binding in pages/app/+Layout.tsx
that slipped in with the React Query refactor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Locks in the contract that the backend works for React Native / native mobile clients by proving it with an integration test, and clears the pre-existing CI breakage that was hiding on main.
Why this matters: The template is about to be used for a new project with a React Native frontend. The backend already returns tokens in the response body and uses
HTTPBearerfor auth, so it should work with mobile — but nothing in the test suite actually proves that, and a regression (e.g. adding a cookie-only code path) would silently break mobile clients without failing any web tests.What's in here
Mobile-client contract
tests/integration/test_mobile_client_flow.py) walks the full flow — register → verify → login → protected call → refresh → protected call — using onlyAuthorization: Bearerheaders. Asserts no response sets aSet-Cookieheader. Also verifies that passing the access token as a cookie (with no header) fails, to prove there's no hidden cookie fallback.Authorizationheader.CI unblock (drive-by fixes)
Main CI has been red since the last backport PR. Three pre-existing bugs, all fixed here:
.github/workflows/ci.ymlhad literal{{APP_SLUG_UNDERSCORE}}_testplaceholders inPOSTGRES_DBandTEST_DATABASE_URL. GitHub Actions reads{{ }}as its own expression syntax and fails to parse the workflow. Fixed by hardcodingstarter_test(the template's own CI runs against this stable name, post-setup projects keep using it for CI since CI databases don't need to match prod names anyway). Removedci.ymlfromsetup.sh's substitution list.test_list_requires_authasserted403for an unauthenticated request. FastAPI'sHTTPBearerreturns401(correct HTTP semantics — 401 = "not authenticated", 403 = "authenticated but forbidden"). Fixed the assertion.app/config.pyhad a line-length format violation thatruff format --checkwould have caught if CI had been running. Fixed by the formatter.Zustand cleanup
README claimed a "Zustand auth store" and a
web/stores/directory — neither exists. The codebase has always used React Query (useCurrentUser()hook inweb/hooks/useAuth.ts). Fixed README and one stale reference in.claude/skills/vike-patterns.md.Test plan
ruff check app/ tests/— passesruff format --check app/ tests/— passes (after format fix)mypy app/ --ignore-missing-imports— passespytest tests/— 104 passed, coverage 92.27% (above 90% threshold)test_full_mobile_client_flow_uses_only_bearer_tokenspassestest_protected_endpoint_rejects_cookie_only_authpasses{{APP_SLUG_UNDERSCORE}}fix unblocked the workflow)