Skip to content

(SP: 2) [Frontend] Remove [locale] layout force-dynamic and move auth to client-side#370

Merged
ViktorSvertoka merged 2 commits intodevelopfrom
perf/layout-auth-client-side-dynamic-removal
Feb 26, 2026
Merged

(SP: 2) [Frontend] Remove [locale] layout force-dynamic and move auth to client-side#370
ViktorSvertoka merged 2 commits intodevelopfrom
perf/layout-auth-client-side-dynamic-removal

Conversation

@ViktorSvertoka
Copy link
Member

@ViktorSvertoka ViktorSvertoka commented Feb 26, 2026

What changed

  • Removed `force-dynamic` and server auth read from `app/[locale]/layout.tsx`
  • Added client auth state layer: `hooks/useAuth.tsx` + `AuthProvider`
  • Updated header flow (`AppChrome`, `MainSwitcher`) to consume `useAuth()`
  • Updated `/api/auth/me` response shape and cache headers (`no-store`)
  • Kept dashboard explicitly dynamic via `app/[locale]/dashboard/layout.tsx`
  • Adjusted `AIWordHelper` to new `/api/auth/me` payload

Why

This unblocks static/ISR rendering for locale pages while preserving dynamic behavior for user-specific dashboard routes.

Validation

  • Targeted ESLint on changed files passed
  • Full repo typecheck has unrelated pre-existing test errors

Closes #369

Summary by CodeRabbit

  • New Features

    • Added authentication context provider to centralize user authentication state management throughout the application.
  • Refactor

    • Admin feature access is now managed through environment-based feature flags for more flexible control.
    • Streamlined authentication API response to return only essential user information.
    • Improved component authentication handling by leveraging context instead of prop-based passing.

@ViktorSvertoka ViktorSvertoka self-assigned this Feb 26, 2026
@ViktorSvertoka ViktorSvertoka added the performance Performance and efficiency optimizations without functional changes. label Feb 26, 2026
@vercel
Copy link
Contributor

vercel bot commented Feb 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
devlovers-net Ignored Ignored Preview Feb 26, 2026 0:03am

Request Review

@netlify
Copy link

netlify bot commented Feb 26, 2026

Deploy Preview for develop-devlovers ready!

Name Link
🔨 Latest commit 19b35c1
🔍 Latest deploy log https://app.netlify.com/projects/develop-devlovers/deploys/69a0367b09625e00080ed379
😎 Deploy Preview https://deploy-preview-370--develop-devlovers.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a988902 and 19b35c1.

📒 Files selected for processing (1)
  • frontend/hooks/useAuth.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/hooks/useAuth.tsx

📝 Walkthrough

Walkthrough

This PR moves authentication from server-side evaluation in the layout (accessing user/cookies) to client-side via a new AuthProvider and useAuth hook. The server layout is simplified to remove getCurrentUser() calls, enabling static/ISR rendering. Header components now derive auth state from the client-side hook instead of receiving it as props. The API endpoint /api/auth/me is streamlined to return only id, role, and username.

Changes

Cohort / File(s) Summary
New auth context and hook
frontend/hooks/useAuth.tsx
Introduces AuthProvider component that fetches user from /api/auth/me on mount with abort handling, and useAuth hook that exposes user, userExists, userId, isAdmin, username, loading, and refresh derived from the context.
Auth API endpoint
frontend/app/api/auth/me/route.ts
Simplified response to return only { id, role, username } instead of full user object; added Cache-Control: no-store header; returns null when no user exists.
Layout and component prop updates
frontend/app/[locale]/layout.tsx, frontend/components/header/AppChrome.tsx, frontend/components/header/MainSwitcher.tsx
Removed user-based props (userExists, userId, showAdminLink) and replaced with enableAdminFeature flag; added AuthProvider wrapper; components now use useAuth hook to derive auth state internally instead of receiving via props.
Auth state consumption updates
frontend/components/q&a/AIWordHelper.tsx
Updated authentication check to derive auth status from data?.id instead of data.user, reflecting new API response structure.

Sequence Diagram(s)

sequenceDiagram
    participant App as React App
    participant AP as AuthProvider
    participant API as /api/auth/me
    participant Ctx as AuthContext
    participant Comp as Header Components

    App->>AP: Render with AuthProvider wrapper
    AP->>AP: useEffect on mount
    AP->>API: POST/GET request with AbortController
    API-->>AP: { id, role, username } or null
    AP->>Ctx: Update user state & memoize derived fields
    Ctx-->>Comp: Provide userExists, userId, isAdmin, loading, refresh
    Comp->>Comp: useAuth() hook consumes context
    Comp-->>App: Render with auth-derived showAdminLink conditional
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

refactor

Suggested reviewers

  • AM1007

Poem

🐰 From server to client, our auth takes flight,
No more force-dynamic, static feels right!
With AuthProvider wrapped 'round the tree,
Context flows gently, isAdmin and me,
Static rendering hops into the light! ✨

🚥 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 clearly and specifically describes the main change: removing force-dynamic from the locale layout and moving authentication to client-side.
Linked Issues check ✅ Passed All coding requirements from #369 are met: getCurrentUser() removed from layout [#369], useAuth/AuthProvider implemented [#369], /api/auth/me updated with no-store headers [#369], header components refactored to use client-side auth [#369], and linting completed [#369].
Out of Scope Changes check ✅ Passed All changes align with issue #369 objectives: layout changes, auth provider implementation, header refactoring, API endpoint updates, and dashboard dynamic layout handling are all in scope.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch perf/layout-auth-client-side-dynamic-removal

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/hooks/useAuth.tsx`:
- Around line 50-84: The refresh and initial load (functions refresh and
loadAuth) can complete out of order and overwrite newer state; implement a
"latest-request-wins" token to ignore stale responses: add a scoped incrementing
requestId (or symbol) that you capture before calling fetchAuth in both refresh
and loadAuth, pass the same AbortSignal for cancellation as needed, then only
call setUser or setLoading(false) if the captured requestId matches the current
latestRequestId; update both refresh and loadAuth to check this token before
mutating state so slower earlier requests cannot overwrite newer results.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 006b39b and a988902.

📒 Files selected for processing (7)
  • frontend/app/[locale]/dashboard/layout.tsx
  • frontend/app/[locale]/layout.tsx
  • frontend/app/api/auth/me/route.ts
  • frontend/components/header/AppChrome.tsx
  • frontend/components/header/MainSwitcher.tsx
  • frontend/components/q&a/AIWordHelper.tsx
  • frontend/hooks/useAuth.tsx

@ViktorSvertoka ViktorSvertoka merged commit 6e3526f into develop Feb 26, 2026
11 checks passed
@ViktorSvertoka ViktorSvertoka deleted the perf/layout-auth-client-side-dynamic-removal branch February 26, 2026 12:07
ViktorSvertoka added a commit that referenced this pull request Feb 26, 2026
* (SP: 3) [Backend] add Nova Poshta shipping foundation + checkout persistence + async label workflow (#364)

* (SP: 2) [Frontend] Reduce Vercel variable costs via caching and analytics cleanup (#367)

* perf(vercel): cut runtime costs via notification, blog cache, and analytics changes

* perf(blog): remove server searchParams usage to preserve ISR

* fix(build): align Netlify Node version and remove SpeedInsights import

* chore(release): bump version to 1.0.4

* (SP: 2) [Frontend] Remove [locale] layout force-dynamic and move auth to client-side (#370)

* refactor(frontend): remove locale layout dynamic auth and move header auth client-side

* fix(frontend): prevent stale auth responses in useAuth and remove redundant dashboard dynamic layout

* (SP: 2) [Frontend] Reduce auth overhead and sync auth state across tabs (#372)

* refactor(frontend): remove locale layout dynamic auth and move header auth client-side

* fix(frontend): prevent stale auth responses in useAuth and remove redundant dashboard dynamic layout

* feat(frontend): sync auth state across tabs via BroadcastChannel

* (SP: 2) [Frontend] Quizzes page ISR + client-side progress + GitHub stars cache (#371)

* perf(quiz-flow): move quiz progress to client-side fetch, enable ISR for quizzes page

- Move user progress fetch from SSR to client-side API (/api/quiz/progress)
- Remove force-dynamic and getCurrentUser() from quizzes page
- Add revalidate=300 for ISR caching
- Use window.history.replaceState for tab URL sync (avoid Next.js navigation)
- Add forceMount to TabsContent to prevent layout shift on tab switch
- Fix nested <main> — use <section> inside DynamicGridBackground
- Cache GitHub stars count in sessionStorage to avoid refetch + re-animation

* perf: replace useRef with useState lazy initializer in GitHubStarButton

Fixes React 19 react-hooks/refs ESLint error — useRef.current cannot
be read during render. Uses useState(getStoredStars) to capture the
sessionStorage value once on mount instead.

* fix: stop star icon trembling on hover in GitHubStarButton

* (SP: 1) [Frontend] Fix quiz timer flash and card layout shift on quizzes page (#373)

* perf(quiz-flow): move quiz progress to client-side fetch, enable ISR for quizzes page

- Move user progress fetch from SSR to client-side API (/api/quiz/progress)
- Remove force-dynamic and getCurrentUser() from quizzes page
- Add revalidate=300 for ISR caching
- Use window.history.replaceState for tab URL sync (avoid Next.js navigation)
- Add forceMount to TabsContent to prevent layout shift on tab switch
- Fix nested <main> — use <section> inside DynamicGridBackground
- Cache GitHub stars count in sessionStorage to avoid refetch + re-animation

* perf: replace useRef with useState lazy initializer in GitHubStarButton

Fixes React 19 react-hooks/refs ESLint error — useRef.current cannot
be read during render. Uses useState(getStoredStars) to capture the
sessionStorage value once on mount instead.

* fix: stop star icon trembling on hover in GitHubStarButton

* fix: eliminate quiz timer flash on language switch

Remove Suspense boundary (loading.tsx) that unmounted QuizContainer
during locale navigation. Synchronous session restore via useReducer
lazy initializer and correct timer initialization via useState lazy
initializer prevent any visible state reset on language switch

* fix: replace quiz card layout shift with skeleton grid during progress load

* chore(release): v1.0.5

---------

Co-authored-by: Liudmyla Sovetovs <milkaegik@gmail.com>
Co-authored-by: Lesia Soloviova <106915140+LesiaUKR@users.noreply.github.com>
ViktorSvertoka added a commit that referenced this pull request Feb 27, 2026
* (SP: 3) [Backend] add Nova Poshta shipping foundation + checkout persistence + async label workflow (#364)

* (SP: 2) [Frontend] Reduce Vercel variable costs via caching and analytics cleanup (#367)

* perf(vercel): cut runtime costs via notification, blog cache, and analytics changes

* perf(blog): remove server searchParams usage to preserve ISR

* fix(build): align Netlify Node version and remove SpeedInsights import

* chore(release): bump version to 1.0.4

* (SP: 2) [Frontend] Remove [locale] layout force-dynamic and move auth to client-side (#370)

* refactor(frontend): remove locale layout dynamic auth and move header auth client-side

* fix(frontend): prevent stale auth responses in useAuth and remove redundant dashboard dynamic layout

* (SP: 2) [Frontend] Reduce auth overhead and sync auth state across tabs (#372)

* refactor(frontend): remove locale layout dynamic auth and move header auth client-side

* fix(frontend): prevent stale auth responses in useAuth and remove redundant dashboard dynamic layout

* feat(frontend): sync auth state across tabs via BroadcastChannel

* (SP: 2) [Frontend] Quizzes page ISR + client-side progress + GitHub stars cache (#371)

* perf(quiz-flow): move quiz progress to client-side fetch, enable ISR for quizzes page

- Move user progress fetch from SSR to client-side API (/api/quiz/progress)
- Remove force-dynamic and getCurrentUser() from quizzes page
- Add revalidate=300 for ISR caching
- Use window.history.replaceState for tab URL sync (avoid Next.js navigation)
- Add forceMount to TabsContent to prevent layout shift on tab switch
- Fix nested <main> — use <section> inside DynamicGridBackground
- Cache GitHub stars count in sessionStorage to avoid refetch + re-animation

* perf: replace useRef with useState lazy initializer in GitHubStarButton

Fixes React 19 react-hooks/refs ESLint error — useRef.current cannot
be read during render. Uses useState(getStoredStars) to capture the
sessionStorage value once on mount instead.

* fix: stop star icon trembling on hover in GitHubStarButton

* (SP: 1) [Frontend] Fix quiz timer flash and card layout shift on quizzes page (#373)

* perf(quiz-flow): move quiz progress to client-side fetch, enable ISR for quizzes page

- Move user progress fetch from SSR to client-side API (/api/quiz/progress)
- Remove force-dynamic and getCurrentUser() from quizzes page
- Add revalidate=300 for ISR caching
- Use window.history.replaceState for tab URL sync (avoid Next.js navigation)
- Add forceMount to TabsContent to prevent layout shift on tab switch
- Fix nested <main> — use <section> inside DynamicGridBackground
- Cache GitHub stars count in sessionStorage to avoid refetch + re-animation

* perf: replace useRef with useState lazy initializer in GitHubStarButton

Fixes React 19 react-hooks/refs ESLint error — useRef.current cannot
be read during render. Uses useState(getStoredStars) to capture the
sessionStorage value once on mount instead.

* fix: stop star icon trembling on hover in GitHubStarButton

* fix: eliminate quiz timer flash on language switch

Remove Suspense boundary (loading.tsx) that unmounted QuizContainer
during locale navigation. Synchronous session restore via useReducer
lazy initializer and correct timer initialization via useState lazy
initializer prevent any visible state reset on language switch

* fix: replace quiz card layout shift with skeleton grid during progress load

* chore(release): v1.0.5

* (SP: 3)[Shop][DB] Reduce Neon compute: throttle janitor + relax checkout polling + add sweep indexes (#375)

* (SP: 3) [Backend] add internal janitor (jobs 1-4), claim/lease + runbook (G0-G6)

* (SP: 3) [Backend] add provider selector, fix payments gating, i18n checkout errors

* Add shop category images to public

* (SP: 3) [Shop][Monobank] I1 structured logging: codes + logging safety checks

* (SP: 3) [Shop][Monobank] Fail-closed non-browser origin posture for webhook + janitor (ORIGIN_BLOCKED)

* (SP: 3) [Shop][Monobank] [Shop][Monobank] J gate: add orders status ownership test and pass all pre-prod invariants

* (SP: 3) [Shop][Monobank]  review fixes (tests, logging, success UI)

* (SP: 1) [Shop][Monobank] Tighten webhook log-code typing; harden DB tests; minor security/log/UI cleanups

* (SP: 1) [Shop][Monobank] harden Monobank webhook (origin/PII-safe logs) and remove duplicate sha256 hashing

* (SP: 1) [Cart] adding route for user orders to cart page

* (SP: 1) [Cart] fix after review cart mpage and adding index for orders

* (SP: 1) [Cart] Fix cart orders summary auth rendering and return totalCount for orders badge

* (SP: 1) [Cart] remove console.warn from CartPageClient to satisfy monobank logging safety invariant, namespace localStorage cart by user and reset on auth change

* (SP: 1) [Cart] rehydrate per cartOwnerId (remove didHydrate coupling)

* (SP: 2)[Backend] shop/shipping schema migrations foundation

* (SP: 2)[Backend] shop/shipping public routes + np cache + sync

* (SP: 2)[Backend] shop/shipping: shipping persistence + currency policy

* (SP: 2)[Backend] shop/shipping: webhook apply + psp fields + enqueue shipping

* (SP: 2)[Backend] shop/shipping: shipments worker + internal run + np mock

* (SP: 2)[Backend] shop/shipping: admin+ui shipping actions

* (SP: 2)[Backend] shop/shipping: retention + log sanitizer + metrics

* (SP: 1)[Backend] stabilize Monobank janitor (job1/job3) and fix failing apply-outcomes tests

* (SP: 1) [db]: add shop shipping core migration

* (SP: 1) [FIX] resolve merge artifacts in order details page

* (SP: 1) [FIX] apply post-review fixes for shipping and admin flows

* (SP: 1) [FIX] align cart shipping imports (localeToCountry + availability reason code)

* (SP: 1) [FIX] hard-block checkout when shipping disabled + i18n reason mapping

* (SP: 1) [FIX] harden webhook enqueue + shipping worker + NP catalog + cart fail-closed

* (SP: 1) [FIX] Initialize shippingMethodsLoading to true to avoid premature checkout.

* (SP: 1) [FIX] migration 17

* (SP: 1) [DB] migrarion to testind DB and adjusting tests

* (SP: 1)[DB] slow down restock janitor + enforce prod interval floor

* (SP: 1) [DB] add order status lite view (opt-in) + instrumentation

* (SP: 1) [DB] replace checkout success router.refresh polling with backoff API polling

* (SP: 1) [DB] throttle sessions activity heartbeat + use count(*) (PK invariant)

* (SP: 1)[DB] enforce production min intervals for internal shipping jobs

* (SP: 1) [DB] add minimal partial indexes for orders sweeps + rollout notes

* (SP: 1) [DB] refactor sweep claim step to FOR UPDATE SKIP LOCKED batching

* (SP: 1)[DB]: slow janitor schedule to every 30 minutes

* (SP: 1)[DB] increase polling delays for MonobankRedirectStatus

* (SP: 1)[FIX] harden webhooks + fix SSR hydration + janitor/np gates + sweeps refactor

* (SP: 1)[FIX] harden shipping enqueue gating + apply NP interval floor

---------

Co-authored-by: Liudmyla Sovetovs <milkaegik@gmail.com>
Co-authored-by: Lesia Soloviova <106915140+LesiaUKR@users.noreply.github.com>
ViktorSvertoka added a commit that referenced this pull request Mar 1, 2026
* (SP: 3) [Backend] add Nova Poshta shipping foundation + checkout persistence + async label workflow (#364)

* (SP: 2) [Frontend] Reduce Vercel variable costs via caching and analytics cleanup (#367)

* perf(vercel): cut runtime costs via notification, blog cache, and analytics changes

* perf(blog): remove server searchParams usage to preserve ISR

* fix(build): align Netlify Node version and remove SpeedInsights import

* chore(release): bump version to 1.0.4

* (SP: 2) [Frontend] Remove [locale] layout force-dynamic and move auth to client-side (#370)

* refactor(frontend): remove locale layout dynamic auth and move header auth client-side

* fix(frontend): prevent stale auth responses in useAuth and remove redundant dashboard dynamic layout

* (SP: 2) [Frontend] Reduce auth overhead and sync auth state across tabs (#372)

* refactor(frontend): remove locale layout dynamic auth and move header auth client-side

* fix(frontend): prevent stale auth responses in useAuth and remove redundant dashboard dynamic layout

* feat(frontend): sync auth state across tabs via BroadcastChannel

* (SP: 2) [Frontend] Quizzes page ISR + client-side progress + GitHub stars cache (#371)

* perf(quiz-flow): move quiz progress to client-side fetch, enable ISR for quizzes page

- Move user progress fetch from SSR to client-side API (/api/quiz/progress)
- Remove force-dynamic and getCurrentUser() from quizzes page
- Add revalidate=300 for ISR caching
- Use window.history.replaceState for tab URL sync (avoid Next.js navigation)
- Add forceMount to TabsContent to prevent layout shift on tab switch
- Fix nested <main> — use <section> inside DynamicGridBackground
- Cache GitHub stars count in sessionStorage to avoid refetch + re-animation

* perf: replace useRef with useState lazy initializer in GitHubStarButton

Fixes React 19 react-hooks/refs ESLint error — useRef.current cannot
be read during render. Uses useState(getStoredStars) to capture the
sessionStorage value once on mount instead.

* fix: stop star icon trembling on hover in GitHubStarButton

* (SP: 1) [Frontend] Fix quiz timer flash and card layout shift on quizzes page (#373)

* perf(quiz-flow): move quiz progress to client-side fetch, enable ISR for quizzes page

- Move user progress fetch from SSR to client-side API (/api/quiz/progress)
- Remove force-dynamic and getCurrentUser() from quizzes page
- Add revalidate=300 for ISR caching
- Use window.history.replaceState for tab URL sync (avoid Next.js navigation)
- Add forceMount to TabsContent to prevent layout shift on tab switch
- Fix nested <main> — use <section> inside DynamicGridBackground
- Cache GitHub stars count in sessionStorage to avoid refetch + re-animation

* perf: replace useRef with useState lazy initializer in GitHubStarButton

Fixes React 19 react-hooks/refs ESLint error — useRef.current cannot
be read during render. Uses useState(getStoredStars) to capture the
sessionStorage value once on mount instead.

* fix: stop star icon trembling on hover in GitHubStarButton

* fix: eliminate quiz timer flash on language switch

Remove Suspense boundary (loading.tsx) that unmounted QuizContainer
during locale navigation. Synchronous session restore via useReducer
lazy initializer and correct timer initialization via useState lazy
initializer prevent any visible state reset on language switch

* fix: replace quiz card layout shift with skeleton grid during progress load

* chore(release): v1.0.5

* (SP: 3)[Shop][DB] Reduce Neon compute: throttle janitor + relax checkout polling + add sweep indexes (#375)

* (SP: 3) [Backend] add internal janitor (jobs 1-4), claim/lease + runbook (G0-G6)

* (SP: 3) [Backend] add provider selector, fix payments gating, i18n checkout errors

* Add shop category images to public

* (SP: 3) [Shop][Monobank] I1 structured logging: codes + logging safety checks

* (SP: 3) [Shop][Monobank] Fail-closed non-browser origin posture for webhook + janitor (ORIGIN_BLOCKED)

* (SP: 3) [Shop][Monobank] [Shop][Monobank] J gate: add orders status ownership test and pass all pre-prod invariants

* (SP: 3) [Shop][Monobank]  review fixes (tests, logging, success UI)

* (SP: 1) [Shop][Monobank] Tighten webhook log-code typing; harden DB tests; minor security/log/UI cleanups

* (SP: 1) [Shop][Monobank] harden Monobank webhook (origin/PII-safe logs) and remove duplicate sha256 hashing

* (SP: 1) [Cart] adding route for user orders to cart page

* (SP: 1) [Cart] fix after review cart mpage and adding index for orders

* (SP: 1) [Cart] Fix cart orders summary auth rendering and return totalCount for orders badge

* (SP: 1) [Cart] remove console.warn from CartPageClient to satisfy monobank logging safety invariant, namespace localStorage cart by user and reset on auth change

* (SP: 1) [Cart] rehydrate per cartOwnerId (remove didHydrate coupling)

* (SP: 2)[Backend] shop/shipping schema migrations foundation

* (SP: 2)[Backend] shop/shipping public routes + np cache + sync

* (SP: 2)[Backend] shop/shipping: shipping persistence + currency policy

* (SP: 2)[Backend] shop/shipping: webhook apply + psp fields + enqueue shipping

* (SP: 2)[Backend] shop/shipping: shipments worker + internal run + np mock

* (SP: 2)[Backend] shop/shipping: admin+ui shipping actions

* (SP: 2)[Backend] shop/shipping: retention + log sanitizer + metrics

* (SP: 1)[Backend] stabilize Monobank janitor (job1/job3) and fix failing apply-outcomes tests

* (SP: 1) [db]: add shop shipping core migration

* (SP: 1) [FIX] resolve merge artifacts in order details page

* (SP: 1) [FIX] apply post-review fixes for shipping and admin flows

* (SP: 1) [FIX] align cart shipping imports (localeToCountry + availability reason code)

* (SP: 1) [FIX] hard-block checkout when shipping disabled + i18n reason mapping

* (SP: 1) [FIX] harden webhook enqueue + shipping worker + NP catalog + cart fail-closed

* (SP: 1) [FIX] Initialize shippingMethodsLoading to true to avoid premature checkout.

* (SP: 1) [FIX] migration 17

* (SP: 1) [DB] migrarion to testind DB and adjusting tests

* (SP: 1)[DB] slow down restock janitor + enforce prod interval floor

* (SP: 1) [DB] add order status lite view (opt-in) + instrumentation

* (SP: 1) [DB] replace checkout success router.refresh polling with backoff API polling

* (SP: 1) [DB] throttle sessions activity heartbeat + use count(*) (PK invariant)

* (SP: 1)[DB] enforce production min intervals for internal shipping jobs

* (SP: 1) [DB] add minimal partial indexes for orders sweeps + rollout notes

* (SP: 1) [DB] refactor sweep claim step to FOR UPDATE SKIP LOCKED batching

* (SP: 1)[DB]: slow janitor schedule to every 30 minutes

* (SP: 1)[DB] increase polling delays for MonobankRedirectStatus

* (SP: 1)[FIX] harden webhooks + fix SSR hydration + janitor/np gates + sweeps refactor

* (SP: 1)[FIX] harden shipping enqueue gating + apply NP interval floor

* (SP: 3) [SHOP] audit-driven e2e purchase readiness hardening (events, notifications, consent, returns) (#378)

* (SP:3)[SHOP] add canonical payment/shipping/admin audit tables + dedupe helper with flagged atomic dual-write

* (SP: 2)[SHOP] add INTL quote flow (request/offer/accept/decline), payment-init gate, and quote expiry/timeout sweeps

* (SP: 3)[SHOP] introduce outbox-driven notifications with projector + worker (phase 3)

* (SP: 3)[SHOP] add minimal returns/RMA lifecycle with atomic audit + canonical events (phase 4)

* (SP: 3)[SHOP] enforce guest status-token lite-only access and audit token usage (phase 5)

* (SP: 3)[SHOP] centralize transition guards and enforce across admin/webhook/worker flows (phase 6)

:wq
n

* (SP:3)[SHOP]: enforce DATABASE_URL_LOCAL preflight + deterministic vitest config

* (SP:3)[SHOP]: require canonical events in prod (fail-fast)

* (SP:3)[SHOP]: implement notifications transport with retries + DLQ

* (SP:3)[SHOP]: persist checkout legal consent artifact

* (SP:1)[SHOP] add migration 0025 for consent + events + audit + prices

* (SP:1)[SHOP] emit shipping_events for shipment worker transitions

* (SP:2)[SHOP] audit admin product mutations (deduped)

* (SP:2)[SHOP] make Monobank webhook retryable on transient apply failures

* (SP:3) [SHOP] enforce guest status-token scopes across order actions

* (SP:1) [SHOP] make product_prices the only write authority

* (SP:1) [SHOP]  add Playwright e2e smoke suite (local DB only)

* (SP:3) [SHOP] explicitly reject exchanges (EXCHANGES_NOT_SUPPORTED)

* (SP: 3)[FIX] harden audit + workers/tests; fix transitions/restock + webhook perf

* (SP: 3)[FIX] harden local-db test safety and tighten shop reliability guards

* (SP: 3)[FIX] fail-closed admin audit, refine shipments-worker outcomes/metrics, tighten quote+tests

* (SP: 1)[FIX] harden shipments-worker claiming/leases and make audit+quote/test paths resilient

* (SP: 1)[FIX] harden quote request errors/logging and sanitize requestId; document best-effort delete audit

* feat(ui): add devops/cloud category icons and styles (#379)

* chore(release): prepare v1.0.6 changelog

* chore: bump version to 1.0.6

---------

Co-authored-by: Liudmyla Sovetovs <milkaegik@gmail.com>
Co-authored-by: Lesia Soloviova <106915140+LesiaUKR@users.noreply.github.com>
ViktorSvertoka added a commit that referenced this pull request Mar 1, 2026
* (SP: 3) [Backend] add Nova Poshta shipping foundation + checkout persistence + async label workflow (#364)

* (SP: 2) [Frontend] Reduce Vercel variable costs via caching and analytics cleanup (#367)

* perf(vercel): cut runtime costs via notification, blog cache, and analytics changes

* perf(blog): remove server searchParams usage to preserve ISR

* fix(build): align Netlify Node version and remove SpeedInsights import

* chore(release): bump version to 1.0.4

* (SP: 2) [Frontend] Remove [locale] layout force-dynamic and move auth to client-side (#370)

* refactor(frontend): remove locale layout dynamic auth and move header auth client-side

* fix(frontend): prevent stale auth responses in useAuth and remove redundant dashboard dynamic layout

* (SP: 2) [Frontend] Reduce auth overhead and sync auth state across tabs (#372)

* refactor(frontend): remove locale layout dynamic auth and move header auth client-side

* fix(frontend): prevent stale auth responses in useAuth and remove redundant dashboard dynamic layout

* feat(frontend): sync auth state across tabs via BroadcastChannel

* (SP: 2) [Frontend] Quizzes page ISR + client-side progress + GitHub stars cache (#371)

* perf(quiz-flow): move quiz progress to client-side fetch, enable ISR for quizzes page

- Move user progress fetch from SSR to client-side API (/api/quiz/progress)
- Remove force-dynamic and getCurrentUser() from quizzes page
- Add revalidate=300 for ISR caching
- Use window.history.replaceState for tab URL sync (avoid Next.js navigation)
- Add forceMount to TabsContent to prevent layout shift on tab switch
- Fix nested <main> — use <section> inside DynamicGridBackground
- Cache GitHub stars count in sessionStorage to avoid refetch + re-animation

* perf: replace useRef with useState lazy initializer in GitHubStarButton

Fixes React 19 react-hooks/refs ESLint error — useRef.current cannot
be read during render. Uses useState(getStoredStars) to capture the
sessionStorage value once on mount instead.

* fix: stop star icon trembling on hover in GitHubStarButton

* (SP: 1) [Frontend] Fix quiz timer flash and card layout shift on quizzes page (#373)

* perf(quiz-flow): move quiz progress to client-side fetch, enable ISR for quizzes page

- Move user progress fetch from SSR to client-side API (/api/quiz/progress)
- Remove force-dynamic and getCurrentUser() from quizzes page
- Add revalidate=300 for ISR caching
- Use window.history.replaceState for tab URL sync (avoid Next.js navigation)
- Add forceMount to TabsContent to prevent layout shift on tab switch
- Fix nested <main> — use <section> inside DynamicGridBackground
- Cache GitHub stars count in sessionStorage to avoid refetch + re-animation

* perf: replace useRef with useState lazy initializer in GitHubStarButton

Fixes React 19 react-hooks/refs ESLint error — useRef.current cannot
be read during render. Uses useState(getStoredStars) to capture the
sessionStorage value once on mount instead.

* fix: stop star icon trembling on hover in GitHubStarButton

* fix: eliminate quiz timer flash on language switch

Remove Suspense boundary (loading.tsx) that unmounted QuizContainer
during locale navigation. Synchronous session restore via useReducer
lazy initializer and correct timer initialization via useState lazy
initializer prevent any visible state reset on language switch

* fix: replace quiz card layout shift with skeleton grid during progress load

* chore(release): v1.0.5

* (SP: 3)[Shop][DB] Reduce Neon compute: throttle janitor + relax checkout polling + add sweep indexes (#375)

* (SP: 3) [Backend] add internal janitor (jobs 1-4), claim/lease + runbook (G0-G6)

* (SP: 3) [Backend] add provider selector, fix payments gating, i18n checkout errors

* Add shop category images to public

* (SP: 3) [Shop][Monobank] I1 structured logging: codes + logging safety checks

* (SP: 3) [Shop][Monobank] Fail-closed non-browser origin posture for webhook + janitor (ORIGIN_BLOCKED)

* (SP: 3) [Shop][Monobank] [Shop][Monobank] J gate: add orders status ownership test and pass all pre-prod invariants

* (SP: 3) [Shop][Monobank]  review fixes (tests, logging, success UI)

* (SP: 1) [Shop][Monobank] Tighten webhook log-code typing; harden DB tests; minor security/log/UI cleanups

* (SP: 1) [Shop][Monobank] harden Monobank webhook (origin/PII-safe logs) and remove duplicate sha256 hashing

* (SP: 1) [Cart] adding route for user orders to cart page

* (SP: 1) [Cart] fix after review cart mpage and adding index for orders

* (SP: 1) [Cart] Fix cart orders summary auth rendering and return totalCount for orders badge

* (SP: 1) [Cart] remove console.warn from CartPageClient to satisfy monobank logging safety invariant, namespace localStorage cart by user and reset on auth change

* (SP: 1) [Cart] rehydrate per cartOwnerId (remove didHydrate coupling)

* (SP: 2)[Backend] shop/shipping schema migrations foundation

* (SP: 2)[Backend] shop/shipping public routes + np cache + sync

* (SP: 2)[Backend] shop/shipping: shipping persistence + currency policy

* (SP: 2)[Backend] shop/shipping: webhook apply + psp fields + enqueue shipping

* (SP: 2)[Backend] shop/shipping: shipments worker + internal run + np mock

* (SP: 2)[Backend] shop/shipping: admin+ui shipping actions

* (SP: 2)[Backend] shop/shipping: retention + log sanitizer + metrics

* (SP: 1)[Backend] stabilize Monobank janitor (job1/job3) and fix failing apply-outcomes tests

* (SP: 1) [db]: add shop shipping core migration

* (SP: 1) [FIX] resolve merge artifacts in order details page

* (SP: 1) [FIX] apply post-review fixes for shipping and admin flows

* (SP: 1) [FIX] align cart shipping imports (localeToCountry + availability reason code)

* (SP: 1) [FIX] hard-block checkout when shipping disabled + i18n reason mapping

* (SP: 1) [FIX] harden webhook enqueue + shipping worker + NP catalog + cart fail-closed

* (SP: 1) [FIX] Initialize shippingMethodsLoading to true to avoid premature checkout.

* (SP: 1) [FIX] migration 17

* (SP: 1) [DB] migrarion to testind DB and adjusting tests

* (SP: 1)[DB] slow down restock janitor + enforce prod interval floor

* (SP: 1) [DB] add order status lite view (opt-in) + instrumentation

* (SP: 1) [DB] replace checkout success router.refresh polling with backoff API polling

* (SP: 1) [DB] throttle sessions activity heartbeat + use count(*) (PK invariant)

* (SP: 1)[DB] enforce production min intervals for internal shipping jobs

* (SP: 1) [DB] add minimal partial indexes for orders sweeps + rollout notes

* (SP: 1) [DB] refactor sweep claim step to FOR UPDATE SKIP LOCKED batching

* (SP: 1)[DB]: slow janitor schedule to every 30 minutes

* (SP: 1)[DB] increase polling delays for MonobankRedirectStatus

* (SP: 1)[FIX] harden webhooks + fix SSR hydration + janitor/np gates + sweeps refactor

* (SP: 1)[FIX] harden shipping enqueue gating + apply NP interval floor

* (SP: 3) [SHOP] audit-driven e2e purchase readiness hardening (events, notifications, consent, returns) (#378)

* (SP:3)[SHOP] add canonical payment/shipping/admin audit tables + dedupe helper with flagged atomic dual-write

* (SP: 2)[SHOP] add INTL quote flow (request/offer/accept/decline), payment-init gate, and quote expiry/timeout sweeps

* (SP: 3)[SHOP] introduce outbox-driven notifications with projector + worker (phase 3)

* (SP: 3)[SHOP] add minimal returns/RMA lifecycle with atomic audit + canonical events (phase 4)

* (SP: 3)[SHOP] enforce guest status-token lite-only access and audit token usage (phase 5)

* (SP: 3)[SHOP] centralize transition guards and enforce across admin/webhook/worker flows (phase 6)

:wq
n

* (SP:3)[SHOP]: enforce DATABASE_URL_LOCAL preflight + deterministic vitest config

* (SP:3)[SHOP]: require canonical events in prod (fail-fast)

* (SP:3)[SHOP]: implement notifications transport with retries + DLQ

* (SP:3)[SHOP]: persist checkout legal consent artifact

* (SP:1)[SHOP] add migration 0025 for consent + events + audit + prices

* (SP:1)[SHOP] emit shipping_events for shipment worker transitions

* (SP:2)[SHOP] audit admin product mutations (deduped)

* (SP:2)[SHOP] make Monobank webhook retryable on transient apply failures

* (SP:3) [SHOP] enforce guest status-token scopes across order actions

* (SP:1) [SHOP] make product_prices the only write authority

* (SP:1) [SHOP]  add Playwright e2e smoke suite (local DB only)

* (SP:3) [SHOP] explicitly reject exchanges (EXCHANGES_NOT_SUPPORTED)

* (SP: 3)[FIX] harden audit + workers/tests; fix transitions/restock + webhook perf

* (SP: 3)[FIX] harden local-db test safety and tighten shop reliability guards

* (SP: 3)[FIX] fail-closed admin audit, refine shipments-worker outcomes/metrics, tighten quote+tests

* (SP: 1)[FIX] harden shipments-worker claiming/leases and make audit+quote/test paths resilient

* (SP: 1)[FIX] harden quote request errors/logging and sanitize requestId; document best-effort delete audit

* feat(ui): add devops/cloud category icons and styles (#379)

* chore(release): prepare v1.0.6 changelog

* chore: bump version to 1.0.6

* fix(orders): close missing brace in checkout shipping snapshot try block

* fix(checkout): correct nested try/catch structure for shipping snapshot

* fix(order-status): remove stale responseMode lite branch

---------

Co-authored-by: Liudmyla Sovetovs <milkaegik@gmail.com>
Co-authored-by: Lesia Soloviova <106915140+LesiaUKR@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Performance and efficiency optimizations without functional changes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant