Skip to content

feat(api): call WolfStar bot API via $api (legacy-style)#303

Draft
RedStar071 wants to merge 16 commits into
mainfrom
cursor/backport-structure-api-88be
Draft

feat(api): call WolfStar bot API via $api (legacy-style)#303
RedStar071 wants to merge 16 commits into
mainfrom
cursor/backport-structure-api-88be

Conversation

@RedStar071

@RedStar071 RedStar071 commented Jul 17, 2026

Copy link
Copy Markdown
Member

Summary

Restores legacy-style bot API access: $api calls NUXT_PUBLIC_API_BASE_URL (https://api.wolfstar.rocks) directly with credentials: "include", like the old apiFetch on the legacy branch.

Changes

  • app/plugins/api.ts — always uses apiBaseUrl (no /api/bot client prefix); reads private discord.clientSecret only on the server; loads sapphire cookie helpers via dynamic server import
  • Bot API crypto helpers live in server/utils/botApi (not #shared) so node:crypto stays out of the client bundle; types remain in #shared/types/botApi
  • SSR attaches a sapphire SAPPHIRE_AUTH cookie via $authorization when a Discord session exists
  • Dashboard / composables keep bot paths (/commands, /guilds/:id, /audit-logs, …)
  • Local Nuxt routes remain for users, auth, moderation logs, and Discord REST guild helpers
  • Runtime payload cache (npmx-style): serialize SSR payload once and serve /_payload.json from cache for public ISR/cache routes
  • SSR cachedFetch keys include resolved host (baseURL), query, and auth headers so authenticated guild responses cannot cross users/filters
  • CommandSubCategory accordion markup fixed (no nested buttons / unnamed regions) so prerendered /commands passes html-validator when live API data loads

Test plan

  • pnpm lint:fix
  • pnpm typecheck
  • pnpm test:unit
  • pnpm build (html-validator clean on /commands)
  • Local Playwright hydration + view-transitions
  • CI Browser / unit / component / a11y / perf green
Open in Web Open in Cursor 

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.

Confidence Score: 4/5

This PR has one contained issue to fix before merging.

The main API migration is coherent, and prior auth-scoped cache issues appear addressed. The remaining issue is a real mutation-cache bug that can skip repeated settings saves.

shared/utils/fetch-cache-config.ts; server/plugins/fetch-cache.ts

T-Rex T-Rex Logs

What T-Rex did

  • Reproduced the mutation cache behavior with a standalone TypeScript harness, showing shouldCacheFetch returns true for the PATCH mutation and that two identical PATCH requests produce the same cache key; the first call misses the cache and hits upstream once, while the second call uses the cached response.
  • Reviewed the environment blockers and recovery steps, noting that Playwright could not start from config.webServer, recovery logs show install and Nuxt types generated, Storybook became reachable despite earlier issues, and transform errors related to Tsconfig prevented full UI rendering; blocker evidence includes a screenshot and a video.

View all artifacts

T-Rex Ran code and verified through T-Rex

Fix All in Claude Code Fix All in Cursor Fix All in Cursor Cloud Agents

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
shared/utils/fetch-cache-config.ts:157-163
**Do not cache mutations**
`shouldCacheFetch` allows every method for allowed bot hosts, and `cachedFetch` returns a stored response before calling `$fetch`. The changed `submitChanges` path now sends `PATCH /guilds/:id/settings` through `$api`, so repeating the same settings body within the TTL hits this cache and skips the bot API update entirely while the UI treats it as saved. Restrict caching to safe read methods before checking the domain.

Reviews (6): Last reviewed commit: "fix(api): keep botApi crypto helpers ser..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

cursoragent and others added 2 commits July 17, 2026 21:05
Backport the old same-origin /api/commands and /api/languages structure,
proxying to the internal bot API and normalizing alias → aliases.

Co-authored-by: RedStar <redstar071@proton.me>
@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 55.20833% with 43 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.14%. Comparing base (8babfde) to head (7bfbb0d).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
shared/utils/fetch-cache-config.ts 64.00% 8 Missing and 10 partials ⚠️
server/utils/discord/index.ts 8.33% 9 Missing and 2 partials ⚠️
app/plugins/api.ts 22.22% 5 Missing and 2 partials ⚠️
server/utils/botApi.ts 77.77% 0 Missing and 4 partials ⚠️
app/plugins/payload-cache.client.ts 50.00% 2 Missing ⚠️
app/composables/useAuditLog.ts 66.66% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #303      +/-   ##
==========================================
- Coverage   71.53%   71.14%   -0.39%     
==========================================
  Files         167      169       +2     
  Lines        3302     3393      +91     
  Branches      702      730      +28     
==========================================
+ Hits         2362     2414      +52     
- Misses        447      468      +21     
- Partials      493      511      +18     
Flag Coverage Δ
component 65.93% <37.50%> (-0.17%) ⬇️
unit 67.31% <58.75%> (-0.37%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
package.json 100.00% <ø> (ø)
server/utils/runtimeConfig.ts 78.57% <ø> (ø)
app/composables/useAuditLog.ts 68.18% <66.66%> (-1.82%) ⬇️
app/plugins/payload-cache.client.ts 50.00% <50.00%> (ø)
server/utils/botApi.ts 77.77% <77.77%> (ø)
app/plugins/api.ts 50.00% <22.22%> (-30.00%) ⬇️
server/utils/discord/index.ts 34.28% <8.33%> (-1.60%) ⬇️
shared/utils/fetch-cache-config.ts 67.74% <64.00%> (-16.88%) ⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed-hq

codspeed-hq Bot commented Jul 17, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 44 untouched benchmarks


Comparing cursor/backport-structure-api-88be (7bfbb0d) with main (8babfde)

Open in CodSpeed

Route dashboard guild/commands/languages handlers through sapphire-plugin-api
with SAPPHIRE_AUTH cookie auth, instead of calling Discord REST locally.
Keep moderation logs, members list, users, and auth on the Nuxt server.

Co-authored-by: RedStar <redstar071@proton.me>
@cursor cursor Bot changed the title feat(api): restore commands/languages proxies to api.wolfstar.rocks feat(api): proxy full dashboard API to api.wolfstar.rocks Jul 17, 2026
Comment thread server/api/guilds/[guild]/logs/index.get.ts
Comment thread server/api/guilds/[guild]/logs/commands.get.ts
Restore the $api plugin against NUXT_PUBLIC_API_BASE_URL, point dashboard
composables at bot paths, and keep a single /api/bot/** BFF for client-side
auth cookie injection. Revert guild handlers to local Discord implementations.

Co-authored-by: RedStar <redstar071@proton.me>
@cursor cursor Bot changed the title feat(api): proxy full dashboard API to api.wolfstar.rocks feat(api): call WolfStar bot API via $api Jul 18, 2026
autofix-ci Bot and others added 3 commits July 18, 2026 11:32
Use window instead of time for defineWrappedResponseHandler rate limits
and apply lint formatting on related $api call sites.

Co-authored-by: RedStar <redstar071@proton.me>
Remove the /api/bot BFF and always point $api at NUXT_PUBLIC_API_BASE_URL
with credentials:include, matching legacy apiFetch behavior. Keep optional
SSR sapphire cookie injection from the better-auth Discord session.

Co-authored-by: RedStar <redstar071@proton.me>
@cursor cursor Bot changed the title feat(api): call WolfStar bot API via $api feat(api): call WolfStar bot API via $api (legacy-style) Jul 18, 2026
Comment thread app/plugins/api.ts
cursoragent and others added 6 commits July 18, 2026 11:52
Relocate sapphire auth crypto and BotApiCommand types to #shared so the
$api plugin can import them without a dynamic #server/utils/bot-api load.

Co-authored-by: RedStar <redstar071@proton.me>
Use camelCase botApi file and symbol names (BotApi* types,
normalizeBotApiCommands, getOptionalBotApiAuthHeaders) in shared.

Co-authored-by: RedStar <redstar071@proton.me>
Drop the redundant NUXT_BOT_API_OAUTH_SECRET alias; sapphire cookie
encryption uses the existing Discord OAuth client secret.

Co-authored-by: RedStar <redstar071@proton.me>
Add npmx-style runtime payload cache so HTML SSR can reuse a serialized
_payload.json response and skip a second full render. Auth routes are
excluded; Netlify uses Blobs storage for the payload-cache mount.

Co-authored-by: RedStar <redstar071@proton.me>
Drop the duplicate BotApiCommand type and command normalizers; type
commands fetches with the existing FlattenedCommand shape.

Co-authored-by: RedStar <redstar071@proton.me>
Include baseURL, query, and auth headers in SSR fetch-cache keys so
authenticated $api responses cannot bleed across users or filters.

Remove nested UButton/role=region markup from CommandSubCategory so
prerendered /commands passes html-validator when live bot API data loads.

Co-authored-by: RedStar <redstar071@proton.me>
@blacksmith-sh

This comment has been minimized.

`$api` plugin setup was destructuring `runtimeConfig.discord.clientSecret`,
which is undefined in the browser and crashed plugin init, causing hydration
mismatches and View Transition failures in Playwright.

Co-authored-by: RedStar <redstar071@proton.me>
Comment thread app/plugins/api.ts Outdated
cursoragent and others added 2 commits July 18, 2026 13:41
…ture-api-88be

Co-authored-by: RedStar <redstar071@proton.me>
Move node:crypto sapphire auth helpers out of #shared into
server/utils/botApi and load them via a dynamic import inside the
$api plugin's server branch so the client bundle never resolves crypto.

Co-authored-by: RedStar <redstar071@proton.me>
Comment on lines +157 to +163
export function shouldCacheFetch(url: string, options: FetchCacheKeyOptions = {}): boolean {
if (typeof url === "string" && url.startsWith("/") && !options.baseURL) {
return true;
}

try {
return isAllowedDomain(resolveFetchCacheUrl(url, options));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Do not cache mutations
shouldCacheFetch allows every method for allowed bot hosts, and cachedFetch returns a stored response before calling $fetch. The changed submitChanges path now sends PATCH /guilds/:id/settings through $api, so repeating the same settings body within the TTL hits this cache and skips the bot API update entirely while the UI treats it as saved. Restrict caching to safe read methods before checking the domain.

Artifacts

Repro: standalone mutation cache harness source

  • Contains supporting evidence from the run (text/typescript; charset=utf-8).

Repro: mutation cache harness execution log

  • Keeps the command output available without making the summary code-heavy.

View artifacts

T-Rex Ran code and verified through T-Rex

Prompt To Fix With AI
This is a comment left during a code review.
Path: shared/utils/fetch-cache-config.ts
Line: 157-163

Comment:
**Do not cache mutations**
`shouldCacheFetch` allows every method for allowed bot hosts, and `cachedFetch` returns a stored response before calling `$fetch`. The changed `submitChanges` path now sends `PATCH /guilds/:id/settings` through `$api`, so repeating the same settings body within the TTL hits this cache and skips the bot API update entirely while the UI treats it as saved. Restrict caching to safe read methods before checking the domain.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Cursor Fix in Cursor Cloud Agents

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants