Skip to content

feat(admin): add custom admin shell with action-required badges - #415

Closed
KaiUweCZE wants to merge 65 commits into
masterfrom
feat/admin
Closed

feat(admin): add custom admin shell with action-required badges#415
KaiUweCZE wants to merge 65 commits into
masterfrom
feat/admin

Conversation

@KaiUweCZE

@KaiUweCZE KaiUweCZE commented May 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a custom apps/admin application as the first step toward our own admin UX instead of forking Medusa Admin.

The main business goal is to surface items that require manual admin action directly in the sidebar:

  • Orders waiting for admin confirmation that are not paid and not partially paid.
  • B2B customers waiting for manual admin approval.

Clicking the sidebar items opens the corresponding prefiltered list.

What changed

  • Added custom admin sidebar with action badges for Orders and Customers.
  • Added admin login against the deployed Medusa backend.
  • Added action-required order list.
  • Added pending B2B customer list.
  • Added Products as the first Medusa Admin API-backed parity screen.
  • Added internal routes/placeholders for the broader admin navigation so users stay inside our admin app.
  • Removed fork-oriented Medusa Admin dependencies from the admin app lockfile.
  • Switched admin production build to vite build --minify esbuild because default Vite/OXC minification hit a local Rolldown OOM.

Business rules covered

Orders badge counts only orders that:

  • wait for admin confirmation,
  • are not paid,
  • are not partially paid.

Customers badge counts only:

  • B2B customers,
  • waiting for manual admin approval.

Badges are hidden when the count is 0. Counts refresh on admin load/page refresh; realtime updates are intentionally out of scope.

Out of scope

  • Realtime badge updates.
  • New backend endpoints.
  • Role-based permissions.
  • The actual approval/confirmation workflows.
  • Full Medusa Admin feature parity.
  • Email/push/external notifications.

Testing

  • pnpm exec biome check --write apps/admin/src/admin-api.ts apps/admin/src/admin-app.tsx apps/admin/src/admin-pages.tsx apps/admin/src/admin-types.ts apps/admin/src/nav-config.tsx apps/admin/src/ styles.css apps/admin/package.json
  • pnpm --dir apps/admin run typecheck
  • pnpm --dir apps/admin run build
  • Smoke checked http://localhost:3001 returns 200.

Notes for review

This is intended to be deployed to Zane for UX review. The next step is to walk through the admin with real data and decide which placeholder admin sections should be implemented first.

Summary by CodeRabbit

  • New Features

    • Brand‑new Admin web app: email/password login, protected shell, navigation, dashboards (action‑required orders, pending B2B), products (search, pagination, details), email logs (preview/resend), order details, Packeta label selection & PDF download, and settings for Packeta, PPL, Payload and QR payments.
  • Style

    • New admin theme: tokens, colours, typography, icons, global CSS and light/dark theme with toggle.
  • Chores

    • Project scaffolding, dev/build config, Docker/Caddy, TypeScript/Vite setup and validation CLI scripts.
  • Documentation

    • Admin parity roadmap, agent plans and implementation guidelines.

Review Change Stack

@semanticdiff-com

semanticdiff-com Bot commented May 21, 2026

Copy link
Copy Markdown

Review changes with  SemanticDiff

Changed Files
File Status
  pnpm-lock.yaml  4% smaller
  AGENTS.md Unsupported file format
  apps/admin/.env.example Unsupported file format
  apps/admin/.gitignore Unsupported file format
  apps/admin/AGENTS.md Unsupported file format
  apps/admin/Caddyfile Unsupported file format
  apps/admin/index.html  0% smaller
  apps/admin/package.json  0% smaller
  apps/admin/postcss.config.js  0% smaller
  apps/admin/project.json  0% smaller
  apps/admin/scripts/validate-token-usage.mjs  0% smaller
  apps/admin/scripts/validate-ui-primitives.mjs  0% smaller
  apps/admin/src/admin-api.ts  0% smaller
  apps/admin/src/admin-app.tsx  0% smaller
  apps/admin/src/admin-auth.ts  0% smaller
  apps/admin/src/admin-config.ts  0% smaller
  apps/admin/src/admin-errors.ts  0% smaller
  apps/admin/src/admin-login-page.tsx  0% smaller
  apps/admin/src/admin-order-detail-page.tsx  0% smaller
  apps/admin/src/admin-packeta-labels-page.tsx  0% smaller
  apps/admin/src/admin-packeta-settings-page.tsx  0% smaller
  apps/admin/src/admin-pages.tsx  0% smaller
  apps/admin/src/admin-payload-settings-page.tsx  0% smaller
  apps/admin/src/admin-ppl-settings-page.tsx  0% smaller
  apps/admin/src/admin-product-detail-page.tsx  0% smaller
  apps/admin/src/admin-rules.ts  0% smaller
  apps/admin/src/admin-settings-page.tsx  0% smaller
  apps/admin/src/admin-store-settings-page.tsx  0% smaller
  apps/admin/src/admin-types.ts  0% smaller
  apps/admin/src/components/admin-detail-field.tsx  0% smaller
  apps/admin/src/components/admin-entity.tsx  0% smaller
  apps/admin/src/components/admin-feedback.tsx  0% smaller
  apps/admin/src/components/admin-form-input.tsx  0% smaller
  apps/admin/src/components/admin-info-list.tsx  0% smaller
  apps/admin/src/components/admin-link-card.tsx  0% smaller
  apps/admin/src/components/admin-link.tsx  0% smaller
  apps/admin/src/components/admin-list.tsx  0% smaller
  apps/admin/src/components/admin-media.tsx  0% smaller
  apps/admin/src/components/admin-page-header.tsx  0% smaller
  apps/admin/src/components/admin-pagination.tsx  0% smaller
  apps/admin/src/components/admin-panel-header.tsx  0% smaller
  apps/admin/src/components/admin-panel.tsx  0% smaller
  apps/admin/src/components/admin-placeholder.tsx  0% smaller
  apps/admin/src/components/admin-preview.tsx  0% smaller
  apps/admin/src/components/admin-search.tsx  0% smaller
  apps/admin/src/components/admin-select-field.tsx  0% smaller
  apps/admin/src/components/admin-settings-form.tsx  0% smaller
  apps/admin/src/components/admin-state.tsx  0% smaller
  apps/admin/src/components/admin-summary-list.tsx  0% smaller
  apps/admin/src/components/admin-table.tsx  0% smaller
  apps/admin/src/components/admin-text-field.tsx  0% smaller
  apps/admin/src/components/admin-theme-toggle.tsx  0% smaller
  apps/admin/src/components/admin-toolbar-button.tsx  0% smaller
  apps/admin/src/hooks/use-admin-theme.ts  0% smaller
  apps/admin/src/main.tsx  0% smaller
  apps/admin/src/nav-config.tsx  0% smaller
  apps/admin/src/styles.css  0% smaller
  apps/admin/src/styles/tokens/_admin-base.css  0% smaller
  apps/admin/src/styles/tokens/_admin-colors.css  0% smaller
  apps/admin/src/styles/tokens/_admin-icons.css Unsupported file format
  apps/admin/src/styles/tokens/_admin-layout.css  0% smaller
  apps/admin/src/styles/tokens/_admin-semantic.css  0% smaller
  apps/admin/src/styles/tokens/_admin-spacing.css  0% smaller
  apps/admin/src/styles/tokens/_admin-typography.css  0% smaller
  apps/admin/src/styles/tokens/components/_admin-form-control.css  0% smaller
  apps/admin/src/styles/tokens/components/atoms/_admin-badge.css  0% smaller
  apps/admin/src/styles/tokens/components/atoms/_admin-button.css  0% smaller
  apps/admin/src/styles/tokens/components/atoms/_admin-checkbox.css  0% smaller
  apps/admin/src/styles/tokens/components/atoms/_admin-input.css  0% smaller
  apps/admin/src/styles/tokens/components/components.css  0% smaller
  apps/admin/src/styles/tokens/components/molecules/_admin-search.css  0% smaller
  apps/admin/src/styles/tokens/index.css Unsupported file format
  apps/admin/src/utils/cx.ts  0% smaller
  apps/admin/src/utils/format.ts  0% smaller
  apps/admin/src/utils/theme.ts  0% smaller
  apps/admin/tsconfig.json  0% smaller
  apps/admin/ui.md Unsupported file format
  apps/admin/vite.config.ts  0% smaller
  docker/development/admin/Dockerfile Unsupported file format
  docs/admin-parity-roadmap.md Unsupported file format

@vercel

vercel Bot commented May 21, 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 May 28, 2026 8:26am

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@KaiUweCZE, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 7 minutes and 7 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

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.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b95c6fcb-6eeb-4b66-94f4-bfcb2b4196c3

📥 Commits

Reviewing files that changed from the base of the PR and between ea84b63 and c6c46a9.

📒 Files selected for processing (1)
  • apps/admin/.gitignore

Walkthrough

Adds a full new admin web application (React + Vite) with env/config, API client and React Query hooks, authentication/session handling, business rules, multiple admin pages (orders, customers, products, emails, Packeta/PPL/QR/Payload), comprehensive styles, CLI validators, and Docker/Caddy deployment.

Changes

Admin Application

Layer / File(s) Summary
Project configuration and tooling
apps/admin/package.json, apps/admin/project.json, apps/admin/tsconfig.json, apps/admin/vite.config.ts, apps/admin/index.html, apps/admin/.env.example, apps/admin/.gitignore
New app manifest, Nx project config, TypeScript and Vite setup, HTML entrypoint, example env var VITE_MEDUSA_BACKEND_URL, and gitignore patterns for env locals.
Data types and contracts
apps/admin/src/admin-types.ts
Comprehensive TypeScript types for admin API shapes: dashboard DTOs, email logs, Packeta/PPL/QR/payload configs, and Medusa admin entity models (orders, customers, products, fulfilments, payments, variants).
Authentication and error handling
apps/admin/src/admin-errors.ts, apps/admin/src/admin-auth.ts, apps/admin/src/admin-login-page.tsx
ApiError type and helpers, sessionStorage token helpers, loginAdmin POST flow with token validation/persistence, auth error mapping, and the LoginPage component with submission/error handling.
API configuration and client
apps/admin/src/admin-config.ts, apps/admin/src/admin-api.ts
MEDUSA_BACKEND_URL resolution and buildMedusaUrl; generic JSON/HTML/Blob fetch helpers, JSON POST helper with error parsing, paginated scanner, and multiple fetchers for orders/customers/products/email logs/Packeta and config endpoints.
React Query hooks and action functions
apps/admin/src/admin-api.ts
React Query hooks for action-required summary/orders, pending B2B customers, products list/detail, email logs/detail, order email templates, Packeta label orders; exported action functions (downloadPacketaLabels, fetchPayloadSsoHtml, update*Config, sendOrderEmail) and paging limits.
Business logic and data transformations
apps/admin/src/admin-rules.ts
Payment-status inference, fulfilment/manual business-status resolution, isActionRequiredOrder / isPendingB2BCustomer predicates, and mappers to app-specific DTOs.
Navigation configuration
apps/admin/src/nav-config.tsx
AdminNavItem type and adminNavItems array mapping routes, icons, labels, sections, and optional badge keys.
App shell and initialization
apps/admin/src/admin-app.tsx, apps/admin/src/main.tsx
AdminApp component with auth gating and sidebar badge counts, authenticated routes and redirects; main.tsx bootstraps React, QueryClient and BrowserRouter.
Page components and rendering
apps/admin/src/admin-pages.tsx, apps/admin/src/admin-product-detail-page.tsx, apps/admin/src/admin-order-detail-page.tsx, apps/admin/src/admin-packeta-labels-page.tsx
Orders/Customers/Products listing pages (search/pagination), Emails page (list + detail + resend), Product and Order detail pages with panels/tables, Packeta labels page with bulk PDF download, generic DataSurface and many UI helpers/formatters.
Packeta & PPL settings pages
apps/admin/src/admin-packeta-settings-page.tsx, apps/admin/src/admin-ppl-settings-page.tsx
Packeta and PPL settings forms with typed form models, sensitive-field clearing semantics, payload mapping, mutation handling, and set-flag helpers.
Payload & QR settings
apps/admin/src/admin-payload-settings-page.tsx, apps/admin/src/admin-settings-page.tsx
Payload SSO iframe/new-tab flows and return-to handling; QR payments settings page with IBAN editing and mutation wiring.
Global styles and theme tokens
apps/admin/src/styles.css, apps/admin/src/styles/tokens/*
Tailwind token entrypoint, base/semantic/colour/layout/spacing/typography/icon tokens, component token partials and index; global stylesheet imports tokens and sets base resets.
UI primitives and components
apps/admin/src/components/*, apps/admin/src/hooks/use-admin-theme.ts, apps/admin/src/utils/*
Wide set of reusable admin UI components (panels, lists, tables, forms, previews, inputs, pagination, media, theme toggle), useAdminTheme hook, cx class util and format helpers.
CLI validators
apps/admin/scripts/validate-token-usage.mjs, apps/admin/scripts/validate-ui-primitives.mjs
Node scripts validating Tailwind token usage and disallowed native primitives in source files; exit non-zero on violations for CI enforcement.
Build & deploy
docker/development/admin/Dockerfile, apps/admin/Caddyfile
Multi-stage Dockerfile to build and serve apps/admin via Caddy; Caddyfile SPA serving, /healthz, compression and security headers.
Docs and agents guidance
docs/admin-parity-roadmap.md, apps/admin/AGENTS.md, AGENTS.md, apps/admin/agent-plans/*, apps/admin/plan-graphs/*, apps/admin/ui.md
Roadmap for Medusa admin parity, AGENTS guidance, plan lanes and generated plan-graph snapshots, and UI token usage guidance.

Sequence Diagram(s)

sequenceDiagram
  participant Browser as Browser
  participant AdminApp as AdminApp (React)
  participant AdminAPI as AdminAPI (client)
  participant Medusa as Medusa Backend

  Browser->>AdminApp: load index.html and mount /src/main.tsx
  AdminApp->>AdminAPI: call useActionRequiredSummary (auth token)
  AdminAPI->>Medusa: GET /admin/orders and /admin/customers
  Medusa-->>AdminAPI: JSON responses
  AdminAPI-->>AdminApp: hooks return data
  AdminApp->>Browser: render sidebar, badges and pages
  Browser->>AdminApp: user navigates (e.g., open order detail)
  AdminApp->>AdminAPI: fetch order detail (GET /admin/orders/:id)
  AdminAPI->>Medusa: GET /admin/orders/:id
  Medusa-->>AdminAPI: order JSON
  AdminAPI-->>AdminApp: return order detail
  AdminApp->>Browser: render order detail page
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/admin
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/admin

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

🤖 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/admin/src/admin-api.ts`:
- Around line 159-161: The has_next computation can be false when
result.countExact is false, hiding more results; update both places where
has_next is set (the objects using count, count_exact, has_next with variables
orders.length and result.countExact and the constant ACTION_REQUIRED_LIST_LIMIT)
so that has_next is true if result.countExact is false OR if orders.length >
ACTION_REQUIRED_LIST_LIMIT (i.e., compute has_next as !result.countExact ||
orders.length > ACTION_REQUIRED_LIST_LIMIT) to ensure it remains truthful when
scan results are inexact.

In `@apps/admin/src/admin-app.tsx`:
- Line 2: Update the Badge import to follow the repository UI path convention:
replace the existing import of Badge from "`@techsio/ui-kit/atoms/badge`" with the
canonical namespace import "import { Badge } from '`@libs/ui/atoms/badge`'".
Ensure the symbol name Badge remains unchanged so all references in
admin-app.tsx continue to resolve.

In `@apps/admin/src/admin-pages.tsx`:
- Around line 1-2: The imports in admin-pages.tsx use the wrong package path;
update the Badge and Button imports (symbols: Badge, Button) to the
repository-standard UI paths by replacing their current
'`@techsio/ui-kit/atoms/`...' imports with '`@libs/ui/atoms/badge`' and
'`@libs/ui/atoms/button`' respectively so the TSX file follows the project's
import convention for UI atoms.

In `@apps/admin/src/styles.css`:
- Around line 110-113: Add visible keyboard focus styles for the interactive
controls that only have :hover today: update .admin-nav-item,
.admin-sidebar-action, .admin-toolbar-button, .admin-pagination-button, and
.admin-login-submit to include :focus-visible rules that mirror the hover
background/color but also add a clear focus indicator (e.g., an outline or
box-shadow) for keyboard users; ensure the existing :hover styles remain
unchanged and prefer :focus-visible over :focus so mouse interactions aren’t
given the same outline, and apply the same change to the other blocks mentioned
around the same file (lines referenced in the review).
- Around line 410-420: The skeleton shimmer currently animates indefinitely for
.admin-row-skeleton; add a prefers-reduced-motion override so users who request
reduced motion don't see the animation: create an `@media`
(prefers-reduced-motion: reduce) rule that targets .admin-row-skeleton (and any
other skeleton classes) and sets animation: none (or animation-duration: 0s) and
a stable background state, and also ensure the `@keyframes` admin-skeleton block
(referenced around the admin-skeleton keyframes) is not applied by this override
so the shimmer stops for reduced-motion users.
- Around line 374-377: .admin-product-meta currently sets justify-content: end
but is not a flex or grid container so the property does nothing; either remove
the justify-content rule or turn the selector into a layout container (e.g., add
display: flex or display: grid) and use the correct value (justify-content:
flex-end) to right-align children. Update the .admin-product-meta rule to
include display: flex (or grid) and change justify-content from "end" to
"flex-end" if you want child alignment, otherwise delete the justify-content
declaration to keep the stylesheet accurate.
- Around line 3-6: In the :root CSS block, update the font-family and
text-rendering to satisfy Stylelint: remove the quotes around the Aptos family
name in the font-family declaration (change "Aptos" to Aptos) and normalize the
text-rendering keyword to lowercase (change optimizeLegibility to
optimizelegibility) so the declarations in styles.css (font-family and
text-rendering) conform to font-family-name-quotes and value-keyword-case rules.

In `@apps/admin/vite.config.ts`:
- Around line 7-10: The Vite dev server config currently uses server.port = 3001
with server.strictPort = false which allows Vite to silently pick a different
port; change server.strictPort to true in the server config object so the
process fails if port 3001 is unavailable (preserving the expected
http://localhost:3001 contract used by smoke tests and CORS allow-lists). Ensure
the change is applied to the server config where port and strictPort are
defined.
🪄 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: df359ce0-0079-46ae-acb3-34d3c4a2fc41

📥 Commits

Reviewing files that changed from the base of the PR and between fb77bb2 and 68fdeb1.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (19)
  • apps/admin/.env.example
  • apps/admin/.gitignore
  • apps/admin/index.html
  • apps/admin/package.json
  • apps/admin/project.json
  • apps/admin/src/admin-api.ts
  • apps/admin/src/admin-app.tsx
  • apps/admin/src/admin-auth.ts
  • apps/admin/src/admin-config.ts
  • apps/admin/src/admin-errors.ts
  • apps/admin/src/admin-login-page.tsx
  • apps/admin/src/admin-pages.tsx
  • apps/admin/src/admin-rules.ts
  • apps/admin/src/admin-types.ts
  • apps/admin/src/main.tsx
  • apps/admin/src/nav-config.tsx
  • apps/admin/src/styles.css
  • apps/admin/tsconfig.json
  • apps/admin/vite.config.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). (3)
  • GitHub Check: main
  • GitHub Check: Greptile Review
  • GitHub Check: Kilo Code Review
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'

Files:

  • apps/admin/src/main.tsx
  • apps/admin/vite.config.ts
  • apps/admin/src/admin-config.ts
  • apps/admin/src/admin-login-page.tsx
  • apps/admin/src/nav-config.tsx
  • apps/admin/src/admin-errors.ts
  • apps/admin/src/admin-auth.ts
  • apps/admin/src/admin-rules.ts
  • apps/admin/src/admin-app.tsx
  • apps/admin/src/admin-types.ts
  • apps/admin/src/admin-api.ts
  • apps/admin/src/admin-pages.tsx
**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Use pnpm CLI to add dependencies; never edit package.json directly

Files:

  • apps/admin/package.json
🧠 Learnings (4)
📚 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/admin/src/main.tsx
  • apps/admin/src/admin-login-page.tsx
  • apps/admin/src/nav-config.tsx
  • apps/admin/src/admin-app.tsx
  • apps/admin/src/admin-pages.tsx
📚 Learning: 2026-02-05T14:43:17.404Z
Learnt from: KaiUweCZE
Repo: NMIT-WR/new-engine PR: 324
File: apps/medusa-be/package.json:0-0
Timestamp: 2026-02-05T14:43:17.404Z
Learning: Validate and enforce React 19 compatibility across monorepo workspaces. Since Medusa UI supports React 19 via root package.json overrides and Medusa Cloud prerequisites show React 19 overrides for npm workspaces, ensure workspace root and all relevant package.json files align with React 19 (18+ requirement is satisfied). When reviewing, verify that overrides exist in the root package.json and that dependent packages in apps or packages directories declare React 19 (or compatible) in their peerDependencies or dependencies as appropriate for workspace usage.

Applied to files:

  • apps/admin/package.json
📚 Learning: 2026-05-07T19:05:58.339Z
Learnt from: redeyecz
Repo: TechsioCZ/new-engine PR: 390
File: apps/medusa-be/package.json:78-81
Timestamp: 2026-05-07T19:05:58.339Z
Learning: When reviewing changes to `package.json`, do not automatically flag dependency additions/removals as "manually edited" or as "bypassing the pnpm lockfile" just because the `package.json` diff shows only that file changed. First verify whether `pnpm-lock.yaml` is missing the corresponding entries. Since `pnpm add` updates both `package.json` and `pnpm-lock.yaml` together, legitimate changes can appear in the `package.json` diff while still being properly tracked in the lockfile.

Applied to files:

  • apps/admin/package.json
📚 Learning: 2026-05-20T15:58:53.048Z
Learnt from: redeyecz
Repo: TechsioCZ/new-engine PR: 413
File: apps/medusa-be/package.json:77-80
Timestamp: 2026-05-20T15:58:53.048Z
Learning: When reviewing monorepo `package.json` files, treat any dependencies/devDependencies using the `paykit-sdk/*` scope (e.g., `paykit-sdk/core`, `paykit-sdk/stripe`, `paykit-sdk/comgate`, `paykit-sdk/gopay`) as coming from the TechsioCZ/new-engine private npm registry. Do not flag dependency version constraints (e.g., `^1.2.0`) as invalid merely because those packages/versions are not found on the public npm registry. Public-web/private-web availability checks against the public npm API are not applicable for these packages; if validation is needed, rely on the private registry/CI install behavior instead.

Applied to files:

  • apps/admin/package.json
🪛 Stylelint (17.11.1)
apps/admin/src/styles.css

[error] 3-3: Expected no quotes around "Aptos" (font-family-name-quotes)

(font-family-name-quotes)


[error] 6-6: Expected "optimizeLegibility" to be "optimizelegibility" (value-keyword-case)

(value-keyword-case)

🔇 Additional comments (15)
apps/admin/package.json (1)

1-27: chore(deps): LGTM!

apps/admin/project.json (1)

1-37: chore(nx): LGTM!

apps/admin/tsconfig.json (1)

1-13: chore(tsconfig): LGTM!

apps/admin/.env.example (1)

1-1: chore(env): LGTM!

apps/admin/.gitignore (1)

1-2: chore(gitignore): LGTM!

apps/admin/vite.config.ts (1)

5-5: 💤 Low value

Missing input: Provide the original review comment (inside <review_comment>...</review_comment>) plus the exact diff/code it refers to so I can rewrite it in the required format.

apps/admin/src/admin-types.ts (1)

1-154: LGTM!

apps/admin/src/admin-errors.ts (1)

1-20: LGTM!

apps/admin/src/admin-auth.ts (1)

1-72: LGTM!

apps/admin/src/admin-login-page.tsx (1)

1-87: LGTM!

apps/admin/src/admin-config.ts (1)

1-15: LGTM!

apps/admin/src/admin-rules.ts (1)

1-185: LGTM!

apps/admin/src/nav-config.tsx (1)

1-130: LGTM!

apps/admin/index.html (1)

1-12: LGTM!

apps/admin/src/main.tsx (1)

1-33: LGTM!

Comment thread apps/admin/src/admin-api.ts Outdated
Comment thread apps/admin/src/admin-app.tsx
Comment thread apps/admin/src/admin-pages.tsx Outdated
Comment on lines +1 to +2
import { Badge } from "@techsio/ui-kit/atoms/badge"
import { Button } from "@techsio/ui-kit/atoms/button"

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 | ⚡ Quick win

fix(admin): use repository-standard UI import paths

Line 1 and Line 2 import UI atoms from @techsio/ui-kit/..., but this codebase requires @libs/ui/... paths in TS/TSX files.

♻️ Proposed fix
-import { Badge } from "`@techsio/ui-kit/atoms/badge`"
-import { Button } from "`@techsio/ui-kit/atoms/button`"
+import { Badge } from "`@libs/ui/atoms/badge`"
+import { Button } from "`@libs/ui/atoms/button`"

As per coding guidelines: **/*.{ts,tsx}: Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'.

📝 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
import { Badge } from "@techsio/ui-kit/atoms/badge"
import { Button } from "@techsio/ui-kit/atoms/button"
import { Badge } from "`@libs/ui/atoms/badge`"
import { Button } from "`@libs/ui/atoms/button`"
🤖 Prompt for 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.

In `@apps/admin/src/admin-pages.tsx` around lines 1 - 2, The imports in
admin-pages.tsx use the wrong package path; update the Badge and Button imports
(symbols: Badge, Button) to the repository-standard UI paths by replacing their
current '`@techsio/ui-kit/atoms/`...' imports with '`@libs/ui/atoms/badge`' and
'`@libs/ui/atoms/button`' respectively so the TSX file follows the project's
import convention for UI atoms.

Comment thread apps/admin/src/styles.css Outdated
Comment thread apps/admin/src/styles.css Outdated
Comment thread apps/admin/src/styles.css Outdated
Comment thread apps/admin/src/styles.css Outdated
Comment thread apps/admin/vite.config.ts
@greptile-apps

greptile-apps Bot commented May 21, 2026

Copy link
Copy Markdown

Greptile Summary

This PR introduces a brand-new custom admin application (apps/admin) built on Vite + React + React Query, replacing the plan to fork Medusa Admin. The core feature is a sidebar with live action-required badges for pending orders and B2B customers awaiting approval, backed by paginated Medusa API scans with configurable concurrency.

  • Auth & shell: sessionStorage-based JWT, automatic redirect on token expiry, protected routing with isAuthenticated state, and a logout button that clears both the token and the React Query cache.
  • Badge logic: useActionRequiredSummary fans out to two sub-queries via Promise.all; badges are hidden at count 0, show a "+" suffix when the 2 000-record scan limit is hit, and refresh every 60 s or on window focus.
  • Supporting pages: products (paginated, searchable), email log viewer with iframe preview sandboxed to empty permissions, Packeta label download with per-order selection, and settings pages for Packeta, PPL, Payload, and QR payments.

Confidence Score: 4/5

Safe to merge for the intended UX-review deployment; one field-spec inconsistency in the product query warrants a quick verification against the running Medusa instance before going to production.

The main open question is whether Medusa's field-selection layer silently ignores variants.id when -variants also appears in the same query string — if it does, every product in the list would show "0 variant" with no error surfaced. The rest of the auth flow, business-rule filtering, badge logic, and sandboxed email preview are solid.

apps/admin/src/admin-api.ts — specifically the PRODUCT_FIELDS constant (lines 180–194) where "variants.id" and "-variants" coexist.

Important Files Changed

Filename Overview
apps/admin/src/admin-api.ts Core API layer: paginated scanning with 2-concurrent batching, React Query hooks, and action-required summary aggregation. Contains a contradictory field spec (variants.id + -variants) in PRODUCT_FIELDS that may silently zero out variant counts.
apps/admin/src/admin-app.tsx Top-level shell with auth state, sidebar, and routing. Auth flow is correct: authenticated users visiting /login get redirected; token expiry clears state and redirects to login.
apps/admin/src/admin-pages.tsx Page components for orders, customers, products, emails. Properly surfaces count_exact flag via formatCountLabel; handles loading/error/empty states consistently.
apps/admin/src/admin-packeta-labels-page.tsx Packeta label download page. Page navigation only resets the feedback banner, not selectedOrderIds; cross-page selections are silently dropped from downloads while appearing to persist in state.
apps/admin/src/admin-auth.ts JWT stored in sessionStorage (cleared on tab close, not transmitted as cookie). Login validates token string type before storing. Logout clears token and React Query cache.
apps/admin/src/admin-rules.ts Client-side business-rule filters for action-required orders and pending B2B customers. Logic correctly excludes partially-paid orders as per spec.
apps/admin/vite.config.ts Minimal Vite config; exposes both VITE_ and NEXT_PUBLIC_ env prefixes; uses esbuild minification to avoid Rolldown OOM.

Sequence Diagram

sequenceDiagram
    participant Browser
    participant AdminApp
    participant MedusaAPI
    participant ReactQuery

    Browser->>AdminApp: Load /login
    AdminApp->>Browser: Render LoginPage

    Browser->>MedusaAPI: POST /auth/user/emailpass
    MedusaAPI-->>Browser: JWT token
    Browser->>Browser: Store token in sessionStorage

    Browser->>AdminApp: setIsAuthenticated(true)
    AdminApp->>ReactQuery: invalidateQueries()
    AdminApp->>Browser: "Navigate to /orders?view=action-required"

    AdminApp->>ReactQuery: useActionRequiredSummary (enabled)
    ReactQuery->>MedusaAPI: fetchQuery(orders) + fetchQuery(customers) [Promise.all]
    MedusaAPI-->>ReactQuery: Orders data (paginated scan, 2 concurrent)
    MedusaAPI-->>ReactQuery: Customers data (paginated scan, 2 concurrent)
    ReactQuery-->>AdminApp: "ActionRequiredSummary { orders, customers }"
    AdminApp->>Browser: "Render sidebar badges (count > 0 shown)"

    Note over AdminApp,ReactQuery: Refetch every 60s (window focus also triggers)

    Browser->>AdminApp: Navigate /orders
    AdminApp->>ReactQuery: useActionRequiredOrders()
    ReactQuery-->>AdminApp: Cached data (staleTime 15s)
    AdminApp->>Browser: Render orders list (first 50)
Loading

Fix All in Codex

Reviews (10): Last reviewed commit: "chore(admin): ignore planning artifacts" | Re-trigger Greptile

Comment thread apps/admin/src/admin-app.tsx
Comment thread apps/admin/src/admin-api.ts
Comment thread apps/admin/src/admin-api.ts
Comment thread apps/admin/src/admin-pages.tsx
@kilo-code-bot

kilo-code-bot Bot commented May 21, 2026

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

This incremental update contains only pnpm-lock.yaml changes (dependency version bumps).
No code changes to review. All previous findings remain valid.

Files Reviewed (0 files)

pnpm-lock.yaml (lockfile - excluded from review per instructions)


Reviewed by laguna-m.1-20260312:free · 129,602 tokens

Comment thread apps/admin/src/admin-api.ts Outdated
Comment thread apps/admin/src/admin-api.ts Outdated

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

♻️ Duplicate comments (8)
apps/admin/src/admin-app.tsx (1)

2-2: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix UI component import path to follow repository convention.

Line 2 imports Badge from @techsio/ui-kit/atoms/badge, but the coding guideline requires imports from @libs/ui/atoms/*.

♻️ Proposed fix
-import { Badge } from "`@techsio/ui-kit/atoms/badge`"
+import { Badge } from "`@libs/ui/atoms/badge`"

As per coding guidelines: **/*.{ts,tsx}: Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'.

🤖 Prompt for 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.

In `@apps/admin/src/admin-app.tsx` at line 2, The import path for the Badge UI
component is using the old package namespace; update the import in admin-app.tsx
so the Badge symbol is imported from the repository convention
'`@libs/ui/atoms/badge`' (i.e., change the module specifier for the existing Badge
import to follow the pattern used for other UI atoms).
apps/admin/src/admin-pages.tsx (1)

1-2: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Import UI components from @libs/ui/atoms/, not @techsio/ui-kit.

Lines 1 and 2 import Badge and Button from @techsio/ui-kit/atoms/*, but the coding guidelines require using @libs/ui/atoms/* for all TS/TSX files.

🔧 Proposed fix
-import { Badge } from "`@techsio/ui-kit/atoms/badge`"
-import { Button } from "`@techsio/ui-kit/atoms/button`"
+import { Badge } from "`@libs/ui/atoms/badge`"
+import { Button } from "`@libs/ui/atoms/button`"

As per coding guidelines: **/*.{ts,tsx}: Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'.

🤖 Prompt for 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.

In `@apps/admin/src/admin-pages.tsx` around lines 1 - 2, Replace the incorrect
imports of Badge and Button from "`@techsio/ui-kit/atoms/`*" with the sanctioned
package path "`@libs/ui/atoms/`*" in admin-pages.tsx: locate the import statements
that reference Badge and Button and change them to import from
'`@libs/ui/atoms/badge`' and '`@libs/ui/atoms/button`' respectively so they follow
the project's import guideline for UI atoms.
apps/admin/src/admin-api.ts (2)

346-353: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

has_next is computed after slicing and will always be false.

Line 349 checks orders.length > ACTION_REQUIRED_LIST_LIMIT, but this happens after line 352 slices orders to exactly ACTION_REQUIRED_LIST_LIMIT items. This means has_next will always be false, breaking pagination. Additionally, when result.countExact is false, has_next should be true to indicate more results may exist beyond the scan limit.

🐛 Proposed fix
+  const totalOrders = orders.length
+
   return {
-    count: orders.length,
+    count: totalOrders,
     count_exact: result.countExact,
-    has_next: orders.length > ACTION_REQUIRED_LIST_LIMIT,
+    has_next:
+      !result.countExact || totalOrders > ACTION_REQUIRED_LIST_LIMIT,
     limit: ACTION_REQUIRED_LIST_LIMIT,
     offset: 0,
     orders: orders.slice(0, ACTION_REQUIRED_LIST_LIMIT),
   }
🤖 Prompt for 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.

In `@apps/admin/src/admin-api.ts` around lines 346 - 353, has_next is computed
after slicing so it will always be false; instead compute has_next before
slicing and respect result.countExact: if result.countExact is false set
has_next to true (unknown more results), otherwise set has_next to
(orders.length > ACTION_REQUIRED_LIST_LIMIT). Update the return to compute the
has_next value using the unsliced orders array (referencing orders,
ACTION_REQUIRED_LIST_LIMIT, and result.countExact), then slice orders with
orders.slice(0, ACTION_REQUIRED_LIST_LIMIT) for the orders field.

372-379: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

has_next is computed after slicing and will always be false.

Line 376 checks customers.length > ACTION_REQUIRED_LIST_LIMIT, but this happens after line 375 slices customers to exactly ACTION_REQUIRED_LIST_LIMIT items. This means has_next will always be false, breaking pagination. Additionally, when result.countExact is false, has_next should be true to indicate more results may exist beyond the scan limit.

🐛 Proposed fix
+  const totalCustomers = customers.length
+
   return {
-    count: customers.length,
+    count: totalCustomers,
     count_exact: result.countExact,
     customers: customers.slice(0, ACTION_REQUIRED_LIST_LIMIT),
-    has_next: customers.length > ACTION_REQUIRED_LIST_LIMIT,
+    has_next:
+      !result.countExact || totalCustomers > ACTION_REQUIRED_LIST_LIMIT,
     limit: ACTION_REQUIRED_LIST_LIMIT,
     offset: 0,
   }
🤖 Prompt for 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.

In `@apps/admin/src/admin-api.ts` around lines 372 - 379, Compute has_next before
slicing and rely on the original customers length and result.countExact: set
has_next = true if result.countExact is false OR if customers.length >
ACTION_REQUIRED_LIST_LIMIT, then slice customers for the returned list; update
the return object (keys count, count_exact, customers, has_next, limit, offset)
to use that computed has_next instead of checking customers.length after
slicing. Ensure you reference the variables customers,
ACTION_REQUIRED_LIST_LIMIT and result.countExact so the logic is applied prior
to customers.slice(...) in the same function.
apps/admin/src/styles.css (4)

1021-1031: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Respect prefers-reduced-motion for the skeleton shimmer.

The admin-skeleton animation loops indefinitely on .admin-row-skeleton. For users who opt into reduced motion, it's good practice to disable the animation to avoid distraction or motion sensitivity issues.

🛠️ Suggested addition
`@media` (prefers-reduced-motion: reduce) {
  .admin-row-skeleton {
    animation: none;
  }
}
🤖 Prompt for 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.

In `@apps/admin/src/styles.css` around lines 1021 - 1031, Add a
prefers-reduced-motion rule to disable the shimmer animation for
motion-sensitive users: update the stylesheet to include a `@media`
(prefers-reduced-motion: reduce) block that targets .admin-row-skeleton and sets
animation: none (and optionally background-size or background-position static if
needed), so the admin-skeleton animation does not loop for users who prefer
reduced motion.

391-394: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

justify-content has no effect without display: flex or grid.

.admin-product-meta declares justify-content: end but isn't a flex or grid container, so the property is silently ignored. Either remove the property or add display: flex to make it functional.

🛠️ Example fix
 .admin-product-meta {
   min-width: 250px;
-  justify-content: end;
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
 }
🤖 Prompt for 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.

In `@apps/admin/src/styles.css` around lines 391 - 394, .admin-product-meta
currently sets justify-content: end but lacks a flex/grid container, so the
property is ignored; update the rule for .admin-product-meta to make it a flex
(or grid) container by adding display: flex (or display: grid) if the intent is
to align children, or remove justify-content: end if you don't want layout
changes — adjust the .admin-product-meta rule accordingly and verify child
alignment after making it a flex/grid container.

110-140: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add :focus-visible styles for keyboard accessibility.

The login inputs have clear :focus outlines (lines 1126–1130), but interactive controls like .admin-nav-item, .admin-sidebar-action, .admin-toolbar-button, and .admin-pagination-button only define :hover states. Without :focus-visible styling, keyboard users cannot tell which control currently has focus, which is an accessibility blocker for navigation and pagination.

🛠️ Suggested addition
.admin-nav-item:focus-visible,
.admin-sidebar-action:focus-visible,
.admin-toolbar-button:focus-visible,
.admin-pagination-button:focus-visible,
.admin-login-submit:focus-visible {
  outline: 3px solid rgba(38, 56, 42, 0.35);
  outline-offset: 2px;
}
🤖 Prompt for 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.

In `@apps/admin/src/styles.css` around lines 110 - 140, Add keyboard focus-visible
styles for interactive controls so keyboard users can see focus: add a
:focus-visible rule targeting .admin-nav-item, .admin-sidebar-action,
.admin-toolbar-button, .admin-pagination-button (and optionally
.admin-login-submit) that applies a visible outline (for example a 3px solid
rgba(38,56,42,0.35)) and an outline-offset (e.g., 2px); place this rule near the
existing hover/active rules for .admin-nav-item/.admin-sidebar-action so it
won't be overridden and ensure it uses :focus-visible (not :focus) to avoid
showing outlines on mouse interactions.

3-6: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Address Stylelint findings: unquote font family and lowercase keyword.

Stylelint flags two issues in the :root block: "Aptos" should be unquoted per the font-family-name-quotes rule, and optimizeLegibility should be lowercase per the value-keyword-case rule.

🛠️ Proposed fix
 :root {
   color: `#1f2520`;
-  font-family: "Aptos", "Segoe UI", sans-serif;
+  font-family: Aptos, "Segoe UI", sans-serif;
   background: `#eef1ea`;
   font-synthesis: none;
-  text-rendering: optimizeLegibility;
+  text-rendering: optimizelegibility;
 }
🤖 Prompt for 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.

In `@apps/admin/src/styles.css` around lines 3 - 6, In the :root block update the
font-family and text-rendering to satisfy Stylelint: remove the unnecessary
quotes around the custom family name in font-family (change "Aptos" to Aptos)
and make the text-rendering value lowercase (change optimizeLegibility to
optimizelegibility) so the font-family-name-quotes and value-keyword-case rules
pass; look for the font-family and text-rendering declarations shown in the diff
to apply these changes.
🤖 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/admin/Caddyfile`:
- Around line 14-18: Add a Content-Security-Policy and a Permissions-Policy into
the existing header block to harden the app; update the header { ... } section
(the header block shown in the Caddyfile) to include a Content-Security-Policy
header with conservative directives (e.g., default-src 'self'; script-src 'self'
'nonce-...'/trusted-cdns as needed; style-src 'self' 'unsafe-inline' only if
required; img-src 'self' data:; connect-src 'self' ...) and a Permissions-Policy
header that disables risky features by default (e.g., geolocation=(), camera=(),
microphone=(), fullscreen=(), payment=()). Adjust specific CSP directives and
allowed sources to match legitimate external resources used by the app.

In `@apps/admin/src/admin-order-detail-page.tsx`:
- Around line 158-164: The current useEffect uses a confusing double-negative
condition; replace the conditional in the effect so it reads positively: compute
firstTemplate from availableTemplates and then use if (!selectedTemplate &&
firstTemplate) setSelectedTemplate(firstTemplate). Update the condition inside
the useEffect that references availableTemplates, selectedTemplate,
setSelectedTemplate and firstTemplate to this clearer form.
- Line 2: The import for the Button component is using the wrong package; update
the import statement that currently reads import { Button } from
"`@techsio/ui-kit/atoms/button`" so it imports from the sanctioned library instead
(use "`@libs/ui/atoms/button`")—locate the Button import at the top of
admin-order-detail-page.tsx and replace the module specifier accordingly to
follow the project import guidelines.

In `@apps/admin/src/admin-packeta-labels-page.tsx`:
- Around line 1-2: The imports currently use the wrong package namespace; update
the Badge and Button imports to follow the repository convention by importing
from '`@libs/ui/atoms/badge`' and '`@libs/ui/atoms/button`' instead of
'`@techsio/ui-kit/atoms/`*' so change the import statements that reference Badge
and Button to use the '`@libs/ui/atoms/`...' paths.
- Line 349: Remove the redundant String() coercion around the displayed value
and render the numeric fields directly: replace the expression
String(label.data?.barcode ?? label.data?.packet_id) with label.data?.barcode ??
label.data?.packet_id in the JSX (in admin-packeta-labels-page.tsx), ensuring
the component displays the numeric value directly; if you have any TypeScript
complaints, narrow or assert the type where the value is read rather than
wrapping with String().

In `@apps/admin/src/admin-packeta-settings-page.tsx`:
- Line 2: The Button component import path violates the repo convention; update
the import in admin-packeta-settings-page.tsx to use the standard UI alias by
replacing the current module specifier with '`@libs/ui/atoms/button`' so it
follows the required pattern (import { Button } from '`@libs/ui/atoms/button`').

In `@apps/admin/src/admin-payload-settings-page.tsx`:
- Line 2: The import for the Button UI component uses the wrong package path;
update the import of Button in admin-payload-settings-page (the import statement
that currently references "`@techsio/ui-kit/atoms/button`") to follow the
repository convention by importing from "`@libs/ui/atoms/button`" so the component
import matches the prescribed pattern used across the codebase.
- Line 43: Replace the fixed 30s window.setTimeout(url) cleanup with
deterministic revocation: when you create the Blob URL (the url variable) and
open the popup, add a one-time cleanup that revokes url either when the popup
finishes navigating/loads or when the page unloads; also handle the popup being
closed by polling popup.closed and revoking immediately. Update the code that
currently calls window.setTimeout(() => URL.revokeObjectURL(url), 30_000) to
instead register a window.addEventListener('beforeunload', ...) { once: true }
to revoke url and revoke url as soon as the opened popup reports load/navigation
complete or is detected closed (use the popup reference created when opening the
window).

In `@apps/admin/src/admin-ppl-settings-page.tsx`:
- Line 2: The import for the Button component is using the wrong path; update
the import in admin-ppl-settings-page.tsx to follow the repo convention by
replacing the current `@techsio/ui-kit/atoms/button` import with
`@libs/ui/atoms/button` (i.e., import { Button } from '`@libs/ui/atoms/button`')
so the Button symbol is imported from the standardized UI atoms namespace.

In `@apps/admin/src/admin-product-detail-page.tsx`:
- Line 1: The import for the UI component Badge uses the wrong module path;
update the named import of Badge to follow the repo convention by changing its
module specifier to '`@libs/ui/atoms/badge`' (keep the existing named import and
usage of Badge intact, e.g., the import statement that currently reads import {
Badge } from "`@techsio/ui-kit/atoms/badge`" should be replaced with the
'`@libs/ui/atoms/badge`' specifier).

In `@apps/admin/src/admin-settings-page.tsx`:
- Line 2: The import of the Button component uses the wrong package; update the
import statement that references Button so it imports from
'`@libs/ui/atoms/button`' instead of '`@techsio/ui-kit/atoms/button`' (locate the
import line that names Button and replace the module specifier to comply with
the project's UI import pattern).

In `@apps/admin/src/styles.css`:
- Line 963: The font-family declaration currently quotes "SFMono-Regular" which
triggers Stylelint's font-family-name-quotes rule; update the font-family
declaration that reads font-family: "Cascadia Mono", "SFMono-Regular", Consolas,
monospace; by removing the quotes around SFMono-Regular (making it
SFMono-Regular) and apply the identical unquoting change to the other occurrence
of the same font-family declaration elsewhere in the file.

---

Duplicate comments:
In `@apps/admin/src/admin-api.ts`:
- Around line 346-353: has_next is computed after slicing so it will always be
false; instead compute has_next before slicing and respect result.countExact: if
result.countExact is false set has_next to true (unknown more results),
otherwise set has_next to (orders.length > ACTION_REQUIRED_LIST_LIMIT). Update
the return to compute the has_next value using the unsliced orders array
(referencing orders, ACTION_REQUIRED_LIST_LIMIT, and result.countExact), then
slice orders with orders.slice(0, ACTION_REQUIRED_LIST_LIMIT) for the orders
field.
- Around line 372-379: Compute has_next before slicing and rely on the original
customers length and result.countExact: set has_next = true if result.countExact
is false OR if customers.length > ACTION_REQUIRED_LIST_LIMIT, then slice
customers for the returned list; update the return object (keys count,
count_exact, customers, has_next, limit, offset) to use that computed has_next
instead of checking customers.length after slicing. Ensure you reference the
variables customers, ACTION_REQUIRED_LIST_LIMIT and result.countExact so the
logic is applied prior to customers.slice(...) in the same function.

In `@apps/admin/src/admin-app.tsx`:
- Line 2: The import path for the Badge UI component is using the old package
namespace; update the import in admin-app.tsx so the Badge symbol is imported
from the repository convention '`@libs/ui/atoms/badge`' (i.e., change the module
specifier for the existing Badge import to follow the pattern used for other UI
atoms).

In `@apps/admin/src/admin-pages.tsx`:
- Around line 1-2: Replace the incorrect imports of Badge and Button from
"`@techsio/ui-kit/atoms/`*" with the sanctioned package path "`@libs/ui/atoms/`*" in
admin-pages.tsx: locate the import statements that reference Badge and Button
and change them to import from '`@libs/ui/atoms/badge`' and
'`@libs/ui/atoms/button`' respectively so they follow the project's import
guideline for UI atoms.

In `@apps/admin/src/styles.css`:
- Around line 1021-1031: Add a prefers-reduced-motion rule to disable the
shimmer animation for motion-sensitive users: update the stylesheet to include a
`@media` (prefers-reduced-motion: reduce) block that targets .admin-row-skeleton
and sets animation: none (and optionally background-size or background-position
static if needed), so the admin-skeleton animation does not loop for users who
prefer reduced motion.
- Around line 391-394: .admin-product-meta currently sets justify-content: end
but lacks a flex/grid container, so the property is ignored; update the rule for
.admin-product-meta to make it a flex (or grid) container by adding display:
flex (or display: grid) if the intent is to align children, or remove
justify-content: end if you don't want layout changes — adjust the
.admin-product-meta rule accordingly and verify child alignment after making it
a flex/grid container.
- Around line 110-140: Add keyboard focus-visible styles for interactive
controls so keyboard users can see focus: add a :focus-visible rule targeting
.admin-nav-item, .admin-sidebar-action, .admin-toolbar-button,
.admin-pagination-button (and optionally .admin-login-submit) that applies a
visible outline (for example a 3px solid rgba(38,56,42,0.35)) and an
outline-offset (e.g., 2px); place this rule near the existing hover/active rules
for .admin-nav-item/.admin-sidebar-action so it won't be overridden and ensure
it uses :focus-visible (not :focus) to avoid showing outlines on mouse
interactions.
- Around line 3-6: In the :root block update the font-family and text-rendering
to satisfy Stylelint: remove the unnecessary quotes around the custom family
name in font-family (change "Aptos" to Aptos) and make the text-rendering value
lowercase (change optimizeLegibility to optimizelegibility) so the
font-family-name-quotes and value-keyword-case rules pass; look for the
font-family and text-rendering declarations shown in the diff to apply these
changes.
🪄 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: f6e774a1-4b70-49f7-a1a4-f6d8f2613502

📥 Commits

Reviewing files that changed from the base of the PR and between 68fdeb1 and 8b06e10.

📒 Files selected for processing (15)
  • apps/admin/Caddyfile
  • apps/admin/src/admin-api.ts
  • apps/admin/src/admin-app.tsx
  • apps/admin/src/admin-order-detail-page.tsx
  • apps/admin/src/admin-packeta-labels-page.tsx
  • apps/admin/src/admin-packeta-settings-page.tsx
  • apps/admin/src/admin-pages.tsx
  • apps/admin/src/admin-payload-settings-page.tsx
  • apps/admin/src/admin-ppl-settings-page.tsx
  • apps/admin/src/admin-product-detail-page.tsx
  • apps/admin/src/admin-settings-page.tsx
  • apps/admin/src/admin-types.ts
  • apps/admin/src/styles.css
  • docker/development/admin/Dockerfile
  • docs/admin-parity-roadmap.md
📜 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: Greptile Review
  • GitHub Check: main
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Kilo Code Review
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'

Files:

  • apps/admin/src/admin-packeta-labels-page.tsx
  • apps/admin/src/admin-product-detail-page.tsx
  • apps/admin/src/admin-app.tsx
  • apps/admin/src/admin-ppl-settings-page.tsx
  • apps/admin/src/admin-payload-settings-page.tsx
  • apps/admin/src/admin-packeta-settings-page.tsx
  • apps/admin/src/admin-order-detail-page.tsx
  • apps/admin/src/admin-types.ts
  • apps/admin/src/admin-settings-page.tsx
  • apps/admin/src/admin-api.ts
  • apps/admin/src/admin-pages.tsx
🧠 Learnings (3)
📚 Learning: 2026-05-07T22:45:20.745Z
Learnt from: BleedingDev
Repo: TechsioCZ/new-engine PR: 397
File: docker/development/medusa-be/Dockerfile:34-38
Timestamp: 2026-05-07T22:45:20.745Z
Learning: For pnpm-based monorepo Dockerfiles that run `pnpm fetch --frozen-lockfile`, ensure the `patches/` directory is copied into the image (e.g., `COPY patches ./patches`) before running `pnpm fetch`. pnpm’s `fetch` reads `patchedDependencies` from the lockfile/workspace configuration and will fail (e.g., `ERR_PNPM_PATCH_NOT_FOUND`) if patch files aren’t present yet—do not move the `COPY patches` step to after `pnpm fetch`.

Applied to files:

  • docker/development/admin/Dockerfile
📚 Learning: 2026-05-07T22:45:38.566Z
Learnt from: BleedingDev
Repo: TechsioCZ/new-engine PR: 397
File: docker/development/n1/Dockerfile:40-44
Timestamp: 2026-05-07T22:45:38.566Z
Learning: When building this repo in Docker, ensure the `patches/` directory is copied into the image (e.g., `COPY patches ./patches`) before running `pnpm fetch --frozen-lockfile`. `pnpm fetch` validates `patchedDependencies` patch file paths from `pnpm-workspace.yaml`/`package.json`, and if `./patches` doesn’t exist yet it will fail with `ERR_PNPM_PATCH_NOT_FOUND`. Place the `COPY patches` step before the `RUN pnpm fetch` step in the relevant service Dockerfiles; this ordering is intentional and should not be flagged as an unnecessary cache-busting change.

Applied to files:

  • docker/development/admin/Dockerfile
📚 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/admin/src/admin-packeta-labels-page.tsx
  • apps/admin/src/admin-product-detail-page.tsx
  • apps/admin/src/admin-app.tsx
  • apps/admin/src/admin-ppl-settings-page.tsx
  • apps/admin/src/admin-payload-settings-page.tsx
  • apps/admin/src/admin-packeta-settings-page.tsx
  • apps/admin/src/admin-order-detail-page.tsx
  • apps/admin/src/admin-settings-page.tsx
  • apps/admin/src/admin-pages.tsx
🪛 Checkov (3.2.529)
docker/development/admin/Dockerfile

[low] 1-51: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🪛 Hadolint (2.14.0)
docker/development/admin/Dockerfile

[warning] 7-7: Pin versions in apt get install. Instead of apt-get install <package> use apt-get install <package>=<version>

(DL3008)

🪛 LanguageTool
docs/admin-parity-roadmap.md

[grammar] ~154-~154: ‘one page’ is missing a hyphen.
Context: ... feature at a time | one route folder / one page slice | complete feature screen with te...

(STARS_AND_STEPS)


[grammar] ~168-~168: Do not use the singular ‘a’ before the plural noun ‘loads’.
Context: ... uses limit and offset. - Selecting a log loads /admin/email-logs/:id. - Empty/loadin...

(VB_A_JJ_NNS)


[misspelling] ~170-~170: Did you mean the verb “log in” instead of the noun ‘login’?
Context: ...shell. - Auth expiry still redirects to login. - `pnpm --dir apps/admin run typecheck...

(LOG_IN)


[style] ~178-~178: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...the old Medusa Admin as the final UX. - Do not edit medusa-be unless the fronten...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~179-~179: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ting endpoints and this is confirmed. - Do not migrate product metadata from `prod...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🪛 Stylelint (17.11.1)
apps/admin/src/styles.css

[error] 963-963: Expected no quotes around "SFMono-Regular" (font-family-name-quotes)

(font-family-name-quotes)


[error] 993-993: Expected no quotes around "SFMono-Regular" (font-family-name-quotes)

(font-family-name-quotes)

🪛 Trivy (0.69.3)
docker/development/admin/Dockerfile

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)

🔇 Additional comments (2)
docker/development/admin/Dockerfile (1)

29-32: ⚡ Quick win

docs(docker): explain why admin runs a second pnpm install after building @techsio/ui-kit (lines 29-32)

apps/admin/package.json depends on @techsio/ui-kit via workspace:*, and libs/ui/package.json exports its JS/types from dist/ (plus prepare runs pnpm build && pnpm build:storybook), so the explicit pnpm --filter=@techsio/ui-kit build before pnpm --filter=admin build is consistent. The extra pnpm install --filter=admin... after the ui-kit build is still unclear—add a short comment stating the specific reason (e.g., lifecycle hooks / pnpm injected deps refresh) or remove it if it’s redundant.

apps/admin/src/admin-types.ts (1)

1-460: LGTM!

Comment thread apps/admin/Caddyfile
Comment thread apps/admin/src/admin-order-detail-page.tsx Outdated
Comment thread apps/admin/src/admin-order-detail-page.tsx
Comment thread apps/admin/src/admin-packeta-labels-page.tsx Outdated
size="sm"
variant="info"
>
{String(label.data?.barcode ?? label.data?.packet_id)}

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.

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Redundant String() coercion.

The String() wrapper is unnecessary since barcode and packet_id are filtered to be numbers (line 371), and React will automatically convert numbers to strings for display.

♻️ Simplify
-                          {String(label.data?.barcode ?? label.data?.packet_id)}
+                          {label.data?.barcode ?? label.data?.packet_id}
📝 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
{String(label.data?.barcode ?? label.data?.packet_id)}
{label.data?.barcode ?? label.data?.packet_id}
🤖 Prompt for 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.

In `@apps/admin/src/admin-packeta-labels-page.tsx` at line 349, Remove the
redundant String() coercion around the displayed value and render the numeric
fields directly: replace the expression String(label.data?.barcode ??
label.data?.packet_id) with label.data?.barcode ?? label.data?.packet_id in the
JSX (in admin-packeta-labels-page.tsx), ensuring the component displays the
numeric value directly; if you have any TypeScript complaints, narrow or assert
the type where the value is read rather than wrapping with String().

Comment thread apps/admin/src/admin-payload-settings-page.tsx Outdated
@@ -0,0 +1,567 @@
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { Button } from "@techsio/ui-kit/atoms/button"

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 | ⚡ Quick win

Fix UI component import path to follow repository convention.

Line 2 imports Button from @techsio/ui-kit/atoms/button, but the coding guideline requires imports from @libs/ui/atoms/*.

♻️ Proposed fix
-import { Button } from "`@techsio/ui-kit/atoms/button`"
+import { Button } from "`@libs/ui/atoms/button`"

As per coding guidelines: **/*.{ts,tsx}: Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'.

📝 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
import { Button } from "@techsio/ui-kit/atoms/button"
import { Button } from "`@libs/ui/atoms/button`"
🤖 Prompt for 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.

In `@apps/admin/src/admin-ppl-settings-page.tsx` at line 2, The import for the
Button component is using the wrong path; update the import in
admin-ppl-settings-page.tsx to follow the repo convention by replacing the
current `@techsio/ui-kit/atoms/button` import with `@libs/ui/atoms/button`
(i.e., import { Button } from '`@libs/ui/atoms/button`') so the Button symbol is
imported from the standardized UI atoms namespace.

@@ -0,0 +1,337 @@
import { Badge } from "@techsio/ui-kit/atoms/badge"

@coderabbitai coderabbitai Bot May 21, 2026

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 | ⚡ Quick win

Fix UI component import path to follow repository convention.

Line 1 imports Badge from @techsio/ui-kit/atoms/badge, but the coding guideline requires imports from @libs/ui/atoms/*.

♻️ Proposed fix
-import { Badge } from "`@techsio/ui-kit/atoms/badge`"
+import { Badge } from "`@libs/ui/atoms/badge`"

As per coding guidelines: **/*.{ts,tsx}: Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'.

📝 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
import { Badge } from "@techsio/ui-kit/atoms/badge"
import { Badge } from "`@libs/ui/atoms/badge`"
🤖 Prompt for 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.

In `@apps/admin/src/admin-product-detail-page.tsx` at line 1, The import for the
UI component Badge uses the wrong module path; update the named import of Badge
to follow the repo convention by changing its module specifier to
'`@libs/ui/atoms/badge`' (keep the existing named import and usage of Badge
intact, e.g., the import statement that currently reads import { Badge } from
"`@techsio/ui-kit/atoms/badge`" should be replaced with the '`@libs/ui/atoms/badge`'
specifier).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Skipping for the same reason: @techsio/ui-kit is the runtime import contract for apps/admin. @libs/ui is only a source/guidance location unless we add and verify a dedicated app alias.

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.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@CodeRabbit no, its not humans having chat, its answer for you. Read it, analyse it and tell me where does this come from and what can/should we do to make this seamless for humans, coding agents and review agents.

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.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if .coderabbit.yaml exists and its contents
fd -i ".coderabbit.yaml" --max-depth 2
cat .coderabbit.yaml 2>/dev/null || echo "NOT FOUND"
# Also check for .coderabbit.yml
cat .coderabbit.yml 2>/dev/null || echo "NOT FOUND"

Length of output: 305



@BleedingDev — here's the full root-cause chain and a concrete fix.


Where it comes from

There is a general coding guideline scoped to **/*.{ts,tsx} that says:

Import UI components using @libs/ui/atoms/… or @libs/ui/molecules/….

There is no .coderabbit.yaml file in the repo, so there are no path-based instruction overrides. When the review runs against apps/admin/**, the general rule fires without any knowledge of the app-specific exception. My long-term memory learnings (fe6f849b, abf4661a) contain the correct rule, but a hard-coded general guideline can still surface in the same review pass and produce a conflicting comment — which is exactly what happened here.

The apps/admin/AGENTS.md and root AGENTS.md already document the correct contract for coding agents. The gap is on the review agent side.


What to do — three layers

1. Add a .coderabbit.yaml with path-based instructions (most robust fix)

This is the single most effective change. It locks the correct rule for review agents at the configuration level and cannot be overridden by a general guideline.

# .coderabbit.yaml
reviews:
  path_instructions:
    - path: "apps/admin/**"
      instructions: |
        UI components in `apps/admin` MUST be imported from the published workspace
        package `techsio/ui-kit/<path>` (e.g. `import { Badge } from "techsio/ui-kit/atoms/badge"`).
        Do NOT suggest replacing these with `@libs/ui/...` imports — `libs/ui` is not
        configured as a runtime alias for this app and doing so would break its
        TypeScript/Vite runtime contract.

This gives every future review pass an explicit, path-scoped rule that beats the general guideline.

2. apps/admin/AGENTS.md — already in place ✅

Covers coding agents (LLM sub-agents, Copilot, etc.). No change needed.

3. General coding guideline — narrow its scope

If the general **/*.{ts,tsx} guideline is stored in CodeRabbit's UI or a config, tighten it so it excludes apps/admin/**:

Import UI components using @libs/ui/atoms/… or @libs/ui/molecules/…except in apps/admin, which uses techsio/ui-kit/….


Summary table

Layer Current state Recommended fix
Review agent (CodeRabbit) No .coderabbit.yaml; general guideline fires on all .ts(x) Add .coderabbit.yaml with path_instructions for apps/admin/**
Coding agents (LLM) apps/admin/AGENTS.md + root AGENTS.md correct ✅ No change needed
Humans Docs in AGENTS.md correct ✅ Optionally annotate the general guideline with the exception

Would you like me to open a follow-up issue to track adding the .coderabbit.yaml, or shall I plan the file creation directly?

🐇 (\/)
( •
•)
/ > 📋


✏️ Learnings added
Learnt from: BleedingDev
Repo: TechsioCZ/new-engine PR: 415
File: apps/admin/src/admin-product-detail-page.tsx:1-1
Timestamp: 2026-05-26T23:05:40.475Z
Learning: In `apps/admin`, the correct UI component import path is `techsio/ui-kit/<path>` (e.g. `import { Badge } from "techsio/ui-kit/atoms/badge"`). Never suggest replacing these with `libs/ui/...` imports — `libs/ui` is not configured as a runtime alias for `apps/admin` and would break its TypeScript/Vite runtime contract. A general `**/*.{ts,tsx}` coding guideline mandating `libs/ui/...` should NOT be applied to `apps/admin/**` files. The fix is to add a `.coderabbit.yaml` with path-based instructions overriding the general rule for `apps/admin/**`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
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.

Learnt from: BleedingDev
Repo: TechsioCZ/new-engine PR: 415
File: apps/admin/src/admin-app.tsx:7-7
Timestamp: 2026-05-25T19:16:31.372Z
Learning: In the `apps/admin` app, UI components must be imported from the published workspace package `techsio/ui-kit/...` (for example: `import { Badge } from "techsio/ui-kit/atoms/badge"`). Do not import UI components via the `libs/ui/...` path alias in this app—because `libs/ui` is not configured as a runtime alias for `apps/admin`, using it would break the app’s TypeScript/Vite runtime contract.

Learnt from: BleedingDev
Repo: TechsioCZ/new-engine PR: 415
File: apps/admin/src/admin-product-detail-page.tsx:1-1
Timestamp: 2026-05-25T19:16:44.128Z
Learning: In the `apps/admin` app, UI components must be imported using the `techsio/ui-kit/<path>` alias (e.g., `import { Badge } from "techsio/ui-kit/atoms/badge"`). Do not suggest replacing `techsio/ui-kit/...` imports with `libs/ui/...` in `apps/admin` unless that specific alias is explicitly defined and verified for that project (via its config/build/CI).

Comment thread apps/admin/src/admin-settings-page.tsx Outdated
Comment thread apps/admin/src/styles.css Outdated

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

🤖 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/admin/AGENTS.md`:
- Around line 19-20: Replace the hard-coded machine-specific path
"C:/Users/pisez/.local/share/medusajs/medusa/packages/admin/dashboard/src" with
a user-agnostic pattern and provide OS-specific examples; for instance, change
the entry to use
"<home>/.local/share/medusajs/medusa/packages/admin/dashboard/src" and add
equivalent examples for Windows
("%USERPROFILE%\\.local\\share\\medusajs\\medusa\\packages\\admin\\dashboard\\src")
and macOS/Linux
("$HOME/.local/share/medusajs/medusa/packages/admin/dashboard/src") so teammates
on different systems can follow the doc without a brittle, user-specific path.
🪄 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: b3980b8e-31c6-42b3-8c25-93ce8dccc34e

📥 Commits

Reviewing files that changed from the base of the PR and between 8b06e10 and c141ecf.

📒 Files selected for processing (7)
  • apps/admin/AGENTS.md
  • apps/admin/src/admin-api.ts
  • apps/admin/src/admin-app.tsx
  • apps/admin/src/admin-order-detail-page.tsx
  • apps/admin/src/admin-pages.tsx
  • apps/admin/src/admin-types.ts
  • apps/admin/src/styles.css
📜 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). (2)
  • GitHub Check: Greptile Review
  • GitHub Check: Kilo Code Review
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'

Files:

  • apps/admin/src/admin-app.tsx
  • apps/admin/src/admin-pages.tsx
  • apps/admin/src/admin-order-detail-page.tsx
  • apps/admin/src/admin-types.ts
  • apps/admin/src/admin-api.ts
apps/admin/src/**/*.{ts,tsx}

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

Use @techsio/ui-kit / libs/ui first before adding custom UI primitives. Inspect UI kit skills before implementing new components.

Token-first approach: Component colors, borders, radius, spacing, typography, and states belong in token mappings or component variants. Use inline className mainly for local layout and composition.

Do not add redundant token overrides if the existing token chain already resolves to the desired value.

If a required visual state cannot be expressed through tokens or component API, treat it as a UI kit API gap. Add a short local workaround only if needed, and prefer a follow-up UI kit improvement.

Do not keep expanding one large file when a feature becomes multi-screen. Prefer src/features/<domain>/... for new substantial sections in the admin app.

Use React Query for server state in the admin app.

Use stable query keys that include filters and IDs in React Query calls.

Background refresh is acceptable for admin counters and dashboards. Prefer polling plus refetch-on-focus before introducing WebSockets or SSE.

Session/cookie auth must send credentials as required by Medusa Admin API. Do not store passwords or secrets in client code.

Files:

  • apps/admin/src/admin-app.tsx
  • apps/admin/src/admin-pages.tsx
  • apps/admin/src/admin-order-detail-page.tsx
  • apps/admin/src/admin-types.ts
  • apps/admin/src/admin-api.ts
apps/admin/src/**/*-api.ts

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

Keep raw HTTP integration in admin-api.ts or a clearly named feature API module.

Files:

  • apps/admin/src/admin-api.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Default write scope is `apps/admin`. Do not edit `apps/medusa-be` unless the current admin task proves that an existing Admin API or custom endpoint cannot support the required workflow.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: When a backend gap is found, document the exact missing endpoint, request/response shape, and user workflow first. Do not work around missing CORS, auth, or backend behavior with frontend hacks.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Treat deployed backend compatibility as a first-class constraint. The admin should work against `NEXT_PUBLIC_MEDUSA_BACKEND_URL` without requiring local backend changes for ordinary UI work.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Before implementing a Medusa admin feature, inspect existing `apps/admin` code, Official Medusa Admin API documentation, Official Medusa Admin development documentation, local Medusa dashboard source, custom admin routes, and repo-local Medusa skills in that priority order.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: When official docs, local Medusa dashboard source, and current project code disagree, preserve current project behavior unless the mismatch is a proven bug.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Admin UX should stay dense, operational, and scannable. Do not introduce marketing layouts, oversized hero sections, decorative cards, or broad visual redesigns while implementing workflow parity.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Keep page components focused on rendering, user interaction, and route state.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Shared contracts and normalized types must have one owner per change. Do not let multiple agents independently rewrite shared type surfaces.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Prefer existing Admin API list/detail endpoints before proposing backend aggregation endpoints.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Never add fake production data to make a screen look complete. Empty states must reflect real empty data.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: For each Medusa dashboard parity slice, identify the matching default Medusa dashboard route/component, Admin API endpoints, custom project endpoints, implement the smallest useful workflow in `apps/admin`, reuse `libs/ui` components, and add smoke verification notes.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Backend work is justified only when the Admin API cannot express the required mutation or read model, frontend scanning would be incorrect due to pagination/filtering limitations, a workflow must be atomic/audited/permission-checked server-side, or custom project integrations already expose backend semantics.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Use plan files for the admin that live in `apps/admin/local/agent-plans`. Use `plan-graph` with explicit dependency overlays; do not assume a pile of `.plan.md` files has an implicit execution order.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: For current-lane status use `dag` against plan selection and dependency overlay. Keep generated graph snapshots under `apps/admin/local/plan-graphs` as local-only files.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: For code changes in `apps/admin`, run `pnpm.cmd --dir apps/admin run typecheck`, `pnpm.cmd --dir apps/admin run build`, and `pnpm.cmd exec biome check --write <changed files>`.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: For user-facing workflow changes, smoke-test in a browser against the deployed backend when possible. Do not perform destructive admin actions against deployed data unless the user explicitly approves.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Keep commits aligned to one workflow slice or planning/documentation slice. Do not mix backend, UI kit, and admin app changes in one commit unless a single feature genuinely requires all three.
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-22T08:57:39.755Z
Learning: Ignore unrelated dirty files outside the active scope when committing.
📚 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/admin/src/admin-app.tsx
  • apps/admin/src/admin-pages.tsx
  • apps/admin/src/admin-order-detail-page.tsx
🪛 LanguageTool
apps/admin/AGENTS.md

[grammar] ~7-~7: There seems to be a noun/verb agreement error. Did you mean “writes” or “wrote”?
Context: ...libs/ui. ## Scope Default - Default write scope is apps/admin. - Do not edit `a...

(SINGULAR_NOUN_VERB_AGREEMENT)


[style] ~49-~49: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...in-rules.ts` or feature rule modules. - Keep page components focused on rendering, u...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[misspelling] ~50-~50: This word is normally spelled as one.
Context: ...g one large file when a feature becomes multi-screen. Prefer src/features/<domain>/... for...

(EN_COMPOUNDS_MULTI_SCREEN)

🪛 markdownlint-cli2 (0.22.1)
apps/admin/AGENTS.md

[warning] 115-115: Files should end with a single newline character

(MD047, single-trailing-newline)

🔇 Additional comments (3)
apps/admin/src/admin-app.tsx (1)

2-2: fix(admin-app): keep UI imports on the repository @libs/ui namespace

This remains unresolved from earlier feedback: Badge should be imported from @libs/ui/atoms/badge.
As per coding guidelines: **/*.{ts,tsx}: Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'.

apps/admin/src/admin-order-detail-page.tsx (1)

2-3: fix(admin-order-detail): use standard @libs/ui import paths

This remains unresolved from prior feedback: both Badge and Button imports should use @libs/ui/atoms/... paths.
As per coding guidelines: **/*.{ts,tsx}: Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'.

apps/admin/src/admin-pages.tsx (1)

1-2: fix(admin-pages): switch UI atom imports to @libs/ui

This is still open from earlier review feedback: Badge and Button should be imported from @libs/ui/atoms/....
As per coding guidelines: **/*.{ts,tsx}: Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'.

Comment thread apps/admin/AGENTS.md Outdated

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

Caution

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

⚠️ Outside diff range comments (7)
apps/admin/src/admin-ppl-settings-page.tsx (1)

484-486: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

fix(ppl): omit untouched secret fields from the payload

The form tells the operator that leaving an already-set secret blank preserves it, but this loop still sends "" for every untouched sensitive field. That can clear existing credentials or trigger validation errors on a normal save. Only send null for explicit clears, and omit blank untouched secrets.

♻️ Suggested fix
   for (const field of SENSITIVE_FIELDS) {
-    payload[field] = clearedFields.has(field) ? null : data[field].trim()
+    if (clearedFields.has(field)) {
+      payload[field] = null
+      continue
+    }
+
+    const value = data[field].trim()
+
+    if (value) {
+      payload[field] = value
+    }
   }
🤖 Prompt for 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.

In `@apps/admin/src/admin-ppl-settings-page.tsx` around lines 484 - 486, The loop
that assigns sensitive fields currently writes empty strings to payload which
can wipe or fail validation; update the logic in the block handling
SENSITIVE_FIELDS so that for each field you set payload[field] = null only when
clearedFields.has(field) is true, set payload[field] to the trimmed value when
data[field].trim() is non-empty, and otherwise omit adding the field to payload
(do not set it to ""), referencing SENSITIVE_FIELDS, payload, clearedFields, and
data to locate and modify the code.
apps/admin/src/admin-app.tsx (2)

72-82: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

fix(auth): clear React Query state when the session is invalidated

When useActionRequiredSummary fails with an auth error, this only drops the token flag. The existing admin query cache survives, so the next login can momentarily reuse the previous operator’s orders/customers/products because the cache keys are backend-scoped, not session-scoped.

♻️ Suggested fix
   useEffect(() => {
     if (summary.isError && isAuthError(summary.error)) {
+      queryClient.clear()
       clearStoredAdminToken()
       setIsAuthenticated(false)
     }
-  }, [summary.error, summary.isError])
+  }, [queryClient, summary.error, summary.isError])
 
-  async function handleAuthenticated() {
+  function handleAuthenticated() {
+    queryClient.clear()
     setIsAuthenticated(true)
-    await queryClient.invalidateQueries()
   }
🤖 Prompt for 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.

In `@apps/admin/src/admin-app.tsx` around lines 72 - 82, When an auth error is
detected in the useEffect (the block checking summary.isError &&
isAuthError(summary.error)), also clear React Query's cache so stale
session-scoped data is not reused; call the QueryClient methods (e.g.
queryClient.clear() or queryClient.removeQueries()/invalidateQueries() as
appropriate) in the same branch after clearStoredAdminToken() and
setIsAuthenticated(false). Update the effect to reference the same queryClient
used in handleAuthenticated so the cache is fully reset when the session is
invalidated.

389-390: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

fix(badges): suppress 0+ action badges

This still renders a badge for { count: 0, countExact: false }. The feature requirement says badges should be hidden at zero, so the render gate should stay tied to count > 0 and let formatCountLabel add the + only for positive inexact counts.

🤖 Prompt for 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.

In `@apps/admin/src/admin-app.tsx` around lines 389 - 390, The badge render gate
in shouldRenderBadge currently returns badge.count > 0 || !badge.countExact
which still shows a badge for {count: 0, countExact: false}; change
shouldRenderBadge to only return badge.count > 0 so zero counts are suppressed,
and leave formatCountLabel (or whatever label formatting function) to add the
trailing '+' for positive inexact counts; update any callers expecting the old
behaviour if necessary.
apps/admin/src/admin-order-detail-page.tsx (1)

716-730: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

fix(payments): make refund fallback keys unique

If both refund.id and payment.id are missing, every first refund falls back to the same key (refund-undefined-0). React can then reuse the wrong row across payments/collections. Include the parent fallback key in the refund fallback as well.

♻️ Suggested fix
-  const paymentRows = (collection.payments ?? []).flatMap((payment, index) => [
-    <PaymentRow
-      collection={collection}
-      fallbackCurrencyCode={fallbackCurrencyCode}
-      key={`payment-${payment.id ?? `${collectionId}-${index}`}`}
-      payment={payment}
-    />,
-    ...(payment.refunds ?? []).map((refund, refundIndex) => (
-      <RefundPaymentRow
-        collection={collection}
-        fallbackCurrencyCode={fallbackCurrencyCode}
-        key={`refund-${refund.id ?? `${payment.id}-${refundIndex}`}`}
-        payment={payment}
-        refund={refund}
-      />
-    )),
-  ])
+  const paymentRows = (collection.payments ?? []).flatMap((payment, index) => {
+    const paymentKey = payment.id ?? `${collectionId}-${index}`
+
+    return [
+      <PaymentRow
+        collection={collection}
+        fallbackCurrencyCode={fallbackCurrencyCode}
+        key={`payment-${paymentKey}`}
+        payment={payment}
+      />,
+      ...(payment.refunds ?? []).map((refund, refundIndex) => (
+        <RefundPaymentRow
+          collection={collection}
+          fallbackCurrencyCode={fallbackCurrencyCode}
+          key={`refund-${refund.id ?? `${paymentKey}-${refundIndex}`}`}
+          payment={payment}
+          refund={refund}
+        />
+      )),
+    ]
+  })
🤖 Prompt for 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.

In `@apps/admin/src/admin-order-detail-page.tsx` around lines 716 - 730, The
refund row key generation can collide when refund.id and payment.id are missing
(producing keys like "refund-undefined-0"), causing React to reuse wrong rows;
update the RefundPaymentRow key in the paymentRows array so its fallback
includes the parent payment/collection fallback (e.g., incorporate the same
fallback used for PaymentRow such as `${collectionId}-${index}` or
`${paymentFallback}`) in addition to the refundIndex to guarantee uniqueness;
locate the paymentRows mapping and change the RefundPaymentRow key expression to
combine refund.id || `<parent-fallback>` and payment.id || `<parent-fallback>`
(or reuse the computed payment fallback variable) so every refund key is unique
across payments/collections.
apps/admin/src/admin-packeta-labels-page.tsx (1)

373-382: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

fix(download): defer Blob URL cleanup until the save has started

Revoking the object URL in the same task can cancel the PDF download in WebKit and some Chromium paths because the browser has not consumed the URL yet. Delay the cleanup to a later tick.

♻️ Suggested fix
 function downloadBlob(blob: Blob, filename: string) {
   const url = URL.createObjectURL(blob)
   const anchor = document.createElement("a")
 
   anchor.href = url
   anchor.download = filename
   document.body.appendChild(anchor)
   anchor.click()
   anchor.remove()
-  URL.revokeObjectURL(url)
+  window.setTimeout(() => URL.revokeObjectURL(url), 0)
 }
🤖 Prompt for 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.

In `@apps/admin/src/admin-packeta-labels-page.tsx` around lines 373 - 382, The
downloadBlob function revokes the object URL immediately after anchor.click
which can abort downloads in some browsers; change it so that
URL.revokeObjectURL is deferred (e.g., call it inside a setTimeout(..., 0) or
requestAnimationFrame) after performing anchor.click and anchor.remove to ensure
the browser has begun the save before cleaning up the URL; update the
downloadBlob function (references: downloadBlob, anchor.click,
URL.revokeObjectURL) accordingly.
apps/admin/src/admin-packeta-settings-page.tsx (1)

511-513: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

fix(packeta): omit untouched secret fields from the payload

These fields are initialised to "", and the UI explicitly tells the operator to leave them blank to keep the current value. This loop still serialises every untouched sensitive field as an empty string, which can wipe an existing credential or fail validation on an otherwise harmless save. Only send null for explicit clears, and omit blank untouched secrets.

♻️ Suggested fix
   for (const field of SENSITIVE_FIELDS) {
-    payload[field] = clearedFields.has(field) ? null : data[field].trim()
+    if (clearedFields.has(field)) {
+      payload[field] = null
+      continue
+    }
+
+    const value = data[field].trim()
+
+    if (value) {
+      payload[field] = value
+    }
   }
🤖 Prompt for 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.

In `@apps/admin/src/admin-packeta-settings-page.tsx` around lines 511 - 513, The
loop is overwriting untouched secret fields with empty strings; change the logic
in the loop over SENSITIVE_FIELDS (the payload assignment using payload[field],
clearedFields, and data) so you only set payload[field] = null when
clearedFields.has(field) is true, set payload[field] = data[field].trim() only
when the trimmed value is non-empty, and otherwise omit the property entirely
(do not assign an empty string) so untouched secrets are not sent.
apps/admin/src/admin-payload-settings-page.tsx (1)

29-46: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

fix(payload): isolate fetched SSO HTML from the admin app origin

Both render paths currently execute backend-provided HTML with the admin app’s privileges: the popup navigates to a same-origin Blob URL and keeps window.opener, and the iframe uses srcDoc without a sandbox. A compromised SSO response can then reach the parent window and any token storage in the admin shell. Please sandbox the iframe and sever the popup opener before navigation.

♻️ Suggested direction
     try {
       const html = await fetchPayloadSsoHtml(returnTo)
       const url = URL.createObjectURL(
         new Blob([html], { type: "text/html;charset=utf-8" })
       )
 
+      popup.opener = null
       popup.location.href = url
       window.setTimeout(() => URL.revokeObjectURL(url), 30_000)
       setFeedback({
         message: "Payload Admin se otevira v novem tabu.",
         tone: "success",
@@
   return (
     <iframe
       className="block min-h-admin-payload-frame w-full border-0 bg-base-reverse"
+      sandbox="allow-forms allow-scripts"
       srcDoc={html}
       title="Payload Admin"
     />
   )
 }

Also applies to: 161-166

🤖 Prompt for 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.

In `@apps/admin/src/admin-payload-settings-page.tsx` around lines 29 - 46, The
fetched SSO HTML is being executed in the admin app origin (via Blob URL and
srcDoc) and the popup keeps window.opener; fix by severing the opener and
sandboxing the iframe: after opening the popup (popup = window.open(...))
immediately set popup.opener = null (and/or use the "noopener" feature) before
calling URL.createObjectURL and navigation, and for the iframe path stop using
srcDoc and instead load the HTML into a Blob URL and set the iframe element’s
sandbox attribute (e.g., sandbox="" or sandbox="allow-scripts" only if
necessary) so it cannot access parent/opener; keep using
URL.revokeObjectURL(url) as before to cleanup.
🤖 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 `@AGENTS.md`:
- Around line 139-143: Add blank lines before and after the fenced TypeScript
example block in AGENTS.md to satisfy markdownlint MD031; specifically ensure
there is an empty line above the opening ```typescript fence and an empty line
after the closing ``` fence that encloses the import lines for Button and Dialog
(the lines containing "import { Button } from '`@techsio/ui-kit/atoms/button`'"
and "import { Dialog } from '`@techsio/ui-kit/molecules/dialog`'"), so the fenced
block is separated from surrounding text.

In `@apps/admin/scripts/validate-token-usage.mjs`:
- Around line 352-368: stripVariants currently only removes leading '!' but
should also support trailing '!' (e.g., "text-sm!") as introduced by Tailwind
v4; update stripVariants (which calls findTopLevelColon) to strip both leading
and trailing '!' characters before/while parsing variants—either by trimming
trailing '!' in the same loop that slices leading '!' or by normalizing
baseClass with a step that removes trailing '!' characters—then continue finding
the top-level colon and slicing as before so behavior for variant parsing
remains unchanged.

In `@apps/admin/src/admin-store-settings-page.tsx`:
- Around line 307-313: The current code collapses missing
preference?.is_tax_inclusive to false via Boolean(preference?.is_tax_inclusive),
so unknown data is displayed as "False"; change the logic in the render around
isTaxInclusive to explicitly check for undefined (e.g.,
preference?.is_tax_inclusive === undefined) and render a neutral fallback Badge
(like "Unknown" or "—" with a muted/outline variant) when absent, otherwise
render the confirmed True/False based on the actual boolean value; update
references to isTaxInclusive and preference?.is_tax_inclusive and adjust the
Badge variant/text accordingly.

In `@apps/admin/src/components/admin-pagination.tsx`:
- Around line 50-51: The computed page value (const page = Math.floor(offset /
pageSize) + 1) can become 0, negative or NaN when offset or pageSize are
invalid—normalize it before passing to Pagination: compute the raw page, coerce
to a finite integer, and clamp to a minimum of 1 (e.g., use Math.floor and then
if the result is not finite or < 1 set page = 1); update the code around the
page calculation (the page constant used for the Pagination component) so
Pagination always receives a positive integer.

In `@apps/admin/src/components/admin-preview.tsx`:
- Around line 58-69: AdminPreviewFrame renders an iframe with no sandbox or
referrerPolicy defaults; add secure defaults by passing a conservative sandbox
(e.g., empty string for full sandboxing) and referrerPolicy="no-referrer" on the
rendered <iframe> and ensure these defaults are applied only when not overridden
via props (check props.sandbox and props.referrerPolicy), so update the
AdminPreviewFrame component to set sandbox and referrerPolicy defaults while
still allowing callers to override them.

In `@apps/admin/src/components/admin-select-field.tsx`:
- Around line 42-48: The onValueChange handler in AdminSelectField currently
only calls the parent onValueChange when details.value[0] is truthy, so a
cleared selection (details.value === []) is never propagated; update the handler
in AdminSelectField to detect an empty details.value and call the parent
onValueChange with a cleared sentinel (e.g., undefined or null) — e.g., compute
const nextValue = details.value[0]; if (nextValue) onValueChange(nextValue);
else onValueChange(undefined) — so the controlled value is updated when the
select is cleared.

In `@apps/admin/src/components/admin-theme-toggle.tsx`:
- Around line 10-23: The theme toggle Switch is icon-only and lacks an
accessible name; update the Switch (the component rendering checked={isDark} and
onCheckedChange calling setPreference) to include an accessible label—either add
an aria-label that reflects the action (e.g., toggles between dark/light and
uses isDark to set the string) or add visually-visible label text (or a
visually-hidden span) associated with the Switch so screen readers get a
meaningful name like "Switch to dark theme" / "Switch to light theme".

In `@apps/admin/src/styles/tokens/_admin-icons.css`:
- Around line 6-9: The CSS icon size tokens are mis-mapped: --text-icon-md
currently points to --text-xl and --text-icon-lg/--text-icon-xl/--text-icon-2xl
all collapse to --text-2xl; update the variable assignments so each icon token
maps to the corresponding text size (e.g., --text-icon-md → --text-md,
--text-icon-lg → --text-lg, --text-icon-xl → --text-xl, --text-icon-2xl →
--text-2xl) to restore a proper scale; make this change in the block that
defines --text-icon-md, --text-icon-lg, --text-icon-xl, and --text-icon-2xl.

In `@apps/admin/src/styles/tokens/index.css`:
- Around line 14-16: Stylelint will flag Tailwind v4 at-rules like `@plugin`,
`@source` and token-specific `@theme` static used in tokens/index.css; update the
Stylelint config (.stylelintrc.json) to either disable the SCSS at-rule check
("scss/at-rule-no-unknown": null/false) or add these names to "ignoreAtRules"
(include "plugin", "source", "theme" — and any other Tailwind-specific at-rules
you use) so Stylelint no longer reports them as unknown.

In `@apps/admin/src/utils/format.ts`:
- Around line 54-57: The currency code passed into formatMoney (currencyCode /
function formatMoney in apps/admin/src/utils/format.ts) is not validated and can
cause Intl.NumberFormat to throw RangeError; before creating Intl.NumberFormat,
normalise currencyCode to a 3-letter uppercase ISO-like value (e.g. if typeof
currencyCode === "string" and matches /^[A-Za-z]{3}$/ then use
currencyCode.toUpperCase()) otherwise fallback to "CZK"; then pass that
validated/normalised value into the NumberFormat constructor so invalid or
non-ISO inputs cannot break the UI.
- Around line 9-14: The runtime treats empty string as falsy so formatCompactId
returns null even when called with a string, breaking the overload contract;
update the guard in formatCompactId (the implementation of function
formatCompactId) to only treat null/undefined as absent (e.g., use value == null
or value === null || value === undefined) so that an empty string input is
preserved and the function returns a string for the string overload as declared.

---

Outside diff comments:
In `@apps/admin/src/admin-app.tsx`:
- Around line 72-82: When an auth error is detected in the useEffect (the block
checking summary.isError && isAuthError(summary.error)), also clear React
Query's cache so stale session-scoped data is not reused; call the QueryClient
methods (e.g. queryClient.clear() or
queryClient.removeQueries()/invalidateQueries() as appropriate) in the same
branch after clearStoredAdminToken() and setIsAuthenticated(false). Update the
effect to reference the same queryClient used in handleAuthenticated so the
cache is fully reset when the session is invalidated.
- Around line 389-390: The badge render gate in shouldRenderBadge currently
returns badge.count > 0 || !badge.countExact which still shows a badge for
{count: 0, countExact: false}; change shouldRenderBadge to only return
badge.count > 0 so zero counts are suppressed, and leave formatCountLabel (or
whatever label formatting function) to add the trailing '+' for positive inexact
counts; update any callers expecting the old behaviour if necessary.

In `@apps/admin/src/admin-order-detail-page.tsx`:
- Around line 716-730: The refund row key generation can collide when refund.id
and payment.id are missing (producing keys like "refund-undefined-0"), causing
React to reuse wrong rows; update the RefundPaymentRow key in the paymentRows
array so its fallback includes the parent payment/collection fallback (e.g.,
incorporate the same fallback used for PaymentRow such as
`${collectionId}-${index}` or `${paymentFallback}`) in addition to the
refundIndex to guarantee uniqueness; locate the paymentRows mapping and change
the RefundPaymentRow key expression to combine refund.id || `<parent-fallback>`
and payment.id || `<parent-fallback>` (or reuse the computed payment fallback
variable) so every refund key is unique across payments/collections.

In `@apps/admin/src/admin-packeta-labels-page.tsx`:
- Around line 373-382: The downloadBlob function revokes the object URL
immediately after anchor.click which can abort downloads in some browsers;
change it so that URL.revokeObjectURL is deferred (e.g., call it inside a
setTimeout(..., 0) or requestAnimationFrame) after performing anchor.click and
anchor.remove to ensure the browser has begun the save before cleaning up the
URL; update the downloadBlob function (references: downloadBlob, anchor.click,
URL.revokeObjectURL) accordingly.

In `@apps/admin/src/admin-packeta-settings-page.tsx`:
- Around line 511-513: The loop is overwriting untouched secret fields with
empty strings; change the logic in the loop over SENSITIVE_FIELDS (the payload
assignment using payload[field], clearedFields, and data) so you only set
payload[field] = null when clearedFields.has(field) is true, set payload[field]
= data[field].trim() only when the trimmed value is non-empty, and otherwise
omit the property entirely (do not assign an empty string) so untouched secrets
are not sent.

In `@apps/admin/src/admin-payload-settings-page.tsx`:
- Around line 29-46: The fetched SSO HTML is being executed in the admin app
origin (via Blob URL and srcDoc) and the popup keeps window.opener; fix by
severing the opener and sandboxing the iframe: after opening the popup (popup =
window.open(...)) immediately set popup.opener = null (and/or use the "noopener"
feature) before calling URL.createObjectURL and navigation, and for the iframe
path stop using srcDoc and instead load the HTML into a Blob URL and set the
iframe element’s sandbox attribute (e.g., sandbox="" or sandbox="allow-scripts"
only if necessary) so it cannot access parent/opener; keep using
URL.revokeObjectURL(url) as before to cleanup.

In `@apps/admin/src/admin-ppl-settings-page.tsx`:
- Around line 484-486: The loop that assigns sensitive fields currently writes
empty strings to payload which can wipe or fail validation; update the logic in
the block handling SENSITIVE_FIELDS so that for each field you set
payload[field] = null only when clearedFields.has(field) is true, set
payload[field] to the trimmed value when data[field].trim() is non-empty, and
otherwise omit adding the field to payload (do not set it to ""), referencing
SENSITIVE_FIELDS, payload, clearedFields, and data to locate and modify the
code.
🪄 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: e6db6b4e-e074-447d-ba08-8b0fb77ab121

📥 Commits

Reviewing files that changed from the base of the PR and between c141ecf and e20f901.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (64)
  • AGENTS.md
  • apps/admin/AGENTS.md
  • apps/admin/index.html
  • apps/admin/package.json
  • apps/admin/postcss.config.js
  • apps/admin/scripts/validate-token-usage.mjs
  • apps/admin/scripts/validate-ui-primitives.mjs
  • apps/admin/src/admin-api.ts
  • apps/admin/src/admin-app.tsx
  • apps/admin/src/admin-login-page.tsx
  • apps/admin/src/admin-order-detail-page.tsx
  • apps/admin/src/admin-packeta-labels-page.tsx
  • apps/admin/src/admin-packeta-settings-page.tsx
  • apps/admin/src/admin-pages.tsx
  • apps/admin/src/admin-payload-settings-page.tsx
  • apps/admin/src/admin-ppl-settings-page.tsx
  • apps/admin/src/admin-product-detail-page.tsx
  • apps/admin/src/admin-settings-page.tsx
  • apps/admin/src/admin-store-settings-page.tsx
  • apps/admin/src/admin-types.ts
  • apps/admin/src/components/admin-detail-field.tsx
  • apps/admin/src/components/admin-entity.tsx
  • apps/admin/src/components/admin-feedback.tsx
  • apps/admin/src/components/admin-form-input.tsx
  • apps/admin/src/components/admin-info-list.tsx
  • apps/admin/src/components/admin-link-card.tsx
  • apps/admin/src/components/admin-link.tsx
  • apps/admin/src/components/admin-list.tsx
  • apps/admin/src/components/admin-media.tsx
  • apps/admin/src/components/admin-page-header.tsx
  • apps/admin/src/components/admin-pagination.tsx
  • apps/admin/src/components/admin-panel-header.tsx
  • apps/admin/src/components/admin-panel.tsx
  • apps/admin/src/components/admin-placeholder.tsx
  • apps/admin/src/components/admin-preview.tsx
  • apps/admin/src/components/admin-search.tsx
  • apps/admin/src/components/admin-select-field.tsx
  • apps/admin/src/components/admin-settings-form.tsx
  • apps/admin/src/components/admin-state.tsx
  • apps/admin/src/components/admin-summary-list.tsx
  • apps/admin/src/components/admin-table.tsx
  • apps/admin/src/components/admin-text-field.tsx
  • apps/admin/src/components/admin-theme-toggle.tsx
  • apps/admin/src/components/admin-toolbar-button.tsx
  • apps/admin/src/hooks/use-admin-theme.ts
  • apps/admin/src/styles.css
  • apps/admin/src/styles/tokens/_admin-base.css
  • apps/admin/src/styles/tokens/_admin-colors.css
  • apps/admin/src/styles/tokens/_admin-icons.css
  • apps/admin/src/styles/tokens/_admin-layout.css
  • apps/admin/src/styles/tokens/_admin-semantic.css
  • apps/admin/src/styles/tokens/_admin-spacing.css
  • apps/admin/src/styles/tokens/_admin-typography.css
  • apps/admin/src/styles/tokens/components/_admin-form-control.css
  • apps/admin/src/styles/tokens/components/atoms/_admin-badge.css
  • apps/admin/src/styles/tokens/components/atoms/_admin-button.css
  • apps/admin/src/styles/tokens/components/atoms/_admin-checkbox.css
  • apps/admin/src/styles/tokens/components/atoms/_admin-input.css
  • apps/admin/src/styles/tokens/components/components.css
  • apps/admin/src/styles/tokens/components/molecules/_admin-search.css
  • apps/admin/src/styles/tokens/index.css
  • apps/admin/src/utils/cx.ts
  • apps/admin/src/utils/format.ts
  • apps/admin/src/utils/theme.ts

Comment thread AGENTS.md
Comment thread apps/admin/scripts/validate-token-usage.mjs
Comment thread apps/admin/src/admin-store-settings-page.tsx Outdated
Comment thread apps/admin/src/components/admin-pagination.tsx Outdated
Comment thread apps/admin/src/components/admin-preview.tsx
Comment thread apps/admin/src/components/admin-theme-toggle.tsx
Comment thread apps/admin/src/styles/tokens/_admin-icons.css
Comment thread apps/admin/src/styles/tokens/index.css
Comment thread apps/admin/src/utils/format.ts
Comment thread apps/admin/src/utils/format.ts

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

Caution

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

⚠️ Outside diff range comments (1)
docker/development/admin/Dockerfile (1)

48-49: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Healthcheck will fail: wget not available in Alpine.

The caddy:2-alpine base image does not include wget by default, so the healthcheck command will fail with wget: not found. This prevents container orchestrators from properly monitoring the admin service.

🔧 Proposed fix to install wget for healthcheck

Option 1: Install wget in the prod stage (preferred for minimal footprint)

 FROM caddy:2-alpine AS prod
 
+RUN apk add --no-cache wget
+
 COPY apps/admin/Caddyfile /etc/caddy/Caddyfile
 COPY --from=build /var/www/apps/admin/dist /srv/admin

Option 2: Use curl instead (if already planning to use curl elsewhere)

 FROM caddy:2-alpine AS prod
 
+RUN apk add --no-cache curl
+
 COPY apps/admin/Caddyfile /etc/caddy/Caddyfile
 COPY --from=build /var/www/apps/admin/dist /srv/admin
 
 EXPOSE 3000
 
 HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
-    CMD wget -qO- http://localhost:3000/healthz || exit 1
+    CMD curl -f http://localhost:3000/healthz || exit 1
🤖 Prompt for 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.

In `@docker/development/admin/Dockerfile` around lines 48 - 49, The HEALTHCHECK
uses wget which is not present in the caddy:2-alpine base image, causing health
probes to always fail; to fix, either install wget (e.g., add apk add --no-cache
wget in the production stage before the HEALTHCHECK) or change the HEALTHCHECK
to use a tool already present (or install curl and use curl -fsS) and update the
HEALTHCHECK CMD accordingly (refer to the HEALTHCHECK line that currently runs
`CMD wget -qO- http://localhost:3000/healthz || exit 1`).
🤖 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 `@docker/development/admin/Dockerfile`:
- Around line 29-32: The Dockerfile currently runs pnpm install
--filter=admin... twice around the pnpm --filter=`@techsio/ui-kit` build, which is
redundant; remove the second pnpm install invocation so the RUN sequence becomes
a single pnpm install --store-dir=/pnpm/store --prefer-offline --frozen-lockfile
--filter=admin... followed by pnpm --filter=`@techsio/ui-kit` build and then the
admin build step, ensuring workspace deps are installed once and `@techsio/ui-kit`
is built afterwards.

---

Outside diff comments:
In `@docker/development/admin/Dockerfile`:
- Around line 48-49: The HEALTHCHECK uses wget which is not present in the
caddy:2-alpine base image, causing health probes to always fail; to fix, either
install wget (e.g., add apk add --no-cache wget in the production stage before
the HEALTHCHECK) or change the HEALTHCHECK to use a tool already present (or
install curl and use curl -fsS) and update the HEALTHCHECK CMD accordingly
(refer to the HEALTHCHECK line that currently runs `CMD wget -qO-
http://localhost:3000/healthz || exit 1`).
🪄 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: 21f82c71-6c2e-4011-b575-08939f62637f

📥 Commits

Reviewing files that changed from the base of the PR and between e20f901 and e0f0a55.

📒 Files selected for processing (1)
  • docker/development/admin/Dockerfile
📜 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). (1)
  • GitHub Check: Greptile Review
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:19.981Z
Learning: Use pnpm as the package manager for the workspace; always use CLI commands (pnpm add, pnpm add -D, pnpm add -w) and never edit package.json directly
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:19.981Z
Learning: Use Biome for linting and formatting code; run Biome only on changed files or paths using the command: bunx biome check --write path/to/file
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:19.981Z
Learning: Use Nx as the build orchestrator for monorepo builds and development workflows; leverage Nx utilities like nx graph, nx affected:build, and nx affected:test
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:19.981Z
Learning: Use RSLib for building shared library projects
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:19.981Z
Learning: Assume the development server is already running on http://localhost:3000 for the frontend demo; never ask to run pnpm dev or check if the dev server is running
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Default write scope is `apps/admin`; treat `libs/ui` as read-only unless the user explicitly widens scope to shared UI-kit authoring
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: If admin usage exposes a UI-kit API gap, document the gap and solve the current slice inside `apps/admin` with a small adapter or bounded workaround; shared `libs/ui` changes belong in a separate task
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Do not edit `apps/medusa-be` unless the current admin task proves that an existing Admin API or custom endpoint cannot support the required workflow
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Treat deployed backend compatibility as a first-class constraint; the admin should work against `NEXT_PUBLIC_MEDUSA_BACKEND_URL` without requiring local backend changes for ordinary UI work
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Before implementing a Medusa admin feature, inspect existing code, official Medusa Admin API docs, official development docs, local Medusa dashboard source, backend custom routes, and repo-local Medusa skills in that order
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: When official docs, local Medusa dashboard source, and current project code disagree, preserve current project behavior unless the mismatch is a proven bug
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Use `techsio/ui-kit` / `libs/ui` first; before adding custom UI primitives, inspect the local UI-kit adoption skills
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Do not rewrite app imports to `libs/ui/...` unless the same change also adds and verifies the package/export/TypeScript/Vite alias contract
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: If a required visual state cannot be expressed through tokens or component API, treat it as a UI kit API gap; add a short local workaround only if needed, and prefer a follow-up UI kit improvement
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Before overriding an existing token, inspect the matching chain under `libs/ui/src/tokens` and preserve the library contract
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: If an app token intentionally remaps an existing UI kit primitive, make that remap explicit in the broadest matching file before touching component token files
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Admin app-only layout tokens may use the `--*-admin-*` namespace; do not add `--*-admin-*` aliases as a substitute for existing UI kit semantic/component tokens
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: In the early admin-design phase, duplicate the relevant UI kit contract tokens explicitly even when values currently match library defaults to keep the admin theme inspectable
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Admin UX should stay dense, operational, and scannable; do not introduce marketing layouts, oversized hero sections, decorative cards, or broad visual redesigns while implementing workflow parity
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Keep page components focused on rendering, user interaction, and route state
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Keep business labels, rules, and API calls in the page or feature module; do not include them in domain-neutral component adapters
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Shared contracts and normalized types must have one owner per change; do not let multiple agents independently rewrite shared type surfaces
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Prefer existing Admin API list/detail endpoints before proposing backend aggregation endpoints
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Background refresh is acceptable for admin counters and dashboards; prefer polling plus refetch-on-focus before introducing WebSockets or SSE
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Session/cookie auth must send credentials as required by Medusa Admin API; do not store passwords or secrets in client code
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Never add fake production data to make a screen look complete; empty states must reflect real empty data
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: For each Medusa dashboard parity slice, identify the matching Medusa dashboard route/component, identify Admin API endpoints, check for custom endpoints, implement the smallest useful workflow, and reuse UI-kit components and existing admin layout patterns
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Backend work is justified only when the current Admin API cannot express the required mutation, frontend scanning would be incorrect, the workflow must be atomic/audited/permission-checked server-side, or a custom project integration exposes backend semantics
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: For code changes in `apps/admin`, run typecheck, build, validate:ui-primitives when adding/changing JSX controls, and validate:token-usage when changing Tailwind classes or token files
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Keep commits aligned to one workflow slice or planning/documentation slice; do not mix backend, UI kit, and admin app changes in one commit unless a single feature genuinely requires all three
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-25T11:23:55.991Z
Learning: Do not perform destructive admin actions against deployed data unless the user explicitly approves that action
📚 Learning: 2026-05-07T22:45:20.745Z
Learnt from: BleedingDev
Repo: TechsioCZ/new-engine PR: 397
File: docker/development/medusa-be/Dockerfile:34-38
Timestamp: 2026-05-07T22:45:20.745Z
Learning: For pnpm-based monorepo Dockerfiles that run `pnpm fetch --frozen-lockfile`, ensure the `patches/` directory is copied into the image (e.g., `COPY patches ./patches`) before running `pnpm fetch`. pnpm’s `fetch` reads `patchedDependencies` from the lockfile/workspace configuration and will fail (e.g., `ERR_PNPM_PATCH_NOT_FOUND`) if patch files aren’t present yet—do not move the `COPY patches` step to after `pnpm fetch`.

Applied to files:

  • docker/development/admin/Dockerfile
📚 Learning: 2026-05-07T22:45:38.566Z
Learnt from: BleedingDev
Repo: TechsioCZ/new-engine PR: 397
File: docker/development/n1/Dockerfile:40-44
Timestamp: 2026-05-07T22:45:38.566Z
Learning: When building this repo in Docker, ensure the `patches/` directory is copied into the image (e.g., `COPY patches ./patches`) before running `pnpm fetch --frozen-lockfile`. `pnpm fetch` validates `patchedDependencies` patch file paths from `pnpm-workspace.yaml`/`package.json`, and if `./patches` doesn’t exist yet it will fail with `ERR_PNPM_PATCH_NOT_FOUND`. Place the `COPY patches` step before the `RUN pnpm fetch` step in the relevant service Dockerfiles; this ordering is intentional and should not be flagged as an unnecessary cache-busting change.

Applied to files:

  • docker/development/admin/Dockerfile
🔇 Additional comments (8)
docker/development/admin/Dockerfile (8)

1-6: LGTM!


12-12: LGTM!


14-23: LGTM!


25-27: LGTM!


34-39: LGTM!


41-47: LGTM!


51-51: LGTM!


7-10: 💤 Low value

Confirm the corepack@0.34.5 pin is intentional and compatible with pnpm@10.30.0.

  • corepack@0.34.5 is a published corepack release (it sits within the 0.34.4–0.34.7 stable patch range), so the pin isn’t entirely arbitrary.
  • Please still ensure corepack enable with 0.34.5 works with the workspace’s pnpm@10.30.0 constraint (e.g., packageManager/lockfile settings) and document why this exact patch version is required.

Comment thread docker/development/admin/Dockerfile
Comment thread apps/admin/src/admin-api.ts
@TechsioCZ TechsioCZ deleted a comment from BleedingDev May 25, 2026
@TechsioCZ TechsioCZ deleted a comment from coderabbitai Bot May 25, 2026
@TechsioCZ TechsioCZ deleted a comment from BleedingDev May 25, 2026
@TechsioCZ TechsioCZ deleted a comment from coderabbitai Bot May 25, 2026
Comment on lines +61 to +70
const printableOrderIds = useMemo(
() =>
currentOrders
.filter((order) => getPacketaLabels(order).length > 0)
.map((order) => order.id),
[currentOrders]
)
const selectedPrintableOrderIds = [...selectedOrderIds].filter((orderId) =>
printableOrderIds.includes(orderId)
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Stale cross-page selections silently dropped from download

selectedPrintableOrderIds is filtered against printableOrderIds, which contains only the current page's printable orders. If a user selects orders on page 1, paginates to page 2, selects more orders, then clicks "Stahnout PDF", only page 2's selections are downloaded — the page 1 selections remain in selectedOrderIds state but never reach downloadPacketaLabels. Meanwhile the "vybrano" counter shows 0 on page 2, which makes it seem like the cross-page state was lost, even though it re-appears when navigating back.

The fix is to clear selectedOrderIds whenever the page offset changes (pass a setSelectedOrderIds reset to AdminPagination's onPageChange), or document that selection is page-scoped in the UI.

Fix in Codex

@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Resolving — my earlier suggestion was incorrect. The @techsio/ui-kit/atoms/... import path is the correct convention for apps/admin; the @libs/ui/... alias is not configured for this app. No change needed.

@BleedingDev

Copy link
Copy Markdown
Collaborator

@KaiUweCZE please fix conflicts and merge current upstream master, so that I can merge it and we can continue building on top of this branch. :)

Comment thread apps/admin/src/admin-api.ts

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

🤖 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/admin/agent-plans/admin-05-products-workflow-parity.plan.md`:
- Around line 1-18: Add a plan-graph metadata block to the "Admin 05 - Products
Workflow Parity" plan that explicitly declares dependency overlays linking the
todo nodes (product-source-map, detail-completeness, basic-edit, complex-edit)
so execution order is deterministic; for example, make product-source-map a
prerequisite for detail-completeness, and detail-completeness a prerequisite for
basic-edit and complex-edit, and include this overlay in the plan's front-matter
under a plan-graph key (matching the existing todo ids) so graph generation uses
the explicit edges instead of inferring order from narrative text.

In `@apps/admin/agent-plans/admin-09-catalog-taxonomy-workflow.plan.md`:
- Line 27: In the execution note for the top-level catalog workflow identified
by "/app/categories" update the duplicated phrase "product detail detail" to
"product detail" so the workflow description reads clearly and professionally;
locate the string "product detail detail" in
admin-09-catalog-taxonomy-workflow.plan.md and replace it with "product detail".

In `@apps/admin/agent-plans/README.md`:
- Around line 10-11: The README command references non-canonical paths
(apps\admin\local\agent-plans and implied snapshots) so update the CLI examples
to use the canonical directories: replace any occurrence of
"apps\admin\local\agent-plans" with "apps\admin\agent-plans" and ensure
generated/graph targets point to "apps\admin\plan-graphs" (e.g., in the python
.codex\skills\plan-graph\scripts\plan_graph.py validate example where
--plans-root and any snapshot/graph output globs are specified); keep the rest
of the command arguments (like --glob and --depends) unchanged.

In
`@apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-11b20afb05/snapshot.json`:
- Around line 8-22: The snapshot file (snapshot.json) contains
workstation-specific absolute paths in "plans_root" and "selected_plan_paths"
and reports unresolved/orphan dependency state; regenerate a clean,
promotion-ready snapshot using repo-relative plan inputs and explicit overlays
(so "plans_root" and all paths are relative), resolve any graph errors/warnings
until the snapshot's errors/warnings arrays are empty, and replace the broken
snapshot in apps/admin/plan-graphs with the cleaned file; check the other
affected snapshot region (lines referenced 547-564) for the same
absolute-paths/unresolved-state and fix them similarly.

In
`@apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-6f9a529b2e/snapshot.json`:
- Around line 574-577: The snapshot contains graph-validation errors: three
orphaned selected plans ("admin-00-operating-contract", "admin-01-boundary-adr",
"admin-02-source-map-and-contracts"); fix by updating the plan graph (link those
plans to upstream/downstream edges or remove them from the selection), then
regenerate the plan-graphs snapshot using the repository’s
graph-generation/validation command, verify no "orphaned" errors remain, and
commit the regenerated snapshot (keeping it local under plan-graphs unless you
intentionally want to promote it).
🪄 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: 8f27eb53-75ec-440b-855c-26b38a737c52

📥 Commits

Reviewing files that changed from the base of the PR and between 8f795ed and ea84b63.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (21)
  • apps/admin/AGENTS.md
  • apps/admin/agent-plans/README.md
  • apps/admin/agent-plans/admin-00-operating-contract.plan.md
  • apps/admin/agent-plans/admin-01-boundary-adr.plan.md
  • apps/admin/agent-plans/admin-02-source-map-and-contracts.plan.md
  • apps/admin/agent-plans/admin-03-shell-settings-parity.plan.md
  • apps/admin/agent-plans/admin-04-orders-workflow-parity.plan.md
  • apps/admin/agent-plans/admin-05-products-workflow-parity.plan.md
  • apps/admin/agent-plans/admin-06-customers-b2b-workflow.plan.md
  • apps/admin/agent-plans/admin-07-extensions-workflow-parity.plan.md
  • apps/admin/agent-plans/admin-08-quality-deploy-verification.plan.md
  • apps/admin/agent-plans/admin-09-catalog-taxonomy-workflow.plan.md
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-1161111402/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-11b20afb05/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-6f9a529b2e/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-9e188c0dc4/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-bada091bc5/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-ffb201321b/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-9-plans-18941fac18/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-9-plans-fcf29b886c/snapshot.json
  • apps/admin/ui.md
📜 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). (2)
  • GitHub Check: Greptile Review
  • GitHub Check: main
🧰 Additional context used
📓 Path-based instructions (2)
apps/admin/agent-plans/**/*.md

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

Plan files for apps/admin live in apps/admin/agent-plans and use plan-graph with explicit dependency overlays instead of assuming implicit execution order

Files:

  • apps/admin/agent-plans/admin-00-operating-contract.plan.md
  • apps/admin/agent-plans/admin-06-customers-b2b-workflow.plan.md
  • apps/admin/agent-plans/admin-07-extensions-workflow-parity.plan.md
  • apps/admin/agent-plans/admin-09-catalog-taxonomy-workflow.plan.md
  • apps/admin/agent-plans/admin-08-quality-deploy-verification.plan.md
  • apps/admin/agent-plans/admin-03-shell-settings-parity.plan.md
  • apps/admin/agent-plans/README.md
  • apps/admin/agent-plans/admin-05-products-workflow-parity.plan.md
  • apps/admin/agent-plans/admin-04-orders-workflow-parity.plan.md
  • apps/admin/agent-plans/admin-02-source-map-and-contracts.plan.md
  • apps/admin/agent-plans/admin-01-boundary-adr.plan.md
apps/admin/plan-graphs/**/*

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

Generated plan graph snapshots in apps/admin should be kept under apps/admin/plan-graphs and remain local-only unless intentionally promoted

Files:

  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-11b20afb05/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-1161111402/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-9-plans-fcf29b886c/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-ffb201321b/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-6f9a529b2e/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-9-plans-18941fac18/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-bada091bc5/snapshot.json
  • apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-9e188c0dc4/snapshot.json
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:44:23.095Z
Learning: Use `libs/ui/...` import alias only in projects that explicitly define and verify this alias in their configuration
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:44:23.095Z
Learning: Use Biome for linting and formatting, running it only on changed files or paths
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:44:23.095Z
Learning: Use pnpm for package management; install packages via CLI commands rather than editing package.json directly
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:44:23.095Z
Learning: Use Nx for orchestrating builds, development workflows, and project dependency management in the monorepo
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:44:23.095Z
Learning: Always assume the development server is already running on http://localhost:3000 for frontend-demo; never ask to run `pnpm dev` or check if the dev server is running
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:44:23.095Z
Learning: Use MCP servers (puppeteer-mcp, GitHub, tavily-mcp, sequential-thinking, desktop-commander, taskmaster) for enhanced development workflows including E2E testing, code review automation, research, architecture planning, batch operations, and task management
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Default write scope is `apps/admin`. Treat `libs/ui` as a read-only dependency for ordinary admin work unless the user explicitly widens the scope to shared UI-kit authoring
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: If admin usage exposes a real UI-kit API gap, document the gap and solve the current slice inside `apps/admin` with a small adapter or bounded workaround. Shared `libs/ui` changes belong in a separate, explicitly scoped task
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Do not edit `apps/medusa-be` unless the current admin task proves that an existing Admin API or custom endpoint cannot support the required workflow
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: If a backend gap is found, document the exact missing endpoint, request/response shape, and user workflow first. Do not work around missing CORS, auth, or backend behavior with frontend hacks
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Treat deployed backend compatibility as a first-class constraint. The admin should work against `NEXT_PUBLIC_MEDUSA_BACKEND_URL` without requiring local backend changes for ordinary UI work
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Before implementing a Medusa admin feature, inspect required sources in order: existing `apps/admin` code, Medusa Admin API docs, Medusa Admin dev docs, local Medusa dashboard source, project custom admin routes, and repo-local Medusa skills
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: When official docs, local Medusa dashboard source, and current project code disagree, preserve current project behavior unless the mismatch is a proven bug
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Use `techsio/ui-kit` / `libs/ui` first. Before adding custom UI primitives, inspect the local UI-kit adoption skills in `.codex/skills/adopting-ui-kit-in-apps/`
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Prefer existing Admin API list/detail endpoints before proposing backend aggregation endpoints in `apps/admin`
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Background refresh is acceptable for admin counters and dashboards. Prefer polling plus refetch-on-focus before introducing WebSockets or SSE in `apps/admin`
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Keep business concepts such as tabs, statuses, URL params, filters, query keys, count logic, and invalidation rules to have one source of truth in the owning domain module
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Centralization means one canonical owner for a concept, not one giant file. Pages and components should consume domain helpers or hooks instead of redefining business mappings locally
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Backend work in `apps/medusa-be` is justified only when the current Admin API cannot express the required mutation or read model, frontend scanning would be incorrect, a workflow must be atomic/audited/permission-checked server-side, or a custom project integration already exposes backend semantics
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: For user-facing workflow changes in `apps/admin`, smoke-test in a browser against the deployed backend when possible. Do not perform destructive admin actions against deployed data unless the user explicitly approves
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Keep commits aligned to one workflow slice or planning/documentation slice. Do not mix backend, UI kit, and admin app changes in one commit unless a single feature genuinely requires all three
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: Admin UX should stay dense, operational, and scannable. Do not introduce marketing layouts, oversized hero sections, decorative cards, or broad visual redesigns while implementing workflow parity
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: For each Medusa dashboard parity slice, identify the matching default Medusa dashboard route/component, identify the Admin API endpoints it uses, check for custom endpoints/plugins, implement the smallest useful workflow, reuse UI-kit components and existing admin layout patterns, and add smoke verification notes
Learnt from: CR
Repo: TechsioCZ/new-engine

Timestamp: 2026-05-27T17:45:08.491Z
Learning: For code changes in `apps/admin`, run verification checks: `pnpm.cmd --dir apps/admin run typecheck`, `pnpm.cmd --dir apps/admin run build`, `pnpm.cmd --dir apps/admin run validate:ui-primitives` when adding/changing JSX controls, `pnpm.cmd --dir apps/admin run validate:token-usage` when changing Tailwind classes or token files, and `pnpm.cmd exec biome check --write` on changed files
🪛 LanguageTool
apps/admin/agent-plans/admin-00-operating-contract.plan.md

[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ds for missing backend configuration. - Do not allow visual redesign to block oper...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

apps/admin/agent-plans/admin-06-customers-b2b-workflow.plan.md

[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...eployed data and backend conventions. - Do not silently hide pending customers whe...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

apps/admin/agent-plans/admin-07-extensions-workflow-parity.plan.md

[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...moke tests without explicit approval. - Do not let extension screens define unrela...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

apps/admin/agent-plans/admin-09-catalog-taxonomy-workflow.plan.md

[duplication] ~27-~27: Possible typo: you repeated a word.
Context: ...l catalog workflow, not a small product detail detail: - Category list columns: name, handle...

(ENGLISH_WORD_REPEAT_RULE)


[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...s: edit, manage translations, delete. - Category create modal: details step, organize/ra...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[grammar] ~31-~31: There seems to be a noun/verb agreement error. Did you mean “creates” or “created”?
Context: ...manage translations, delete. - Category create modal: details step, organize/ranking s...

(SINGULAR_NOUN_VERB_AGREEMENT)


[style] ~33-~33: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ath/children sidebar, metadata, JSON. - Category organize/ranking: tree-style hierarchy ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~44-~44: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ployed categories during smoke tests. - Do not implement category delete until con...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~57-~57: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...rget feat/admin-catalog-categories. - Category mutations and ranking: `feat/admin-cate...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

apps/admin/agent-plans/admin-08-quality-deploy-verification.plan.md

[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...arity without listing remaining gaps. - Do not ignore console/network errors from ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

apps/admin/agent-plans/admin-03-shell-settings-parity.plan.md

[style] ~41-~41: Consider using “incomplete” to avoid wordiness.
Context: ...reference data, so store read parity is not complete until that data path is mapped. Settin...

(NOT_ABLE_PREMIUM)

apps/admin/ui.md

[uncategorized] ~34-~34: Loose punctuation mark.
Context: ...e. ### Hypothetical Example libs/ui: - --color-button-fg: var(--color-fg-p...

(UNLIKELY_OPENING_PUNCTUATION)

apps/admin/agent-plans/admin-05-products-workflow-parity.plan.md

[uncategorized] ~26-~26: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...taxonomy workflows are owned by Admin 09 so product work does not become an oversiz...

(COMMA_COMPOUND_SENTENCE_2)


[style] ~32-~32: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...tadata conventions across components. - Do not add backend endpoints for core Medu...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

apps/admin/agent-plans/admin-02-source-map-and-contracts.plan.md

[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...write page UI just to clean up types. - Do not guess endpoint semantics when local...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

apps/admin/AGENTS.md

[uncategorized] ~158-~158: Possible missing comma found.
Context: ...icit execution order. For current-lane status use dag against the same plan selecti...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~182-182: Possible missing comma found.
Context: ...usawhen available. - For dashboard parity inspect
/.local/share/medusa-js/medus...

(AI_HYDRA_LEO_MISSING_COMMA)

🪛 markdownlint-cli2 (0.22.1)
apps/admin/ui.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🔇 Additional comments (8)
apps/admin/agent-plans/admin-04-orders-workflow-parity.plan.md (1)

1-18: Duplicate of the dependency-overlay issue already raised for another apps/admin/agent-plans/*.plan.md file.

apps/admin/agent-plans/admin-02-source-map-and-contracts.plan.md (1)

1-18: Duplicate of the dependency-overlay issue already raised for another apps/admin/agent-plans/*.plan.md file.

apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-1161111402/snapshot.json (1)

8-22: Duplicate of the snapshot portability/promotion-readiness issue already raised in another plan-graph snapshot file.

apps/admin/plan-graphs/admin-00-operating-contract-plus-9-plans-fcf29b886c/snapshot.json (1)

8-23: Duplicate of the snapshot portability/promotion-readiness issue already raised in another plan-graph snapshot file.

apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-ffb201321b/snapshot.json (1)

8-22: Duplicate of the snapshot portability/promotion-readiness issue already raised in another plan-graph snapshot file.

apps/admin/agent-plans/admin-01-boundary-adr.plan.md (1)

1-18: Duplicate of the dependency-overlay issue already raised for another apps/admin/agent-plans/*.plan.md file.

apps/admin/plan-graphs/admin-00-operating-contract-plus-9-plans-18941fac18/snapshot.json (1)

13-23: chore(plan-graph): avoid machine-specific absolute paths in promoted snapshots

Same root cause as already flagged: embedding local absolute filesystem paths makes promoted graph snapshots non-portable and noisy across contributors.

Also applies to: 88-89

apps/admin/AGENTS.md (1)

95-113: LGTM!

Also applies to: 123-130, 156-159, 181-182, 187-187

Comment on lines +1 to +18
---
name: Admin 05 - Products Workflow Parity
overview: Turn the product list/detail into a useful product management surface with carefully staged edit capabilities.
todos:
- id: product-source-map
content: "Map default Medusa product list/detail/create/edit routes, forms, fields, and mutation endpoints."
status: completed
- id: detail-completeness
content: "Complete product detail read sections for variants, options, images, categories, sales channels, shipping profile, stock, metadata, and organization."
status: in_progress
- id: basic-edit
content: "Add basic edit flows for title, subtitle, handle, status, description, organization, and metadata after contracts are confirmed."
status: pending
- id: complex-edit
content: "Add variants, pricing, media, and inventory edits only after source mapping and validation rules are explicit."
status: pending
isProject: 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 | ⚡ Quick win

Please add explicit dependency overlays for this plan in plan-graph metadata.

This plan currently has no explicit dependency overlay declaration, so execution order is inferred from narrative text. Please encode dependencies explicitly so graph generation/blocking stays deterministic across operators.

As per coding guidelines: “Plan files for apps/admin live in apps/admin/agent-plans and use plan-graph with explicit dependency overlays instead of assuming implicit execution order”.

🤖 Prompt for 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.

In `@apps/admin/agent-plans/admin-05-products-workflow-parity.plan.md` around
lines 1 - 18, Add a plan-graph metadata block to the "Admin 05 - Products
Workflow Parity" plan that explicitly declares dependency overlays linking the
todo nodes (product-source-map, detail-completeness, basic-edit, complex-edit)
so execution order is deterministic; for example, make product-source-map a
prerequisite for detail-completeness, and detail-completeness a prerequisite for
basic-edit and complex-edit, and include this overlay in the plan's front-matter
under a plan-graph key (matching the existing todo ids) so graph generation uses
the explicit edges instead of inferring order from narrative text.

Comment thread apps/admin/agent-plans/admin-09-catalog-taxonomy-workflow.plan.md Outdated
Comment thread apps/admin/agent-plans/README.md Outdated
Comment on lines +10 to +11
python .codex\skills\plan-graph\scripts\plan_graph.py validate --plans-root apps\admin\local\agent-plans --glob "admin-*.plan.md" `
--depends admin-00-operating-contract:admin-01-boundary-adr `

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 | ⚡ Quick win

Align command paths with canonical plan and graph directories.

The commands currently point to apps\admin\local\..., but this conflicts with the documented repository contract for plan and snapshot locations. Please switch to apps\admin\agent-plans and apps\admin\plan-graphs so validation/generation targets the canonical paths.

Proposed doc fix
-python .codex\skills\plan-graph\scripts\plan_graph.py validate --plans-root apps\admin\local\agent-plans --glob "admin-*.plan.md" `
+python .codex\skills\plan-graph\scripts\plan_graph.py validate --plans-root apps\admin\agent-plans --glob "admin-*.plan.md" `
...
-python .codex\skills\dag\scripts\dag.py --plans-root apps\admin\local\agent-plans --glob "admin-*.plan.md" --state-dir apps\admin\local\plan-graphs --lanes 4 --max-depth 2 `
+python .codex\skills\dag\scripts\dag.py --plans-root apps\admin\agent-plans --glob "admin-*.plan.md" --state-dir apps\admin\plan-graphs --lanes 4 --max-depth 2 `

As per coding guidelines: “Plan files for apps/admin live in apps/admin/agent-plans …” and “Generated plan graph snapshots in apps/admin should be kept under apps/admin/plan-graphs …”.

Also applies to: 31-31

🤖 Prompt for 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.

In `@apps/admin/agent-plans/README.md` around lines 10 - 11, The README command
references non-canonical paths (apps\admin\local\agent-plans and implied
snapshots) so update the CLI examples to use the canonical directories: replace
any occurrence of "apps\admin\local\agent-plans" with "apps\admin\agent-plans"
and ensure generated/graph targets point to "apps\admin\plan-graphs" (e.g., in
the python .codex\skills\plan-graph\scripts\plan_graph.py validate example where
--plans-root and any snapshot/graph output globs are specified); keep the rest
of the command arguments (like --glob and --depends) unchanged.

Comment on lines +574 to +577
"errors": [
"admin-00-operating-contract: selected plan is orphaned (no upstream or downstream edges); link it explicitly or exclude it from the graph selection",
"admin-01-boundary-adr: selected plan is orphaned (no upstream or downstream edges); link it explicitly or exclude it from the graph selection",
"admin-02-source-map-and-contracts: selected plan is orphaned (no upstream or downstream edges); link it explicitly or exclude it from the graph selection"

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 | ⚡ Quick win

fix(plan-graph): regenerate before commit when snapshot contains graph errors

This snapshot is committed with unresolved graph validation errors (orphaned selected plans), so the promoted graph state is internally inconsistent and can mislead planning workflows.

As per coding guidelines: “Generated plan graph snapshots in apps/admin should be kept under apps/admin/plan-graphs and remain local-only unless intentionally promoted”.

🤖 Prompt for 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.

In
`@apps/admin/plan-graphs/admin-00-operating-contract-plus-8-plans-6f9a529b2e/snapshot.json`
around lines 574 - 577, The snapshot contains graph-validation errors: three
orphaned selected plans ("admin-00-operating-contract", "admin-01-boundary-adr",
"admin-02-source-map-and-contracts"); fix by updating the plan graph (link those
plans to upstream/downstream edges or remove them from the selection), then
regenerate the plan-graphs snapshot using the repository’s
graph-generation/validation command, verify no "orphaned" errors remain, and
commit the regenerated snapshot (keeping it local under plan-graphs unless you
intentionally want to promote it).

@BleedingDev

Copy link
Copy Markdown
Collaborator

@KaiUweCZE please gitignore the plans, it heavily polutes the PR.

Comment on lines +180 to +194
const PRODUCT_FIELDS = [
"id",
"title",
"handle",
"status",
"*collection",
"*sales_channels",
"variants.id",
"thumbnail",
"-type",
"-options",
"-tags",
"-images",
"-variants",
].join(",")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Contradictory variant field selectors in PRODUCT_FIELDS

"variants.id" (explicitly include variants with only the id sub-field) and "-variants" (exclude the variants relation entirely) coexist in the same field query string. In Medusa v2's field-selection layer, -variants acts as a relation-level exclude; if it takes precedence over the more specific variants.id selector, the API returns no variants data at all. toProductListItem then falls back to product.variants?.length ?? 0, silently setting variant_count: 0 for every product in the list — the count column would show "0 variant" across the board without any error.

Fix in Codex

@KaiUweCZE KaiUweCZE closed this May 29, 2026
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