Skip to content

Lso/feat/shop design#252

Merged
ViktorSvertoka merged 9 commits into
developfrom
lso/feat/shop-design
Feb 2, 2026
Merged

Lso/feat/shop design#252
ViktorSvertoka merged 9 commits into
developfrom
lso/feat/shop-design

Conversation

@liudmylasovetovs
Copy link
Copy Markdown
Collaborator

@liudmylasovetovs liudmylasovetovs commented Feb 2, 2026

Description

This PR standardizes the Shop module codebase by reorganizing tests under the Shop folder structure, aligning component names with React PascalCase conventions, and removing redundant/unused code for better readability and maintenance.


Related Issue

Issue: #<issue_number>


Changes

  • Moved Shop-related tests into the /shop test folder structure to keep domain boundaries clear and improve discoverability.
  • Renamed Shop components to PascalCase to match React conventions and reduce naming inconsistencies across the codebase.
  • Cleaned up code by removing unused imports/props, simplifying local logic, and applying small formatting/consistency fixes (no behavior changes intended).

Database Changes (if applicable)

  • Schema migration required
  • Seed data updated
  • Breaking changes to existing queries
  • Transaction-safe migration
  • Migration tested locally on Neon

How Has This Been Tested?

  • Tested locally
  • Verified in development environment
  • Checked responsive layout (if UI-related)
  • Tested accessibility (keyboard / screen reader)

Screenshots (if applicable)


Checklist

Before submitting

  • Code has been self-reviewed
  • No TypeScript or console errors
  • Code follows project conventions
  • Scope is limited to this feature/fix
  • No unrelated refactors included
  • English used in code, commits, and docs
  • New dependencies discussed with team
  • Database migration tested locally (if applicable)
  • GitHub Projects card moved to In Review

Reviewers

Summary by CodeRabbit

  • New Features

    • Improved active-state styling for filters and navigation for clearer interaction feedback.
  • Bug Fixes

    • Tightened currency/price validation to reject unsafe or invalid minor-unit inputs.
    • Improved error logging for payment webhook failures to aid troubleshooting.
  • Refactor

    • Normalized module import paths for more consistent resolution across environments.
    • Reorganized and adjusted test suites for clarity and structure.
  • Documentation

    • Removed redundant inline comments across the codebase.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Feb 2, 2026

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

Project Deployment Actions Updated (UTC)
devlovers-net Ready Ready Preview, Comment Feb 2, 2026 2:22am

@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 2, 2026

Deploy Preview for develop-devlovers ready!

Name Link
🔨 Latest commit 579512e
🔍 Latest deploy log https://app.netlify.com/projects/develop-devlovers/deploys/69800a1225f3af0008c380ac
😎 Deploy Preview https://deploy-preview-252--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
Copy Markdown
Contributor

coderabbitai Bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

Normalized many frontend import paths to PascalCase, removed widespread comments, tightened money/minor-unit validation, added/removed/adjusted several tests, and added targeted runtime logging in the Stripe webhook and small hardenings in order/restock flows.

Changes

Cohort / File(s) Summary
Import Path Normalization (PascalCase)
frontend/app/[locale]/shop/admin/..., frontend/app/[locale]/shop/..., frontend/components/header/..., frontend/components/shop/..., frontend/components/shop/header/...
Replaced many kebab-case imports with PascalCase file paths (e.g., shop-admin-topbarShopAdminTopbar, cart-providerCartProvider). Mostly module-resolution changes; verify case-sensitive filesystems.
Money parsing & currency tightening
frontend/lib/shop/money.ts, frontend/lib/shop/currency.ts
Stricter validation added: safety checks for minor units, tightened parseMajorToMinor (trim, leading-dot normalization, rounding, safe-integer enforcement) and new assert helpers. Public signatures unchanged but behavior more restrictive.
Order / restock / checkout adjustments
frontend/lib/services/orders/checkout.ts, frontend/lib/services/orders/restock.ts, frontend/lib/services/orders/...
Removed many comments and made targeted runtime hardenings: stricter variant/config validation (throws on missing), workerId values updated for restock calls, and paymentStatus access now via PAYMENT_STATUS_KEY constant.
Stripe webhook logging
frontend/app/api/shop/webhooks/stripe/route.ts
Catch block now accepts error param and emits a console.warn with code and merged metadata before returning 500 — control flow unchanged but failures are now logged.
UI tweak: ProductFilters active state
frontend/components/shop/ProductFilters.tsx
Added active:text-accent to non-selected filter items to apply accent color during active interactions in addition to hover.
Cart & ClearCart import fixes
frontend/app/[locale]/shop/cart/CartPageClient.tsx, frontend/components/shop/ClearCartOnMount.tsx, frontend/components/.../CartButton.tsx, frontend/components/header/...
Updated import paths to match actual component filenames (CartProvider, ClearCartOnMount, CartButton). No logic change; check module resolution.
Tests added / removed / modified
frontend/lib/tests/shop/order-items-snapshot-immutable.test.ts, frontend/lib/tests/shop/orders-access.test.ts, many frontend/lib/tests/...
Added new tests (order-items snapshot immutability, orders-access), removed some legacy tests, and trimmed many test comments. Some import paths and test data adjusted; run CI to validate.
Widespread comment/doc cleanup & formatting
frontend/lib/..., frontend/lib/services/..., frontend/lib/tests/..., frontend/lib/validation/...
Large-scale removal of explanatory comments/docblocks and minor formatting changes across many libs and services. Mostly non-functional but affects many files; review domain-specific areas touched.
Minor logging/error handling additions in rate-limit & webhook migration paths
frontend/lib/security/rate-limit.ts, frontend/lib/...
Some catch blocks now log warnings (migration/error paths) where previously swallowed; behavior otherwise preserved. Verify logging expectations.

Sequence Diagram(s)

(omitted — changes do not introduce a new multi-component control flow requiring diagram)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • AM1007
  • ViktorSvertoka

Poem

"🐰 I hopped through imports, neat and bright,
Caps where kebabs once took flight.
I nibbled comments, trimmed the fluff,
Tightened cents so cents are tough.
Tests now guard the snapshots true — hooray, a rabbit's review!"

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
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.
Title check ❓ Inconclusive The title 'Lso/feat/shop design' is vague and uses a non-descriptive branch prefix format that doesn't clearly convey the main changes: standardizing Shop module codebase by reorganizing tests and aligning component naming. Revise the title to be more descriptive and meaningful, such as 'Standardize Shop module: reorganize tests, rename components to PascalCase' or 'Refactor Shop module: update component naming and test structure'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch lso/feat/shop-design

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
Copy Markdown
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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/lib/tests/shop/checkout-concurrency-stock1.test.ts (1)

227-250: ⚠️ Potential issue | 🟡 Minor

Avoid swallowing cleanup errors in tests.

The empty catch {} hides DB cleanup failures, which can leave residual data and cause flaky follow-up tests. Consider logging the error (or rethrowing in CI) so failures are visible.

🛠️ Suggested fix
-    } catch {}
+    } catch (err) {
+      // eslint-disable-next-line no-console
+      console.warn('checkout concurrency cleanup failed', err);
+    }
🤖 Fix all issues with AI agents
In `@frontend/lib/services/orders/checkout.ts`:
- Around line 507-509: The loop over normalizedItems silently continues when cfg
is missing which masks invariant violations (dbProducts.length ===
uniqueProductIds.length). Update the loop in checkout.ts so that when
variantMap.get(item.productId) returns undefined you either throw an Error
(fail-fast) or emit a warning via the existing logger (e.g., processLogger or
orderLogger) with context (item.productId, normalizedItems, uniqueProductIds);
reference the variables normalizedItems, variantMap, item.productId, dbProducts
and uniqueProductIds to locate and change the behavior from a silent continue to
an explicit error or logged warning.

In `@frontend/lib/tests/shop/restock-release-failure-invariant.test.ts`:
- Around line 132-137: The empty catch around the restockOrder call swallows any
unexpected errors; change the test to catch the error and assert it matches the
simulated release failure instead of ignoring it. Specifically, update the try {
await restockOrder(orderId, {...}) } catch {} block in
restock-release-failure-invariant.test.ts to capture the thrown error from
restockOrder and assert its type/message/instance indicates the simulated
"release failure" (or rethrow if it is not the expected error), referencing the
restockOrder call and the simulated release failure in your assertions so only
the intended error is accepted.
🧹 Nitpick comments (12)
frontend/lib/tests/shop/restock-stale-claim-gate.test.ts (1)

130-138: Consider verifying final state after processing.

The first test (lines 62-72) verifies stockRestored and restockedAt remain unchanged when the order is skipped. For consistency and completeness, this test should verify that stockRestored is true and restockedAt is set after successful processing.

💡 Suggested addition after line 138
       expect(processed).toBe(1);
+
+      const [row] = await db
+        .select({
+          stockRestored: orders.stockRestored,
+          restockedAt: orders.restockedAt,
+        })
+        .from(orders)
+        .where(eq(orders.id, orderId))
+        .limit(1);
+
+      expect(row?.stockRestored).toBe(true);
+      expect(row?.restockedAt).not.toBeNull();
     } finally {
frontend/lib/security/rate-limit.ts (1)

185-185: Add error logging or an explanatory comment to the empty catch block.

Empty catch blocks silently swallow errors, making it difficult to diagnose issues like database connection failures, permission errors, or constraint violations. While the key migration is non-critical to rate limiting functionality, logging failures would improve operational visibility and help identify systematic migration problems.

🔍 Proposed fix to add error logging
-    } catch {}
+    } catch (err) {
+      // Migration failed, but rate limiting continues with legacy key
+      console.warn('[rate-limit] Failed to migrate legacy key:', legacyKey, err);
+    }

Alternatively, if logging is intentionally omitted, add a comment explaining why:

-    } catch {}
+    } catch {
+      // Ignore migration errors; rate limiting continues with legacy key
+    }
frontend/lib/services/products/admin/queries.ts (1)

43-58: Consider preserving a brief note about the defensive validation rationale.

The removed guard comment explained why assertMoneyMinorInt is called (DB drivers may not guarantee integer types). While the function name is self-documenting, a one-line comment could help future maintainers understand this isn't redundant validation.

📝 Optional: add a brief rationale comment
+  // Defensive: validate DB driver returns integers for minor-unit columns
   return rows.map(r => ({
     currency: r.currency as CurrencyCode,
     priceMinor: assertMoneyMinorInt(
frontend/app/api/shop/webhooks/stripe/route.ts (1)

1510-1521: Consider logging the secondary failure for operational visibility.

The empty catch block silently swallows any error from the claim-release operation. While the primary error is already logged and the 500 response is returned regardless, logging this secondary failure could help diagnose intermittent database connectivity issues.

💡 Optional: Add minimal logging for claim-release failures
     try {
       await db
         .update(stripeEvents)
         .set({ claimExpiresAt: new Date(0) })
         .where(
           and(
             eq(stripeEvents.eventId, event.id),
             eq(stripeEvents.claimedBy, STRIPE_WEBHOOK_INSTANCE_ID),
             isNull(stripeEvents.processedAt)
           )
         );
-    } catch {}
+    } catch (claimReleaseErr) {
+      logWarn('stripe_webhook_claim_release_failed', {
+        ...eventMeta(),
+        code: 'CLAIM_RELEASE_FAILED',
+      });
+    }
frontend/lib/tests/shop/stripe-webhook-psp-fields.test.ts (2)

38-42: Unusual empty line within headers object.

There's an empty line (line 40) between the header entries. While this doesn't affect functionality, it's inconsistent formatting that may have been introduced accidentally during cleanup.

🧹 Suggested fix
   return new NextRequest('http://localhost:3000/api/shop/webhooks/stripe', {
     method: 'POST',
     headers: {
       'Content-Type': 'application/json',
-
       'Stripe-Signature': 't=1,v1=test',
     },

162-168: Unusual empty line within object literal.

Similar to the headers object, there's an empty line (line 164) between order fields. This appears to be accidental formatting.

🧹 Suggested fix
     await db.insert(orders).values({
       id: orderId,
       totalAmountMinor: 900,
       totalAmount: '9.00',
       currency: 'USD',
       paymentStatus: 'requires_payment',
       paymentProvider: 'stripe',
       paymentIntentId,
-
       idempotencyKey: idemKey,
frontend/lib/shop/currency.ts (1)

13-18: Consider aligning validation with money.ts for consistency.

assertMinorUnitsStrict here lacks the Number.isSafeInteger() check that assertIntegerCentsStrict in money.ts now enforces. For very large amounts (>2^53), this could silently accept values that lose precision.

♻️ Optional: Add safe integer validation
 function assertMinorUnitsStrict(minor: number): number {
   if (!Number.isFinite(minor) || !Number.isInteger(minor) || minor < 0) {
     throw new Error('Invalid money minor-units value');
   }
+  if (!Number.isSafeInteger(minor)) {
+    throw new Error('Money minor-units exceeds JS safe integer range');
+  }
   return minor;
 }
frontend/lib/shop/money.ts (1)

29-34: Redundant ternary branch.

Both branches of the inner ternary (Number.isFinite(input) ? String(input) : String(input)) produce the same result, making the isFinite check here superfluous.

♻️ Simplify the expression
   const raw =
     typeof input === 'string'
       ? input.trim()
-      : Number.isFinite(input)
-        ? String(input)
-        : String(input);
+      : String(input);
frontend/lib/tests/shop/restock-stuck-reserving-sweep.test.ts (3)

48-48: Consider adding clarity to the time offset calculation.

The magic number 2 * 60 * 60 * 1000 (2 hours in milliseconds) sets up a timestamp condition for the sweep logic test. Since a comment was removed here, consider extracting this to a named constant or adding a brief inline comment to aid future maintainability.

📝 Optional refactor
+    // Created 2 hours ago to trigger sweep (> 10min threshold)
     const createdAt = new Date(Date.now() - 2 * 60 * 60 * 1000);

Or extract to a constant:

+    const TWO_HOURS_MS = 2 * 60 * 60 * 1000;
-    const createdAt = new Date(Date.now() - 2 * 60 * 60 * 1000);
+    const createdAt = new Date(Date.now() - TWO_HOURS_MS);

53-66: Consider removing as any type assertion.

The as any cast at line 66 bypasses TypeScript's type checking for the product insert. While common in test code, this can mask schema mismatches or missing required fields. Consider aligning the object literal with the expected schema type to restore type safety.


68-93: Consider removing as any type assertion.

Similar to the product insert, the as any cast at line 93 suppresses type checking for the order insert. Removing this assertion would help catch potential schema drift during development.

frontend/lib/services/orders/checkout.ts (1)

280-280: Consider documenting the intentional empty catch block.

Empty catch blocks are typically a code smell and may be flagged by linters. While silently falling through to the delimiter-based parsing is the correct behavior here, a brief comment clarifies this is intentional and not an oversight.

📝 Suggested documentation
-    } catch {}
+    } catch {
+      // Intentionally empty: fall through to delimiter-based parsing
+    }

Comment thread frontend/lib/services/orders/checkout.ts Outdated
Comment thread frontend/lib/tests/shop/restock-release-failure-invariant.test.ts Outdated
Copy link
Copy Markdown
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

🤖 Fix all issues with AI agents
In `@frontend/lib/tests/shop/restock-stale-claim-gate.test.ts`:
- Around line 138-139: Remove the duplicate assertion expecting processed to
equal 1: in the test that currently contains two identical lines
"expect(processed).toBe(1);" keep a single assertion and delete the redundant
one so the test only asserts processed once.

Comment thread frontend/lib/tests/shop/restock-stale-claim-gate.test.ts Outdated
@ViktorSvertoka ViktorSvertoka merged commit 2bcafdd into develop Feb 2, 2026
10 checks passed
@ViktorSvertoka ViktorSvertoka deleted the lso/feat/shop-design branch February 2, 2026 05:52
ViktorSvertoka added a commit that referenced this pull request Feb 3, 2026
* chore: bump Node.js to 20 for Netlify

* feat(md) add netlify status (#234)

* (SP 2) [Shop UI] Unify storefront styles across components and interactions (#236)

* Host (#237)

* feat(md) add netlify status

* feat(files): add packages

* fix(auth): use currentTarget for email input validity

* Host (#238)

* feat(md) add netlify status

* feat(files): add packages

* fix(auth): use currentTarget for email input validity

* fix(auth): use currentTarget for email input validity

* fix(auth): use currentTarget in password field

* (SP 1) [Shop UI] Add page metadata across shop routes (#239)

* (SP 2) [Shop UI] Unify storefront styles across components and interactions

* (SP 1) [Shop UI] Add page metadata across shop routes

* (SP: 3) [Cache] Add Upstash Redis cache for Q&A (#241)

* feat(md) add netlify status

* feat(files): add packages

* fix(auth): use currentTarget for email input validity

* fix(auth): use currentTarget for email input validity

* fix(auth): use currentTarget in password field

* feat(qa): add Redis cache layer for Q&A

* Fix Q&A Redis cache parsing for Upstash REST (#243)

* feat(md) add netlify status

* feat(files): add packages

* fix(auth): use currentTarget for email input validity

* fix(auth): use currentTarget for email input validity

* fix(auth): use currentTarget in password field

* feat(qa): add Redis cache layer for Q&A

* fix(qa): handle non-string Redis cache values

* feat(Blog):Adding pagination (#244)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added scroll on the main blog page on filtering by author, fied breadcrumbs category translaion, added category to the recommended cards, fixed search for localisations

* feat(Blog): Changed image size on the post details page

* feat(Blog): added tests

* feat(Blog): fix for big post on the post page, added tests

* feat(Blog): resolving comments

* feat(Blog): fixed hover for social links icins - dark theme

* feat(Blog): bringing the style on the blog page to a single site style

* feat(blog): aligning syles

* feat(blog): resolving comment from CodeRabbit

* feat(blog):fix comment for deployment

* feat(Blog): adding pagination

* feat(Blog): Addind Text formatting visibility

* (SP:2) feat(api): clean up AI helper for Vercel & fix orders i18n (#245)

- Refactor /api/ai/explain route for Vercel deployment
    - Replace dynamic import with static import of groq-sdk
    - Use request.json() instead of Netlify-safe body parsing
    - Add proper error handling with Groq.APIError types
    - Simplify GET health check endpoint
    - Update model from llama3-70b-8192 to llama-3.3-70b-versatile
- Add table.openOrder and table.orderId to en/uk/pl locales

* refactor(home): update button, cards, and online counter UI (#248)

Improve primary button styles
Fix card overflow and add subtle highlights
Redesign online users counter and reduce font size

* fix(api): enforce rate limiting (#246)

* (SP:2) feat(api): clean up AI helper for Vercel & fix orders i18n

  - Refactor /api/ai/explain route for Vercel deployment
    - Replace dynamic import with static import of groq-sdk
    - Use request.json() instead of Netlify-safe body parsing
    - Add proper error handling with Groq.APIError types
    - Simplify GET health check endpoint
    - Update model from llama3-70b-8192 to llama-3.3-70b-versatile
- Add table.openOrder and table.orderId to en/uk/pl locales

* fix(api): enforce rate limiting

---------

Co-authored-by: Viktor Svertoka <victor.svertoka@gmail.com>

* feat(Blog):formating text (#249)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added scroll on the main blog page on filtering by author, fied breadcrumbs category translaion, added category to the recommended cards, fixed search for localisations

* feat(Blog): Changed image size on the post details page

* feat(Blog): added tests

* feat(Blog): fix for big post on the post page, added tests

* feat(Blog): resolving comments

* feat(Blog): fixed hover for social links icins - dark theme

* feat(Blog): bringing the style on the blog page to a single site style

* feat(blog): aligning syles

* feat(blog): resolving comment from CodeRabbit

* feat(blog):fix comment for deployment

* feat(Blog): adding pagination

* feat(Blog): Addind Text formatting visibility

* feat(Blog):adding text formating fix

* ref(files): refactoring code & bag fix (#250)

* chore(release): v0.5.2

* Lso/feat/shop design (#252)

* feat(i18n): add translations for blog categories, and UI components (#253)

- Translate blog category labels in mobile menu, cards, and filters
  - Add CTA hover variants translations
  - Add aria-label translations for theme toggle, cart, search, GitHub star
  - Update translation files for EN, UK, PL locales

* feat blog: fix for paddings on mobile  (#254)

* feat(Blog):fix for clickable link in post details, fix for author details

* feat(Blog):refactoring after removing author modal

* feat(Blog): fix unified date format

* feat(Blog): Fix for  click-outside-to-close search, recommended posts are limited to 3

* feat(Blog): selectedAuthorData fixed

* feat(Blog): Added description for /blog/[slug] metadata, Added Schema.org JSON‑LD for Article (BlogPosting) and BreadcrumbList , Added <time datetime> tags where blog dates renders

* feat(Blog): fix hover social links, fixed duplication not found search

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added: breadcrumbs to the post details page and updated the BreadcrumbList, logo to the cocial links in User info, Fixed: main container alignment, category navigation in breadcrumbs

* feat(Blog): Added scroll on the main blog page on filtering by author, fied breadcrumbs category translaion, added category to the recommended cards, fixed search for localisations

* feat(Blog): Changed image size on the post details page

* feat(Blog): added tests

* feat(Blog): fix for big post on the post page, added tests

* feat(Blog): resolving comments

* feat(Blog): fixed hover for social links icins - dark theme

* feat(Blog): bringing the style on the blog page to a single site style

* feat(blog): aligning syles

* feat(blog): resolving comment from CodeRabbit

* feat(blog):fix comment for deployment

* feat(Blog): adding pagination

* feat(Blog): Addind Text formatting visibility

* feat(Blog):adding text formating fix

* chore(lint): finalize ESLint + Prettier (#256)

* feat(leaderboard): finalize components and fix lint errors (#259)

* (SP 1) [FIX] set up eslint/prettier + stabilize formatting workflow (own files only) (#264)

* (SP 2) [Shop UI] Unify storefront styles across components and interactions

* (SP 1) [Shop UI] Add page metadata across shop routes

* (SP 1) [FIX] names of components, replacing tests, clean code

* (SP 1) [FIX] remove magic constant and align restock sweep test typing

* (SP 1) [FIX] remove duplicate

* (SP 1) [FIX] set up eslint/prettier + stabilize formatting workflow (own files only)

* (SP 1) [FIX] Tailwind hints

* (SP 1) [FIX] Tailwind hints revert

* (SP: 5) [Quiz] Redis caching + guest session fix + cleanup (#263)

* feat(quiz-ui): quiz UI polish - tabs, category accents, color scheme (issues #181, #193, #194)

- Refactor QaTabButton to shared CategoryTabButton component
- Add category accent colors to QuizCard, buttons, progress indicators
- Standardize colors with CSS variables, traffic light timer
- Add DynamicGridBackground to quizzes list page
- Border-only answer feedback, semi-transparent progress styles

* docs: update .gitignore

* fix(quiz): align disqualification threshold with warning banner

Changed violationsCount > 3 to >= 3 in QuizResult points block
to match the warning banner threshold at line 124.

* feat(quiz-testing): add quiz unit tests

- Configure Vitest for quiz module
- Add test factories and setup utilities
- Add quiz-crypto tests (13 tests)
- Add quiz-session tests (12 tests)

* test(quiz): add integration tests for verify-answer API and useAntiCheat hook (#199)

- verify-answer.test.ts: 8 tests for API endpoint
  - Correct/wrong answer verification
  - Validation errors (missing fields, tampered data)
  - Security: rejects modified encrypted answers

- quiz-anticheat.test.ts: 10 tests for useAntiCheat hook
  - Detects copy, paste, context-menu, tab-switch events
  - Respects isActive flag
  - Reset and cleanup functionality

Total quiz tests: 52 (9 setup + 25 unit + 18 integration)

* test(quiz): expand test coverage to 90%+ with hooks, API routes, and UI flow

Add 28 new tests covering:
- useQuizSession hook (6 tests)
- useQuizGuards hook (8 tests)
- guest-quiz storage (5 tests)
- guest-result API route (5 tests)
- quiz-slug API route (3 tests)
- QuizContainer UI flow (1 test)

Coverage: 35% -> 90.94% (quiz scope)
Tests: 52 -> 80

* chore: remove coverage-quiz from git, add to .gitignore

* chore: add coverage-quiz to .gitignore, fix quiz guards test

* fix(a11y): improve quiz accessibility and i18n compliance

* fix(sl/feat/quiz): replace with correct name for react icon

* feat(quiz): implement Redis caching + session fixes + cleanup

Closes #260, #261, #262

- Add quiz-answers-redis.ts with getOrCreateQuizAnswersCache()
- Cache correct answers per quiz (12h TTL)
- Replace AES-256-GCM decryption with O(1) Redis lookup
- Add initializeQuizCache server action
- Update verify-answer route to use Redis

- Allow restoring 'completed' sessions (not just 'in_progress')
- Only clear session for authenticated users after submit
- Guest result screen now survives language switch

- Delete PendingResultHandler.tsx (never executes)
- Delete start-session/route.ts (broken import, unused)
- Delete quiz-crypto.ts (AES replaced by Redis)
- Delete quiz-crypto.test.ts (tests dead code)
- Rewrite verify-answer.test.ts for Redis API (8 tests)
- Fix quiz-session.test.ts for completed session restore

* chore(quiz): delete unused start-session route

Part of #262 cleanup - route had broken import after Redis migration.

* git commit -m "fix(quiz): add NaN seed validation and cache/DB fallback

- Validate seed param to prevent NaN breaking question shuffle
- Add cache recovery in verify-answer when Redis cache expires
- Add DB fallback in getCorrectAnswer when Redis unavailable

* chore: remove redis ttl for static quiz and qa caches (#265)

* fix(layout): remove duplicate padding from quiz routes (#266)

* feat(quiz-ui): quiz UI polish - tabs, category accents, color scheme (issues #181, #193, #194)

- Refactor QaTabButton to shared CategoryTabButton component
- Add category accent colors to QuizCard, buttons, progress indicators
- Standardize colors with CSS variables, traffic light timer
- Add DynamicGridBackground to quizzes list page
- Border-only answer feedback, semi-transparent progress styles

* docs: update .gitignore

* fix(quiz): align disqualification threshold with warning banner

Changed violationsCount > 3 to >= 3 in QuizResult points block
to match the warning banner threshold at line 124.

* feat(quiz-testing): add quiz unit tests

- Configure Vitest for quiz module
- Add test factories and setup utilities
- Add quiz-crypto tests (13 tests)
- Add quiz-session tests (12 tests)

* test(quiz): add integration tests for verify-answer API and useAntiCheat hook (#199)

- verify-answer.test.ts: 8 tests for API endpoint
  - Correct/wrong answer verification
  - Validation errors (missing fields, tampered data)
  - Security: rejects modified encrypted answers

- quiz-anticheat.test.ts: 10 tests for useAntiCheat hook
  - Detects copy, paste, context-menu, tab-switch events
  - Respects isActive flag
  - Reset and cleanup functionality

Total quiz tests: 52 (9 setup + 25 unit + 18 integration)

* test(quiz): expand test coverage to 90%+ with hooks, API routes, and UI flow

Add 28 new tests covering:
- useQuizSession hook (6 tests)
- useQuizGuards hook (8 tests)
- guest-quiz storage (5 tests)
- guest-result API route (5 tests)
- quiz-slug API route (3 tests)
- QuizContainer UI flow (1 test)

Coverage: 35% -> 90.94% (quiz scope)
Tests: 52 -> 80

* chore: remove coverage-quiz from git, add to .gitignore

* chore: add coverage-quiz to .gitignore, fix quiz guards test

* fix(a11y): improve quiz accessibility and i18n compliance

* fix(sl/feat/quiz): replace with correct name for react icon

* feat(quiz): implement Redis caching + session fixes + cleanup

Closes #260, #261, #262

- Add quiz-answers-redis.ts with getOrCreateQuizAnswersCache()
- Cache correct answers per quiz (12h TTL)
- Replace AES-256-GCM decryption with O(1) Redis lookup
- Add initializeQuizCache server action
- Update verify-answer route to use Redis

- Allow restoring 'completed' sessions (not just 'in_progress')
- Only clear session for authenticated users after submit
- Guest result screen now survives language switch

- Delete PendingResultHandler.tsx (never executes)
- Delete start-session/route.ts (broken import, unused)
- Delete quiz-crypto.ts (AES replaced by Redis)
- Delete quiz-crypto.test.ts (tests dead code)
- Rewrite verify-answer.test.ts for Redis API (8 tests)
- Fix quiz-session.test.ts for completed session restore

* chore(quiz): delete unused start-session route

Part of #262 cleanup - route had broken import after Redis migration.

* git commit -m "fix(quiz): add NaN seed validation and cache/DB fallback

- Validate seed param to prevent NaN breaking question shuffle
- Add cache recovery in verify-answer when Redis cache expires
- Add DB fallback in getCorrectAnswer when Redis unavailable

* fix(layout): remove duplicate padding from quiz routes

Add isQuizzesPath to MainSwitcher to exclude /quiz and /quizzes routes
from extra px-6 padding, matching Q&A page behavior.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: liudmylasovetovs <127711697+liudmylasovetovs@users.noreply.github.com>
Co-authored-by: KomrakovaAnna <komrakova.anna@gmail.com>
Co-authored-by: Tetiana Zorii <131365289+TiZorii@users.noreply.github.com>
Co-authored-by: Yuliia Nazymko <122815071+YNazymko12@users.noreply.github.com>
Co-authored-by: AlinaRyabova <115992255+AlinaRyabova@users.noreply.github.com>
Co-authored-by: Lesia Soloviova <106915140+LesiaUKR@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
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.

2 participants