Skip to content

(SP: 3) [Testing] Vitest config + unit + integration tests for quiz module#204

Merged
ViktorSvertoka merged 11 commits into
developfrom
sl/feat/quiz
Jan 25, 2026
Merged

(SP: 3) [Testing] Vitest config + unit + integration tests for quiz module#204
ViktorSvertoka merged 11 commits into
developfrom
sl/feat/quiz

Conversation

@LesiaUKR
Copy link
Copy Markdown
Collaborator

@LesiaUKR LesiaUKR commented Jan 25, 2026

Week 6

Closes #197
Closes #198
Closes #199
Closes #205

Goal

Set up quiz testing foundation and achieve 90%+ coverage for critical quiz logic, hooks, API routes, and UI flow.

Scope

  • Quiz test factories and setup utilities
  • Unit tests for crypto, session, guest storage
  • Integration tests for API routes, hooks, and UI flow

Changes

Setup / Infrastructure

  • lib/tests/__mocks__/server-only.ts (server-only mock)
  • lib/tests/factories/quiz/quiz.ts
  • lib/tests/quiz/setup.ts
  • lib/tests/quiz/quiz-setup.test.ts (9 tests)

Unit Tests

  • lib/tests/quiz/quiz-crypto.test.ts (13 tests)
  • lib/tests/quiz/quiz-session.test.ts (12 tests)
  • lib/tests/quiz/use-quiz-session.test.ts (6 tests)
  • lib/tests/quiz/guest-quiz.test.ts (5 tests)

Integration Tests

  • lib/tests/quiz/verify-answer.test.ts (8 tests)
  • lib/tests/quiz/quiz-anticheat.test.ts (10 tests)
  • lib/tests/quiz/use-quiz-guards.test.ts (8 tests)
  • lib/tests/quiz/guest-result-route.test.ts (5 tests)
  • lib/tests/quiz/quiz-slug-route.test.ts (3 tests)
  • components/quiz/tests/quiz-container-flow.test.tsx (1 test)

Test Metrics

Metric Value
Test files 11
Total tests 80
Unit tests 36 (45%)
Integration tests 35 (44%)
Setup tests 9 (11%)
Line coverage (quiz scope) 90.94%

Coverage by Module

Module Lines
quiz-crypto.ts 96.87%
useQuizSession.ts 100%
[slug]/route.ts 100%
verify-answer/route.ts 92.3%
useQuizGuards.ts 90.76%
guest-quiz.ts 90%
guest-result/route.ts 85.71%
quiz-session.ts 84%

Expected Impact

  • 90%+ coverage for quiz module critical paths
  • Regression protection for security (encryption, anti-cheat)
  • Regression protection for UX (session persistence, guards)
  • Solid foundation for future quiz features

Out of Scope

  • Full E2E flows (Playwright)
  • Database integration tests

Summary by CodeRabbit

  • Tests
    • Added extensive quiz test coverage: anti-cheat, encryption/verification, session persistence, guest flows, API routes, hooks, and end-to-end quiz flow.
  • Tests / Utilities
    • Introduced reusable test factories, environment setup, and localStorage mocks to simplify quiz tests.
  • Chores
    • Enabled additional coverage reporting and ignored a new coverage output directory; added a test-coverage dev dependency.

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

…(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
Changed violationsCount > 3 to >= 3 in QuizResult points block
to match the warning banner threshold at line 124.
- Configure Vitest for quiz module
- Add test factories and setup utilities
- Add quiz-crypto tests (13 tests)
- Add quiz-session tests (12 tests)
…eat 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)
@netlify
Copy link
Copy Markdown

netlify Bot commented Jan 25, 2026

Deploy Preview for develop-devlovers ready!

Name Link
🔨 Latest commit 786b33c
🔍 Latest deploy log https://app.netlify.com/projects/develop-devlovers/deploys/6976554777523d0008eb820f
😎 Deploy Preview https://deploy-preview-204--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 Jan 25, 2026

📝 Walkthrough

Walkthrough

Adds comprehensive quiz testing infrastructure: test factories, test environment utilities, vitest coverage config and devDependency, and ~13 new test files covering crypto, session persistence, anti-cheat, hooks, API routes, storage helpers, and a UI flow test.

Changes

Cohort / File(s) Summary
Test Factories & Setup
frontend/lib/tests/factories/quiz/quiz.ts, frontend/lib/tests/quiz/setup.ts
New quiz test factories (MockQuestion, MockQuizSession, factory helpers, deterministic counter) and test env utilities (TEST_ENCRYPTION_KEY, setup/cleanup, mock localStorage installable API).
Unit Tests — Utilities & Hooks
frontend/lib/tests/quiz/quiz-crypto.test.ts, frontend/lib/tests/quiz/quiz-session.test.ts, frontend/lib/tests/quiz/quiz-anticheat.test.ts
New unit tests for encryption/decryption (tamper detection, base64), session save/load/expiry semantics, and anti-cheat hook event tracking and cleanup.
API Route Tests
frontend/lib/tests/quiz/verify-answer.test.ts, frontend/lib/tests/quiz/guest-result-route.test.ts, frontend/lib/tests/quiz/quiz-slug-route.test.ts
Tests for POST /api/quiz/verify-answer, POST /api/quiz/guest-result, and GET /api/quiz/[slug] covering success, validation errors, not-found, and persistence flows with mocked DB/auth.
Hook & Integration Tests
frontend/lib/tests/quiz/use-quiz-guards.test.ts, frontend/lib/tests/quiz/use-quiz-session.test.ts
Tests for navigation guards, beforeunload handling, external-nav flows, session restore/clear/save behavior, and interactions with persistence helpers.
Storage & Setup Validation
frontend/lib/tests/quiz/guest-quiz.test.ts, frontend/lib/tests/quiz/quiz-setup.test.ts
Tests for guest-result localStorage helpers, TTL/invalid JSON handling, factory outputs, encryption key setup/cleanup, and mock localStorage behavior.
UI Flow Test
frontend/components/quiz/tests/quiz-container-flow.test.tsx
End-to-end style test for quiz container: rules → start → answer selection → verify API call → transition to guest login, with multiple mocks (i18n, anti-cheat, toasts, submission).
Config & DevDependencies
frontend/vitest.config.ts, frontend/package.json, frontend/.gitignore
Vitest test include extended and coverage section added (provider: v8, reporters text/html, include globs), @vitest/coverage-v8 added to devDependencies, and /coverage-quiz ignored in .gitignore.

Sequence Diagram(s)

(Skipped — changes are test additions and utilities; no new multi-component runtime control flow introduced that requires diagramming.)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • AM1007
  • ViktorSvertoka

Poem

🐰
I hopped through mocks and keys so bright,
Built quizzes for the testing night,
Encrypting answers, sessions kept,
Guards and routes and flows well-stepped,
Now coverage blooms — a carrot light. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.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 accurately captures the main change: adding Vitest configuration and comprehensive unit/integration tests for the quiz module, which aligns with all changes in the PR.
Linked Issues check ✅ Passed The PR fully addresses all linked issues (#197, #198, #199, #205): Vitest config with v8 coverage [#197], unit tests for crypto/session utilities [#198], integration tests for API/hooks [#199], and expanded coverage to 90%+ with hooks/API/UI tests [#205].
Out of Scope Changes check ✅ Passed All changes are in-scope: test files (factories, unit/integration tests), test configuration (vitest.config, setup utilities), test infrastructure (coverage, gitignore), and dependencies (@vitest/coverage-v8) directly support testing objectives.

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

✨ Finishing touches
  • 📝 Generate docstrings

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: 1

Caution

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

⚠️ Outside diff range comments (1)
frontend/package.json (1)

67-77: Fix peer dependency mismatch: @vitest/coverage-v8@4.0.18 requires vitest@4.0.18.

@vitest/coverage-v8 declares pinned peer dependencies (exact version match). The current setup violates this: @vitest/coverage-v8@4.0.18 expects vitest@4.0.18, not 4.0.16.

Choose one:

  • Downgrade @vitest/coverage-v8 to ^4.0.16 to match vitest
  • Upgrade vitest to ^4.0.18 to match the coverage package
Option 1: Downgrade coverage package
-    "@vitest/coverage-v8": "^4.0.18",
+    "@vitest/coverage-v8": "^4.0.16",
Option 2: Upgrade vitest
-    "vitest": "^4.0.16"
+    "vitest": "^4.0.18"
🤖 Fix all issues with AI agents
In `@frontend/lib/tests/quiz/setup.ts`:
- Around line 7-8: Replace the hardcoded high-entropy TEST_ENCRYPTION_KEY value
with a clearly labeled low-entropy test key (e.g., "test-key-000") or add a
Gitleaks allowlist comment immediately above TEST_ENCRYPTION_KEY to mark it as a
non-secret test artifact; update the exported constant TEST_ENCRYPTION_KEY in
frontend/lib/tests/quiz/setup.ts accordingly and ensure the comment states it's
intentionally non-sensitive for tests so static scanners will ignore it.
🧹 Nitpick comments (7)
frontend/lib/tests/quiz/setup.ts (1)

14-24: Restore prior QUIZ_ENCRYPTION_KEY after tests.
Current cleanup deletes any preexisting value, which can break other suites.

♻️ Preserve and restore prior env value
+let previousQuizEncryptionKey: string | undefined;
+
 export function setupQuizTestEnv(): void {
-  process.env.QUIZ_ENCRYPTION_KEY = TEST_ENCRYPTION_KEY;
+  previousQuizEncryptionKey = process.env.QUIZ_ENCRYPTION_KEY;
+  process.env.QUIZ_ENCRYPTION_KEY = TEST_ENCRYPTION_KEY;
 }
 
 export function cleanupQuizTestEnv(): void {
-  delete process.env.QUIZ_ENCRYPTION_KEY;
+  if (typeof previousQuizEncryptionKey === 'undefined') {
+    delete process.env.QUIZ_ENCRYPTION_KEY;
+  } else {
+    process.env.QUIZ_ENCRYPTION_KEY = previousQuizEncryptionKey;
+  }
+  previousQuizEncryptionKey = undefined;
 }
frontend/lib/tests/factories/quiz/quiz.ts (1)

65-71: Use a single timestamp for deterministic sessions.
Minor, but helps avoid flaky assertions if tests compare fields.

♻️ Suggested change
 export function createMockQuizSession(
   overrides?: Partial<MockQuizSession>
 ): MockQuizSession {
+  const now = Date.now();
   return {
     status: 'in_progress',
     currentIndex: 0,
     answers: [],
     questionStatus: 'answering',
     selectedAnswerId: null,
-    startedAt: Date.now(),
-    savedAt: Date.now(),
+    startedAt: now,
+    savedAt: now,
     ...overrides,
   };
 }
frontend/lib/tests/quiz/quiz-anticheat.test.ts (3)

75-99: Consider adding a test for tab becoming visible again.

The test verifies isTabActive becomes false when the tab is hidden, but there's no test verifying it returns to true when the tab becomes visible again. This would complete the visibility change coverage.

📝 Suggested additional test case
it('sets isTabActive back to true when tab becomes visible', () => {
  const { result } = renderHook(() => useAntiCheat(true));

  // Hide tab
  Object.defineProperty(document, 'hidden', { value: true, writable: true, configurable: true });
  act(() => {
    document.dispatchEvent(new Event('visibilitychange'));
  });
  expect(result.current.isTabActive).toBe(false);

  // Show tab
  Object.defineProperty(document, 'hidden', { value: false, writable: true, configurable: true });
  act(() => {
    document.dispatchEvent(new Event('visibilitychange'));
  });
  expect(result.current.isTabActive).toBe(true);
});

113-125: Consider verifying showWarning resets after timeout.

The test verifies showWarning becomes true on violation, but doesn't verify it returns to false after the 3000ms timeout. Since fake timers are already set up, this would be straightforward to add.

📝 Suggested enhancement
     it('sets showWarning to true when violation occurs', () => {
         const { result } = renderHook(() => useAntiCheat(true));

         expect(result.current.showWarning).toBe(false);

         act(() => {
             document.dispatchEvent(new Event('copy'));
         });

         expect(result.current.showWarning).toBe(true);
+
+        act(() => {
+            vi.advanceTimersByTime(3000);
+        });
+
+        expect(result.current.showWarning).toBe(false);
     });
-

51-61: Minor: Consider consistent toast verification across event tests.

The copy event test (line 48) verifies toast.warning was called with the expected message, but the paste and context-menu tests don't include this verification. Consider adding toast assertions for consistency, or removing from the copy test if comprehensive toast coverage isn't needed.

frontend/lib/tests/quiz/verify-answer.test.ts (2)

55-74: Consider making wrong answer selection more robust.

Line 61 assumes questions[0].answers[1] is always wrong, which depends on the factory implementation detail that the correct answer is at index 0. This could break silently if the factory changes.

📝 More robust wrong answer selection
     it('returns isCorrect: false for wrong answer', async () => {
       const questions = createMockQuestions(3);
       const correctAnswersMap = createCorrectAnswersMap(questions);
       const encryptedAnswers = encryptAnswers(correctAnswersMap);

       const questionId = questions[0].id;
-      const wrongAnswerId = questions[0].answers[1].id; // second answer is wrong
+      const correctAnswerId = correctAnswersMap[questionId];
+      const wrongAnswer = questions[0].answers.find(a => a.id !== correctAnswerId);
+      const wrongAnswerId = wrongAnswer!.id;

       const request = createVerifyRequest({
         questionId,
         answerId: wrongAnswerId,
         encryptedAnswers,
       });

95-108: Consider adding error message assertion.

The test for missing answerId only checks the status code but doesn't verify the error message like the questionId test does (line 92). Consider adding the assertion for consistency.

📝 Suggested enhancement
       const response = await POST(request);
+      const data = await response.json();

       expect(response.status).toBe(400);
+      expect(data.error).toBe('Missing required fields');
     });

Comment on lines +7 to +8
export const TEST_ENCRYPTION_KEY =
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Gitleaks likely to fail on hardcoded key.
Static analysis already flagged this; CI may block. Use an allowlist comment or a low‑entropy test key.

✅ Safer test key (low‑entropy)
-export const TEST_ENCRYPTION_KEY =
-  'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2';
+export const TEST_ENCRYPTION_KEY =
+  '0000000000000000000000000000000000000000000000000000000000000000';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const TEST_ENCRYPTION_KEY =
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2';
export const TEST_ENCRYPTION_KEY =
'0000000000000000000000000000000000000000000000000000000000000000';
🧰 Tools
🪛 Gitleaks (8.30.0)

[high] 7-8: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🤖 Prompt for AI Agents
In `@frontend/lib/tests/quiz/setup.ts` around lines 7 - 8, Replace the hardcoded
high-entropy TEST_ENCRYPTION_KEY value with a clearly labeled low-entropy test
key (e.g., "test-key-000") or add a Gitleaks allowlist comment immediately above
TEST_ENCRYPTION_KEY to mark it as a non-secret test artifact; update the
exported constant TEST_ENCRYPTION_KEY in frontend/lib/tests/quiz/setup.ts
accordingly and ensure the comment states it's intentionally non-sensitive for
tests so static scanners will ignore it.

…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
Comment thread frontend/coverage-quiz/sorter.js Fixed
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: 5

🤖 Fix all issues with AI agents
In `@frontend/coverage-quiz/app/api/quiz/guest-result/index.html`:
- Around line 1-116: Remove the committed Istanbul-generated coverage HTML
(app/api/quiz/guest-result/index.html) and other generated coverage directories,
add an appropriate ignore rule like coverage-quiz/ or **/coverage*/ to
.gitignore, commit the removal and updated .gitignore, and (optionally) wire
coverage reporting into CI (e.g., Codecov/Coveralls) instead of committing
coverage artifacts.

In `@frontend/coverage-quiz/base.css`:
- Around line 5-9: The CSS for the body selector contains duplicate font names
and redundant properties causing Biome duplicate-property warnings; update the
body rule in base.css (the "body" selector) to use a deduplicated, standardized
font-family string (e.g., remove repeated entries so only "Helvetica Neue,
Helvetica, Arial, sans-serif" remains) and remove or consolidate any repeated
properties (like duplicate color or font-size declarations) elsewhere in the
file (also check the other affected blocks around lines referenced) so each
property appears only once per selector or exclude coverage-quiz/** from linting
if these are generated assets.

In `@frontend/coverage-quiz/block-navigation.js`:
- Around line 24-29: toggleClass currently calls
missingCoverageElements.item(currentIndex).classList.remove(...) but
currentIndex can be undefined on first navigation, causing a null reference;
update toggleClass (and/or initialization of currentIndex) to guard the removal
by checking that missingCoverageElements.item(currentIndex) is non-null before
calling .classList.remove, then perform the .classList.add on
missingCoverageElements.item(index) and set currentIndex = index; alternatively
ensure currentIndex is initialized to a valid integer before toggleClass is ever
invoked. Use the function name toggleClass and the variables currentIndex and
missingCoverageElements.item(...) to locate and apply the guard.
- Around line 41-63: Both navigation functions (goToPrevious and goToNext) call
makeCurrent(0) when missingCoverageElements is empty, which leads to makeCurrent
attempting to access missingCoverageElements.item(0) and crashing; fix by adding
an early guard in each function (or a shared check before navigation) that
returns immediately if missingCoverageElements.length === 0 so makeCurrent is
never called on an empty list, leaving existing index logic unchanged.

In `@frontend/lib/tests/quiz/use-quiz-guards.test.ts`:
- Around line 148-160: The test's final assertion is not being invoked because
the matcher is referenced as a property; in the test using useQuizGuards(),
replace the incorrect ".toBeNull" with a call ".toBeNull()" so the assertion
runs; update the assertion that checks
sessionStorage.getItem(getQuizReloadKey(params.quizId)) in the test that calls
result.current.markQuitting() to use .toBeNull() (referencing getQuizReloadKey,
useQuizGuards, and markQuitting to locate the test).
♻️ Duplicate comments (7)
frontend/coverage-quiz/app/api/quiz/verify-answer/index.html (1)

1-116: Auto-generated coverage file — same concern as above.

This file should be excluded from version control along with the rest of the coverage-quiz/ directory.

frontend/coverage-quiz/app/api/quiz/[slug]/index.html (1)

1-116: Auto-generated coverage file — same concern as above.

This file should be excluded from version control along with the rest of the coverage-quiz/ directory.

frontend/coverage-quiz/hooks/index.html (1)

1-131: Auto-generated coverage file — same concern as above.

This file should be excluded from version control along with the rest of the coverage-quiz/ directory.

frontend/coverage-quiz/lib/quiz/guest-quiz.ts.html (1)

1-244: Auto-generated coverage file — same concern as above.

This file should be excluded from version control along with the rest of the coverage-quiz/ directory. Note that this file also embeds source code, making it redundant with the actual source files.

frontend/coverage-quiz/hooks/useQuizGuards.ts.html (1)

1-430: Auto-generated coverage file — same concern as above.

This file should be excluded from version control along with the rest of the coverage-quiz/ directory.

frontend/coverage-quiz/lib/quiz/quiz-session.ts.html (1)

1-283: Auto-generated coverage report - same concern as other coverage files.

This is another Istanbul coverage artifact that should not be committed. See the comment on quiz-crypto.ts.html for details.

frontend/coverage-quiz/hooks/useQuizSession.ts.html (1)

1-313: Auto-generated coverage report - same concern as other coverage files.

This is another Istanbul coverage artifact that should not be committed. See the comment on quiz-crypto.ts.html for details.

🧹 Nitpick comments (9)
frontend/vitest.config.ts (1)

16-22: Consider adding components/quiz source files to the coverage configuration with explicit file extensions.

UI tests are configured to run under components/quiz/tests, but coverage.include currently omits those component source files, so coverage metrics won't be collected for them. Additionally, Vitest v4 recommends including file extensions in coverage globs for clarity and to avoid inadvertently capturing non-source files.

✅ Suggested update
     coverage: {
       provider: 'v8',
       reporter: ['text', 'html'],
-      include: ['lib/quiz/**', 'hooks/**', 'app/api/quiz/**'],
+      include: ['lib/quiz/**/*.ts', 'hooks/**/*.ts', 'app/api/quiz/**/*.ts', 'components/quiz/**/*.tsx'],
     },
frontend/coverage-quiz/block-navigation.js (1)

74-84: event.which is deprecated.

event.which is deprecated in favor of event.key. Consider updating for better compatibility with modern browsers.

♻️ Suggested refactor using event.key
-switch (event.which) {
-    case 78: // n
-    case 74: // j
-        goToNext();
-        break;
-    case 66: // b
-    case 75: // k
-    case 80: // p
-        goToPrevious();
-        break;
-}
+switch (event.key.toLowerCase()) {
+    case 'n':
+    case 'j':
+        goToNext();
+        break;
+    case 'b':
+    case 'k':
+    case 'p':
+        goToPrevious();
+        break;
+}
frontend/coverage-quiz/sorter.js (2)

84-86: Consider using DOM methods instead of innerHTML concatenation.

While this code operates on trusted Istanbul-generated content, using innerHTML concatenation can be a code smell. A safer pattern uses DOM methods.

♻️ Safer alternative using DOM methods
 if (col.sortable) {
     col.defaultDescSort = col.type === 'number';
-    colNode.innerHTML =
-        colNode.innerHTML + '<span class="sorter"></span>';
+    var sorterSpan = document.createElement('span');
+    sorterSpan.className = 'sorter';
+    colNode.appendChild(sorterSpan);
 }

189-193: Legacy IE compatibility check may be unnecessary.

The attachEvent fallback (line 192) is for IE8 and earlier, which are no longer supported by modern tooling. If IE8 support is not required, this can be simplified.

♻️ Simplified without IE8 fallback
-if (el.addEventListener) {
-    el.addEventListener('click', ithSorter(i));
-} else {
-    el.attachEvent('onclick', ithSorter(i));
-}
+el.addEventListener('click', ithSorter(i));
frontend/coverage-quiz/index.html (1)

167-171: window.onload assignment may conflict with other scripts.

Direct assignment to window.onload overwrites any previously assigned handlers. Since sorter.js uses addEventListener('load', ...), there's no conflict in this specific case, but this pattern can cause issues if scripts are reordered.

♻️ Safer pattern using addEventListener
-<script>
-    window.onload = function () {
-        prettyPrint();
-    };
-</script>
+<script>
+    window.addEventListener('load', function () {
+        prettyPrint();
+    });
+</script>
frontend/coverage-quiz/app/api/quiz/verify-answer/route.ts.html (1)

1-232: Coverage HTML artifacts should not be committed to the repository.

These auto-generated Istanbul coverage reports are currently tracked in frontend/coverage-quiz/, even though .gitignore has a /coverage rule at the root level (which doesn't match the frontend/coverage-quiz/ subdirectory). Coverage artifacts typically should be:

  • Generated during CI/CD and published as build artifacts
  • Uploaded to a coverage service (Codecov, Coveralls, etc.)
  • Added to .gitignore to prevent bloating the repository

Consider either adding frontend/coverage-quiz/ to .gitignore or removing this directory if it was committed unintentionally. Alternatively, generate these reports dynamically via a coverage reporting service instead of committing them.

frontend/lib/tests/quiz/use-quiz-guards.test.ts (1)

64-83: Consider using a more realistic external URL for clarity.

The test uses javascript:void(0) as the external link href. While this technically works (it doesn't contain the current pathname), using a realistic external URL like https://example.com would make the test's intent clearer and better represent real-world scenarios.

Suggested improvement
-    link.setAttribute('href', 'javascript:void(0)');
+    link.setAttribute('href', 'https://example.com');
frontend/lib/tests/quiz/use-quiz-session.test.ts (1)

46-49: Consider adding afterEach with vi.restoreAllMocks() for consistency.

The sibling test file use-quiz-guards.test.ts includes an afterEach hook with vi.restoreAllMocks(). Adding the same here ensures mock cleanup consistency across test files and prevents potential test pollution.

Suggested improvement
   beforeEach(() => {
     sessionStorage.clear();
     vi.clearAllMocks();
   });
 
+  afterEach(() => {
+    vi.restoreAllMocks();
+  });
 
   it('restores session on reload', async () => {
frontend/coverage-quiz/lib/quiz/quiz-crypto.ts.html (1)

1-331: Remove coverage reports from source control and add to .gitignore.

The frontend/coverage-quiz/ directory containing auto-generated Istanbul coverage HTML reports is currently tracked in git. These artifacts should not be committed as they:

  • Are auto-generated and can be recreated from source
  • Bloat the repository with 22+ static files
  • Create unnecessary noise in diffs

The current .gitignore has /coverage at root level, but this does not exclude frontend/coverage-quiz/. Add frontend/coverage-quiz/ to .gitignore to prevent future commits of coverage reports.

Comment thread frontend/coverage-quiz/app/api/quiz/guest-result/index.html Outdated
Comment thread frontend/coverage-quiz/base.css Outdated
Comment on lines +24 to +29
function toggleClass(index) {
missingCoverageElements
.item(currentIndex)
.classList.remove('highlighted');
missingCoverageElements.item(index).classList.add('highlighted');
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Potential null reference on first navigation.

When toggleClass is first called, currentIndex is undefined, so missingCoverageElements.item(currentIndex) returns null, causing a crash on .classList.remove().

🐛 Proposed fix
 function toggleClass(index) {
-    missingCoverageElements
-        .item(currentIndex)
-        .classList.remove('highlighted');
+    if (typeof currentIndex === 'number') {
+        missingCoverageElements
+            .item(currentIndex)
+            .classList.remove('highlighted');
+    }
     missingCoverageElements.item(index).classList.add('highlighted');
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function toggleClass(index) {
missingCoverageElements
.item(currentIndex)
.classList.remove('highlighted');
missingCoverageElements.item(index).classList.add('highlighted');
}
function toggleClass(index) {
if (typeof currentIndex === 'number') {
missingCoverageElements
.item(currentIndex)
.classList.remove('highlighted');
}
missingCoverageElements.item(index).classList.add('highlighted');
}
🤖 Prompt for AI Agents
In `@frontend/coverage-quiz/block-navigation.js` around lines 24 - 29, toggleClass
currently calls missingCoverageElements.item(currentIndex).classList.remove(...)
but currentIndex can be undefined on first navigation, causing a null reference;
update toggleClass (and/or initialization of currentIndex) to guard the removal
by checking that missingCoverageElements.item(currentIndex) is non-null before
calling .classList.remove, then perform the .classList.add on
missingCoverageElements.item(index) and set currentIndex = index; alternatively
ensure currentIndex is initialized to a valid integer before toggleClass is ever
invoked. Use the function name toggleClass and the variables currentIndex and
missingCoverageElements.item(...) to locate and apply the guard.

Comment on lines +41 to +63
function goToPrevious() {
var nextIndex = 0;
if (typeof currentIndex !== 'number' || currentIndex === 0) {
nextIndex = missingCoverageElements.length - 1;
} else if (missingCoverageElements.length > 1) {
nextIndex = currentIndex - 1;
}

makeCurrent(nextIndex);
}

function goToNext() {
var nextIndex = 0;

if (
typeof currentIndex === 'number' &&
currentIndex < missingCoverageElements.length - 1
) {
nextIndex = currentIndex + 1;
}

makeCurrent(nextIndex);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing bounds check for empty element list.

If missingCoverageElements is empty (no uncovered blocks), both goToPrevious and goToNext will call makeCurrent(0), which then calls missingCoverageElements.item(0) returning null and causing a crash.

🐛 Proposed fix - add early return
 function goToPrevious() {
+    if (missingCoverageElements.length === 0) {
+        return;
+    }
     var nextIndex = 0;
     // ...
 }

 function goToNext() {
+    if (missingCoverageElements.length === 0) {
+        return;
+    }
     var nextIndex = 0;
     // ...
 }
🤖 Prompt for AI Agents
In `@frontend/coverage-quiz/block-navigation.js` around lines 41 - 63, Both
navigation functions (goToPrevious and goToNext) call makeCurrent(0) when
missingCoverageElements is empty, which leads to makeCurrent attempting to
access missingCoverageElements.item(0) and crashing; fix by adding an early
guard in each function (or a shared check before navigation) that returns
immediately if missingCoverageElements.length === 0 so makeCurrent is never
called on an empty list, leaving existing index logic unchanged.

Comment thread frontend/lib/tests/quiz/use-quiz-guards.test.ts
@ViktorSvertoka ViktorSvertoka merged commit 6046e26 into develop Jan 25, 2026
8 checks passed
@ViktorSvertoka ViktorSvertoka deleted the sl/feat/quiz branch January 25, 2026 17:44
ViktorSvertoka added a commit that referenced this pull request Jan 25, 2026
* (SP: 1) [Security] Enforce origin posture for shop APIs (admin/checkout same-origin; internal/webhooks non-browser) + docs

* (SP: 1) [DB] Align stripe_events.order_id FK CASCADE across schema and migrations

* feat(i18n): localize quiz anti-cheat, header and blog filters (#175)

* feat(Blog): Adding last published post to the blog and category page, recommended posts, Changing styles to one unified format, Bug fixes

* Update leaderboard-style

* Update leaderboard-style

* teat(Blog): fix of hover on author, fix of the line

* (SP: 3) [Observability] Extend structured logging + correlation IDs across all shop routes; purge console.*; enforce explicit error codes

* (SP: 1) [Admin][Security] Add safe product delete (PRODUCT_IN_USE) + mobile cards UI; tighten env/docs, locale normalization, cache-control, and logging semantics

* fix: npm installing

* (SP: 1) [Admin] Align products list in use checks with DB column names (order_items/inventory_moves)

* fix:Update leaderboard: fixed background

* fix: remove email from CurrentUser type to prevent PII exposure

* refactor: align leaderboard UI with brand style (fixed bg, css vars, podium glow)

* (SP: 1) [Frontend] About Us Page. Fixed game, topics, mobile layout

- Fixed mobile tabs in FeaturesSection (icon-only on mobile)
- Fixed game bugs: collision detection, animation, scoring system
- Added multiple obstacle types with level progression
- Improved game sizing for mobile while preserving desktop
- Updated TopicsSection with local SVG icons and hover borders
- Made DynamicGridBackground static grid opt-in via showStaticGrid prop
- Limited SponsorsWall to display max 10 sponsors
- Optimized CommunitySection button layout for mobile

* refactor: update accent color hover effects to Footer

- Update Footer links to use --accent-primary on hover
- Update ThemeToggle icons to use --accent-primary on hover
- Both components adapt colors to light/dark theme

* refactor: improve accessibility

- Add focus-visible styles for keyboard navigation accessibility

* (SP: 1) [Shop] Fix Stripe checkout success redirect (remove duplicate locale /uk/uk) (#186)

* fix:leaderboard  update leaderboard-style (#187)

* fix:leaderboard update leaderboard-style on mobile (#188)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

---------

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

* (SP: 1) [Frontend] Changing hero headline on shop main page (#190)

* (SP: 1) [Shop] Fix checkout redirect 404 by removing duplicate locale in in-app routes and Stripe return_url

* (SP: 1) [Shop] Fix locale cart page and orderid page

* (SP: 1) [Frontend] Changin hero headline on shop main page

* (SP: 1) [Frontend] Fix styles shop home page, buttons (#191)

* Feature/leaderboard style update (#192)

* (SP: 7) [UI] Quiz UI polish: tabs styling, category accents, color scheme (#181, #193, #194) (#195)

* Sanity (#196)

* 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

* (SP: 3) [AI] Add AI word helper with Groq integration (#200)

* (SP: 3) [AI] Add AI word helper with Groq integration

- Implement Groq API with Llama 3.1 70B model
- Add text selection detection on Q&A page
- Create floating "Explain" button
- Build draggable modal with 3-language support (uk/en/pl)
- Add localStorage caching for instant repeated lookups
- Implement guest CTA (login/signup)
- Add rate limiting (10 requests/min)
- Auth-gated feature (registered users only)

Components:
- SelectableText: Detects text selection
- FloatingExplainButton: Appears on selection
- AIWordHelper: Main modal with explanations

* (SP: 1) i18n: fix Polish locale and set EN as default

* Sanity (#202)

* 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

* Sanity (#203)

* 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

* (SP: 3) [Frontend] Refactor Header UI and navigation states (#201)

* (SP: 3) [Frontend] Refactor Header UI and navigation states

- Add icon to the language switcher

- Add GitHub icon with stars indicator (frontend only)

- Update logo styles

- Improve touch interaction styles

- Verify correct placement and alignment of all header components

- Make mobile header modal full-screen

- Disable background scroll when mobile menu is open

- Highlight active navigation item

- Update navigation styles:

- Highlight Shop link when user is on Home pages
- Highlight Home link when user is on Shop pages
- Style changes only, no routing or logic changes

* fix CodeRabbit

* update HeaderButton styles

* fix: add accessibility for HeaderButton

* (SP: 3) [Testing] Vitest config + unit + integration tests for quiz module (#204)

* 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

* Feature/leaderboard style update (#206)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

* fix: move row border to first cell to resolve CodeRabbit issue

* fix: move row border to first cell to resolve CodeRabbit issue new

* fix(leaderboard): improve table mobile

* fix(leaderboard): correct malformed shadow class syntax for avatar glow

* test(q&a): add comprehensive qa tests and coverage setup (#208)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* (SP: 1) [Frontend] Remove Contacts References (#211)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* chore(nav): remove contacts page references

* Sanity (#209)

* 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

* chore(release): update changelog for v0.5.0

* chore(release): v0.5.0

---------

Co-authored-by: liudmylasovetovs <milkaegik@gmail.com>
Co-authored-by: Tetiana Zorii <131365289+TiZorii@users.noreply.github.com>
Co-authored-by: Anna <komrakova.anna@gmail.com>
Co-authored-by: AlinaRyabova <alinavr7@gmail.com>
Co-authored-by: Yevhenii Datsenko <yevheniydatsenko@gmail.com>
Co-authored-by: YNazymko12 <yulychka12@gmail.com>
Co-authored-by: liudmylasovetovs <127711697+liudmylasovetovs@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: Yuliia Nazymko <122815071+YNazymko12@users.noreply.github.com>
@LesiaUKR LesiaUKR restored the sl/feat/quiz branch January 27, 2026 18:53
ViktorSvertoka added a commit that referenced this pull request Jan 31, 2026
* (SP: 1) [Security] Enforce origin posture for shop APIs (admin/checkout same-origin; internal/webhooks non-browser) + docs

* (SP: 1) [DB] Align stripe_events.order_id FK CASCADE across schema and migrations

* feat(i18n): localize quiz anti-cheat, header and blog filters (#175)

* feat(Blog): Adding last published post to the blog and category page, recommended posts, Changing styles to one unified format, Bug fixes

* Update leaderboard-style

* Update leaderboard-style

* teat(Blog): fix of hover on author, fix of the line

* (SP: 3) [Observability] Extend structured logging + correlation IDs across all shop routes; purge console.*; enforce explicit error codes

* (SP: 1) [Admin][Security] Add safe product delete (PRODUCT_IN_USE) + mobile cards UI; tighten env/docs, locale normalization, cache-control, and logging semantics

* fix: npm installing

* (SP: 1) [Admin] Align products list in use checks with DB column names (order_items/inventory_moves)

* fix:Update leaderboard: fixed background

* fix: remove email from CurrentUser type to prevent PII exposure

* refactor: align leaderboard UI with brand style (fixed bg, css vars, podium glow)

* (SP: 1) [Frontend] About Us Page. Fixed game, topics, mobile layout

- Fixed mobile tabs in FeaturesSection (icon-only on mobile)
- Fixed game bugs: collision detection, animation, scoring system
- Added multiple obstacle types with level progression
- Improved game sizing for mobile while preserving desktop
- Updated TopicsSection with local SVG icons and hover borders
- Made DynamicGridBackground static grid opt-in via showStaticGrid prop
- Limited SponsorsWall to display max 10 sponsors
- Optimized CommunitySection button layout for mobile

* refactor: update accent color hover effects to Footer

- Update Footer links to use --accent-primary on hover
- Update ThemeToggle icons to use --accent-primary on hover
- Both components adapt colors to light/dark theme

* refactor: improve accessibility

- Add focus-visible styles for keyboard navigation accessibility

* (SP: 1) [Shop] Fix Stripe checkout success redirect (remove duplicate locale /uk/uk) (#186)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard  update leaderboard-style (#187)

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

* fix:leaderboard update leaderboard-style on mobile (#188)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

---------

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

* (SP: 1) [Frontend] Changing hero headline on shop main page (#190)

* (SP: 1) [Shop] Fix checkout redirect 404 by removing duplicate locale in in-app routes and Stripe return_url

* (SP: 1) [Shop] Fix locale cart page and orderid page

* (SP: 1) [Frontend] Changin hero headline on shop main page

* (SP: 1) [Frontend] Fix styles shop home page, buttons (#191)

* fix: move row border to first cell to resolve CodeRabbit issue

* fix: move row border to first cell to resolve CodeRabbit issue new

* Feature/leaderboard style update (#192)

* (SP: 7) [UI] Quiz UI polish: tabs styling, category accents, color scheme (#181, #193, #194) (#195)

* Sanity (#196)

* 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

* (SP: 3) [AI] Add AI word helper with Groq integration (#200)

* (SP: 3) [AI] Add AI word helper with Groq integration

- Implement Groq API with Llama 3.1 70B model
- Add text selection detection on Q&A page
- Create floating "Explain" button
- Build draggable modal with 3-language support (uk/en/pl)
- Add localStorage caching for instant repeated lookups
- Implement guest CTA (login/signup)
- Add rate limiting (10 requests/min)
- Auth-gated feature (registered users only)

Components:
- SelectableText: Detects text selection
- FloatingExplainButton: Appears on selection
- AIWordHelper: Main modal with explanations

* (SP: 1) i18n: fix Polish locale and set EN as default

* Sanity (#202)

* 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

* Sanity (#203)

* 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

* (SP: 3) [Frontend] Refactor Header UI and navigation states (#201)

* (SP: 3) [Frontend] Refactor Header UI and navigation states

- Add icon to the language switcher

- Add GitHub icon with stars indicator (frontend only)

- Update logo styles

- Improve touch interaction styles

- Verify correct placement and alignment of all header components

- Make mobile header modal full-screen

- Disable background scroll when mobile menu is open

- Highlight active navigation item

- Update navigation styles:

- Highlight Shop link when user is on Home pages
- Highlight Home link when user is on Shop pages
- Style changes only, no routing or logic changes

* fix CodeRabbit

* update HeaderButton styles

* fix: add accessibility for HeaderButton

* (SP: 3) [Testing] Vitest config + unit + integration tests for quiz module (#204)

* 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(leaderboard): improve table mobile

* fix(leaderboard): correct malformed shadow class syntax for avatar glow

* Feature/leaderboard style update (#206)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

* fix: move row border to first cell to resolve CodeRabbit issue

* fix: move row border to first cell to resolve CodeRabbit issue new

* fix(leaderboard): improve table mobile

* fix(leaderboard): correct malformed shadow class syntax for avatar glow

* test(q&a): add comprehensive qa tests and coverage setup (#208)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* (SP: 1) [Frontend] Remove Contacts References (#211)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* chore(nav): remove contacts page references

* Sanity (#209)

* 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

* chore(release): update changelog for v0.5.0

* chore(release): v0.5.0

* [Refactor] Code Quality Improvements: Accessibility, Mobile Support, … (#213)

* fix(leaderboard): adjust podium heights for better visibility on desktop

* Feature/leaderboard style update (#214)

* fix(leaderboard): fix layout centering

* feat(Blog) (#216)

* feat(Blog) (#218)

* 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

* (SP: 1) feat(i18n): translate 404 error page (#217)

- Add 404 translations (uk/en/pl)
- Implement [Global/Local/Combined] strategy
- Add helpful navigation links

* (SP: 2) [Frontend] Refactor Home HeroSection and Footer stylestor/home (#221)

* (SP:1) fix: 404 page layout (#219)

- 404 translations (uk/en/pl)
- Implement Global strategy

* feat(Blog) (#222)

* 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

* Update AI model from 'llama-3.3-70b-versatile' to 'llama3-70b-8192' (#223)

* (SP 2) [Frontend] Update Features section content and improve mobile UX (#224)

* (SP 2) [Frontend] Update Features section content and improve mobile UX

- Features Section: Refined feature content and visuals.
- Mobile UX: Improved responsive layout and scaling for feature cards and interactive elements.
- Visual Enhancements: Added dynamic particle background effects to the Pricing section.

* fix(review): address accessibility, security, and performance feedback

* fix(review): resolve accessibility and hydration issues

* fix(perf): implement frame-rate independent animations

* fix(review): address accessibility, security, and performance feedback

* fix(review): enable SSR for features section and support HiDPI canvas

* fix(review): correct HiDPI logic for particle canvas measurements

* (SP:3) feat(i18n): add UA and PL translations for shop/admin pages

Add comprehensive i18n support for shop and admin sections in 3 languages (en, uk,
  pl).

  Translation coverage:
  - Shop pages: main page, products, cart, checkout, orders
  - Admin pages: dashboard, products management, orders management
  - Navigation: header, mobile menu, category links
  - Product components: cards, filters, sort, badges (NEW/SALE)
  - Category names: Apparel, Lifestyle, Collectibles
  - All UI buttons, labels, and actions

  Key changes:
  - Added ~250+ translation keys to messages/en.json, messages/uk.json,
  messages/pl.json
  - Updated 20+ components to use useTranslations() and getTranslations()
  - Implemented color translation in cart and product detail pages
  - Translated hero message
  - Added badge translations

* fix(i18n): correct translation keys and localization in shop pages

  - Replace confusing error.order with success.orderLabel in checkout success page
  heading
  - Localize boolean stockRestored display (yes/no instead of true/false) in order
  details
  - Fix active state detection for shop category links in mobile menu using search
  params
  - Add missing translation keys (orderLabel, yes, no) to all locales (en, uk, pl)

* fix(netlify): resolve AI API crash and 404 locale/theme issues

AI fixes:
  - Extract getClientIp to separate file (avoid db import crash)
  - Add missing zod dependency to package.json

  404 page fixes:
  - Use NEXT_LOCALE cookie for locale detection on Netlify
  - Add theme detection script in root layout
  - Update styling with hero background and gradient text

* Update frontend/app/not-found.tsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* (SP:3) feat(i18n): translate about page and auth form validation messages

  - Add about page translations (EN, UK, PL)
  - Add auth.fields.validation translations for form errors

* fix(api): resolve Netlify 503 errors and harden AI explain endpoint

 - Use dynamic import for groq-sdk (Netlify compatibility)                                                    - Bypass rate limiting for unknown IPs (serverless safety)
  - Safe JSON parsing with request.text() + empty body check
  - Fix ReferenceError: remove undefined errorMessage variable
  - Remove sensitive debug info from client responses
  - Add i18n keys: pricing.heading, sponsors.ctaAriaLabel

* feat(api): add GET health check endpoint for ai-explain

* chore(release): v0.5.1

---------

Co-authored-by: liudmylasovetovs <milkaegik@gmail.com>
Co-authored-by: Tetiana Zorii <131365289+TiZorii@users.noreply.github.com>
Co-authored-by: Anna <komrakova.anna@gmail.com>
Co-authored-by: AlinaRyabova <alinavr7@gmail.com>
Co-authored-by: Yevhenii Datsenko <yevheniydatsenko@gmail.com>
Co-authored-by: YNazymko12 <yulychka12@gmail.com>
Co-authored-by: liudmylasovetovs <127711697+liudmylasovetovs@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: Yuliia Nazymko <122815071+YNazymko12@users.noreply.github.com>
Co-authored-by: Yevhenii Datsenko <134847096+yevheniidatsenko@users.noreply.github.com>
Co-authored-by: tetiana zorii <tanyusha.zoriy@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@ViktorSvertoka ViktorSvertoka mentioned this pull request Jan 31, 2026
20 tasks
ViktorSvertoka added a commit that referenced this pull request Jan 31, 2026
* (SP: 1) [Security] Enforce origin posture for shop APIs (admin/checkout same-origin; internal/webhooks non-browser) + docs

* (SP: 1) [DB] Align stripe_events.order_id FK CASCADE across schema and migrations

* feat(i18n): localize quiz anti-cheat, header and blog filters (#175)

* feat(Blog): Adding last published post to the blog and category page, recommended posts, Changing styles to one unified format, Bug fixes

* Update leaderboard-style

* Update leaderboard-style

* teat(Blog): fix of hover on author, fix of the line

* (SP: 3) [Observability] Extend structured logging + correlation IDs across all shop routes; purge console.*; enforce explicit error codes

* (SP: 1) [Admin][Security] Add safe product delete (PRODUCT_IN_USE) + mobile cards UI; tighten env/docs, locale normalization, cache-control, and logging semantics

* fix: npm installing

* (SP: 1) [Admin] Align products list in use checks with DB column names (order_items/inventory_moves)

* fix:Update leaderboard: fixed background

* fix: remove email from CurrentUser type to prevent PII exposure

* refactor: align leaderboard UI with brand style (fixed bg, css vars, podium glow)

* (SP: 1) [Frontend] About Us Page. Fixed game, topics, mobile layout

- Fixed mobile tabs in FeaturesSection (icon-only on mobile)
- Fixed game bugs: collision detection, animation, scoring system
- Added multiple obstacle types with level progression
- Improved game sizing for mobile while preserving desktop
- Updated TopicsSection with local SVG icons and hover borders
- Made DynamicGridBackground static grid opt-in via showStaticGrid prop
- Limited SponsorsWall to display max 10 sponsors
- Optimized CommunitySection button layout for mobile

* refactor: update accent color hover effects to Footer

- Update Footer links to use --accent-primary on hover
- Update ThemeToggle icons to use --accent-primary on hover
- Both components adapt colors to light/dark theme

* refactor: improve accessibility

- Add focus-visible styles for keyboard navigation accessibility

* (SP: 1) [Shop] Fix Stripe checkout success redirect (remove duplicate locale /uk/uk) (#186)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard  update leaderboard-style (#187)

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

* fix:leaderboard update leaderboard-style on mobile (#188)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

---------



* (SP: 1) [Frontend] Changing hero headline on shop main page (#190)

* (SP: 1) [Shop] Fix checkout redirect 404 by removing duplicate locale in in-app routes and Stripe return_url

* (SP: 1) [Shop] Fix locale cart page and orderid page

* (SP: 1) [Frontend] Changin hero headline on shop main page

* (SP: 1) [Frontend] Fix styles shop home page, buttons (#191)

* fix: move row border to first cell to resolve CodeRabbit issue

* fix: move row border to first cell to resolve CodeRabbit issue new

* Feature/leaderboard style update (#192)

* (SP: 7) [UI] Quiz UI polish: tabs styling, category accents, color scheme (#181, #193, #194) (#195)

* Sanity (#196)

* 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

* (SP: 3) [AI] Add AI word helper with Groq integration (#200)

* (SP: 3) [AI] Add AI word helper with Groq integration

- Implement Groq API with Llama 3.1 70B model
- Add text selection detection on Q&A page
- Create floating "Explain" button
- Build draggable modal with 3-language support (uk/en/pl)
- Add localStorage caching for instant repeated lookups
- Implement guest CTA (login/signup)
- Add rate limiting (10 requests/min)
- Auth-gated feature (registered users only)

Components:
- SelectableText: Detects text selection
- FloatingExplainButton: Appears on selection
- AIWordHelper: Main modal with explanations

* (SP: 1) i18n: fix Polish locale and set EN as default

* Sanity (#202)

* 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

* Sanity (#203)

* 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

* (SP: 3) [Frontend] Refactor Header UI and navigation states (#201)

* (SP: 3) [Frontend] Refactor Header UI and navigation states

- Add icon to the language switcher

- Add GitHub icon with stars indicator (frontend only)

- Update logo styles

- Improve touch interaction styles

- Verify correct placement and alignment of all header components

- Make mobile header modal full-screen

- Disable background scroll when mobile menu is open

- Highlight active navigation item

- Update navigation styles:

- Highlight Shop link when user is on Home pages
- Highlight Home link when user is on Shop pages
- Style changes only, no routing or logic changes

* fix CodeRabbit

* update HeaderButton styles

* fix: add accessibility for HeaderButton

* (SP: 3) [Testing] Vitest config + unit + integration tests for quiz module (#204)

* 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(leaderboard): improve table mobile

* fix(leaderboard): correct malformed shadow class syntax for avatar glow

* Feature/leaderboard style update (#206)

* fix:leaderboard  update leaderboard-style

* fix:leaderboard update leaderboard-style on mobile

* fix: resolve CodeRabbit issues and conflicts

* fix: move row border to first cell to resolve CodeRabbit issue

* fix: move row border to first cell to resolve CodeRabbit issue new

* fix(leaderboard): improve table mobile

* fix(leaderboard): correct malformed shadow class syntax for avatar glow

* test(q&a): add comprehensive qa tests and coverage setup (#208)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* (SP: 1) [Frontend] Remove Contacts References (#211)

* test(q&a): add comprehensive qa tests and coverage setup

* test(q&a): align mocks and reset in qa tests

* chore(nav): remove contacts page references

* Sanity (#209)

* 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

* chore(release): update changelog for v0.5.0

* chore(release): v0.5.0

* [Refactor] Code Quality Improvements: Accessibility, Mobile Support, … (#213)

* fix(leaderboard): adjust podium heights for better visibility on desktop

* Feature/leaderboard style update (#214)

* fix(leaderboard): fix layout centering

* feat(Blog) (#216)

* feat(Blog) (#218)

* 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

* (SP: 1) feat(i18n): translate 404 error page (#217)

- Add 404 translations (uk/en/pl)
- Implement [Global/Local/Combined] strategy
- Add helpful navigation links

* (SP: 2) [Frontend] Refactor Home HeroSection and Footer stylestor/home (#221)

* (SP:1) fix: 404 page layout (#219)

- 404 translations (uk/en/pl)
- Implement Global strategy

* feat(Blog) (#222)

* 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

* Update AI model from 'llama-3.3-70b-versatile' to 'llama3-70b-8192' (#223)

* (SP 2) [Frontend] Update Features section content and improve mobile UX (#224)

* (SP 2) [Frontend] Update Features section content and improve mobile UX

- Features Section: Refined feature content and visuals.
- Mobile UX: Improved responsive layout and scaling for feature cards and interactive elements.
- Visual Enhancements: Added dynamic particle background effects to the Pricing section.

* fix(review): address accessibility, security, and performance feedback

* fix(review): resolve accessibility and hydration issues

* fix(perf): implement frame-rate independent animations

* fix(review): address accessibility, security, and performance feedback

* fix(review): enable SSR for features section and support HiDPI canvas

* fix(review): correct HiDPI logic for particle canvas measurements

* (SP:3) feat(i18n): add UA and PL translations for shop/admin pages

Add comprehensive i18n support for shop and admin sections in 3 languages (en, uk,
  pl).

  Translation coverage:
  - Shop pages: main page, products, cart, checkout, orders
  - Admin pages: dashboard, products management, orders management
  - Navigation: header, mobile menu, category links
  - Product components: cards, filters, sort, badges (NEW/SALE)
  - Category names: Apparel, Lifestyle, Collectibles
  - All UI buttons, labels, and actions

  Key changes:
  - Added ~250+ translation keys to messages/en.json, messages/uk.json,
  messages/pl.json
  - Updated 20+ components to use useTranslations() and getTranslations()
  - Implemented color translation in cart and product detail pages
  - Translated hero message
  - Added badge translations

* fix(i18n): correct translation keys and localization in shop pages

  - Replace confusing error.order with success.orderLabel in checkout success page
  heading
  - Localize boolean stockRestored display (yes/no instead of true/false) in order
  details
  - Fix active state detection for shop category links in mobile menu using search
  params
  - Add missing translation keys (orderLabel, yes, no) to all locales (en, uk, pl)

* fix(netlify): resolve AI API crash and 404 locale/theme issues

AI fixes:
  - Extract getClientIp to separate file (avoid db import crash)
  - Add missing zod dependency to package.json

  404 page fixes:
  - Use NEXT_LOCALE cookie for locale detection on Netlify
  - Add theme detection script in root layout
  - Update styling with hero background and gradient text

* Update frontend/app/not-found.tsx



* (SP:3) feat(i18n): translate about page and auth form validation messages

  - Add about page translations (EN, UK, PL)
  - Add auth.fields.validation translations for form errors

* fix(api): resolve Netlify 503 errors and harden AI explain endpoint

 - Use dynamic import for groq-sdk (Netlify compatibility)                                                    - Bypass rate limiting for unknown IPs (serverless safety)
  - Safe JSON parsing with request.text() + empty body check
  - Fix ReferenceError: remove undefined errorMessage variable
  - Remove sensitive debug info from client responses
  - Add i18n keys: pricing.heading, sponsors.ctaAriaLabel

* feat(api): add GET health check endpoint for ai-explain

* chore(release): v0.5.1

---------

Co-authored-by: liudmylasovetovs <milkaegik@gmail.com>
Co-authored-by: Tetiana Zorii <131365289+TiZorii@users.noreply.github.com>
Co-authored-by: Anna <komrakova.anna@gmail.com>
Co-authored-by: AlinaRyabova <alinavr7@gmail.com>
Co-authored-by: Yevhenii Datsenko <yevheniydatsenko@gmail.com>
Co-authored-by: YNazymko12 <yulychka12@gmail.com>
Co-authored-by: liudmylasovetovs <127711697+liudmylasovetovs@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: Yuliia Nazymko <122815071+YNazymko12@users.noreply.github.com>
Co-authored-by: Yevhenii Datsenko <134847096+yevheniidatsenko@users.noreply.github.com>
Co-authored-by: tetiana zorii <tanyusha.zoriy@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.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

3 participants