Skip to content

Refactoring code & bag fix#250

Merged
ViktorSvertoka merged 1 commit into
developfrom
fix/ref
Feb 1, 2026
Merged

Refactoring code & bag fix#250
ViktorSvertoka merged 1 commit into
developfrom
fix/ref

Conversation

@ViktorSvertoka
Copy link
Copy Markdown
Member

@ViktorSvertoka ViktorSvertoka commented Feb 1, 2026

Summary by CodeRabbit

  • New Features

    • Added CodeRabbit configuration for automated code reviews on the develop branch.
  • Bug Fixes & Improvements

    • Simplified error handling UI in the AI word helper—error states now display a single retry button instead of complex panels.
  • Removals

    • Deleted quiz datasets for TypeScript, Angular, CSS, HTML, and Git courses (all related seed scripts removed as well).
    • Removed project structure documentation file.

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

@ViktorSvertoka ViktorSvertoka self-assigned this Feb 1, 2026
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Feb 1, 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 1, 2026 8:55pm

@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 1, 2026

Deploy Preview for develop-devlovers ready!

Name Link
🔨 Latest commit ecc2e0c
🔍 Latest deploy log https://app.netlify.com/projects/develop-devlovers/deploys/697fbdce6dbf1d00089703fa
😎 Deploy Preview https://deploy-preview-250--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 1, 2026

📝 Walkthrough

Walkthrough

This pull request performs a large-scale cleanup operation removing inline comments and documentation throughout the frontend codebase, deletes all quiz data JSON files and associated seed scripts, removes project documentation, and refactors rate-limiting logic with simplified error UI in the AI explain endpoint.

Changes

Cohort / File(s) Summary
Configuration & Workflow
.coderabbit.yaml, .github/workflows/shop-janitor-restock-stale.yml
Added CodeRabbit configuration with auto_review enabled for develop branch; removed comment lines from workflow file without behavioral changes.
Shop Admin Pages
frontend/app/[locale]/shop/admin/orders/page.tsx, frontend/app/[locale]/shop/admin/products/_components/product-form.tsx
Removed inline comments and reformatted JSX; no functional logic changes. Minor formatting adjustments to <dt> elements and conditional labels.
Shop Cart & Checkout Pages
frontend/app/[locale]/shop/CartPageClient.tsx, frontend/app/[locale]/shop/checkout/payment/StripePaymentClient.tsx, frontend/app/[locale]/shop/checkout/payment/[orderId]/page.tsx, frontend/app/[locale]/shop/checkout/success/*
Removed explanatory comments from navigation, error handling, and UI sections. Minor whitespace and JSX formatting adjustments in StripePaymentClient; no behavioral changes.
Shop Product & Order Pages
frontend/app/[locale]/shop/orders/page.tsx, frontend/app/[locale]/shop/orders/[id]/page.tsx, frontend/app/[locale]/shop/products/page.tsx, frontend/app/[locale]/shop/products/[slug]/page.tsx, frontend/app/[locale]/shop/page.tsx
Removed navigation, styling, and canonicalization comments; reformatted metadata descriptions and NAV_LINK calls. No functional changes.
API Routes - Admin & Cart
frontend/app/api/shop/admin/orders/[id]/route.ts, frontend/app/api/shop/admin/orders/reconcile-stale/route.ts, frontend/app/api/shop/admin/products/[id]/route.ts, frontend/app/api/shop/admin/products/[id]/status/route.ts, frontend/app/api/shop/cart/rehydrate/route.ts
Removed security/invariant documentation comments and observability notes. Minor refactoring in DELETE logic condensed to single expressions; control flow unchanged.
API Routes - Core Endpoints
frontend/app/api/ai/explain/route.ts, frontend/app/api/shop/checkout/route.ts, frontend/app/api/shop/internal/orders/restock-stale/route.ts, frontend/app/api/shop/webhooks/stripe/route.ts
Removed legacy/MVP comments and observability annotations. Functional change in explain endpoint: rate limiter now enforces hard block at MAX_REQUESTS_PER_WINDOW limit and returns resetIn value; added explicit handling for 429 and 404 Groq errors.
Q&A Components
frontend/components/q&a/AIWordHelper.tsx, frontend/components/q&a/AccordionList.tsx, frontend/components/q&a/SelectableText.tsx
Significant refactoring in AIWordHelper: error UI for RATE_LIMITED/SERVICE_UNAVAILABLE replaced with simplified retry button, reducing UI branching. Minor comment and formatting changes in other components.
Quiz Components
frontend/components/quiz/CountdownTimer.tsx, frontend/components/quiz/QuizContainer.tsx
Refactored formatting and introduced useQuizGuards hook for centralized exit handling. Whitespace adjustments to visibility handlers, JSX attributes, and timestamp calculations; semantics unchanged.
Shared & Shop UI Components
frontend/components/shared/HeaderButton.tsx, frontend/components/shop/add-to-cart-button.tsx, frontend/components/shop/admin/admin-pagination.tsx, frontend/components/shop/admin/admin-product-delete-button.tsx, frontend/components/shop/cart-provider.tsx, frontend/components/shop/product-card.tsx, frontend/components/shop/product-filters.tsx, frontend/components/shop/product-sort.tsx, frontend/components/shop/products-toolbar.tsx, frontend/components/shop/shop-hero.tsx
Removed inline comments across UI sections. shop-hero.tsx: removed three decorative span elements (base gradient, hover wave overlay, glass inset) from CTA button. Other changes are comment removals with no behavioral impact.
UI Core Components
frontend/components/ui/button.tsx, frontend/components/ui/particle-canvas.tsx
Formatting and whitespace adjustments; switched quote styles and added semicolons in particle-canvas. Public API signatures unchanged.
Database Queries & Schema
frontend/db/queries/quiz.ts, frontend/db/schema/shop.ts
Removed inline documentation comments from quiz queries and shop schema definitions; no logic changes.
Quiz Seed Scripts
frontend/db/seed-quiz-*.ts, json/quizzes/*/seed-quiz-*.ts
Removed seed scripts for Angular, CSS, Git, HTML, JavaScript, Node.js, React, and TypeScript quizzes. Previously contained ORM-based database seeding logic for multi-locale quiz content, category management, and part-wise orchestration. Primarily formatting changes in remaining seed files (string wrapping, line breaks).
Quiz Data Files
frontend/parse/typescript/**/typescript-*-quiz-*.json, json/quizzes/angular/**/*-quiz-*.json, json/quizzes/css/**/*-quiz-*.json, json/quizzes/git/*-quiz-*.json, json/quizzes/html/**/*-quiz-*.json
Deleted all quiz data JSON files (parts 1-4) for TypeScript (fundamentals & advanced), Angular (beginner/medium & advanced), CSS (fundamentals & advanced), Git, and HTML (advanced). Each file contained 10 multilingual quiz questions with answer options and correctness flags.
Documentation & Config Files
frontend/project-structure.txt, frontend/checkout.json
Removed project structure documentation (649 lines) and checkout.json test fixture; no code impact.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant RateLimiter
    participant ExplainAPI as AI Explain Route
    participant GroqAPI as Groq API
    
    Client->>ExplainAPI: POST /api/ai/explain (with API key)
    ExplainAPI->>RateLimiter: checkRateLimit(userId, MAX_REQUESTS_PER_WINDOW)
    
    alt Within Limit
        RateLimiter->>RateLimiter: Increment counter, compute resetIn
        RateLimiter-->>ExplainAPI: {allowed: true, remaining, resetIn}
        ExplainAPI->>GroqAPI: Send explanation request
        alt Success
            GroqAPI-->>ExplainAPI: Groq response
            ExplainAPI-->>Client: Parsed explanation
        else 429 Rate Limited
            GroqAPI-->>ExplainAPI: 429 error
            ExplainAPI-->>Client: {error: "rate_limit_exceeded", resetIn}
        else 404 Model Unavailable
            GroqAPI-->>ExplainAPI: 404 error
            ExplainAPI-->>Client: {error: "model_unavailable"}
        end
    else At/Over Limit
        RateLimiter->>RateLimiter: Return allowed: false, remaining: 0
        RateLimiter-->>ExplainAPI: {allowed: false, remaining: 0, resetIn}
        ExplainAPI-->>Client: {error: "rate_limit_exceeded", resetIn}
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

refactor, comment-cleanup, data-removal

Suggested reviewers

  • AM1007

Poem

🐰 Comments fade like morning dew,
JSON quizzes bid adieu,
Rate limits tightened, errors clear,
UI simplified, code runs near.
Hop through this cleanup with care and cheer! 🎯

🚥 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 'Refactoring code & bag fix' is vague and contains a typo ('bag' instead of likely 'bug'). It fails to clearly convey the primary changes in this large, multi-faceted PR involving comment removal, formatting cleanup, quiz data deletion, and rate limiting improvements. Revise the title to be more specific and accurate, such as 'Remove comments and clean up formatting across codebase' or 'Clean up code comments, format fixes, and remove quiz data files', and correct the apparent typo.
✅ 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 fix/ref

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

Caution

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

⚠️ Outside diff range comments (2)
frontend/db/queries/quiz.ts (1)

217-253: ⚠️ Potential issue | 🟠 Major

Ensure deterministic answer order per question.

The answers are ordered only by quizAnswers.displayOrder, which can interleave rows from different questions and lead to unstable per-question ordering after grouping. Add quizAnswers.quizQuestionId to the orderBy to keep answer order deterministic within each question.

🔧 Proposed fix
-    .orderBy(quizAnswers.displayOrder);
+    .orderBy(quizAnswers.quizQuestionId, quizAnswers.displayOrder);
frontend/app/api/ai/explain/route.ts (1)

42-64: ⚠️ Potential issue | 🟡 Minor

Handle the exact reset boundary to avoid “0 minutes” blocks.
At the exact resetAt timestamp, the limiter can still block and produce a 0-minute retry message. Using >= and clamping resetIn avoids that edge case.

🔧 Suggested fix
-  if (!entry || now > entry.resetAt) {
+  if (!entry || now >= entry.resetAt) {
     rateLimiter.set(userId, { count: 1, resetAt: now + RATE_LIMIT_WINDOW_MS });
     return {
       allowed: true,
       remaining: MAX_REQUESTS_PER_WINDOW - 1,
       resetIn: RATE_LIMIT_WINDOW_MS,
     };
   }

   if (entry.count >= MAX_REQUESTS_PER_WINDOW) {
-    const resetIn = entry.resetAt - now;
+    const resetIn = Math.max(0, entry.resetAt - now);
     return { allowed: false, remaining: 0, resetIn };
   }
🤖 Fix all issues with AI agents
In `@frontend/components/quiz/QuizContainer.tsx`:
- Around line 229-291: The verifyAnswer fetch can hang indefinitely; wrap the
fetch in an AbortController with a timeout: in verifyAnswer create an
AbortController, pass controller.signal to fetch, start a timer (setTimeout)
that calls controller.abort() after a configurable timeout (e.g., 5-10s), and
clear the timer once fetch settles; ensure verifyAnswer rejects with the
abort/fetch error so the existing retry loop in handleAnswer handles it, and
leave handleAnswer's finally logic (setIsVerifyingAnswer(false)) unchanged so it
runs when the fetch rejects. Reference: verifyAnswer, handleAnswer,
setIsVerifyingAnswer, and sleep.

In `@frontend/db/seed-quiz-angular-advanced.ts`:
- Around line 224-230: Usage strings reference the wrong path; update the three
console.log messages that currently mention
"db/seeds/seed-quiz-angular-advanced.ts" (the lines where usage/example/upload
instructions are printed) to use the correct path
"db/seed-quiz-angular-advanced.ts" so the displayed CLI examples match the
actual file location.
- Around line 72-79: The seed script references non-existent JSON files via the
partPath construction (using projectRoot and partNumber) and will throw ENOENT
when readFileSync runs; either remove this seed file
(frontend/db/seed-quiz-angular-advanced.ts) if the quiz data is no longer
required, or restore the missing files
json/quizzes/angular/advanced/angular-advanced-quiz-part1.json through
part4.json so readFileSync succeeds — update or delete any calls to the seed
function that rely on this file accordingly.

In `@frontend/db/seed-quiz-css-advanced.ts`:
- Around line 219-225: Update the three usage messages printed by the
console.log calls in seed-quiz-css-advanced.ts to reference the correct script
path (remove the extra "seeds" segment) so developers run the right file;
specifically edit the three console.log strings that currently show
"db/seeds/seed-quiz-css-advanced.ts" to "db/seed-quiz-css-advanced.ts" (leave
the examples and flags unchanged).

In `@frontend/db/seed-quiz-css.ts`:
- Around line 67-75: The loadQuestions function is trying to read non-existent
files and causes seedQuizFromJson to crash; fix by removing or guarding the file
reads: update loadQuestions to not read parse/css/fundamentals files (either
return an empty QuestionData[] and log a clear warning or read from the correct
existing source), and update calls in seedQuizFromJson so they no longer assume
valid data (wrap the calls to loadQuestions in try/catch or skip them and handle
empty arrays). Refer to the loadQuestions function and the seedQuizFromJson
calls to ensure the seed script no longer throws when the JSON files are
missing.

In `@frontend/db/seed-quiz-javascript-advanced.ts`:
- Around line 68-77: The seed script attempts to load files like
javascript-advanced-quiz-part{1..4}.json via readFileSync using the partPath
variable (in the loadQuestions function) but those JSON files no longer exist,
causing ENOENT at runtime; fix by adding an existence check
(fs.existsSync(partPath)) before JSON.parse(readFileSync(...)) in loadQuestions
and handle missing files gracefully (either return an empty questions array for
that part and log a clear error via console.error or throw a descriptive error
that explains the files are missing), or alternatively remove/disable the seed
script if those data files will not be restored. Ensure you reference partPath,
readFileSync, QuizPartData (and the file names
javascript-advanced-quiz-part*.json) when making the change so the correct code
is updated.

In `@frontend/db/seed-quiz-nodejs-advanced.ts`:
- Around line 72-79: The seed script seed-quiz-nodejs-advanced.ts is left
referencing deleted JSON quiz files (see the const partPath usage) causing
failures; either delete the entire seed script file to match the PR objective of
removing quiz data, or restore the corresponding JSON files under
json/quizzes/node/advanced and update the const partPath construction if paths
changed so the script can find the files. Ensure any other code that imports or
invokes seed-quiz-nodejs-advanced.ts is also removed or updated accordingly.
🧹 Nitpick comments (5)
frontend/app/[locale]/shop/products/[slug]/page.tsx (1)

41-41: Avoid as any to keep type safety.

Consider narrowing result by kind or exporting a typed Product from getProductPageData so product is strongly typed without any.

.github/workflows/shop-janitor-restock-stale.yml (1)

5-5: Consider documenting the cron schedule.

While the comment removal aligns with this PR's cleanup objectives, cron expressions are notoriously cryptic. A brief inline comment (e.g., # Runs every 5 minutes) would improve readability for future maintainers unfamiliar with cron syntax.

frontend/components/q&a/AIWordHelper.tsx (2)

517-773: Consider extracting the error rendering logic to a named function.

The IIFE pattern (() => {...})() inside JSX works but is inconsistent with the renderGuestCTA() pattern already used in this component (line 375). Extracting this to a renderErrorState() function would improve consistency and readability.

♻️ Suggested refactor
+  const renderErrorState = () => {
+    if (!error) return null;
+    const messages = getLocalizedMessages(activeLocale);
+    
+    return (
+      <div className="flex flex-col items-center justify-center gap-4 py-8">
+        {error === 'RATE_LIMITED' ? (
+          // ... existing RATE_LIMITED JSX
+        ) : error === 'SERVICE_UNAVAILABLE' ? (
+          // ... existing SERVICE_UNAVAILABLE JSX
+        ) : (
+          // ... existing generic error JSX
+        )}
+      </div>
+    );
+  };

   // In the render:
-  {error &&
-    (() => {
-      const messages = getLocalizedMessages(activeLocale);
-      return (
-        // ... large inline block
-      );
-    })()}
+  {error && renderErrorState()}

525-528: Consider extracting retry threshold constants.

The values 3 and 5 for retry attempt thresholds are hardcoded in multiple places. Extracting them as named constants would improve maintainability and make the behavior easier to adjust.

♻️ Suggested refactor
+const RETRY_WARNING_THRESHOLD = 3;
+const RETRY_DISABLE_THRESHOLD = 5;

 // Then replace usages:
-rateLimitState.retryAttempts >= 3
+rateLimitState.retryAttempts >= RETRY_WARNING_THRESHOLD

-rateLimitState.retryAttempts >= 5
+rateLimitState.retryAttempts >= RETRY_DISABLE_THRESHOLD

Also applies to: 555-564, 567-572, 701-704, 721-728, 733-738

frontend/db/seed-quiz-angular-advanced.ts (1)

2-2: New existsSync import and projectRoot logic differs from sibling seed scripts.

This file now imports existsSync and uses it to dynamically determine projectRoot, while the HTML and CSS seed scripts use process.cwd() directly. This inconsistency could lead to different behaviors when running seeds from different working directories.

Consider aligning the approach across all seed scripts for consistency.

Also applies to: 67-69

Comment on lines 229 to +291
const verifyAnswer = async (answerId: string) => {
const response = await fetch('/api/quiz/verify-answer', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
questionId: currentQuestion.id,
answerId,
encryptedAnswers,
}),
});

if (!response.ok) {
throw new Error('Verify answer failed');
}
const response = await fetch('/api/quiz/verify-answer', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
questionId: currentQuestion.id,
answerId,
encryptedAnswers,
}),
});

const data = await response.json();
if (!response.ok) {
throw new Error('Verify answer failed');
}

if (typeof data.isCorrect !== 'boolean') {
throw new Error('Invalid verify response');
}
const data = await response.json();

return data.isCorrect;
};
if (typeof data.isCorrect !== 'boolean') {
throw new Error('Invalid verify response');
}

const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
return data.isCorrect;
};

const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));

const handleAnswer = async (answerId: string) => {
if (state.questionStatus !== 'answering') return;
if (isVerifyingAnswer) return;
const handleAnswer = async (answerId: string) => {
if (state.questionStatus !== 'answering') return;
if (isVerifyingAnswer) return;

setIsVerifyingAnswer(true);
setIsVerifyingAnswer(true);

const maxRetries = 1;
let attempt = 0;
const maxRetries = 1;
let attempt = 0;

try {
while (true) {
try {
const isCorrect = await verifyAnswer(answerId);
try {
while (true) {
try {
const isCorrect = await verifyAnswer(answerId);

dispatch({
type: 'ANSWER_SELECTED',
payload: {
answerId,
isCorrect,
questionId: currentQuestion.id,
},
});
return;
} catch {
if (attempt >= maxRetries) {
toast.error(tQuestion('verifyFailed'));
dispatch({
type: 'ANSWER_SELECTED',
payload: {
answerId,
isCorrect,
questionId: currentQuestion.id,
},
});
return;
} catch {
if (attempt >= maxRetries) {
toast.error(tQuestion('verifyFailed'));
return;
}
attempt += 1;
toast(tQuestion('verifyRetry'));
await sleep(600);
}
attempt += 1;
toast(tQuestion('verifyRetry'));
await sleep(600);
}
} finally {
setIsVerifyingAnswer(false);
}
} finally {
setIsVerifyingAnswer(false);
}
};
};
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

🧩 Analysis chain

🌐 Web query:

AbortController fetch support Next.js 16 browser compatibility

💡 Result:

Next.js 16’s official minimum browser targets are Chrome 111+, Edge 111+, Firefox 111+, and Safari 16.4+. These are the environments you should assume for client-side APIs like fetch() and AbortController. [1][2][3]

  • Client-side (browser) fetch(..., { signal }): Within Next.js 16’s supported browser range, AbortController / AbortSignal is available, so abortable fetch works without extra polyfills. AbortController is the standard way to cancel a fetch and causes the promise to reject with an AbortError. [3]
  • Older browsers: Next.js 16 no longer targets older Safari/Chrome/Firefox versions by default, so if you override browserslist to include older browsers, you may need to add your own polyfill for AbortController (Next.js docs mention built-in polyfills like fetch(), but do not imply AbortController is polyfilled for legacy browsers). [1]
  • Server-side (Node.js runtime): Next.js 16 requires Node.js 20.9+. On the server, fetch supports passing an abort signal as well (the platform API is available in this runtime baseline). [2]

Sources: Next.js supported browsers (Oct 1, 2025) [1]; Next.js 16 upgrade guide browser/Node requirements [2]; MDN AbortSignal / aborting fetch behavior [3].


Add a timeout/abort to verifyAnswer to prevent a stuck quiz.

If the network request hangs indefinitely, the fetch promise never settles, so the finally block won't execute and isVerifyingAnswer remains true, blocking the user from proceeding. AbortController with a timeout allows the retry logic to run and surfaces a clearer error to the user.

🛠️ Suggested fix (AbortController timeout)
 const verifyAnswer = async (answerId: string) => {
-  const response = await fetch('/api/quiz/verify-answer', {
-    method: 'POST',
-    headers: { 'Content-Type': 'application/json' },
-    body: JSON.stringify({
-      questionId: currentQuestion.id,
-      answerId,
-      encryptedAnswers,
-    }),
-  });
+  const controller = new AbortController();
+  const timeoutId = window.setTimeout(() => controller.abort(), 8000);
+  try {
+    const response = await fetch('/api/quiz/verify-answer', {
+      method: 'POST',
+      headers: { 'Content-Type': 'application/json' },
+      signal: controller.signal,
+      body: JSON.stringify({
+        questionId: currentQuestion.id,
+        answerId,
+        encryptedAnswers,
+      }),
+    });

-  if (!response.ok) {
-    throw new Error('Verify answer failed');
-  }
+    if (!response.ok) {
+      throw new Error('Verify answer failed');
+    }

-  const data = await response.json();
+    const data = await response.json();

-  if (typeof data.isCorrect !== 'boolean') {
-    throw new Error('Invalid verify response');
-  }
+    if (typeof data.isCorrect !== 'boolean') {
+      throw new Error('Invalid verify response');
+    }

-  return data.isCorrect;
+    return data.isCorrect;
+  } catch (error) {
+    if (error instanceof DOMException && error.name === 'AbortError') {
+      throw new Error('Verify answer timed out');
+    }
+    throw error;
+  } finally {
+    clearTimeout(timeoutId);
+  }
 };

AbortController is fully supported in Next.js 16's target browsers (Chrome 111+, Edge 111+, Firefox 111+, Safari 16.4+) with no known caveats.

📝 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
const verifyAnswer = async (answerId: string) => {
const response = await fetch('/api/quiz/verify-answer', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
questionId: currentQuestion.id,
answerId,
encryptedAnswers,
}),
});
if (!response.ok) {
throw new Error('Verify answer failed');
}
const response = await fetch('/api/quiz/verify-answer', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
questionId: currentQuestion.id,
answerId,
encryptedAnswers,
}),
});
const data = await response.json();
if (!response.ok) {
throw new Error('Verify answer failed');
}
if (typeof data.isCorrect !== 'boolean') {
throw new Error('Invalid verify response');
}
const data = await response.json();
return data.isCorrect;
};
if (typeof data.isCorrect !== 'boolean') {
throw new Error('Invalid verify response');
}
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
return data.isCorrect;
};
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
const handleAnswer = async (answerId: string) => {
if (state.questionStatus !== 'answering') return;
if (isVerifyingAnswer) return;
const handleAnswer = async (answerId: string) => {
if (state.questionStatus !== 'answering') return;
if (isVerifyingAnswer) return;
setIsVerifyingAnswer(true);
setIsVerifyingAnswer(true);
const maxRetries = 1;
let attempt = 0;
const maxRetries = 1;
let attempt = 0;
try {
while (true) {
try {
const isCorrect = await verifyAnswer(answerId);
try {
while (true) {
try {
const isCorrect = await verifyAnswer(answerId);
dispatch({
type: 'ANSWER_SELECTED',
payload: {
answerId,
isCorrect,
questionId: currentQuestion.id,
},
});
return;
} catch {
if (attempt >= maxRetries) {
toast.error(tQuestion('verifyFailed'));
dispatch({
type: 'ANSWER_SELECTED',
payload: {
answerId,
isCorrect,
questionId: currentQuestion.id,
},
});
return;
} catch {
if (attempt >= maxRetries) {
toast.error(tQuestion('verifyFailed'));
return;
}
attempt += 1;
toast(tQuestion('verifyRetry'));
await sleep(600);
}
attempt += 1;
toast(tQuestion('verifyRetry'));
await sleep(600);
}
} finally {
setIsVerifyingAnswer(false);
}
} finally {
setIsVerifyingAnswer(false);
}
};
};
const verifyAnswer = async (answerId: string) => {
const controller = new AbortController();
const timeoutId = window.setTimeout(() => controller.abort(), 8000);
try {
const response = await fetch('/api/quiz/verify-answer', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
signal: controller.signal,
body: JSON.stringify({
questionId: currentQuestion.id,
answerId,
encryptedAnswers,
}),
});
if (!response.ok) {
throw new Error('Verify answer failed');
}
const data = await response.json();
if (typeof data.isCorrect !== 'boolean') {
throw new Error('Invalid verify response');
}
return data.isCorrect;
} catch (error) {
if (error instanceof DOMException && error.name === 'AbortError') {
throw new Error('Verify answer timed out');
}
throw error;
} finally {
clearTimeout(timeoutId);
}
};
🤖 Prompt for AI Agents
In `@frontend/components/quiz/QuizContainer.tsx` around lines 229 - 291, The
verifyAnswer fetch can hang indefinitely; wrap the fetch in an AbortController
with a timeout: in verifyAnswer create an AbortController, pass
controller.signal to fetch, start a timer (setTimeout) that calls
controller.abort() after a configurable timeout (e.g., 5-10s), and clear the
timer once fetch settles; ensure verifyAnswer rejects with the abort/fetch error
so the existing retry loop in handleAnswer handles it, and leave handleAnswer's
finally logic (setIsVerifyingAnswer(false)) unchanged so it runs when the fetch
rejects. Reference: verifyAnswer, handleAnswer, setIsVerifyingAnswer, and sleep.

Comment on lines +72 to +79
const partPath = join(
projectRoot,
'json',
'quizzes',
'angular',
'advanced',
`angular-advanced-quiz-part${partNumber}.json`
);
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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the Angular Advanced quiz JSON files exist
echo "=== Checking for Angular Advanced quiz data files ==="
for i in 1 2 3 4; do
  file="json/quizzes/angular/advanced/angular-advanced-quiz-part${i}.json"
  if [ -f "$file" ]; then
    echo "✓ Found: $file"
  else
    echo "✗ Missing: $file"
  fi
done

echo ""
echo "=== Broader search for quiz JSON files ==="
fd -t f "\.json$" "json/quizzes/" 2>/dev/null | head -20

echo ""
echo "=== Check seed script content ==="
cat -n frontend/db/seed-quiz-angular-advanced.ts | sed -n '70,85p'

Repository: DevLoversTeam/devlovers.net

Length of output: 1049


Remove this seed script or restore the referenced JSON data files.

The seed script attempts to load JSON files from json/quizzes/angular/advanced/angular-advanced-quiz-part{1,2,3,4}.json (lines 72-79), but these files do not exist in the repository. When readFileSync() executes at line 80, it will fail with an ENOENT error. Either delete this seed script if the quiz data is no longer needed, or restore the missing JSON files.

🤖 Prompt for AI Agents
In `@frontend/db/seed-quiz-angular-advanced.ts` around lines 72 - 79, The seed
script references non-existent JSON files via the partPath construction (using
projectRoot and partNumber) and will throw ENOENT when readFileSync runs; either
remove this seed file (frontend/db/seed-quiz-angular-advanced.ts) if the quiz
data is no longer required, or restore the missing files
json/quizzes/angular/advanced/angular-advanced-quiz-part1.json through
part4.json so readFileSync succeeds — update or delete any calls to the seed
function that rely on this file accordingly.

Comment on lines +224 to +230
console.log(
'Usage: npx tsx db/seeds/seed-quiz-angular-advanced.ts <part-number>'
);
console.log('Example: npx tsx db/seeds/seed-quiz-angular-advanced.ts 1');
console.log('Or upload all: npx tsx db/seeds/seed-quiz-angular-advanced.ts all');
console.log(
'Or upload all: npx tsx db/seeds/seed-quiz-angular-advanced.ts all'
);
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

Incorrect file path in usage instructions.

Same issue as in the CSS seed script: the usage instructions reference db/seeds/seed-quiz-angular-advanced.ts, but this file is at db/seed-quiz-angular-advanced.ts (no seeds subdirectory).

🔧 Proposed fix
-    console.log(
-      'Usage: npx tsx db/seeds/seed-quiz-angular-advanced.ts <part-number>'
-    );
-    console.log('Example: npx tsx db/seeds/seed-quiz-angular-advanced.ts 1');
-    console.log(
-      'Or upload all: npx tsx db/seeds/seed-quiz-angular-advanced.ts all'
-    );
+    console.log(
+      'Usage: npx tsx db/seed-quiz-angular-advanced.ts <part-number>'
+    );
+    console.log('Example: npx tsx db/seed-quiz-angular-advanced.ts 1');
+    console.log(
+      'Or upload all: npx tsx db/seed-quiz-angular-advanced.ts all'
+    );
📝 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
console.log(
'Usage: npx tsx db/seeds/seed-quiz-angular-advanced.ts <part-number>'
);
console.log('Example: npx tsx db/seeds/seed-quiz-angular-advanced.ts 1');
console.log('Or upload all: npx tsx db/seeds/seed-quiz-angular-advanced.ts all');
console.log(
'Or upload all: npx tsx db/seeds/seed-quiz-angular-advanced.ts all'
);
console.log(
'Usage: npx tsx db/seed-quiz-angular-advanced.ts <part-number>'
);
console.log('Example: npx tsx db/seed-quiz-angular-advanced.ts 1');
console.log(
'Or upload all: npx tsx db/seed-quiz-angular-advanced.ts all'
);
🤖 Prompt for AI Agents
In `@frontend/db/seed-quiz-angular-advanced.ts` around lines 224 - 230, Usage
strings reference the wrong path; update the three console.log messages that
currently mention "db/seeds/seed-quiz-angular-advanced.ts" (the lines where
usage/example/upload instructions are printed) to use the correct path
"db/seed-quiz-angular-advanced.ts" so the displayed CLI examples match the
actual file location.

Comment on lines +219 to +225
console.log(
'Usage: npx tsx db/seeds/seed-quiz-css-advanced.ts <part-number>'
);
console.log('Example: npx tsx db/seeds/seed-quiz-css-advanced.ts 1');
console.log('Or upload all: npx tsx db/seeds/seed-quiz-css-advanced.ts all');
console.log(
'Or upload all: npx tsx db/seeds/seed-quiz-css-advanced.ts all'
);
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

Incorrect file path in usage instructions.

The usage instructions reference db/seeds/seed-quiz-css-advanced.ts, but this file is located at db/seed-quiz-css-advanced.ts (without the seeds subdirectory). This will mislead developers trying to run the script.

🔧 Proposed fix
-    console.log(
-      'Usage: npx tsx db/seeds/seed-quiz-css-advanced.ts <part-number>'
-    );
-    console.log('Example: npx tsx db/seeds/seed-quiz-css-advanced.ts 1');
-    console.log(
-      'Or upload all: npx tsx db/seeds/seed-quiz-css-advanced.ts all'
-    );
+    console.log(
+      'Usage: npx tsx db/seed-quiz-css-advanced.ts <part-number>'
+    );
+    console.log('Example: npx tsx db/seed-quiz-css-advanced.ts 1');
+    console.log(
+      'Or upload all: npx tsx db/seed-quiz-css-advanced.ts all'
+    );
📝 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
console.log(
'Usage: npx tsx db/seeds/seed-quiz-css-advanced.ts <part-number>'
);
console.log('Example: npx tsx db/seeds/seed-quiz-css-advanced.ts 1');
console.log('Or upload all: npx tsx db/seeds/seed-quiz-css-advanced.ts all');
console.log(
'Or upload all: npx tsx db/seeds/seed-quiz-css-advanced.ts all'
);
console.log(
'Usage: npx tsx db/seed-quiz-css-advanced.ts <part-number>'
);
console.log('Example: npx tsx db/seed-quiz-css-advanced.ts 1');
console.log(
'Or upload all: npx tsx db/seed-quiz-css-advanced.ts all'
);
🤖 Prompt for AI Agents
In `@frontend/db/seed-quiz-css-advanced.ts` around lines 219 - 225, Update the
three usage messages printed by the console.log calls in
seed-quiz-css-advanced.ts to reference the correct script path (remove the extra
"seeds" segment) so developers run the right file; specifically edit the three
console.log strings that currently show "db/seeds/seed-quiz-css-advanced.ts" to
"db/seed-quiz-css-advanced.ts" (leave the examples and flags unchanged).

Comment on lines 67 to 75
async function loadQuestions(partNumber: number): Promise<QuestionData[]> {
const partPath = join(process.cwd(), 'parse', 'css', 'fundamentals', `css-quiz-part${partNumber}.json`);
const partPath = join(
process.cwd(),
'parse',
'css',
'fundamentals',
`css-quiz-part${partNumber}.json`
);
const partData: QuizPartData = JSON.parse(readFileSync(partPath, 'utf-8'));
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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

fd -a -g 'css-quiz-part*.json' parse/css/fundamentals

Repository: DevLoversTeam/devlovers.net

Length of output: 180


🏁 Script executed:

# Search for the parse directory
fd -a -g 'parse' -t d

# Search for any css-quiz-part JSON files anywhere
fd -a -g 'css-quiz-part*.json'

# Check if there are any quiz JSON files at all
fd -a -g '*quiz*.json' | head -20

Repository: DevLoversTeam/devlovers.net

Length of output: 105


🏁 Script executed:

# List the structure of frontend/parse
tree frontend/parse -L 3 2>/dev/null || find frontend/parse -type f | head -30

# Search globally for css-quiz-part JSON files
fd -a -g 'css-quiz-part*.json'

# Search for quiz JSON files
fd -a -g '*quiz*.json' | head -20

Repository: DevLoversTeam/devlovers.net

Length of output: 153


🏁 Script executed:

# Check the seed-quiz-css.ts file to see if loadQuestions is called
cat -n frontend/db/seed-quiz-css.ts

# Check the questions.json file structure
head -50 frontend/parse/questions.json

Repository: DevLoversTeam/devlovers.net

Length of output: 9426


Remove or fix the broken loadQuestions function—referenced JSON files do not exist.

The loadQuestions function attempts to load from parse/css/fundamentals/css-quiz-part{1-4}.json, but neither the css/fundamentals/ subdirectory nor these JSON files exist in the repository. This function is actively called by seedQuizFromJson() at lines 235 and 254, meaning the seed script will throw an error and fail immediately when run. Either restore the missing quiz data files or remove this seed script entirely.

🤖 Prompt for AI Agents
In `@frontend/db/seed-quiz-css.ts` around lines 67 - 75, The loadQuestions
function is trying to read non-existent files and causes seedQuizFromJson to
crash; fix by removing or guarding the file reads: update loadQuestions to not
read parse/css/fundamentals files (either return an empty QuestionData[] and log
a clear warning or read from the correct existing source), and update calls in
seedQuizFromJson so they no longer assume valid data (wrap the calls to
loadQuestions in try/catch or skip them and handle empty arrays). Refer to the
loadQuestions function and the seedQuizFromJson calls to ensure the seed script
no longer throws when the JSON files are missing.

Comment on lines +68 to 77
const partPath = join(
process.cwd(),
'parse',
'js',
'advanced',
`javascript-advanced-quiz-part${partNumber}.json`
);
const partData: QuizPartData = JSON.parse(readFileSync(partPath, 'utf-8'));
return partData.questions;
}
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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for the required JSON quiz data files

echo "=== Searching for javascript-advanced-quiz-part JSON files ==="
fd --type f 'javascript-advanced-quiz-part.*\.json$'

echo ""
echo "=== Checking parse/js/advanced directory ==="
fd --type d 'advanced' 2>/dev/null || echo "No 'advanced' directory found"

echo ""
echo "=== Listing parse directory structure if it exists ==="
if [ -d "parse" ]; then
  find parse -type f -name "*.json" 2>/dev/null | head -20
else
  echo "parse directory does not exist"
fi

Repository: DevLoversTeam/devlovers.net

Length of output: 266


This seed script will fail at runtime — required JSON data files are missing.

The script loads quiz data from parse/js/advanced/javascript-advanced-quiz-part{1,2,3,4}.json, but these files no longer exist in the repository. The readFileSync call on line 76 will throw an ENOENT error when the loadQuestions function is invoked.

Either restore the JSON data files or remove/disable this seed script to prevent runtime failures.

🤖 Prompt for AI Agents
In `@frontend/db/seed-quiz-javascript-advanced.ts` around lines 68 - 77, The seed
script attempts to load files like javascript-advanced-quiz-part{1..4}.json via
readFileSync using the partPath variable (in the loadQuestions function) but
those JSON files no longer exist, causing ENOENT at runtime; fix by adding an
existence check (fs.existsSync(partPath)) before JSON.parse(readFileSync(...))
in loadQuestions and handle missing files gracefully (either return an empty
questions array for that part and log a clear error via console.error or throw a
descriptive error that explains the files are missing), or alternatively
remove/disable the seed script if those data files will not be restored. Ensure
you reference partPath, readFileSync, QuizPartData (and the file names
javascript-advanced-quiz-part*.json) when making the change so the correct code
is updated.

Comment on lines +72 to +79
const partPath = join(
projectRoot,
'json',
'quizzes',
'node',
'advanced',
`nodejs-advanced-quiz-part${partNumber}.json`
);
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

🧩 Analysis chain

🏁 Script executed:

# Check if the quiz JSON files this seed script depends on exist
fd -t f 'nodejs-advanced-quiz-part[0-9]+\.json$' 'json/quizzes/node/advanced' 2>/dev/null || echo "No files found"

Repository: DevLoversTeam/devlovers.net

Length of output: 85


🏁 Script executed:

# List all files in the json/quizzes/node/advanced directory to see what exists
find json/quizzes/node/advanced -type f 2>/dev/null | head -20 || echo "Directory not found or empty"

Repository: DevLoversTeam/devlovers.net

Length of output: 53


🏁 Script executed:

# Confirm the seed script file still exists
ls -la frontend/db/seed-quiz-nodejs-advanced.ts 2>/dev/null || echo "File not found"

Repository: DevLoversTeam/devlovers.net

Length of output: 160


🏁 Script executed:

# Check the readFileSync calls and error handling in the seed script
cat -n frontend/db/seed-quiz-nodejs-advanced.ts | head -100

Repository: DevLoversTeam/devlovers.net

Length of output: 3338


🏁 Script executed:

# Look for where loadQuestions is called and if there's error handling
grep -n "loadQuestions\|readFileSync\|try\|catch" frontend/db/seed-quiz-nodejs-advanced.ts

Repository: DevLoversTeam/devlovers.net

Length of output: 454


Remove this seed script to match the PR's stated objective.

The PR summary indicates it "deletes all quiz data JSON files and associated seed scripts," but this seed script remains. The required JSON files in json/quizzes/node/advanced/ have been deleted, causing the seed script to fail when called. Either remove this seed script file (frontend/db/seed-quiz-nodejs-advanced.ts) to match the PR objectives, or restore the JSON files if this quiz data should be retained.

🤖 Prompt for AI Agents
In `@frontend/db/seed-quiz-nodejs-advanced.ts` around lines 72 - 79, The seed
script seed-quiz-nodejs-advanced.ts is left referencing deleted JSON quiz files
(see the const partPath usage) causing failures; either delete the entire seed
script file to match the PR objective of removing quiz data, or restore the
corresponding JSON files under json/quizzes/node/advanced and update the const
partPath construction if paths changed so the script can find the files. Ensure
any other code that imports or invokes seed-quiz-nodejs-advanced.ts is also
removed or updated accordingly.

@ViktorSvertoka ViktorSvertoka merged commit eaf3eb0 into develop Feb 1, 2026
11 checks passed
@ViktorSvertoka ViktorSvertoka deleted the fix/ref branch February 1, 2026 21:03
ViktorSvertoka added a commit that referenced this pull request Feb 1, 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

---------

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>
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.

1 participant