Commit Graph

36 Commits

Author SHA1 Message Date
af8e14c545 fix(deploy): inject runtime secrets and force-recreate containers on deploy
Some checks failed
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 1m33s
Deploy — Staging / Build & push — admin (push) Successful in 57s
Deploy — Staging / Build & push — storefront (push) Successful in 58s
Deploy — Staging / Deploy to staging VPS (push) Failing after 18s
- Add --force-recreate to podman compose up so stale containers are never
  reused across deploys when the image tag (staging) is reused
- Inject CLERK_SECRET_KEY and ADMIN_CLERK_SECRET_KEY from Gitea secrets into
  ~/staging/.env on the VPS via printf (variables expand on the runner before
  SSH, so secrets never touch VPS shell history; file gets chmod 600)
- Update compose.yml: storefront gets CLERK_SECRET_KEY, admin gets
  CLERK_SECRET_KEY mapped from ADMIN_CLERK_SECRET_KEY

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 12:42:06 +03:00
9ede637f39 fix(docker): correct server.js path for monorepo standalone output
All checks were successful
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 2m41s
Deploy — Staging / Build & push — admin (push) Successful in 3m4s
Deploy — Staging / Build & push — storefront (push) Successful in 3m16s
Deploy — Staging / Deploy to staging VPS (push) Successful in 31s
With outputFileTracingRoot set to the repo root, Next.js standalone mirrors
the full monorepo directory tree inside .next/standalone/. server.js lands at
apps/storefront/server.js (not at the root), so the CMD must reflect that.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 12:10:39 +03:00
0da06b965d deploy: change ports mapping
All checks were successful
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 2m46s
Deploy — Staging / Build & push — admin (push) Successful in 1m33s
Deploy — Staging / Build & push — storefront (push) Successful in 1m41s
Deploy — Staging / Deploy to staging VPS (push) Successful in 30s
2026-03-08 12:00:56 +03:00
439d6d4455 fix(ci): fix YAML parse error in deploy workflow caused by inner heredoc
Some checks failed
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 1m29s
Deploy — Staging / Build & push — admin (push) Successful in 54s
Deploy — Staging / Build & push — storefront (push) Successful in 53s
Deploy — Staging / Deploy to staging VPS (push) Failing after 24s
The compose file was written via a bash << 'COMPOSE' heredoc nested inside
the YAML run: | block scalar. Lines like "name: petloft-staging" at column 0
cause the YAML parser to break out of the block scalar early, making the
entire workflow file invalid YAML — Gitea silently drops invalid workflows,
so no jobs triggered at all.

Fix: move compose.yml to deploy/staging/compose.yml in the repo, substitute
${REGISTRY} on the runner, base64-encode the result, and decode it on the VPS
inside the SSH session. No inner heredoc needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 11:37:02 +03:00
b333047753 workflow trigger 2026-03-08 11:29:45 +03:00
0b9ac5cd46 fix(deploy): create /opt/staging and write compose.yml on every deploy
The VPS had no /opt/staging directory or compose file, causing the deploy
step to fail with "No such file or directory". Now the workflow:
- Creates /opt/staging if missing
- Writes compose.yml on every deploy (keeps it in sync with CI)
- Touches .env so podman compose doesn't error if no secrets file exists yet

Also adds deploy/staging/.env.example documenting runtime secrets that must
be set manually on the VPS after first deploy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 11:10:52 +03:00
bfc20ac293 fix(deps): add tailwind-merge to root package.json as direct dependency
Some checks failed
Deploy — Staging / Build & push — admin (push) Has been cancelled
Deploy — Staging / Build & push — storefront (push) Has been cancelled
Deploy — Staging / Deploy to staging VPS (push) Has been cancelled
Deploy — Staging / Lint, Typecheck & Test (push) Has been cancelled
turbo prune storefront --docker excludes admin, so tailwind-merge was
not installed at root in Docker (it was only hoisted because of admin's dep).
@heroui/styles/node_modules/tailwind-variants requires tailwind-merge >=3.0.0
and walks up to root to find it. Adding it as a root-level dep ensures npm ci
always installs it regardless of which workspace is being built.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 10:55:16 +03:00
33fed9382a fix(deps): upgrade tailwind-merge to v3 and declare lucide-react in storefront
Some checks failed
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 2m40s
Deploy — Staging / Build & push — admin (push) Successful in 3m40s
Deploy — Staging / Build & push — storefront (push) Failing after 2m39s
Deploy — Staging / Deploy to staging VPS (push) Has been skipped
- apps/admin: tailwind-merge ^2.6.1 → ^3.4.0 so root resolves to v3.x,
  satisfying @heroui/styles/node_modules/tailwind-variants peer dep (>=3.0.0)
- apps/storefront: add lucide-react ^0.400.0 as explicit dep (used in
  SearchEmptyState and SearchResultsPanel but was previously undeclared)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 10:31:29 +03:00
5b0a727bce fix(ci): replace turbo-pruned lockfile with full root lockfile to fix @heroui/react missing in Docker
Some checks failed
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 2m7s
Deploy — Staging / Build & push — admin (push) Successful in 3m20s
Deploy — Staging / Build & push — storefront (push) Failing after 2m30s
Deploy — Staging / Deploy to staging VPS (push) Has been skipped
turbo prune cannot fully parse the npm 11 lockfile format, causing it to
generate an incomplete out/package-lock.json that drops non-hoisted workspace
entries (apps/storefront/node_modules/@heroui/react and related packages).
Replacing it with the full root lockfile ensures npm ci in the Docker deps
stage installs all packages including non-hoisted ones.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 04:38:54 +03:00
5391b3b428 fix(docker): copy full deps stage into storefront builder, not just root node_modules
@heroui/react cannot be hoisted to the root by npm (peer dep constraints)
and is installed at apps/storefront/node_modules/ instead. The builder stage
was only copying /app/node_modules, leaving @heroui/react absent when
next build ran.

Switch to COPY --from=deps /app/ ./ so both root and workspace-level
node_modules are present, then COPY full/ . layers the source on top.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 04:20:43 +03:00
829fec9ac1 fix(ci): use --load + docker push instead of --push for HTTP registry
Some checks failed
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 2m8s
Deploy — Staging / Build & push — admin (push) Successful in 1m22s
Deploy — Staging / Build & push — storefront (push) Failing after 1m35s
Deploy — Staging / Deploy to staging VPS (push) Has been skipped
docker build --push uses buildkit's internal push which connects directly
to the registry over HTTPS, bypassing the Podman daemon. Since the Gitea
registry is HTTP-only, this fails with "server gave HTTP response to HTTPS client".

Switch to --load (exports image into Podman daemon) then docker push (goes
through the daemon which has insecure=true in registries.conf → uses HTTP).
Tag the SHA variant with docker tag before pushing both.

Also:
- Add NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME ARG/ENV to admin Dockerfile
- Add STAGING_ prefix note to both Dockerfiles builder stage
- Add STAGING_NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME to workflow env and
  pass it as --build-arg for admin builds only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 04:14:47 +03:00
6b63cbb6cd fix(ci): update Dockerfiles and workflow to include new Cloudinary environment variable
Some checks failed
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 2m6s
Deploy — Staging / Build & push — admin (push) Failing after 2m7s
Deploy — Staging / Build & push — storefront (push) Failing after 1m35s
Deploy — Staging / Deploy to staging VPS (push) Has been skipped
- Added NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME to both admin and storefront Dockerfiles to ensure it is available during the build process.
- Updated deploy-staging.yml to pass the new Cloudinary variable as a build argument.
- Clarified comments regarding the handling of NEXT_PUBLIC_* variables and Gitea secret prefixes.

This change enhances the build configuration for both applications, ensuring all necessary environment variables are correctly passed during the Docker build process.
2026-03-08 04:05:01 +03:00
bc7306fea4 fix(ci): pass NEXT_PUBLIC build args and fix docker push
Some checks failed
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 2m11s
Deploy — Staging / Build & push — admin (push) Failing after 2m8s
Deploy — Staging / Build & push — storefront (push) Failing after 1m42s
Deploy — Staging / Deploy to staging VPS (push) Has been skipped
Two issues in the admin (and upcoming storefront) build:

1. Missing Clerk publishableKey during prerender
   NEXT_PUBLIC_* vars are baked into the client bundle at build time. If absent,
   Next.js SSG fails with "@clerk/clerk-react: Missing publishableKey".
   Added ARG + ENV in both Dockerfiles builder stage and pass them via
   --build-arg in the workflow. Admin and storefront use different Clerk
   instances so the key is selected per matrix.app with a shell conditional.

2. "No output specified with docker-container driver" warning
   setup-buildx-action with driver:docker was not switching the driver in the
   Podman environment. Removed the step and switched to docker build --push
   which pushes directly during the build, eliminating the separate push steps
   and the missing-output warning.

New secrets required:
  STAGING_NEXT_PUBLIC_CONVEX_URL
  STAGING_NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY        (storefront)
  STAGING_ADMIN_NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY  (admin)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 03:31:58 +03:00
7a6da4f18f fix(ci): fix convex missing from prune output and npm version mismatch
Some checks failed
CI / Lint, Typecheck & Test (push) Successful in 2m5s
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 2m5s
Deploy — Staging / Build & push — admin (push) Failing after 3m11s
Deploy — Staging / Build & push — storefront (push) Failing after 2m23s
Deploy — Staging / Deploy to staging VPS (push) Has been skipped
Two root causes for the Docker build failures:

1. convex/_generated/api not found (both apps)
   turbo prune only traces npm workspace packages; the root convex/ directory
   is not a workspace package so it is excluded from out/full/. Copy it
   manually into the prune output after turbo prune runs.

2. @heroui/react not found (storefront)
   package-lock.json was generated with npm@11 but node:20-alpine ships
   npm@10. turbo warns it cannot parse the npm 11 lockfile and generates an
   incomplete out/package-lock.json, causing npm ci inside Docker to miss
   packages. Upgrade npm to 11 in the deps stage of both Dockerfiles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 03:16:29 +03:00
fc5f98541b fix(ci): fix deploy-staging registry and buildx driver issues
Some checks failed
CI / Lint, Typecheck & Test (push) Successful in 2m6s
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 2m56s
Deploy — Staging / Build & push — admin (push) Failing after 3m7s
Deploy — Staging / Build & push — storefront (push) Failing after 2m30s
Deploy — Staging / Deploy to staging VPS (push) Has been skipped
- Remove top-level env.REGISTRY — Gitea does not expand secrets in
  workflow-level env blocks; reference secrets.STAGING_REGISTRY directly
- Add docker/setup-buildx-action with driver: docker to avoid the
  docker-container driver which requires --privileged on rootless Podman
- Update secret names comment to clarify STAGING_ prefix convention
  (Gitea has no environment-level secrets, so prefixes distinguish staging/prod)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 02:55:41 +03:00
70b728a474 feat(docker): add Dockerfiles and update next.config.js for admin and storefront applications
Some checks failed
CI / Lint, Typecheck & Test (push) Successful in 2m7s
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 2m3s
Deploy — Staging / Build & push — admin (push) Failing after 1m8s
Deploy — Staging / Build & push — storefront (push) Failing after 1m5s
Deploy — Staging / Deploy to staging VPS (push) Has been skipped
- Introduced Dockerfiles for both admin and storefront applications to streamline the build and deployment process using multi-stage builds.
- Configured the Dockerfiles to install dependencies, build the applications, and set up a minimal runtime environment.
- Updated next.config.js for both applications to enable standalone output and set the outputFileTracingRoot for proper file tracing in a monorepo setup.

This commit enhances the containerization of the applications, improving deployment efficiency and reducing image sizes.
2026-03-08 02:02:58 +03:00
79640074cd feat(ci): add Gitea CI workflow for staging deployment
- Introduced a new workflow in deploy-staging.yml to automate the deployment process for the staging environment.
- The workflow includes steps for CI tasks (linting, type checking, testing), building and pushing Docker images for storefront and admin applications, and deploying to a VPS.
- Configured environment variables and secrets for secure access to the Docker registry and VPS.

This commit enhances the CI/CD pipeline by streamlining the deployment process to the staging environment.
2026-03-08 01:42:57 +03:00
c1ab930e48 fix: ignore convex-test scheduler unhandled rejections in Vitest
All checks were successful
CI / Lint, Typecheck & Test (push) Successful in 2m11s
Add onUnhandledError to filter 'Write outside of transaction ...
_scheduled_functions' errors so CI passes. These occur when
order/fulfillment mutations schedule email sends and convex-test
runs them after the transaction closes.

Made-with: Cursor
2026-03-08 01:20:22 +03:00
9013905d01 fix: resolve CI test failures (carts, stripe, shipping, scaffold, cart session)
Some checks failed
CI / Lint, Typecheck & Test (push) Failing after 2m13s
- carts.test: add required product fields (parentCategorySlug, childCategorySlug)
  and variant fields (weight, weightUnit)
- stripeActions.test: use price in cents (2499) for variant/cart and expect
  unit_amount: 2499 in line_items assertion
- useShippingRate.test: expect fallback error message for plain Error rejections
- scaffold.test: enable @ alias in root vitest.config for storefront imports
- useCartSession.test: mock useConvexAuth instead of ConvexProviderWithClerk
  for reliable unit tests

Made-with: Cursor
2026-03-08 01:05:51 +03:00
23efcab80c fix: resolve CI and workspace lint errors (admin + storefront)
Some checks failed
CI / Lint, Typecheck & Test (push) Failing after 2m11s
- Allow require() in next.config.js (eslint-disable) for both apps
- Replace all catch (e: any) with catch (e: unknown) and proper error handling
- Remove no-explicit-any: add types (PreviewProduct, ProductImage, Id<addresses>,
  ProductDetailReview, error payloads) across admin and storefront
- Admin: use next/image in ImageUploadSection and ProductImageCarousel; remove
  unused layout fonts and sidebar imports; fix products page useMemo deps
- Storefront: use Link for /sign-in in header actions; fix useAddressMutations
  and product detail types; remove unused imports/vars and fix useMemo deps

Made-with: Cursor
2026-03-08 00:45:57 +03:00
2f5537cf7e feat(lint): add ESLint configuration for admin and storefront applications
Some checks failed
CI / Lint, Typecheck & Test (push) Failing after 1m16s
- Introduced eslint.config.mjs files for both admin and storefront to extend Next.js linting rules.
- Updated package.json files to replace the default Next.js lint command with a direct ESLint command for improved linting control.
2026-03-08 00:37:15 +03:00
51663df27d ci: add Gitea CI workflow and track Convex generated types
Some checks failed
CI / Lint, Typecheck & Test (push) Failing after 2m11s
- Add .gitea/workflows/ci.yml — runs lint, typecheck, and tests on every push
- Remove convex/_generated from .gitignore and commit the generated files so CI
  has the type information it needs without requiring a live Convex backend

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 00:25:45 +03:00
9cee6b0671 Merge pull request 'feat/admin' (#2) from feat/admin into main
Reviewed-on: http://72.61.144.167:3000/admin/the-pet-loft/pulls/2
2026-03-07 20:51:12 +00:00
9e1ec55c46 Merge pull request 'feat(storefront): add payment/carrier assets, CustomerConfidenceBooster, and footer enhancements' (#1) from feat/storefront into main
Reviewed-on: http://72.61.144.167:3000/admin/the-pet-loft/pulls/1
2026-03-07 20:49:34 +00:00
e28a6524a3 feat(env): update .gitignore and package files for Convex integration
- Added .env.staging files for admin and storefront applications to .gitignore.
- Updated package.json and package-lock.json to include @convex-dev/resend and its dependencies.
- Introduced new Convex-related modules and updated peer dependencies for better compatibility.

This commit enhances the environment configuration and integrates the Resend service into the project.
2026-03-07 22:50:45 +03:00
5f7c3cece9 feat(orders): implement return request functionality and order timeline
- Added RequestReturnDialog component for initiating return requests.
- Enhanced OrderDetailPageView to handle return requests and display order timeline.
- Updated OrderActions to include return request button based on order status.
- Introduced OrderTimeline component to visualize order events.
- Modified order-related types and constants to support return functionality.
- Updated UI components for better styling and user experience.

This commit improves the order management system by allowing users to request returns and view the timeline of their orders.
2026-03-07 19:47:55 +03:00
0f91d3dc05 feat(convex): add implementation rules and configuration for backend functions
- Introduced a comprehensive markdown document outlining implementation rules for Convex functions, including syntax, registration, HTTP endpoints, and TypeScript usage.
- Created a new configuration file for the Convex app, integrating the Resend service.
- Added a new HTTP route for handling Shippo webhooks to ensure proper response handling.
- Implemented integration tests for order timeline events, covering various scenarios including order fulfillment and status changes.
- Enhanced existing functions with type safety improvements and additional validation logic.

This commit establishes clear guidelines for backend development and improves the overall structure and reliability of the Convex application.
2026-03-07 19:32:06 +03:00
83a5172397 feat(admin): update configuration and documentation for order processing
- Removed .env.example file as it is no longer needed.
- Updated next.config.js to include turbopack configuration.
- Added detailed implementation plans for order processing and UI design in new markdown files.
- Introduced API usage guide for background removal service.

This commit enhances the order processing backend and UI design documentation, ensuring clarity and improved configuration management.
2026-03-07 19:31:10 +03:00
3d50cb895c feat(orders): implement QA audit fixes — return flow, refund webhook, TS cleanup
Convex backend (AUDIT-5–10):
- schema: add returnLabelUrl, returnTrackingNumber, returnCarrier fields +
  by_return_tracking_number_and_carrier and by_stripe_payment_intent_id indexes
- orders: markReturnReceived now sets status="completed"; add getOrderByPaymentIntent
  and applyReturnAccepted internal helpers
- returnActions: add acceptReturn action — creates Shippo return label (is_return:true),
  persists label data, sends return label email to customer
- stripeActions: handle refund.updated webhook to auto-mark orders refunded via Stripe Dashboard
- shippoWebhook: add getOrderByReturnTracking; applyTrackingUpdate extended with
  isReturnTracking flag (return events use return_tracking_update type, skip delivered transition)
- emails: add sendReturnLabelEmail; fulfillmentActions: createShippingLabel action

Admin UI (AUDIT-1–6):
- OrderActionsBar: full rewrite per authoritative action matrix; remove UpdateStatusDialog;
  add AcceptReturnButton for delivered+returnRequested state
- AcceptReturnButton: new action component matching CreateLabelButton pattern
- FulfilmentCard: add returnLabelUrl prop; show "Return label" row; rename outbound
  label to "Outbound label" when both are present
- statusConfig: add return_accepted to OrderEventType and EVENT_TYPE_LABELS
- orders detail page and all supporting cards/components

Storefront & shared (TS fixes):
- checkout/success, CheckoutErrorState, OrderReviewStep, PaymentStep: replace
  Button as/color/isLoading/variant="flat" with HeroUI v3-compatible props
- ReviewList: isLoading → isPending for HeroUI v3 Button
- packages/utils: add return and completed entries to ORDER_STATUS_LABELS/COLORS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 17:59:29 +03:00
8e4309892c feat(admin): implement variant management — list, create, edit, preview, activate/deactivate, delete (Plan 05)
- Extend addVariant with dimension fields and SKU uniqueness check; expand updateVariant to full field set; update getByIdForAdmin to return all variants (active + inactive)
- Add generateSku utility to @repo/utils; auto-generates SKU from brand, product name, attributes, and weight with manual-override support
- Move ProductSearchSection to components/shared and fix nav link /variants → /variant
- Variants page: product search, loading skeleton, variants table, toolbar with create button
- VariantsTable: 8 columns, activate/deactivate toggle, delete with AlertDialog confirmation
- VariantPreviewDialog: read-only full variant details with sections for pricing, inventory, shipping, attributes
- VariantForm: zod schema with superRefine for dimension and on-sale validation, auto-SKU generation
- CreateVariantDialog and EditVariantDialog wiring dollarsToCents on submit
- Install sonner and add Toaster to root layout; install ShadCN Switch component

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 09:32:32 +03:00
1ea527ca1f feat(admin): implement product image upload & gallery management (Plan 04)
- Add Next.js API route for server-side Cloudinary upload with structured
  public_id (the-pet-loft/products/{id}/main|gallery-n) and asset_folder
  for portal folder visibility in dynamic folder mode
- Add background removal flow via Image Processing API with side-by-side
  original vs processed preview (Skeleton while loading)
- Dual upload buttons: processed (background removed) or original file
- Horizontal drag-and-drop image gallery using @dnd-kit/sortable with
  horizontalListSortingStrategy; reorder persisted via reorderImages mutation
- Per-image delete with AlertDialog confirmation
- 180° rotation technique for card layout: drag handle top, image center,
  delete bottom
- Debounced product search (300 ms) with inline results (max 3); clears
  gallery state when search input is cleared
- Install: cloudinary, @dnd-kit/core/sortable/utilities, embla-carousel-react,
  ShadCN carousel component
- Configure next.config.js with Cloudinary remote image pattern
- Mark checklist items 3.5 and 3.6 complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 06:45:03 +03:00
5168553bae feat(admin): implement product management — list, create, edit, archive (Plan 03)
Covers checklist items 3.1–3.4, 3.10–3.11 (product list, create, edit,
archive/restore, SEO fields, admin search).

Backend (convex/products.ts):
- Extended create/update with shortDescription, brand, attributes,
  seoTitle, seoDescription, canonicalSlug
- Both mutations now set createdAt/updatedAt timestamps
- Added getByIdForAdmin (admin-only, returns full product with relations)

UI — new pages:
- products/page.tsx: table with debounced search, column visibility
  dropdown, client-side sort, 10-row skeleton, load-more pagination,
  row preview dialog, per-row actions menu
- products/new/page.tsx: create product page
- products/[id]/edit/page.tsx: pre-populated edit page with archive button

UI — new components:
- ProductForm: shared form (create + edit); zod + react-hook-form,
  auto-slug, collapsible Attributes + SEO sections, submit spinner
- ProductPreviewDialog: read-only full-product dialog
- ProductActionsMenu: kebab menu (Edit link + Archive AlertDialog)

ShadCN components installed: table, badge, alert-dialog, dialog,
scroll-area, form, select, label, checkbox, textarea

Also:
- Updated CLAUDE.md: form submit buttons must use inline SVG spinner
  with data-icon="inline-start"; link-styled buttons use buttonVariants
  on <Link> (Button render prop not in TS types)
- Updated docs: checklist and plan marked complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 17:38:13 +03:00
a5e61d02fd feat(storefront): add payment/carrier assets, CustomerConfidenceBooster, and footer enhancements
- Add payment method SVGs (Visa, Mastercard, Apple Pay, Google Pay, Klarna, Link, Revolut Pay, Billie, Cartes, Discover)
- Add carrier images (DPD, Evri)
- Add CustomerConfidenceBooster section component
- Enhance Footer with payment methods and carrier display
- Wire CustomerConfidenceBooster into shop pages (PetCategory, RecentlyAdded, ShopIndex, SubCategory, Tag, TopCategory) and home page
- Update tsconfig.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 14:48:02 +03:00
2dc8878db7 feat(admin): implement navigation & layout (Plan 02, Phases 1–3)
Phase 1 — Active route highlighting
- NavMain derives isActive from usePathname() at render time
- Flat links: exact match; collapsible groups: startsWith; sub-items: exact match
- Removed hardcoded isActive fields from NAV_LINKS

Phase 2 — Dynamic breadcrumbs
- Added ROUTE_LABELS map to app.constants.ts
- Created DynamicBreadcrumb component (pathname-driven, ShadCN primitives)
- Wired DynamicBreadcrumb into dashboard layout header

Phase 3 — Mobile shell (observation only, no structural changes needed)

Icons — migrated all sidebar/breadcrumb icons from lucide-react to @hugeicons/react + @hugeicons/core-free-icons

Infra
- tsconfig.json: moduleResolution → bundler (required for hugeicons ESM exports)
- Renamed middleware.ts → proxy.ts (Next.js 15.5 convention)
- Added @hugeicons/mcp-server to .mcp.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 19:41:52 +03:00
a897089fdc feat(admin): implement admin auth & authorization system (Phases 0–6)
Complete implementation of the admin authentication and authorization
plan using a separate Clerk instance (App B) for cryptographic isolation
from the storefront.

Convex backend changes:
- auth.config.ts: dual JWT provider (storefront + admin Clerk issuers)
- http.ts: add /clerk-admin-webhook route with separate signing secret
- users.ts: role-aware upsertFromClerk (optional role arg), store reads
  publicMetadata.role from JWT, assertSuperAdmin internal query
- model/users.ts: add requireSuperAdmin helper
- adminInvitations.ts: inviteAdmin action (super_admin gated, Clerk Backend SDK)

Admin app (apps/admin):
- Route groups: (auth) for sign-in, (dashboard) for gated pages
- AdminUserSync, AdminAuthGate, AccessDenied, LoadingSkeleton components
- useAdminAuth hook with loading/authorized/denied state machine
- RequireRole component for super_admin-only UI sections
- useStoreUserEffect hook for Clerk→Convex user sync
- Sidebar shell with nav-main, nav-user, app-sidebar
- clerkMiddleware with /sign-in excluded from auth.protect
- ShadCN UI components (sidebar, dropdown, avatar, etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 16:13:07 +03:00
cc15338ad9 feat: initial commit — storefront, convex backend, and shared packages
Completes the first milestone of The Pet Loft ecommerce platform:
- apps/storefront: full customer-facing Next.js app with HeroUI (cart,
  checkout, orders, wishlist, product detail, shop, search, auth)
- convex/: serverless backend with schema, queries, mutations, actions,
  HTTP routes, Stripe/Shippo integrations, and co-located tests
- packages/types, packages/utils, packages/convex: shared workspace packages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 09:31:18 +03:00