Skip to content

feat(herbatika): load homepage carousel from CMS - #450

Merged
redeyecz merged 6 commits into
masterfrom
feat-herbatica-payload-content
Jul 14, 2026
Merged

redeyecz merged 6 commits into
masterfrom
feat-herbatica-payload-content

Conversation

@KaiUweCZE

@KaiUweCZE KaiUweCZE commented Jun 15, 2026 •

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features
    • Homepage hero section now pulls hero banners from the CMS.
    • Hero banners support custom CTA labels and image alt text for improved accessibility.
  • Improvements
    • Faster homepage loading by fetching storefront state and CMS hero banners in parallel.
    • Enhanced link safety for hero banner URLs, preventing unsafe protocol-relative paths and restricting allowed protocols.

@semanticdiff-com

semanticdiff-com Bot commented Jun 15, 2026 •

Copy link
Copy Markdown

@vercel

vercel Bot commented Jun 15, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
new-engine-ui-storybook Ready Ready Preview, Comment Jul 14, 2026 4:21pm

@coderabbitai

coderabbitai Bot commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@redeyecz, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a02d3ce5-1a0a-4219-9089-4098e08aacff

📥 Commits

Reviewing files that changed from the base of the PR and between f9698c7 and 34d1fe3.

📒 Files selected for processing (1)
  • apps/herbatika/src/components/herbatika-homepage.tsx

Walkthrough

The PR adds an auto-populated internalTitle field to Payload hero carousels and redacts it from medusa-be responses. Herbatika now fetches, sanitises, and renders CMS hero banners with dynamic CTA labels and image alt text, while retaining fallback banners.

Changes

Payload CMS: internalTitle for HeroCarousels

Layer / File(s) Summary
HeroCarousel type contract and label translations
apps/payload/src/payload-types.ts, apps/payload/src/lib/constants/labels.ts
Adds internalTitle, makes heading optional and nullable, extends selectable fields, and adds translations.
HeroCarousels collection: helpers, field, and beforeValidate hook
apps/payload/src/collections/hero-carousels.ts
Resolves localised title candidates, configures the admin title field, relaxes heading, and assigns internalTitle before validation.
Seed data and medusa-be redaction
apps/payload/src/seed.ts, apps/medusa-be/src/modules/payload/service.ts
Seeds internalTitle and recursively redacts it from cached and returned Payload data.

Herbatika Frontend: CMS-driven hero banners

Layer / File(s) Summary
CMS and banner data type contracts
apps/herbatika/src/lib/storefront/cms-types.ts, apps/herbatika/src/components/homepage/homepage.data.types.ts
Adds CmsHeroCarousel and optional CTA and image-alt fields to HeroBannerItem.
CMS hero-carousel fetch module and public exports
apps/herbatika/src/lib/storefront/cms-hero-carousels.ts, apps/herbatika/src/lib/storefront/cms.ts
Fetches and sorts CMS carousels, sanitises URLs, maps valid records, filters invalid records, and re-exports the new helpers.
Homepage page, component, and carousel card wiring
apps/herbatika/src/app/page.tsx, apps/herbatika/src/components/herbatika-homepage.tsx, apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx
Fetches CMS banners concurrently with storefront data, passes them to the homepage, applies fallback banners, and renders dynamic CTA and alt text.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant HomePage
  participant fetchCmsHeroBanners
  participant prefetchHomePageStorefrontData
  participant HerbatikaHomepage
  participant HomepageHeroCarouselSection

  Browser->>HomePage: request homepage
  HomePage->>fetchCmsHeroBanners: fetch concurrently
  HomePage->>prefetchHomePageStorefrontData: prefetch concurrently
  fetchCmsHeroBanners-->>HomePage: HeroBannerItem[]
  prefetchHomePageStorefrontData-->>HomePage: dehydratedState
  HomePage->>HerbatikaHomepage: render with heroBanners
  HerbatikaHomepage->>HomepageHeroCarouselSection: provide CMS or fallback banners
  HomepageHeroCarouselSection-->>Browser: render carousel
Loading

Possibly related PRs

Suggested labels: released

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: loading the Herbatika homepage carousel from CMS.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-herbatica-payload-content
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat-herbatica-payload-content

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.

@greptile-apps

greptile-apps Bot commented Jun 15, 2026 •

Copy link
Copy Markdown

Greptile Summary

This PR adds CMS-managed hero banners to the Herbatika homepage. The main changes are:

  • Fetch CMS carousel data during homepage rendering.
  • Map CMS banners to homepage carousel items.
  • Add CTA labels and image alt text support.
  • Add and backfill the Payload internalTitle field.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
apps/herbatika/src/lib/storefront/cms-hero-carousels.ts Maps validated CMS carousel data into homepage hero banner props.
apps/payload/src/collections/hero-carousels.ts Adds an administrative title derived from existing carousel content.
apps/payload/src/migrations/20260714_142450_add_hero_carousel_internal_title.ts Backfills hero carousel titles before enforcing the database constraint.

Reviews (6): Last reviewed commit: "fix(payload): lint" | Re-trigger Greptile

Comment thread apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
Comment thread apps/herbatika/src/lib/storefront/cms-hero-carousels.ts Outdated
Comment thread apps/herbatika/src/lib/storefront/cms-hero-carousels.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Jun 15, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue

WARNING

File Line Issue
apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx 23 Fallback label regresses image-only CMS banners without image alt text; ctaLabel should be used before the generic "Herbatika banner" fallback so link and image labels remain descriptive.
apps/payload/src/collections/hero-carousels.ts 73 Required internalTitle has no explicit backfill for existing hero carousel documents; beforeValidate only runs on create/update, so existing CMS rows may remain blank in the admin list until edited.
apps/payload/src/collections/hero-carousels.ts 117 beforeValidate overwrites internalTitle on partial programmatic updates; updates that omit internalTitle, heading, and button can silently replace the stored title with button text, URL, or "Hero banner".

SUGGESTION

File Line Issue
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
Files Reviewed (7 files)
  • apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx - 1 issue
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts - 0 issues (previous href validation issue fixed in latest commit)
  • apps/medusa-be/src/modules/payload/service.ts - 0 issues
  • apps/payload/src/collections/hero-carousels.ts - 2 issues
  • apps/payload/src/lib/constants/labels.ts - 0 issues (previous diacritics issue fixed in latest commit)
  • apps/payload/src/payload-types.ts - 0 issues
  • apps/payload/src/seed.ts - 0 issues

Fix these issues in Kilo Cloud

Previous Review Summary (commit 120739a)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 120739a)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue

WARNING

File Line Issue
apps/herbatika/src/lib/storefront/cms-hero-carousels.ts 36 CMS-provided buttonHref is used as a NextLink target after only trimming, with blank values normalized to /; unsafe schemes or missing links should be validated/rejected instead.

SUGGESTION

File Line Issue
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
Files Reviewed (7 files)
  • apps/herbatika/src/app/page.tsx
  • apps/herbatika/src/components/herbatika-homepage.tsx
  • apps/herbatika/src/components/homepage/homepage.data.types.ts
  • apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms-types.ts
  • apps/herbatika/src/lib/storefront/cms.ts

Fix these issues in Kilo Cloud


Reviewed by nex-n2-pro:free · 1,855,161 tokens

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/herbatika/src/lib/storefront/cms-hero-carousels.ts`:
- Around line 1-4: The file cms-hero-carousels.ts performs server-side CMS data
fetching through the fetchCmsJson and resolveCmsMediaUrl imports from
cms-client, but is missing the server-only boundary enforcement. Add import
"server-only" as the first import statement in this file to explicitly enforce
that this module can only be used on the server side, in accordance with the
coding guidelines.

In `@apps/payload/src/collections/hero-carousels.ts`:
- Around line 111-121: Add a type guard in the beforeValidate hook callback
function to verify that the data parameter is a Record-like object before
accessing its properties. After the existing falsy check for data, add an
additional guard using typeof data === 'object' or a similar type validation to
ensure data is an actual object/record before attempting to access
data.internalTitle. This defensive check will improve type safety and prevent
potential runtime errors when processing the data parameter.

In `@apps/payload/src/lib/constants/labels.ts`:
- Around line 110-114: The Czech and Slovak translation strings in the
internalTitle property are missing proper diacritical marks, which impacts the
admin UI experience for users in those locales. Update the cs translation from
"Interni nazev" to "Interní název" and the sk translation from "Interny nazov"
to "Interný názov" to include the correct Czech and Slovak characters with
diacritics.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: eb964cde-956b-4f0c-94ed-70034a25cb4b

📥 Commits

Reviewing files that changed from the base of the PR and between f4b731d and 047dc65.

📒 Files selected for processing (12)
  • apps/herbatika/src/app/page.tsx
  • apps/herbatika/src/components/herbatika-homepage.tsx
  • apps/herbatika/src/components/homepage/homepage.data.types.ts
  • apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms-types.ts
  • apps/herbatika/src/lib/storefront/cms.ts
  • apps/medusa-be/src/modules/payload/service.ts
  • apps/payload/src/collections/hero-carousels.ts
  • apps/payload/src/lib/constants/labels.ts
  • apps/payload/src/payload-types.ts
  • apps/payload/src/seed.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: main
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Greptile Review
  • GitHub Check: Kilo Code Review
🧰 Additional context used
📓 Path-based instructions (28)
apps/payload/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/payload/.cursor/rules/access-control-advanced.md)

apps/payload/**/*.{ts,tsx}: Implement locale-specific access control using Access function to check user authentication and locale, allowing authenticated users all locales and public users only English content
Implement device-specific access control using Access function to check user-agent headers, distinguishing between mobile and desktop access
Create IP-based access restriction using factory function that returns an Access function checking x-forwarded-for or x-real-ip headers against allowed IP list
Implement time-based access control to restrict records to today's date range using Access function with createdAt date comparisons
Create time-based access factory function that returns recent records (last N days) for regular users while granting admins full access
Implement scheduled content access control distinguishing editors/admins who see all content from public users who see only content within publish/unpublish date windows
Implement subscription-based access control using async Access function to verify active subscription status, with admin bypass
Create tier-based subscription access factory function that checks subscription tier hierarchy and returns false on inactive subscriptions or errors
Implement role-based access factory function createRoleBasedAccess that checks if user has any of the specified roles
Implement organization-scoped access factory function createOrgScopedAccess that restricts documents to user's organization IDs with optional admin bypass
Implement team-based access factory function createTeamBasedAccess that filters documents by user's team IDs with admin bypass
Implement time-limited access factory function createTimeLimitedAccess that restricts documents to last N days with admin bypass
Implement public + authenticated collection pattern where create/update/delete are restricted to admins/editors, read shows published content to public and all content to authenticated users
Implement self-service collection...

Files:

  • apps/payload/src/seed.ts
  • apps/payload/src/lib/constants/labels.ts
  • apps/payload/src/payload-types.ts
  • apps/payload/src/collections/hero-carousels.ts
apps/payload/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/payload/.cursor/rules/access-control.md)

apps/payload/**/*.{ts,tsx,js,jsx}: Implement the 'admin only' access pattern in Payload CMS by checking if user roles include 'admin' and returning a boolean result
Implement the 'admin or self' access pattern in Payload CMS by checking admin role first, then falling back to self-referential query constraints (e.g., { id: { equals: user?.id } })
Implement the 'authenticated or published' access pattern in Payload CMS by returning true for authenticated users and applying query constraints for public access to published documents
In Payload CMS Local API calls, set overrideAccess: false when passing a user parameter to ensure access control is enforced rather than bypassed
Do NOT rely on the default Local API behavior in Payload CMS, as access control is skipped by default (overrideAccess: true) - always explicitly set overrideAccess: false when implementing access control

apps/payload/**/*.{ts,tsx,js,jsx}: When performing nested operations in hooks, always pass req parameter to maintain transaction context across all-or-nothing database operations
Pass req to req.payload.find() calls within hooks to maintain atomic transaction context across MongoDB, PostgreSQL, and SQLite databases
Pass req to req.payload.update() calls within hooks to ensure changes are included in the same transaction and can be rolled back together on errors
Use payload.db.beginTransaction(), payload.db.commitTransaction(), and payload.db.rollbackTransaction() for manual transaction control when needed

apps/payload/**/*.{ts,tsx,js,jsx}: Custom endpoints in Payload are not authenticated by default. Always check req.user to verify user authentication before processing requests.
Use req.payload for database operations instead of direct database access to ensure access control and hooks execute properly.
Use the addDataAndFileToRequest helper from Payload to handle both JSON parsing and file uploads in POST endpoints.
Use headersWithCors helper from Payload ...

Files:

  • apps/payload/src/seed.ts
  • apps/payload/src/lib/constants/labels.ts
  • apps/payload/src/payload-types.ts
  • apps/payload/src/collections/hero-carousels.ts
apps/payload/**/*.{ts,tsx,js,jsx,graphql}

📄 CodeRabbit inference engine (apps/payload/.cursor/rules/queries.md)

Use GraphQL queries with proper field selection, filtering (where), limiting (limit), and sorting (sort) when querying Payload CMS via GraphQL

Files:

  • apps/payload/src/seed.ts
  • apps/payload/src/lib/constants/labels.ts
  • apps/payload/src/payload-types.ts
  • apps/payload/src/collections/hero-carousels.ts
apps/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Import UI components using the @techsio/ui-kit namespace, not @libs/ui, for runtime apps

Files:

  • apps/payload/src/seed.ts
  • apps/herbatika/src/lib/storefront/cms-types.ts
  • apps/medusa-be/src/modules/payload/service.ts
  • apps/herbatika/src/app/page.tsx
  • apps/herbatika/src/components/homepage/homepage.data.types.ts
  • apps/payload/src/lib/constants/labels.ts
  • apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx
  • apps/payload/src/payload-types.ts
  • apps/payload/src/collections/hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms.ts
  • apps/herbatika/src/components/herbatika-homepage.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Run Biome linting and formatting only on changed files using 'bunx biome check --write path/to/file'

Files:

  • apps/payload/src/seed.ts
  • apps/herbatika/src/lib/storefront/cms-types.ts
  • apps/medusa-be/src/modules/payload/service.ts
  • apps/herbatika/src/app/page.tsx
  • apps/herbatika/src/components/homepage/homepage.data.types.ts
  • apps/payload/src/lib/constants/labels.ts
  • apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx
  • apps/payload/src/payload-types.ts
  • apps/payload/src/collections/hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms.ts
  • apps/herbatika/src/components/herbatika-homepage.tsx
apps/**/!(medusa-be)/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use modern React patterns and React 19 for frontend applications in the monorepo

Files:

  • apps/payload/src/seed.ts
  • apps/herbatika/src/lib/storefront/cms-types.ts
  • apps/medusa-be/src/modules/payload/service.ts
  • apps/herbatika/src/app/page.tsx
  • apps/herbatika/src/components/homepage/homepage.data.types.ts
  • apps/payload/src/lib/constants/labels.ts
  • apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx
  • apps/payload/src/payload-types.ts
  • apps/payload/src/collections/hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms.ts
  • apps/herbatika/src/components/herbatika-homepage.tsx
apps/herbatika/**

📄 CodeRabbit inference engine (AGENTS.md)

apps/herbatika/**: Read apps/herbatika/AGENTS.md before editing Herbatika app and follow its specific configuration which overrides root assumptions
Herbatika app runs on http://localhost:3001 and routes work through libs/ui/skills and libs/storefront-data/skills workflows

Files:

  • apps/herbatika/src/lib/storefront/cms-types.ts
  • apps/herbatika/src/app/page.tsx
  • apps/herbatika/src/components/homepage/homepage.data.types.ts
  • apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms.ts
  • apps/herbatika/src/components/herbatika-homepage.tsx
apps/herbatika/src/**

📄 CodeRabbit inference engine (apps/herbatika/AGENTS.md)

apps/herbatika/src/**: Put Herbatika visual differences in src/styles/tokens/**; avoid JSX className overrides that duplicate UI-kit component props/tokens.
Use kebab-case for file names and PascalCase for React component names in Herbatika.

Files:

  • apps/herbatika/src/lib/storefront/cms-types.ts
  • apps/herbatika/src/app/page.tsx
  • apps/herbatika/src/components/homepage/homepage.data.types.ts
  • apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms.ts
  • apps/herbatika/src/components/herbatika-homepage.tsx
apps/herbatika/src/lib/storefront/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/herbatika/AGENTS.md)

In Herbatika storefront composition, prefer the preset surface from @techsio/storefront-data: shared hooks, flows, query keys, query options, cache policy, and SSR helpers.

Files:

  • apps/herbatika/src/lib/storefront/cms-types.ts
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms.ts
apps/herbatika/src/lib/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/herbatika/AGENTS.md)

Keep app-local storefront code thin: SDK instance, field defaults, localized text, toasts, analytics, form DTOs, address adapters, and Herbatika-specific read models can stay in app code. Move repeated backend communication, query key construction, cache sync, and mutation invalidation into libs/storefront-data.

Files:

  • apps/herbatika/src/lib/storefront/cms-types.ts
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms.ts
apps/herbatika/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/herbatika/AGENTS.md)

apps/herbatika/src/**/*.{ts,tsx}: Use explicit package subpath imports from @techsio/storefront-data. Do not import from package roots or dist/.
Keep server-only and client-only boundaries explicit in Herbatika app code; use 'server-only' and 'getServerQueryClient' for Server Component/SSR data paths.

Files:

  • apps/herbatika/src/lib/storefront/cms-types.ts
  • apps/herbatika/src/app/page.tsx
  • apps/herbatika/src/components/homepage/homepage.data.types.ts
  • apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms.ts
  • apps/herbatika/src/components/herbatika-homepage.tsx
apps/herbatika/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/herbatika/AGENTS.md)

Keep source files at a soft limit of ~200 lines; exceeding this should trigger refactor consideration.

Files:

  • apps/herbatika/src/lib/storefront/cms-types.ts
  • apps/herbatika/src/app/page.tsx
  • apps/herbatika/src/components/homepage/homepage.data.types.ts
  • apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx
  • apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
  • apps/herbatika/src/lib/storefront/cms.ts
  • apps/herbatika/src/components/herbatika-homepage.tsx
apps/medusa-be/src/modules/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa modules under apps/medusa-be/src/modules

Files:

  • apps/medusa-be/src/modules/payload/service.ts
apps/medusa-be/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/**/*.{ts,tsx}: Use TypeScript for type checking - run npx tsc --noEmit for validation
Forbidden: Non-null assertions (!) - always use type guards and validation instead
Annotate generic field access with explicit unknown type before type guards - const v: unknown = result[field]
Don't use as Type without validation - always validate before casting
Use Modules.* and ContainerRegistrationKeys.* constants instead of hardcoding strings
Batch operations with CHUNK_SIZE to avoid unbounded operations
Extract pure functions to separate files for testability without runtime dependencies

Files:

  • apps/medusa-be/src/modules/payload/service.ts
apps/medusa-be/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/**/*.{ts,tsx,js,jsx}: Use Biome linter with ultracite preset - run bunx biome check --write . and always use braces in conditionals
Comments should explain 'why', never 'what' - use self-documenting code via clear naming
Always use const per declaration - const a = 1; const b = 2 is correct, one variable per line
Use nullish coalescing (??) operator instead of logical OR (||) for default values

Files:

  • apps/medusa-be/src/modules/payload/service.ts
apps/medusa-be/src/modules/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/modules/**/*.ts: Module directories use hyphens (my-module/), module keys use underscores (my_module), and export module key as constant
Loaders cannot resolve cross-module dependencies - use __hooks.onApplicationStart for deferred initialization instead

Files:

  • apps/medusa-be/src/modules/payload/service.ts
apps/medusa-be/src/modules/**/service.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/modules/**/service.ts: Extend MedusaService for auto-CRUD - don't use super(...arguments), use super(container, options) explicitly
Module service constructors must call super(container, options) explicitly when extending MedusaService
Use dbService.sqlRaw<Type[]>() for raw SQL queries with proper TypeScript typing
Use ICachingModuleService (Modules.CACHING) with computeKey(), get(), set(), and clear() by tags for cache operations
Separate HTTP client layer from orchestration layer - HTTP client handles retries/parsing, orchestration handles tokens/caching/rate-limiting
Module cross-module dependencies: Declare in medusa-config.ts dependencies array and inject via container in provider constructor

Files:

  • apps/medusa-be/src/modules/payload/service.ts
apps/medusa-be/src/{api,modules}/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Use MedusaError with proper error types - INVALID_DATA(400), NOT_FOUND(404), UNAUTHORIZED(401), NOT_ALLOWED(400), DUPLICATE_ERROR(422), CONFLICT(409)

Files:

  • apps/medusa-be/src/modules/payload/service.ts
apps/medusa-be/src/{modules,api}/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Provider ID format in DB: {identifier}_{id} (e.g., my_shipping_default), in container: fp_{identifier}_{id}

Files:

  • apps/medusa-be/src/modules/payload/service.ts
apps/medusa-be/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Medusa backend custom logic should be organized in api/, modules/, workflows/, admin/, subscribers/, and jobs/ directories under apps/medusa-be/src/

Files:

  • apps/medusa-be/src/modules/payload/service.ts
apps/herbatika/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (apps/herbatika/AGENTS.md)

apps/herbatika/src/**/*.{jsx,tsx}: Use internal UI primitives/components from @techsio/ui-kit instead of native controls in app code. Avoid raw , , , <textarea>, , inline SVG icons. For Next.js links/images, prefer the UI-kit component with next/link or next/image adapter support when that component exposes it. Files: apps/herbatika/src/app/page.tsx apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx apps/herbatika/src/components/herbatika-homepage.tsx apps/herbatika/src/**/*.{jsx,tsx,css} 📄 CodeRabbit inference engine (apps/herbatika/AGENTS.md) Use token-based utility classes instead of raw Tailwind palette/spacing values. Prefer tokenized classes like p-200, mt-300, gap-150, text-success, bg-danger over raw Tailwind values like p-4, mt-8, bg-red-600. Files: apps/herbatika/src/app/page.tsx apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx apps/herbatika/src/components/herbatika-homepage.tsx apps/payload/**/collections/**/*.{ts,js} 📄 CodeRabbit inference engine (apps/payload/.cursor/rules/components.md) apps/payload/**/collections/**/*.{ts,js}: Define Field, Cell, and SaveButton components within collection admin config to customize Collection edit and list views in Payload CMS Use 'ui' field type with custom Field component for presentational UI elements that do not store data in Payload CMS documents Files: apps/payload/src/collections/hero-carousels.ts apps/payload/**/{hooks,collections,globals}/**/*.{ts,tsx} 📄 CodeRabbit inference engine (apps/payload/.cursor/rules/payload-overview.md) apps/payload/**/{hooks,collections,globals}/**/*.{ts,tsx}: Always pass req to nested operations in hooks to maintain transaction safety Use beforeChange hook to auto-set dates Check req.context to prevent hook loops Files: apps/payload/src/collections/hero-carousels.ts apps/payload/**/{collections,globals}/**/*.{ts,tsx} 📄 CodeRabbit inference engine (apps/payload/.cursor/rules/payload-overview.md) apps/payload/**/{collections,globals}/**/*.{ts,tsx}: Use slugField() for auto-generating slugs Use versions: { drafts: true } to enable draft/publish functionality Use virtual: true with afterRead hook for computed fields Use admin.condition for conditional field visibility Use validate function for custom field validation Use filterOptions on field to filter relationship options Use beforeDelete hook for cascading deletes Use point field with near/within for geospatial queries Use join field type for reverse relationships Use collection custom endpoints for custom routes Use localization + localized: true for multi-language support Files: apps/payload/src/collections/hero-carousels.ts apps/payload/**/{collections,access,globals}/**/*.{ts,tsx} 📄 CodeRabbit inference engine (apps/payload/.cursor/rules/payload-overview.md) Use access control with query to restrict operations by user Files: apps/payload/src/collections/hero-carousels.ts apps/payload/**/{collections,globals,app,hooks}/**/*.{ts,tsx} 📄 CodeRabbit inference engine (apps/payload/.cursor/rules/payload-overview.md) Use Jobs queue with tasks for background job processing Files: apps/payload/src/collections/hero-carousels.ts apps/payload/**/collections/**/*.{ts,tsx} 📄 CodeRabbit inference engine (apps/payload/AGENTS.md) apps/payload/**/collections/**/*.{ts,tsx}: Always pass req to nested operations in hooks to maintain transaction safety Always pass req to nested payload operations in collection hooks to maintain transaction atomicity Prevent infinite hook loops by using context flags (e.g., context.skipHooks) in afterChange hooks Field-level access control must return only boolean values, not query constraints Index frequently queried fields to improve query performance Set appropriate maxDepth on relationship fields to prevent over-fetching related documents Use beforeValidate hooks for data formatting Use beforeChange hooks for business logic Use afterChange hooks for side effects and notifications Use afterRead hooks for computed/virtual fields Use beforeDelete hooks for cascading deletes Keep collections in separate files within the collections directory Use reusable field factories for common field patterns Validate and format data using beforeValidate hooks before field validation Disable validation for draft documents using validate: false in drafts configuration Files: apps/payload/src/collections/hero-carousels.ts 🧠 Learnings (2) 📚 Learning: 2026-06-14T17:05:00.817Z Learnt from: KaiUweCZE Repo: TechsioCZ/new-engine PR: 442 File: apps/herbatika/src/components/reviews/product-review-token-page.tsx:36-42 Timestamp: 2026-06-14T17:05:00.817Z Learning: When reviewing code in apps/herbatika that calls `useProducts(input: ProductListInput, options?)`, treat `enabled` provided inside the first argument (`input`) as intentional and valid. The `ProductListInput` type includes an optional `enabled?: boolean` (via `BaseStorefrontProductListInput & { enabled?: boolean }`), and the hook infrastructure strips `enabled` before constructing the HTTP request and query key (following the same `stripListInput` behavior used elsewhere). Therefore, do NOT flag `useProducts({ enabled: ... , ... }, options)` as a contract violation; `enabled` belongs in the input object, not in the `options` argument. Applied to files: apps/herbatika/src/lib/storefront/cms-types.ts apps/herbatika/src/app/page.tsx apps/herbatika/src/components/homepage/homepage.data.types.ts apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx apps/herbatika/src/lib/storefront/cms-hero-carousels.ts apps/herbatika/src/lib/storefront/cms.ts apps/herbatika/src/components/herbatika-homepage.tsx 📚 Learning: 2025-12-16T19:45:17.746Z Learnt from: BleedingDev Repo: NMIT-WR/new-engine PR: 207 File: libs/ui/src/molecules/select.tsx:50-50 Timestamp: 2025-12-16T19:45:17.746Z Learning: When reviewing Tailwind classes in TSX/TS files, prefer using square brackets for arbitrary CSS values and complex expressions. Specifically: - Do not use the parentheses syntax (z-(--z-index)) for anything beyond simple CSS variable references; this syntax auto-wraps in var() and cannot handle calc or complex functions. - Use the square brackets syntax (e.g., h-[calc(var(--available-height)-var(--spacing-content))]) for calc expressions, var with calc, and any complex CSS expressions. This rule applies broadly to Tailwind v4 usage in TSX code across the project. Applied to files: apps/herbatika/src/app/page.tsx apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx apps/herbatika/src/components/herbatika-homepage.tsx 🔇 Additional comments (19) apps/payload/src/payload-types.ts (1) 343-343: LGTM! Also applies to: 345-345, 618-618 apps/payload/src/collections/hero-carousels.ts (7) 16-17: LGTM! 19-20: LGTM! 22-41: LGTM! 43-51: LGTM! 69-74: LGTM! 86-86: LGTM! 64-65: LGTM! apps/payload/src/seed.ts (1) 297-297: LGTM! apps/medusa-be/src/modules/payload/service.ts (1) 46-46: LGTM! apps/herbatika/src/lib/storefront/cms-types.ts (1) 55-62: LGTM! apps/herbatika/src/components/homepage/homepage.data.types.ts (1) 6-8: LGTM! apps/herbatika/src/lib/storefront/cms-hero-carousels.ts (3) 14-33: LGTM! 35-61: LGTM! 63-75: LGTM! apps/herbatika/src/lib/storefront/cms.ts (1) 8-11: LGTM! Also applies to: 19-19, 28-28, 31-32, 39-39 apps/herbatika/src/components/herbatika-homepage.tsx (1) 4-4: LGTM! Also applies to: 15-21, 25-25 apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx (1) 21-23: LGTM! Also applies to: 27-27, 32-32, 49-49 apps/herbatika/src/app/page.tsx (1) 3-3: LGTM! Also applies to: 7-10, 14-14

Comment thread apps/herbatika/src/lib/storefront/cms-hero-carousels.ts
Comment thread apps/payload/src/collections/hero-carousels.ts
Comment thread apps/payload/src/lib/constants/labels.ts
Comment thread apps/payload/src/collections/hero-carousels.ts
KaiUweCZE and others added 5 commits July 14, 2026 14:31
� Conflicts:
�	apps/herbatika/src/components/homepage/sections/homepage-hero-carousel-section.tsx
* fallback for internalTitle when update data omits the field
* fix tsc errors in payload tests
* run migration in production (payload config)
@redeyecz
redeyecz force-pushed the feat-herbatica-payload-content branch from 36f0edb to f9698c7 Compare July 14, 2026 15:46
@github-actions

Copy link
Copy Markdown

Storybook A11y Report

⚠️ Non-blocking mode: violations will NOT fail CI (A11Y_REPORT_FAIL_ON_VIOLATIONS=false).

Light

No a11y report JSON found for light. Storybook test-runner likely failed before reporting.

Dark

No a11y report JSON found for dark. Storybook test-runner likely failed before reporting.

@redeyecz
redeyecz merged commit 0b5e37e into master Jul 14, 2026
8 of 9 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.22.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

This branch was successfully deployed

1 active deployment
Preview — 34d1fe3f Deployed Jul 14, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants