Skip to content

[Frontend] Update#33

Merged
kernelcoffee merged 5 commits into
masterfrom
dev/refactoring_and_update
Jul 12, 2026
Merged

[Frontend] Update#33
kernelcoffee merged 5 commits into
masterfrom
dev/refactoring_and_update

Conversation

@kernelcoffee

@kernelcoffee kernelcoffee commented Jul 12, 2026

Copy link
Copy Markdown
Owner
  • SteamGiftsClient rate limiting + retry/backoff: all 12 HTTP call sites go through shared _get/_post wrappers. GETs retry transport errors, 5xx and 429 (honoring Retry-After) with backoff; POSTs (state-mutating) only retry connect errors so a request that may have reached the server is never replayed. Six new tests cover the retry semantics.
  • GiveawayService split: 1,027-line class → 81-line facade over three mixins (giveaway_sync/giveaway_entry/giveaway_query), methods preserved verbatim, import path unchanged.
  • mypy config fix: keys after [[tool.mypy.overrides]] silently join that table — strict flags had stopped applying; restoring them surfaced 40 hidden errors, all fixed.
  • Zero skipped tests: last two route tests now run with raise_server_exceptions=False.
  • Frontend: react-hooks/set-state-in-effect re-enabled after refactoring Settings.tsx and Dashboard.tsx.
  • APScheduler: 4.x evaluated — no stable release exists; <4 pin stays (documented in TOFIX.md).

Two-stage frontend dependency refresh:

  • In-range updates: React 19.2.7, react-router 7.18, TanStack Query 5.101, Tailwind 4.3, vitest 4.1, typescript-eslint 8.63, zustand 5.0.14.
  • Major bumps: vite 8.1 + plugin-react 6 (build ~10s → ~0.6s), eslint 10.7 (@eslint/js now an explicit dev dep), jsdom 29, lucide-react 1.24, TypeScript 6.0.3 (the ceiling typescript-eslint supports — TS 7 deferred; deprecated baseUrl dropped from tsconfig).

All 12 HTTP call sites now go through shared _get/_post wrappers:

- A RateLimiter (30 requests/60s by default, same sliding-window
  implementation the Steam client already used) paces every request.
- GETs retry transient failures up to max_retries with exponential
  backoff: transport errors, 5xx responses, and 429 (honoring a
  numeric Retry-After header). Persistent transport failures surface
  as SteamGiftsError; persistent HTTP errors return the last response
  so existing status handling in each method still applies.
- POSTs (enter/hide/comment - state-mutating) are retried only on
  connect errors, where the request never reached the server.

Tests: 757 passed, 2 skipped.
GiveawayService (1027 lines) is now an 81-line facade composing three
focused modules, with every method preserved verbatim and the public
class path unchanged (services.giveaway_service.GiveawayService):

- services/giveaway_sync.py   - scrape->cache sync steps (5 methods)
- services/giveaway_entry.py  - entering, safety, hide, comments (6)
- services/giveaway_query.py  - listings, stats, eligibility (17)

Also fixes a TOML footgun introduced with the APScheduler override:
keys placed after a [[tool.mypy.overrides]] table belong to that table,
so warn_return_any / warn_unused_configs / disallow_untyped_defs had
silently stopped applying globally. With them restored, 40 hidden
errors surfaced; all are now fixed (annotations on **kwargs, dunders,
pydantic validators, lifespan/endpoints; typed intermediates for
response.json() returns; BeautifulSoup attribute coercions in
_refresh_xsrf_token).

Tests: 757 passed, 2 skipped; ruff and mypy clean.
The two route-registration tests in test_api_main.py were skipped
because the settings route raises without a database and TestClient
re-raises handler exceptions by default. Running them with
raise_server_exceptions=False makes them exact "route exists" checks
(200/500, never 404) with no DB required.

Backend suite: 759 passed, 0 skipped. TOFIX.md updated (the scheduler
e2e file was already re-enabled by the automation consolidation).
Refactor the two components that needed the rule disabled:

- Settings.tsx: the form is now an inner SettingsForm component that
  initializes its state directly from the loaded settings (useState
  initializer) and is remounted via key={settings.updated_at} when a
  save/refetch delivers new server state - no effect-driven setState.
- Dashboard.tsx: JobCountdown derives the countdown string during
  render from job.next_run; the effect only owns a 1s tick interval.

eslint passes with zero warnings; 170 frontend tests pass; tsc clean.
@kernelcoffee kernelcoffee merged commit 8ef110c into master Jul 12, 2026
10 checks passed
@kernelcoffee kernelcoffee deleted the dev/refactoring_and_update branch July 12, 2026 23:32
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