Skip to content

(SP: 3) [SHOP] add public legal surfaces and align checkout consent with privacy flow#419

Merged
ViktorSvertoka merged 5 commits intodevelopfrom
lso/feat/shop-legal
Mar 27, 2026
Merged

(SP: 3) [SHOP] add public legal surfaces and align checkout consent with privacy flow#419
ViktorSvertoka merged 5 commits intodevelopfrom
lso/feat/shop-legal

Conversation

@liudmylasovetovs
Copy link
Copy Markdown
Collaborator

@liudmylasovetovs liudmylasovetovs commented Mar 27, 2026

Description

This PR completes the Phase 4 legal/compliance work for Shop across Workstream 8 and Workstream 9.

It adds public legal surfaces required for shop users, exposes them through shop-scoped footer links, and aligns the checkout consent flow with the privacy/cookie wording so consent is no longer recorded implicitly.

The goal of this PR is to close the remaining launch-blocking legal UX gaps without changing payment, shipping, or order lifecycle behavior outside the exact scope of these workstreams.

Note:

  • Seller-information surface is now public and customer-facing.
  • Fields that still do not have confirmed merchant data are shown with neutral placeholder-safe content instead of internal diagnostics or invented values.

Related Issue

Issue: #<issue_number>


Changes

  • Added separate public shop legal pages for seller information, payment policy, delivery policy, and returns policy.
  • Added shop-scoped footer legal links so a guest can reach all required policy surfaces from the Shop footer.
  • Reworked legal copy to be customer-facing and removed internal/engineering wording from public policy pages.
  • Added explicit checkout legal consent in UI and passed legal consent versions from cart page into checkout client flow.
  • Updated checkout validation/persistence so normal checkout no longer writes silent checkout_implicit consent without explicit user action.
  • Aligned cookie/privacy wording so checkout consent copy, cookie banner wording, and privacy-policy wording do not contradict each other.
  • Added/updated focused shop tests for public legal surfaces, footer legal links, public seller information, and checkout consent behavior.
  • Added Playwright-friendly data-testid selectors to footer legal links for stable test automation.

Database Changes (if applicable)

  • Schema migration required
  • Seed data updated
  • Breaking changes to existing queries
  • Transaction-safe migration
  • Migration tested locally on Neon

How Has This Been Tested?

  • Tested locally
  • Verified in development environment
  • Checked responsive layout (if UI-related)
  • Tested accessibility (keyboard / screen reader)

Additional notes:

  • Focused Shop Vitest suites were run against the local test database only.
  • WS8 legal/footer tests passed.
  • WS9 checkout-consent/privacy-alignment tests passed after fixing a narrow test typing issue.

Screenshots (if applicable)


Checklist

Before submitting

  • Code has been self-reviewed
  • No TypeScript or console errors
  • Code follows project conventions
  • Scope is limited to this feature/fix
  • No unrelated refactors included
  • English used in code, commits, and docs
  • New dependencies discussed with team
  • Database migration tested locally (if applicable)
  • GitHub Projects card moved to In Review

Reviewers

Summary by CodeRabbit

  • New Features

    • New legal pages: Seller Information, Payment Policy, Delivery Policy, Returns Policy
    • Checkout now requires explicit consent to Terms of Service and Privacy Policy (checkbox) and blocks submission until accepted
    • Footer now shows links to the new legal pages
  • Chores

    • Cookie banner messaging and button labels updated
    • Public support/seller contact details surfaced on legal pages
    • Example environment config updated to include seller identifier (EDRPOU)

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 27, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
devlovers-net Ignored Ignored Preview Mar 27, 2026 8:08pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

📝 Walkthrough

Walkthrough

Adds localized public legal pages and content components, enforces explicit checkout legal consent (client UI, payload validation, route handling, and order service), introduces public support/seller helpers and env var NP_SENDER_EDRPOU, updates footer links/translations, and includes extensive tests for legal pages and consent flows.

Changes

Cohort / File(s) Summary
Environment & Config
frontend/.env.example
Added NP_SENDER_EDRPOU and clarified Nova Poshta sender/provider comment.
Public Seller & Contact Helpers
frontend/lib/legal/public-contact.ts, frontend/lib/legal/public-seller-information.ts
New public support email constant/accessor and seller information types + env-driven getPublicSellerInformation().
Legal Pages (route + page)
frontend/app/[locale]/delivery-policy/page.tsx, frontend/app/[locale]/payment-policy/page.tsx, frontend/app/[locale]/returns-policy/page.tsx, frontend/app/[locale]/seller-information/page.tsx
New localized Next.js pages with generateMetadata and server-rendered content via LegalPageShell.
Legal Content Components
frontend/components/legal/DeliveryPolicyContent.tsx, frontend/components/legal/PaymentPolicyContent.tsx, frontend/components/legal/ReturnsPolicyContent.tsx, frontend/components/legal/SellerInformationContent.tsx, frontend/components/legal/TermsOfServiceContent.tsx, frontend/components/legal/PrivacyPolicyContent.tsx
Added new content components with last-updated constants and switched multiple components to use getPublicSupportEmail() (and seller data) instead of translation-based email.
Legal Page Shell & Footer
frontend/components/legal/LegalPageShell.tsx, frontend/components/shared/Footer.tsx, frontend/components/tests/footer-shop-legal-links.test.tsx
Legal shell uses public support email; footer now conditionally renders shop-specific legal links, adds test IDs, and includes tests for shop vs non-shop rendering.
Cart UI (consent)
frontend/app/[locale]/shop/cart/CartPageClient.tsx, frontend/app/[locale]/shop/cart/page.tsx
Cart client now requires/displayes consent checkbox, tracks legalConsentAccepted/UI error, passes termsVersion/privacyVersion to client, and includes versions from getShopLegalVersions().
Checkout API / Service / Validation
frontend/app/api/shop/checkout/route.ts, frontend/lib/validation/shop.ts, frontend/lib/services/orders/checkout.ts
Made legalConsent required in schema, added LEGAL_CONSENT_REQUIRED handling, enforce explicit consent in createOrderWithItems signature and resolution, added replay-grace logic for consent snapshot insertion during idempotency.
Tests: Contract & Scenarios
frontend/lib/tests/shop/checkout-legal-consent-contract.test.ts, frontend/lib/tests/shop/checkout-legal-consent-phase4.test.ts, frontend/lib/tests/shop/checkout-route-stripe-disabled-recovery.test.ts, frontend/lib/tests/shop/legal-cookie-privacy-alignment-phase4.test.ts, frontend/lib/tests/shop/public-legal-pages-phase4.test.ts, frontend/lib/tests/shop/public-seller-information-phase4.test.ts, frontend/lib/tests/shop/checkout-shipping-phase3.test.ts, frontend/lib/tests/shop/order-items-variants.test.ts
New and updated test suites covering payload contract, idempotency replay behavior for missing consent, route error handling, translation alignment, public legal page metadata, public seller info contract, and propagation of legalConsent in existing shipping/order tests.
Translations
frontend/messages/en.json, frontend/messages/pl.json, frontend/messages/uk.json
Added footer labels, shop.checkout.consent copy, revised CookieBanner copy/CTAs, and expanded legal.* structured content for seller/payment/delivery/returns across locales.

Sequence Diagram

sequenceDiagram
    actor User
    participant Cart as CartPageClient
    participant API as /api/shop/checkout
    participant OrderSvc as createOrderWithItems
    participant DB as Database

    User->>Cart: Toggle consent checkbox
    Cart->>Cart: Update legalConsentAccepted state

    User->>Cart: Click "Place Order"
    alt consent not accepted
        Cart->>Cart: Set legalConsentUiError + checkoutError
        Cart-->>User: Block submission (UI)
    else consent accepted
        Cart->>API: POST /api/shop/checkout (payload includes legalConsent with termsAccepted, privacyAccepted, termsVersion, privacyVersion)
        API->>API: Validate via checkoutPayloadSchema
        alt schema fails due to legalConsent
            API->>Cart: 400 LEGAL_CONSENT_REQUIRED
        else validation ok
            API->>OrderSvc: createOrderWithItems(..., legalConsent)
            OrderSvc->>DB: Insert order (may insert/ensure consent snapshot during idempotency replay)
            DB-->>OrderSvc: Order + consent persisted
            OrderSvc-->>API: Order result
            API-->>Cart: 200 success (order created)
            Cart-->>User: Redirect to confirmation
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • AM1007
  • ViktorSvertoka
  • LesiaUKR

"🐰
I hopped through env and pages bright,
I stitched consent where users write,
I fetched the seller, mailed a care,
Footer links now show everywhere.
Hooray — the legal garden's right!"

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: adding public legal surfaces (seller information, payment/delivery/returns policies) and aligning checkout consent with the privacy flow. It is specific, directly related to the changeset, and concise.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lso/feat/shop-legal

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fc1b33375a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
frontend/lib/services/orders/checkout.ts (1)

521-545: ⚠️ Potential issue | 🟠 Major

Don't backfill explicit consent versions from env defaults.

Now that checkout requires explicit consent, silently replacing blank termsVersion / privacyVersion with current env values can persist acceptance for a document version the caller never actually sent. This service is the last guard before persistence, so it should fail closed here instead of normalizing.

💡 Proposed fix
-  const versions = getShopLegalVersions();
-
   const termsAccepted = args.legalConsent.termsAccepted;
   const privacyAccepted = args.legalConsent.privacyAccepted;
@@
-  const termsVersion = normalizeLegalVersion(
-    args.legalConsent.termsVersion,
-    versions.termsVersion
-  );
-  const privacyVersion = normalizeLegalVersion(
-    args.legalConsent.privacyVersion,
-    versions.privacyVersion
-  );
+  const termsVersion = args.legalConsent.termsVersion.trim();
+  const privacyVersion = args.legalConsent.privacyVersion.trim();
+
+  if (!termsVersion || !privacyVersion) {
+    throw new InvalidPayloadError(
+      'Legal consent versions are required before checkout.',
+      {
+        code: 'LEGAL_CONSENT_REQUIRED',
+      }
+    );
+  }

After this, normalizeLegalVersion() and the getShopLegalVersions import can be removed if nothing else uses them.

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

In `@frontend/lib/services/orders/checkout.ts` around lines 521 - 545, Currently
the code silently backfills missing consent versions using getShopLegalVersions
and normalizeLegalVersion; instead, update the checkout validation to require
explicit args.legalConsent.termsVersion and args.legalConsent.privacyVersion
when termsAccepted/privacyAccepted are true and throw an InvalidPayloadError
(e.g., code: 'TERMS_VERSION_REQUIRED' / 'PRIVACY_VERSION_REQUIRED') if they are
missing or blank; remove the calls to normalizeLegalVersion and
getShopLegalVersions (and the imports) if nothing else depends on them after
this change.
🧹 Nitpick comments (1)
frontend/lib/tests/shop/legal-cookie-privacy-alignment-phase4.test.ts (1)

23-44: Consider adding locale identification to test assertions for easier debugging.

When iterating over locales, if an assertion fails, the error message won't indicate which locale caused the failure. Consider using it.each or adding the locale to the assertion message.

💡 Suggested improvement
-  it('keeps checkout consent keys present for all supported locales', () => {
-    for (const messages of [en, uk, pl]) {
+  it.each([
+    ['en', en],
+    ['uk', uk],
+    ['pl', pl],
+  ] as const)('keeps checkout consent keys present for %s locale', (_locale, messages) => {
       expect(
         getAtPath(messages as Record<string, unknown>, [
           'shop',
           'cart',
           'checkout',
           'consent',
           'prefix',
         ])
       ).toBeTruthy();

       expect(
         getAtPath(messages as Record<string, unknown>, [
           'shop',
           'cart',
           'checkout',
           'consent',
           'required',
         ])
       ).toBeTruthy();
-    }
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/lib/tests/shop/legal-cookie-privacy-alignment-phase4.test.ts` around
lines 23 - 44, The test 'keeps checkout consent keys present for all supported
locales' iterates over locale message objects (en, uk, pl) without identifying
which locale fails; update the test using it.each or include the locale variable
in the expect messages so failures show the locale, e.g., iterate with a
(localeName, messages) pair and call getAtPath(messages, [...]) inside expects
that include localeName in the failure message; reference the test name and the
variables en, uk, pl and the helper getAtPath to locate the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/components/tests/footer-shop-legal-links.test.tsx`:
- Around line 3-4: The Link mock used in footer-shop-legal-links.test.tsx is
dropping props and therefore not forwarding data-testid attributes (so selectors
like "footer-legal-link-*" aren’t actually tested); update the mocked Link
component to accept and forward all anchor props (e.g., include a rest props
parameter and spread it onto the returned <a> element) so data-testid, target,
rel, etc. are preserved when the Footer renders, ensuring the existing tests
that query by data-testid exercise the real selector contract.

In `@frontend/lib/legal/public-contact.ts`:
- Around line 1-5: The PUBLIC_SUPPORT_EMAIL constant used by
getPublicSupportEmail() ('contact@devlovers.net') conflicts with the translation
key legal.contactEmail which contains "devlovers.net@gmail.com"; pick one source
of truth: either update PUBLIC_SUPPORT_EMAIL (and getPublicSupportEmail) to the
correct address used in translations, or update all translation entries
(en.json, pl.json, uk.json) to match PUBLIC_SUPPORT_EMAIL, or remove the unused
legal.contactEmail key from all message files if every component now imports
getPublicSupportEmail() directly; ensure the chosen email is consistent across
PUBLIC_SUPPORT_EMAIL, getPublicSupportEmail, and translation keys (or remove
those keys) so no components reference differing addresses.

In `@frontend/lib/services/orders/checkout.ts`:
- Around line 512-519: The new hard-fail on missing legal consent (throwing
InvalidPayloadError) makes the path racy with idempotency: ensure order and
order_legal_consents are persisted atomically or make the missing-consent state
transient/retriable. Update the checkout flow to either (a) insert or upsert the
order_legal_consents row before finalizing the order inside the same DB
transaction so creation is atomic with the order, or (b) change the validation
in assertIdempotencyCompatible to tolerate a transiently-missing
order_legal_consents by treating “no consent yet but order recently created with
same idempotency key” as retriable (retryable error) instead of a hard
rejection; locate and update the throw at the InvalidPayloadError site and the
logic in assertIdempotencyCompatible and the later consent-handling block to
implement one of these two strategies and ensure idempotent safe behavior for
repeated requests.

In `@frontend/messages/pl.json`:
- Around line 1748-1750: The Polish copy is inconsistent: checkout.ts
(orderTotalCents) includes shipping in the pre-confirmation total, but the keys
shop.cart.summary.shippingInformationalOnly and shippingPayOnDeliveryNote still
state shipping is informational/not charged; update those keys in pl.json
(including the similar block at 1778-1780) so their wording matches the
charges.title/body (or otherwise clearly state that shipping is included in the
total charged before order confirmation), ensuring all cart summary strings
consistently reflect that shipping is included.

---

Outside diff comments:
In `@frontend/lib/services/orders/checkout.ts`:
- Around line 521-545: Currently the code silently backfills missing consent
versions using getShopLegalVersions and normalizeLegalVersion; instead, update
the checkout validation to require explicit args.legalConsent.termsVersion and
args.legalConsent.privacyVersion when termsAccepted/privacyAccepted are true and
throw an InvalidPayloadError (e.g., code: 'TERMS_VERSION_REQUIRED' /
'PRIVACY_VERSION_REQUIRED') if they are missing or blank; remove the calls to
normalizeLegalVersion and getShopLegalVersions (and the imports) if nothing else
depends on them after this change.

---

Nitpick comments:
In `@frontend/lib/tests/shop/legal-cookie-privacy-alignment-phase4.test.ts`:
- Around line 23-44: The test 'keeps checkout consent keys present for all
supported locales' iterates over locale message objects (en, uk, pl) without
identifying which locale fails; update the test using it.each or include the
locale variable in the expect messages so failures show the locale, e.g.,
iterate with a (localeName, messages) pair and call getAtPath(messages, [...])
inside expects that include localeName in the failure message; reference the
test name and the variables en, uk, pl and the helper getAtPath to locate the
change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b2fec2be-756e-48fd-80a9-fa5dff3f0d75

📥 Commits

Reviewing files that changed from the base of the PR and between 7ab6d41 and fc1b333.

📒 Files selected for processing (30)
  • frontend/.env.example
  • frontend/app/[locale]/delivery-policy/page.tsx
  • frontend/app/[locale]/payment-policy/page.tsx
  • frontend/app/[locale]/returns-policy/page.tsx
  • frontend/app/[locale]/seller-information/page.tsx
  • frontend/app/[locale]/shop/cart/CartPageClient.tsx
  • frontend/app/[locale]/shop/cart/page.tsx
  • frontend/app/api/shop/checkout/route.ts
  • frontend/components/legal/DeliveryPolicyContent.tsx
  • frontend/components/legal/LegalPageShell.tsx
  • frontend/components/legal/PaymentPolicyContent.tsx
  • frontend/components/legal/PrivacyPolicyContent.tsx
  • frontend/components/legal/ReturnsPolicyContent.tsx
  • frontend/components/legal/SellerInformationContent.tsx
  • frontend/components/legal/TermsOfServiceContent.tsx
  • frontend/components/shared/Footer.tsx
  • frontend/components/tests/footer-shop-legal-links.test.tsx
  • frontend/lib/legal/public-contact.ts
  • frontend/lib/legal/public-seller-information.ts
  • frontend/lib/services/orders/checkout.ts
  • frontend/lib/tests/shop/checkout-legal-consent-contract.test.ts
  • frontend/lib/tests/shop/checkout-legal-consent-phase4.test.ts
  • frontend/lib/tests/shop/checkout-route-stripe-disabled-recovery.test.ts
  • frontend/lib/tests/shop/legal-cookie-privacy-alignment-phase4.test.ts
  • frontend/lib/tests/shop/public-legal-pages-phase4.test.ts
  • frontend/lib/tests/shop/public-seller-information-phase4.test.ts
  • frontend/lib/validation/shop.ts
  • frontend/messages/en.json
  • frontend/messages/pl.json
  • frontend/messages/uk.json

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (6)
frontend/messages/en.json (1)

1718-1720: Add a production guard for seller placeholders.

Publishing "To be added" on legal seller fields in production can create compliance exposure. Consider a release-time check that blocks deploys when this placeholder exists in public legal copy.

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

In `@frontend/messages/en.json` around lines 1718 - 1720, Add a release-time
(CI/prepublish) validation that fails the build if the seller placeholder
exists: scan frontend/messages/en.json for the placeholders.toBeAdded key or the
literal value "To be added" and exit non‑zero when found; integrate this check
into the existing CI pipeline or npm prepublish script (e.g.,
validate-localization or prepublish step) so deploys are blocked if that
placeholder is present in production-bound builds.
frontend/lib/tests/shop/checkout-shipping-phase3.test.ts (1)

158-158: Consider extracting TEST_LEGAL_CONSENT to a shared test utilities module.

The same constant is duplicated across order-items-variants.test.ts, checkout-shipping-phase3.test.ts, and checkout-legal-consent-phase4.test.ts. Extracting it to a shared test helper would reduce duplication and ensure consistency when version strings need updating.

Also applies to: 225-225, 272-272, 315-315, 357-357, 438-438, 460-460, 495-495

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

In `@frontend/lib/tests/shop/checkout-shipping-phase3.test.ts` at line 158,
Multiple tests duplicate the TEST_LEGAL_CONSENT constant; extract it into a
shared test utilities module and import it from tests to remove duplication.
Create or reuse a test helper (e.g., test/utils or tests/helpers) that exports
TEST_LEGAL_CONSENT, update references in files using the constant (tests
mentioning TEST_LEGAL_CONSENT such as in order-items-variants.test,
checkout-shipping-phase3.test, checkout-legal-consent-phase4.test) to import
from that helper, and ensure any tests still pass by keeping the exported value
identical to the current constant.
frontend/messages/pl.json (2)

325-328: Use policy-style labels in the legal footer.

"Płatność", "Dostawa" and "Zwroty" read like actions/categories, while these links open policy pages. Matching the destination titles will make the footer clearer and more consistent with "Polityka Prywatności" / "Warunki Świadczenia Usług".

Suggested copy tweak
-    "payment": "Płatność",
-    "delivery": "Dostawa",
-    "returns": "Zwroty",
+    "payment": "Polityka płatności",
+    "delivery": "Polityka dostawy",
+    "returns": "Polityka zwrotów",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/messages/pl.json` around lines 325 - 328, Replace the action-style
values for the JSON keys "payment", "delivery", and "returns" with policy-style
labels that match the destination pages (e.g., change "Płatność" → "Polityka
płatności", "Dostawa" → "Polityka dostawy", "Zwroty" → "Polityka zwrotów") so
the footer reads consistently with "Polityka Prywatności" and "Warunki
Świadczenia Usług"; update the values for the keys "payment", "delivery", and
"returns" in the messages JSON accordingly.

485-492: Prefer a neutral checkbox sentence here.

"Zapoznałem(-am) się..." reads awkwardly in a legal consent checkbox and forces a gendered form. A neutral construction will read cleaner for all customers.

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

In `@frontend/messages/pl.json` around lines 485 - 492, The consent checkbox text
under the "consent" object uses a gendered phrase in "prefix" ("Zapoznałem(-am)
się..."); change it to a neutral construction and ensure the pieces still
concatenate correctly with "termsLink", "and", "privacyLink", and "suffix".
Update "consent.prefix" to a neutral sentence such as a short neutral verb form
(e.g., "Potwierdzam zapoznanie się i akceptuję") and, if needed, make a matching
neutral adjustment to "consent.required" so the validation message uses
non-gendered language as well.
frontend/messages/uk.json (2)

1743-1745: Replace редирект / авторитетним with customer-facing wording.

This sentence still sounds internal on a public policy page. Something like “повернення на сторінку магазину” and “остаточним підтвердженням” would read much more naturally.

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

In `@frontend/messages/uk.json` around lines 1743 - 1745, Update the "body" string
under the "confirmation" object (keys "confirmation" -> "title"/"body") to use
customer-facing phrasing: replace the word "редирект" with "повернення на
сторінку магазину" and replace "авторитетним підтвердженням" with "остаточним
підтвердженням" so the sentence reads naturally for customers.

1764-1766: Use one carrier naming convention across the Ukrainian shop copy.

This block adds another Nova Poshta variant, while the same file also uses Нова пошта / Нової пошти in Line 412 and Line 950. Picking one form here will keep the policy page consistent with the rest of the checkout flow.

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

In `@frontend/messages/uk.json` around lines 1764 - 1766, The strings for keys
"warehouse", "locker", and "courier" use the Latin "Nova Poshta" variant; update
these three values to the Cyrillic naming used elsewhere ("Нова пошта" /
appropriate inflection) so they match the existing entries (e.g., change
"Самовивіз із відділення Nova Poshta" to the same wording pattern used in lines
that currently use "Нова пошта"). Ensure the inflection matches the phrase
(nominative/genitive) consistent with other entries in the file.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/messages/en.json`:
- Around line 1746-1748: Update the inconsistent shipping statements in
frontend/messages/en.json by harmonizing the "body" text for the affected
message objects (the entries with "title": "What is charged online" and the
other similar entry around the 1776–1778 block) so they consistently state
whether the delivery cost shown in checkout is an estimated/indicative charge or
the actual amount charged, and clarify when shipping is paid (e.g., "delivery
cost shown is an estimate included in your checkout total" OR "delivery is paid
to the carrier on delivery; the checkout shows an estimated delivery cost for
reference"). Modify the "body" values to use one clear version across all
related keys and ensure any legal copy elsewhere (the entries around lines
~403–404) matches that same stance to remove the contradiction.

In `@frontend/messages/pl.json`:
- Around line 1713-1714: Update the Polish meta description string for the
seller page (the "metaDescription" entry in frontend/messages/pl.json) to
include the missing noun after "kontaktowe" so the snippet reads grammatically
correct; replace the fragment "Publiczne dane sprzedawcy i kontaktowe dla sklepu
DevLovers." with a version that explicitly names the contact info (for example,
"Publiczne dane sprzedawcy i dane kontaktowe sklepu DevLovers." or "Publiczne
dane sprzedawcy i informacje kontaktowe sklepu DevLovers.") so the browser
preview is not broken.

In `@frontend/messages/uk.json`:
- Around line 1747-1749: The "charges" translation entry contradicts earlier
policy text that states shipping is "Лише інформаційно" and paid to the carrier
on delivery; decide which billing model is correct and make the copy consistent:
either change the "charges" key (title/body) to state that shipping is
informational and paid on delivery, or update the earlier policy paragraphs (the
ones referenced at lines 403-404 and 1777-1779) to reflect that shipping is
added to the order total and may be charged online—ensure the chosen model is
used consistently across the "charges" entry and the other policy paragraphs so
the public legal copy mirrors the actual checkout behavior.

---

Nitpick comments:
In `@frontend/lib/tests/shop/checkout-shipping-phase3.test.ts`:
- Line 158: Multiple tests duplicate the TEST_LEGAL_CONSENT constant; extract it
into a shared test utilities module and import it from tests to remove
duplication. Create or reuse a test helper (e.g., test/utils or tests/helpers)
that exports TEST_LEGAL_CONSENT, update references in files using the constant
(tests mentioning TEST_LEGAL_CONSENT such as in order-items-variants.test,
checkout-shipping-phase3.test, checkout-legal-consent-phase4.test) to import
from that helper, and ensure any tests still pass by keeping the exported value
identical to the current constant.

In `@frontend/messages/en.json`:
- Around line 1718-1720: Add a release-time (CI/prepublish) validation that
fails the build if the seller placeholder exists: scan frontend/messages/en.json
for the placeholders.toBeAdded key or the literal value "To be added" and exit
non‑zero when found; integrate this check into the existing CI pipeline or npm
prepublish script (e.g., validate-localization or prepublish step) so deploys
are blocked if that placeholder is present in production-bound builds.

In `@frontend/messages/pl.json`:
- Around line 325-328: Replace the action-style values for the JSON keys
"payment", "delivery", and "returns" with policy-style labels that match the
destination pages (e.g., change "Płatność" → "Polityka płatności", "Dostawa" →
"Polityka dostawy", "Zwroty" → "Polityka zwrotów") so the footer reads
consistently with "Polityka Prywatności" and "Warunki Świadczenia Usług"; update
the values for the keys "payment", "delivery", and "returns" in the messages
JSON accordingly.
- Around line 485-492: The consent checkbox text under the "consent" object uses
a gendered phrase in "prefix" ("Zapoznałem(-am) się..."); change it to a neutral
construction and ensure the pieces still concatenate correctly with "termsLink",
"and", "privacyLink", and "suffix". Update "consent.prefix" to a neutral
sentence such as a short neutral verb form (e.g., "Potwierdzam zapoznanie się i
akceptuję") and, if needed, make a matching neutral adjustment to
"consent.required" so the validation message uses non-gendered language as well.

In `@frontend/messages/uk.json`:
- Around line 1743-1745: Update the "body" string under the "confirmation"
object (keys "confirmation" -> "title"/"body") to use customer-facing phrasing:
replace the word "редирект" with "повернення на сторінку магазину" and replace
"авторитетним підтвердженням" with "остаточним підтвердженням" so the sentence
reads naturally for customers.
- Around line 1764-1766: The strings for keys "warehouse", "locker", and
"courier" use the Latin "Nova Poshta" variant; update these three values to the
Cyrillic naming used elsewhere ("Нова пошта" / appropriate inflection) so they
match the existing entries (e.g., change "Самовивіз із відділення Nova Poshta"
to the same wording pattern used in lines that currently use "Нова пошта").
Ensure the inflection matches the phrase (nominative/genitive) consistent with
other entries in the file.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: afa31371-415d-44d1-9385-4f8a8b659f03

📥 Commits

Reviewing files that changed from the base of the PR and between fc1b333 and 4d7b0b3.

📒 Files selected for processing (9)
  • frontend/components/tests/footer-shop-legal-links.test.tsx
  • frontend/lib/services/orders/checkout.ts
  • frontend/lib/tests/shop/checkout-legal-consent-phase4.test.ts
  • frontend/lib/tests/shop/checkout-shipping-phase3.test.ts
  • frontend/lib/tests/shop/legal-cookie-privacy-alignment-phase4.test.ts
  • frontend/lib/tests/shop/order-items-variants.test.ts
  • frontend/messages/en.json
  • frontend/messages/pl.json
  • frontend/messages/uk.json
✅ Files skipped from review due to trivial changes (1)
  • frontend/lib/tests/shop/legal-cookie-privacy-alignment-phase4.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/components/tests/footer-shop-legal-links.test.tsx

@ViktorSvertoka ViktorSvertoka merged commit 9200267 into develop Mar 27, 2026
6 checks passed
@ViktorSvertoka ViktorSvertoka deleted the lso/feat/shop-legal branch March 27, 2026 19:45
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