Skip to content

Release v1.0.12#451

Merged
ViktorSvertoka merged 7 commits intomainfrom
develop
Apr 23, 2026
Merged

Release v1.0.12#451
ViktorSvertoka merged 7 commits intomainfrom
develop

Conversation

@ViktorSvertoka
Copy link
Copy Markdown
Member

@ViktorSvertoka ViktorSvertoka commented Apr 23, 2026

Summary by CodeRabbit

  • New Features

    • Added category support and styling for PHP, Laravel, C#, and .NET.
    • Introduced Dashboard section showcasing learning progress, quiz history, and account activity.
  • Bug Fixes

    • Improved shop cart stability during server-side rendering.
    • Enhanced number formatting for platform statistics.
    • Brightened Django category accent color on dark theme.
  • Documentation

    • Updated README with dashboard overview and quick-start links.
    • Blog section now reflects in-house management workflow.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 23, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
devlovers-net Ignored Ignored Apr 23, 2026 0:30am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2026

📝 Walkthrough

Walkthrough

Release v1.0.12 introduces a registry-driven category system for centralized styling/icon management, refactors environment variable resolution for shop cart capabilities to be runtime-safe on Netlify, removes all Sanity CMS studio infrastructure, updates blog management to in-house admin panel, adjusts LinkedIn follower display formatting, and bumps package version.

Changes

Cohort / File(s) Summary
Release Documentation
CHANGELOG.md, frontend/package.json
Version bump to 1.0.12 with documentation of registry-driven category system, blog migration, cart env resolution fix, and LinkedIn follower adjustment.
Category Registry System
frontend/data/categoryRegistry.ts, frontend/data/category.ts, frontend/data/categoryStyles.ts
Introduces new typed categoryRegistry with category metadata (slug, title, icon, colors, Tailwind classes); refactors categoryData and categoryTabStyles to derive from registry while preserving exported API signatures for backward compatibility.
Shop Cart Runtime Safety
frontend/app/[locale]/shop/cart/capabilities.ts, frontend/lib/env/stripe.ts, frontend/lib/env/monobank.ts, frontend/lib/env/provider-runtime.ts
Migrates provider capability checks (Stripe, Monobank) to use readServerEnv() for runtime-safe server environment access; adds fail-closed error handling to prevent SSR crashes when unrelated env vars are missing.
Cart Capability Testing
frontend/lib/tests/shop/public-cart-env-contract.test.ts
Refactors test suite to remove provider-specific mocks and drive all capability resolution through readServerEnv mock; adds resilience tests for missing auth/database env and validates runtime-only configuration behavior.
About Page Updates
frontend/components/about/HeroSection.tsx, frontend/lib/about/stats.ts
Updates LinkedIn follower fallback from 1.8k+ to 2k+ and refines formatMetric to omit .0 for whole-thousand compact numbers.
Documentation Restructuring
README.md
Removes platform overview, tech stack table, repository structure, and getting-started sections; adds Dashboard section, updates blog entry to reflect in-house admin instead of Sanity CMS, and restores production/develop URLs.
Sanity CMS Infrastructure Removal
studio/.gitignore, studio/.prettierrc, studio/eslint.config.mjs, studio/package.json, studio/sanity.cli.ts, studio/sanity.config.ts, studio/schemaTypes/..., studio/tsconfig.json
Completely removes Sanity Studio configuration, CLI config, ESLint/Prettier configs, TypeScript config, package manifest, and all schema type definitions (post, author, category, blockContent, socialLink).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

refactor, UI, UX

Suggested reviewers

  • LesiaUKR
  • AM1007
  • liudmylasovetovs

Poem

🐰 A registry blooms, categories aligned,
With Sanity's studio left far behind,
Safe server reads make the cart run true,
LinkedIn shines brighter at version 1.0.12! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Release v1.0.12' directly corresponds to the pull request's primary objective of releasing version 1.0.12, as evidenced by the CHANGELOG.md documenting the 1.0.12 release and package.json version bump from 1.0.11 to 1.0.12.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

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

🧹 Nitpick comments (1)
frontend/data/category.ts (1)

13-15: Sort by displayOrder when deriving categoryData.

Right now the exported array depends on registry insertion order. Since each item carries displayOrder, sort the derived data explicitly to prevent future ordering drift.

♻️ Proposed refactor
-export const categoryData = categoryRegistry.map(item =>
-  createCategory(item.slug, item.title, item.displayOrder)
-);
+export const categoryData = [...categoryRegistry]
+  .sort((a, b) => a.displayOrder - b.displayOrder)
+  .map(item => createCategory(item.slug, item.title, item.displayOrder));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/data/category.ts` around lines 13 - 15, categoryData currently maps
categoryRegistry in insertion order, causing output to drift; before mapping
call createCategory, sort the registry by each item's displayOrder to ensure
deterministic ordering. Locate categoryData and replace the direct map over
categoryRegistry with a sorted iteration (e.g., copy and sort categoryRegistry
by item.displayOrder) and then map to createCategory(item.slug, item.title,
item.displayOrder).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/app/`[locale]/shop/cart/capabilities.ts:
- Around line 25-40: Both resolveMonobankCheckoutEnabled and
resolveMonobankGooglePayEnabled can throw when calling readServerEnv (and thus
reintroduce SSR/runtime crashes); move any readServerEnv and isFlagEnabled calls
into the same fail-closed try/catch boundary so exceptions are caught and the
function returns false. Concretely, in resolveMonobankCheckoutEnabled wrap the
paymentsEnabled read and check (readServerEnv('PAYMENTS_ENABLED') +
isFlagEnabled) inside the try/catch that also calls isMonobankEnabled and return
false on any exception; do the same in resolveMonobankGooglePayEnabled so the
SHOP_MONOBANK_GPAY_ENABLED read is performed inside a try/catch and returns
false on error, referencing resolveMonobankCheckoutEnabled,
resolveMonobankGooglePayEnabled, isFlagEnabled, readServerEnv, and
isMonobankEnabled to locate the changes.

In `@frontend/lib/about/stats.ts`:
- Around line 16-18: The compact-thousands formatting branch that computes value
= n / 1000 and returns (Number.isInteger(value) ? value.toString() :
value.toFixed(1)) + 'k+' can produce strings like "2.0k+"; update the return to
strip a trailing ".0" after formatting (e.g., generate the formatted string
using toFixed(1) when needed, then remove a trailing ".0" via a replace or
similar) so the final result becomes "2k+" instead of "2.0k+" while still
preserving one decimal for non-round values.

In `@frontend/lib/env/stripe.ts`:
- Around line 37-42: The mode inference currently uses a raw NODE_ENV check;
change the logic that computes the mode (the const mode using rawMode and
nodeEnv) to reuse the existing isProductionLikeRuntime() helper so a
production-like runtime (e.g., APP_ENV=production) yields 'live' when
STRIPE_MODE is missing; update the other location that makes the same decision
(the later defaulting logic that currently checks nodeEnv) to also call
isProductionLikeRuntime(); ensure rawMode still accepts 'test'|'live' values
first, otherwise return 'live' when isProductionLikeRuntime() is true and 'test'
otherwise.

In `@frontend/lib/tests/shop/public-cart-env-contract.test.ts`:
- Around line 173-183: The test "enables stripe capability from runtime-only env
when config is valid" uses mock Stripe secret-shaped strings which trigger
secret scanners; update the readServerEnvMock implementation used in that test
(and the nearby case keys 'PAYMENTS_ENABLED', 'STRIPE_SECRET_KEY',
'STRIPE_WEBHOOK_SECRET', 'NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY') to construct
scanner-safe fixtures from non-secret fragments (e.g., join or concat innocuous
pieces like 'sk_test', 'runtime_only', '123456' or use clearly synthetic names
like 'stripe_runtime_key_1') so the values preserve test behavior but no longer
resemble real secret literals. Ensure the change is applied to the same mock in
lines around that test (cases for the four keys).

In `@README.md`:
- Around line 84-90: Remove the empty blockquote line inside the TIP admonition
and insert an HTML separator between the two admonitions so markdownlint MD028
is not triggered; specifically, edit the README.md section containing the
"[!IMPORTANT]" and "[!TIP]" blocks to delete the blank ">" line inside the TIP
block and add a separator (for example an HTML comment or <hr/>) between the
"[!IMPORTANT]" and "[!TIP]" callouts to prevent adjacent blockquote lint
failures.
- Around line 3-7: Inside the [!NOTE] block in the README replace the nested H3
"### Train smarter, interview stronger." with plain bold text (e.g., **Train
smarter, interview stronger.**) so the H1 is not immediately followed by a
lower-level heading; update the line containing "### Train smarter, interview
stronger." accordingly to remove the leading "###" and use bold formatting
instead.

---

Nitpick comments:
In `@frontend/data/category.ts`:
- Around line 13-15: categoryData currently maps categoryRegistry in insertion
order, causing output to drift; before mapping call createCategory, sort the
registry by each item's displayOrder to ensure deterministic ordering. Locate
categoryData and replace the direct map over categoryRegistry with a sorted
iteration (e.g., copy and sort categoryRegistry by item.displayOrder) and then
map to createCategory(item.slug, item.title, item.displayOrder).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: febd5bd8-f975-47b8-8847-100fc3771600

📥 Commits

Reviewing files that changed from the base of the PR and between 2edb4d1 and ba6060d.

⛔ Files ignored due to path filters (15)
  • assets/01-screencapture.png is excluded by !**/*.png
  • assets/02-screencapture.png is excluded by !**/*.png
  • assets/03-screencapture.png is excluded by !**/*.png
  • assets/04-screencapture.png is excluded by !**/*.png
  • assets/05-screencapture.png is excluded by !**/*.png
  • assets/06-screencapture.png is excluded by !**/*.png
  • assets/07-screencapture.png is excluded by !**/*.png
  • assets/08-screencapture.png is excluded by !**/*.png
  • assets/09-screencapture.png is excluded by !**/*.png
  • frontend/package-lock.json is excluded by !**/package-lock.json
  • frontend/public/icons/csharp.svg is excluded by !**/*.svg
  • frontend/public/icons/dotnet.svg is excluded by !**/*.svg
  • frontend/public/icons/laravel.svg is excluded by !**/*.svg
  • frontend/public/icons/php.svg is excluded by !**/*.svg
  • studio/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (27)
  • CHANGELOG.md
  • README.md
  • frontend/app/[locale]/shop/cart/capabilities.ts
  • frontend/components/about/HeroSection.tsx
  • frontend/data/category.ts
  • frontend/data/categoryRegistry.ts
  • frontend/data/categoryStyles.ts
  • frontend/lib/about/stats.ts
  • frontend/lib/env/monobank.ts
  • frontend/lib/env/provider-runtime.ts
  • frontend/lib/env/stripe.ts
  • frontend/lib/tests/shop/public-cart-env-contract.test.ts
  • frontend/package.json
  • studio/.gitignore
  • studio/.prettierrc
  • studio/eslint.config.mjs
  • studio/package.json
  • studio/sanity.cli.ts
  • studio/sanity.config.ts
  • studio/schemaTypes/author.ts
  • studio/schemaTypes/blockContent.ts
  • studio/schemaTypes/category.ts
  • studio/schemaTypes/index.ts
  • studio/schemaTypes/post.ts
  • studio/schemaTypes/socialLink.ts
  • studio/static/.gitkeep
  • studio/tsconfig.json
💤 Files with no reviewable changes (14)
  • studio/static/.gitkeep
  • studio/eslint.config.mjs
  • studio/schemaTypes/blockContent.ts
  • studio/package.json
  • studio/tsconfig.json
  • studio/.prettierrc
  • studio/.gitignore
  • studio/schemaTypes/author.ts
  • studio/schemaTypes/category.ts
  • studio/schemaTypes/index.ts
  • studio/schemaTypes/socialLink.ts
  • studio/sanity.cli.ts
  • studio/schemaTypes/post.ts
  • studio/sanity.config.ts

Comment on lines 25 to 40
export function resolveMonobankCheckoutEnabled(): boolean {
return resolveStandardStorefrontProviderCapabilities().monobankCheckoutEnabled;
const paymentsEnabled = isFlagEnabled(readServerEnv('PAYMENTS_ENABLED'));
if (!paymentsEnabled) return false;

try {
return isMonobankEnabled();
} catch {
return false;
}
}

export function resolveMonobankGooglePayEnabled(): boolean {
return resolveStandardStorefrontProviderCapabilities()
.monobankGooglePayEnabled;
if (!resolveMonobankCheckoutEnabled()) return false;

return isFlagEnabled(readServerEnv('SHOP_MONOBANK_GPAY_ENABLED'));
}
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

Keep Monobank env reads inside the fail-closed boundary.

Line 26 and Line 39 can still throw before returning false, which can reintroduce the cart SSR/runtime crash path this change is trying to prevent.

🛡️ Proposed fail-closed adjustment
 export function resolveMonobankCheckoutEnabled(): boolean {
-  const paymentsEnabled = isFlagEnabled(readServerEnv('PAYMENTS_ENABLED'));
-  if (!paymentsEnabled) return false;
-
   try {
+    const paymentsEnabled = isFlagEnabled(readServerEnv('PAYMENTS_ENABLED'));
+    if (!paymentsEnabled) return false;
+
     return isMonobankEnabled();
   } catch {
     return false;
   }
 }
 
 export function resolveMonobankGooglePayEnabled(): boolean {
-  if (!resolveMonobankCheckoutEnabled()) return false;
-
-  return isFlagEnabled(readServerEnv('SHOP_MONOBANK_GPAY_ENABLED'));
+  try {
+    if (!resolveMonobankCheckoutEnabled()) return false;
+
+    return isFlagEnabled(readServerEnv('SHOP_MONOBANK_GPAY_ENABLED'));
+  } catch {
+    return false;
+  }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/app/`[locale]/shop/cart/capabilities.ts around lines 25 - 40, Both
resolveMonobankCheckoutEnabled and resolveMonobankGooglePayEnabled can throw
when calling readServerEnv (and thus reintroduce SSR/runtime crashes); move any
readServerEnv and isFlagEnabled calls into the same fail-closed try/catch
boundary so exceptions are caught and the function returns false. Concretely, in
resolveMonobankCheckoutEnabled wrap the paymentsEnabled read and check
(readServerEnv('PAYMENTS_ENABLED') + isFlagEnabled) inside the try/catch that
also calls isMonobankEnabled and return false on any exception; do the same in
resolveMonobankGooglePayEnabled so the SHOP_MONOBANK_GPAY_ENABLED read is
performed inside a try/catch and returns false on error, referencing
resolveMonobankCheckoutEnabled, resolveMonobankGooglePayEnabled, isFlagEnabled,
readServerEnv, and isMonobankEnabled to locate the changes.

Comment on lines +16 to +18
if (n >= 1000) {
const value = n / 1000;
return (Number.isInteger(value) ? value.toString() : value.toFixed(1)) + 'k+';
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:

#!/bin/bash
# Description: Verify compact formatting around thousand boundaries without running repository code.

node - <<'NODE'
for (const n of [1000, 1500, 1999, 2000]) {
  const value = n / 1000;
  const current = (Number.isInteger(value) ? value.toString() : value.toFixed(1)) + 'k+';
  const fixed = (Number.isInteger(value) ? value.toString() : value.toFixed(1).replace(/\.0$/, '')) + 'k+';
  console.log(`${n}: current=${current}, fixed=${fixed}`);
}
NODE

Repository: DevLoversTeam/devlovers.net

Length of output: 192


🏁 Script executed:

cat -n frontend/lib/about/stats.ts | sed -n '14,20p'

Repository: DevLoversTeam/devlovers.net

Length of output: 315


Strip rounded .0 from compact metric values.

Line 18 produces 2.0k+ for values like 1999 because toFixed(1) rounds 1.999 to 2.0. Strip the trailing .0 after formatting to avoid this visual artifact.

🔧 Proposed fix
   if (n >= 1000) {
     const value = n / 1000;
-    return (Number.isInteger(value) ? value.toString() : value.toFixed(1)) + 'k+';
+    const formatted = Number.isInteger(value)
+      ? value.toString()
+      : value.toFixed(1).replace(/\.0$/, '');
+    return formatted + 'k+';
   }
📝 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
if (n >= 1000) {
const value = n / 1000;
return (Number.isInteger(value) ? value.toString() : value.toFixed(1)) + 'k+';
if (n >= 1000) {
const value = n / 1000;
const formatted = Number.isInteger(value)
? value.toString()
: value.toFixed(1).replace(/\.0$/, '');
return formatted + 'k+';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/lib/about/stats.ts` around lines 16 - 18, The compact-thousands
formatting branch that computes value = n / 1000 and returns
(Number.isInteger(value) ? value.toString() : value.toFixed(1)) + 'k+' can
produce strings like "2.0k+"; update the return to strip a trailing ".0" after
formatting (e.g., generate the formatted string using toFixed(1) when needed,
then remove a trailing ".0" via a replace or similar) so the final result
becomes "2k+" instead of "2.0k+" while still preserving one decimal for
non-round values.

Comment on lines 37 to +42
const mode =
(nonEmpty(process.env.STRIPE_MODE) as 'test' | 'live' | null) ??
(runtimeEnv.NODE_ENV === 'production' ? 'live' : 'test');
rawMode === 'test' || rawMode === 'live'
? rawMode
: String(nodeEnv).trim().toLowerCase() === 'production'
? 'live'
: 'test';
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

Use the same production-like signal when inferring Stripe mode.

Line 40 only checks NODE_ENV, but Line 57 treats APP_ENV=production as production-like. In that case, a missing STRIPE_MODE defaults to test and then rejects checkout. Reuse isProductionLikeRuntime() for the default mode decision.

🔧 Proposed fix
+  const productionLike = isProductionLikeRuntime();
   const mode =
     rawMode === 'test' || rawMode === 'live'
       ? rawMode
-      : String(nodeEnv).trim().toLowerCase() === 'production'
+      : productionLike || String(nodeEnv).trim().toLowerCase() === 'production'
         ? 'live'
         : 'test';
 
   const paymentsEnabled =
     paymentsFlag === 'true' && !!secretKey && !!webhookSecret;
@@
-  if (isProductionLikeRuntime() && mode !== 'live') {
+  if (productionLike && mode !== 'live') {

Also applies to: 57-57

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/lib/env/stripe.ts` around lines 37 - 42, The mode inference
currently uses a raw NODE_ENV check; change the logic that computes the mode
(the const mode using rawMode and nodeEnv) to reuse the existing
isProductionLikeRuntime() helper so a production-like runtime (e.g.,
APP_ENV=production) yields 'live' when STRIPE_MODE is missing; update the other
location that makes the same decision (the later defaulting logic that currently
checks nodeEnv) to also call isProductionLikeRuntime(); ensure rawMode still
accepts 'test'|'live' values first, otherwise return 'live' when
isProductionLikeRuntime() is true and 'test' otherwise.

Comment on lines +173 to +183
it('enables stripe capability from runtime-only env when config is valid', async () => {
readServerEnvMock.mockImplementation((key: string) => {
switch (key) {
case 'PAYMENTS_ENABLED':
return 'true';
case 'STRIPE_SECRET_KEY':
return 'sk_test_runtime_only_1234567890';
case 'STRIPE_WEBHOOK_SECRET':
return 'whsec_runtime_only_1234567890';
case 'NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY':
return 'pk_test_runtime_only_1234567890';
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

Avoid secret-shaped Stripe fixtures in source.

Line 226 is already flagged by secret scanning. These are fake values, but constructing them from parts avoids recurring scanner noise while preserving runtime test behavior.

🔐 Proposed scanner-safe fixture construction
+const stripeFixture = (...parts: string[]) => parts.join('_');
+
   it('enables stripe capability from runtime-only env when config is valid', async () => {
     readServerEnvMock.mockImplementation((key: string) => {
       switch (key) {
         case 'PAYMENTS_ENABLED':
           return 'true';
         case 'STRIPE_SECRET_KEY':
-          return 'sk_test_runtime_only_1234567890';
+          return stripeFixture('sk', 'test', 'runtime', 'only', '1234567890');
         case 'STRIPE_WEBHOOK_SECRET':
-          return 'whsec_runtime_only_1234567890';
+          return stripeFixture('whsec', 'runtime', 'only', '1234567890');
         case 'NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY':
-          return 'pk_test_runtime_only_1234567890';
+          return stripeFixture('pk', 'test', 'runtime', 'only', '1234567890');
         default:
           return baselineCartEnv(key);
       }
@@
         case 'PAYMENTS_ENABLED':
           return 'true';
         case 'STRIPE_SECRET_KEY':
-          return 'sk_test_placeholder';
+          return stripeFixture('sk', 'test', 'placeholder');
         case 'STRIPE_WEBHOOK_SECRET':
-          return 'whsec_placeholder_value';
+          return stripeFixture('whsec', 'placeholder', 'value');
         case 'NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY':
-          return 'pk_test_placeholder';
+          return stripeFixture('pk', 'test', 'placeholder');

Also applies to: 218-230

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/lib/tests/shop/public-cart-env-contract.test.ts` around lines 173 -
183, The test "enables stripe capability from runtime-only env when config is
valid" uses mock Stripe secret-shaped strings which trigger secret scanners;
update the readServerEnvMock implementation used in that test (and the nearby
case keys 'PAYMENTS_ENABLED', 'STRIPE_SECRET_KEY', 'STRIPE_WEBHOOK_SECRET',
'NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY') to construct scanner-safe fixtures from
non-secret fragments (e.g., join or concat innocuous pieces like 'sk_test',
'runtime_only', '123456' or use clearly synthetic names like
'stripe_runtime_key_1') so the values preserve test behavior but no longer
resemble real secret literals. Ensure the change is applied to the same mock in
lines around that test (cases for the four keys).

Comment thread README.md
Comment on lines +3 to +7
> [!NOTE]
>
> ### Train smarter, interview stronger.
>
> DevLovers is a multi-language interview prep platform with curated Q&A, timed quizzes, leaderboard rankings, a developer blog, and a personal dashboard to track real learning progress.
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

Fix the skipped heading level in the note.

### immediately after the H1 triggers markdownlint MD001. This can be bold text instead of a nested heading.

📝 Proposed fix
 > [!NOTE]
 >
-> ### Train smarter, interview stronger.
+> **Train smarter, interview stronger.**
 >
 > DevLovers is a multi-language interview prep platform with curated Q&A, timed quizzes, leaderboard rankings, a developer blog, and a personal dashboard to track real learning progress.
📝 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
> [!NOTE]
>
> ### Train smarter, interview stronger.
>
> DevLovers is a multi-language interview prep platform with curated Q&A, timed quizzes, leaderboard rankings, a developer blog, and a personal dashboard to track real learning progress.
> [!NOTE]
>
> **Train smarter, interview stronger.**
>
> DevLovers is a multi-language interview prep platform with curated Q&A, timed quizzes, leaderboard rankings, a developer blog, and a personal dashboard to track real learning progress.
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)

[warning] 5-5: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 3 - 7, Inside the [!NOTE] block in the README replace
the nested H3 "### Train smarter, interview stronger." with plain bold text
(e.g., **Train smarter, interview stronger.**) so the H1 is not immediately
followed by a lower-level heading; update the line containing "### Train
smarter, interview stronger." accordingly to remove the leading "###" and use
bold formatting instead.

Comment thread README.md
Comment on lines +84 to +90
> [!IMPORTANT]
> **Contact me:** [contact@devlovers.net](mailto:contact@devlovers.net)

**Contact me:** [contact@devlovers.net](mailto:contact@devlovers.net)
> [!TIP]
> **Production:** [devlovers.net](https://devlovers.net)
>
> **Develop:** [develop.devlovers.net](https://develop-devlovers.netlify.app) [![Netlify Status](https://api.netlify.com/api/v1/badges/0d21e84e-ea55-47f0-b841-c8eb91f2c9a0/deploy-status)](https://app.netlify.com/projects/develop-devlovers/deploys)
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

Avoid adjacent blockquote lint failures.

The back-to-back admonitions and blank quoted line can trigger markdownlint MD028. Add an HTML separator between callouts and remove the blank blockquote line inside the TIP.

📝 Proposed fix
 > [!IMPORTANT]
 > **Contact me:** [contact@devlovers.net](mailto:contact@devlovers.net)
 
+<!-- -->
+
 > [!TIP]
 > **Production:** [devlovers.net](https://devlovers.net)
->
 > **Develop:** [develop.devlovers.net](https://develop-devlovers.netlify.app) [![Netlify Status](https://api.netlify.com/api/v1/badges/0d21e84e-ea55-47f0-b841-c8eb91f2c9a0/deploy-status)](https://app.netlify.com/projects/develop-devlovers/deploys)
📝 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
> [!IMPORTANT]
> **Contact me:** [contact@devlovers.net](mailto:contact@devlovers.net)
**Contact me:** [contact@devlovers.net](mailto:contact@devlovers.net)
> [!TIP]
> **Production:** [devlovers.net](https://devlovers.net)
>
> **Develop:** [develop.devlovers.net](https://develop-devlovers.netlify.app) [![Netlify Status](https://api.netlify.com/api/v1/badges/0d21e84e-ea55-47f0-b841-c8eb91f2c9a0/deploy-status)](https://app.netlify.com/projects/develop-devlovers/deploys)
> [!IMPORTANT]
> **Contact me:** [contact@devlovers.net](mailto:contact@devlovers.net)
<!-- -->
> [!TIP]
> **Production:** [devlovers.net](https://devlovers.net)
> **Develop:** [develop.devlovers.net](https://develop-devlovers.netlify.app) [![Netlify Status](https://api.netlify.com/api/v1/badges/0d21e84e-ea55-47f0-b841-c8eb91f2c9a0/deploy-status)](https://app.netlify.com/projects/develop-devlovers/deploys)
🧰 Tools
🪛 LanguageTool

[style] ~87-~87: Using many exclamation marks might seem excessive (in this case: 3 exclamation marks for a text that’s 1575 characters long)
Context: ....net](mailto:contact@devlovers.net) > [!TIP] > Production: [devlovers.net](h...

(EN_EXCESSIVE_EXCLAMATION)

🪛 markdownlint-cli2 (0.22.0)

[warning] 86-86: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 84 - 90, Remove the empty blockquote line inside the
TIP admonition and insert an HTML separator between the two admonitions so
markdownlint MD028 is not triggered; specifically, edit the README.md section
containing the "[!IMPORTANT]" and "[!TIP]" blocks to delete the blank ">" line
inside the TIP block and add a separator (for example an HTML comment or <hr/>)
between the "[!IMPORTANT]" and "[!TIP]" callouts to prevent adjacent blockquote
lint failures.

@ViktorSvertoka ViktorSvertoka merged commit 6f088df into main Apr 23, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants