Skip to content

feat(commerce): add product variants and size guide config#299

Merged
onerandomdevv merged 2 commits into
devfrom
feat/product-variants-sizeguide
May 21, 2026
Merged

feat(commerce): add product variants and size guide config#299
onerandomdevv merged 2 commits into
devfrom
feat/product-variants-sizeguide

Conversation

@SAHEED2010
Copy link
Copy Markdown
Collaborator

@SAHEED2010 SAHEED2010 commented May 21, 2026

What does this PR do?

Implements B-11c — Product Variants + Size Guide Config. This extends the product flow with variant combination generation, image-to-variant assignment support, product size guide configuration, and idempotent seeding for all 7 platform-managed SizeGuide records.

Task

B-11c — Product: Variants + Size Guide Config

What changed

  • Added variant support to product create/update DTOs
  • Added product variant combination generation
  • Added auto-generated variantLabel behavior
  • Added priceOverride handling where null falls back to product.retailPriceKobo
  • Added ProductImage assignedVariantIds support
  • Added fallback behavior where empty assignedVariantIds means image applies to all variants
  • Added ProductSizeGuideConfig creation when productSubCategory is present
  • Added support for all 7 platform guide types:
    • CLOTHING_WOMEN
    • CLOTHING_MEN
    • CLOTHING_CHILDREN
    • CLOTHING_UNISEX
    • FOOTWEAR_WOMEN
    • FOOTWEAR_MEN
    • FOOTWEAR_CHILDREN
  • Updated product detail response to include variant and size guide config data
  • Updated prisma/seed.ts to upsert all 7 platform SizeGuide records idempotently

Files changed

  • apps/backend/src/domains/commerce/product/dto/create-product.dto.ts
  • apps/backend/src/domains/commerce/product/dto/update-product.dto.ts
  • apps/backend/src/domains/commerce/product/product.service.ts
  • apps/backend/src/prisma/seed.ts

Verification

  • pnpm.cmd run lint — PASS
  • npx.cmd tsc --noEmit — PASS
  • pnpm.cmd run build — PASS
  • npx.cmd prisma db seed — PASS

Seed result

npx.cmd prisma db seed completed successfully.

All 7 platform SizeGuide records are upserted idempotently.

The seed also printed an existing environment warning: ADMIN_BOOTSTRAP_PASSWORD is missing, so admin creation was skipped. This is unrelated to B-11c.

Scope control

  • No Prisma migration added
  • No POST /size-guides endpoint added
  • No upload/moderation logic added
  • No inventory stock cache logic added
  • No embedding generation added
  • No posts/feed/search/order/payment/payout logic added
  • No unrelated Clawpatch findings patched
  • .env.local was not staged or committed

Type of change

  • New feature
  • Bug fix
  • Refactor / cleanup
  • Database migration included
  • Chore / maintenance
  • Documentation

Area affected

  • Backend
  • Web
  • WhatsApp
  • Shared package
  • Database / Prisma
  • GitHub / CI / infrastructure

How to test this

  1. Create or update a product with variant dimension values such as color and size.
  2. Confirm the backend generates variant combinations with readable variantLabel values.
  3. Create or update a product with image assignedVariantIds.
  4. Confirm product detail response includes variants, image variant assignment data, and size guide config.
  5. Run npx.cmd prisma db seed.

Expected result:

  • Variant combinations are generated correctly.
  • priceOverride: null falls back to the product retail price.
  • Product images with empty assignedVariantIds apply to all variants.
  • Product detail response includes variant data and size guide config.
  • All 7 platform SizeGuide records are present after seed.
  • Running seed multiple times does not create duplicate SizeGuide records.

Pre-commit checklist

  • Backend lint/type/build pass when backend is affected
  • Web lint/type/build pass when web is affected
  • Shared package build passes when shared is affected
  • No console.log left in production code
  • No secrets or .env files committed
  • No new any types added
  • No non-MVP legacy features reintroduced
  • All money values are BigInt kobo, never float
  • Paystack webhook changes verify HMAC before processing
  • Database migrations are Prisma migrations, not db push
  • Database migrations are backward-compatible or risk is documented

Screenshots

N/A — backend-only PR. No UI changes.

Notes for reviewer

This task was originally assigned to Developer A but was handed over. The PR is intentionally scoped to B-11c only: variants, image assignment metadata, size guide config, and SizeGuide seed records.

Summary by CodeRabbit

Release Notes

  • New Features
    • Products now support variants with customizable options for different configurations and combinations
    • Implemented comprehensive product image upload and management with content moderation capabilities
    • Added configurable size guides to provide detailed product specifications and sizing information

Review Change Stack

@SAHEED2010 SAHEED2010 requested a review from onerandomdevv as a code owner May 21, 2026 13:47
@codesandbox
Copy link
Copy Markdown

codesandbox Bot commented May 21, 2026

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

Warning

Rate limit exceeded

@SAHEED2010 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 42 minutes and 59 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8975b2ea-7e2c-441e-afb0-68d5e95a8b71

📥 Commits

Reviewing files that changed from the base of the PR and between f00df00 and 7f05f30.

📒 Files selected for processing (2)
  • apps/backend/src/domains/commerce/product/product.service.ts
  • apps/backend/src/prisma/seed.ts
📝 Walkthrough

Walkthrough

This PR extends the product domain with support for variants (with dimensional overrides), product images with moderation status, and platform size guides. Input DTOs define nested validation contracts, the service refactors create and update flows into Prisma transactions, and a seeding script provisions default size guides.

Changes

Product variants, images, and size guides

Layer / File(s) Summary
Input DTOs and validation contracts
apps/backend/src/domains/commerce/product/dto/create-product.dto.ts, apps/backend/src/domains/commerce/product/dto/update-product.dto.ts
New nested DTOs (ProductVariantOverrideDto, ProductVariantOptionsDto, ProductImageInputDto, ProductSizeGuideConfigDto) define input contracts with class-validator rules. CreateProductDto and UpdateProductDto are extended with optional hasVariants, variantOptions, images, and sizeGuideConfig fields.
Data layer shapes and Prisma selections
apps/backend/src/domains/commerce/product/product.service.ts (imports, types, selects)
Prisma select objects retrieve variants, images, and size guides; public selects filter to active variants and non-blocked images. Response interfaces (OwnerProductResponse, PublicProductResponse) are extended with variants, images, and optional size guide config fields. Internal types map Prisma records to response and write shapes.
Product creation with variants and images
apps/backend/src/domains/commerce/product/product.service.ts (createProduct)
createProduct extracts variant options, normalizes images, and derives size guide config from DTO, then persists in a single transaction: product creation, variant/image/size guide creation, and reload with expanded selections.
Product update with variant and image rebuild
apps/backend/src/domains/commerce/product/product.service.ts (updateProduct)
updateProduct computes whether to rebuild variants/images based on DTO changes, conditionally deletes and recreates them in a transaction. Size guide config is upserted when provided and deleted when explicitly null.
Variant/image helpers and response mapping
apps/backend/src/domains/commerce/product/product.service.ts (helpers, mapping)
Private helpers generate variant combinations, validate dimensions, normalize images, resolve variant IDs from labels, and transform size guide config for persistence. toOwnerResponse and toPublicResponse populate mapped variants, images, and size guides; new helpers transform records to response shapes with stringification.
Seed platform size guides
apps/backend/src/prisma/seed.ts
Seed script defines sizeGuidesToSeed array with dimensional ranges for clothing and footwear guide types, then upserts them in main() with version and active flags.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • onerandomdevv

🐰 Variants dance in dimensions new,
Images bloom with guiding hue,
Transactions wrap the three in one,
Size guides bloom—the commerce dance is done!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main feature: adding product variants and size guide configuration to the commerce domain.
Description check ✅ Passed The PR description comprehensively covers the template sections with detailed what/why, type of change, affected areas, testing steps, verification, and scope control.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/product-variants-sizeguide

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

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
apps/backend/src/prisma/seed.ts (2)

14-17: ⚡ Quick win

Rename the seed constant to SCREAMING_SNAKE_CASE.

sizeGuidesToSeed should follow the constants naming rule.

Suggested change
-const sizeGuidesToSeed: Array<{
+const SIZE_GUIDES_TO_SEED: Array<{
   type: GuideType;
   sizes: Prisma.InputJsonValue;
 }> = [
...
-  for (const guide of sizeGuidesToSeed) {
+  for (const guide of SIZE_GUIDES_TO_SEED) {

As per coding guidelines, "Use SCREAMING_SNAKE_CASE for enum values and constants".

Also applies to: 345-345

🤖 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/backend/src/prisma/seed.ts` around lines 14 - 17, Rename the constant
sizeGuidesToSeed to SCREAMING_SNAKE_CASE (e.g., SIZE_GUIDES_TO_SEED) everywhere
it's declared and referenced in the file (seed.ts) to follow the constants
naming rule; update the const declaration and any uses of sizeGuidesToSeed
(including the other occurrence around line 345) to the new NAME so imports/refs
remain consistent.

344-344: ⚡ Quick win

Avoid introducing new console.log in backend code.

Use structured logging (nestjs-pino/pino logger) instead of console.log for this new log line.

As per coding guidelines, "Never use 'console.log' in production code — use NestJS Logger (pino) for backend, guarded development checks for frontend".

🤖 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/backend/src/prisma/seed.ts` at line 344, Replace the console.log call
that prints "Syncing platform size guides..." with a structured pino logger
call: import pino (or use the existing nestjs-pino logger if available in this
script), create/get a logger instance (e.g., const logger = pino() or use
injected PinoLogger) and call logger.info('Syncing platform size guides...');
remove the console.log line so all backend logging uses pino/nestjs-pino
instead.
apps/backend/src/domains/commerce/product/dto/create-product.dto.ts (1)

131-143: ⚡ Quick win

Rename boolean fields to required prefixes.

includesFootwear and useCustomSizes don’t follow the backend boolean naming convention. Please rename them to prefixed forms (for example hasFootwear / isUsingCustomSizes) for consistency across DTO/service contracts.

As per coding guidelines, "All boolean field names must be prefixed with 'is', 'has', 'can', or 'should' (e.g. isActive, hasVariants)".

🤖 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/backend/src/domains/commerce/product/dto/create-product.dto.ts` around
lines 131 - 143, Rename the boolean fields in ProductSizeGuideConfigDto to
follow boolean-prefix convention: change includesFootwear -> hasFootwear and
useCustomSizes -> isUsingCustomSizes; update the property names and any related
decorators/validation (`@IsOptional`, `@IsBoolean`) in the ProductSizeGuideConfigDto
class and then update all usages (constructors, mappers, services, tests,
serializers, API contracts) that read or write ProductSizeGuideConfigDto so they
reference hasFootwear and isUsingCustomSizes instead of the old names to keep
DTO/service contracts consistent.
🤖 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/backend/src/domains/commerce/product/product.service.ts`:
- Line 377: Replace the current logic that picks imageUrl from images[0] with
logic that finds the image marked isDefault; specifically, wherever imageUrl is
set from images[0] (the occurrences around the imageUrl assignment at lines
noted), change it to use images?.find(img => img.isDefault)?.url ?? null so the
primary image comes from the default flag and still safely falls back to null if
none exist; update both occurrences mentioned (the two imageUrl assignments) and
ensure you handle images being undefined or empty.
- Around line 567-596: When variants are rebuilt (productVariant.deleteMany +
this.createProductVariants) but images are left unchanged,
image.assignedVariantIds can reference deleted variant IDs; update the update
path in product.service.ts so that after creating new variants
(createProductVariants) and before keeping/creating images (createProductImages)
you either (a) clear assignedVariantIds on existing productImage records or (b)
remap/filter assignedVariantIds to only IDs present in the newly created
variants; implement this logic in the branch that handles variants !== null and
images === null (and the branch using createdVariants when images are provided)
by loading existing product images (tx.productImage.findMany) and updating their
assignedVariantIds with tx.productImage.updateMany / update to ensure no stale
variant IDs remain.

---

Nitpick comments:
In `@apps/backend/src/domains/commerce/product/dto/create-product.dto.ts`:
- Around line 131-143: Rename the boolean fields in ProductSizeGuideConfigDto to
follow boolean-prefix convention: change includesFootwear -> hasFootwear and
useCustomSizes -> isUsingCustomSizes; update the property names and any related
decorators/validation (`@IsOptional`, `@IsBoolean`) in the ProductSizeGuideConfigDto
class and then update all usages (constructors, mappers, services, tests,
serializers, API contracts) that read or write ProductSizeGuideConfigDto so they
reference hasFootwear and isUsingCustomSizes instead of the old names to keep
DTO/service contracts consistent.

In `@apps/backend/src/prisma/seed.ts`:
- Around line 14-17: Rename the constant sizeGuidesToSeed to
SCREAMING_SNAKE_CASE (e.g., SIZE_GUIDES_TO_SEED) everywhere it's declared and
referenced in the file (seed.ts) to follow the constants naming rule; update the
const declaration and any uses of sizeGuidesToSeed (including the other
occurrence around line 345) to the new NAME so imports/refs remain consistent.
- Line 344: Replace the console.log call that prints "Syncing platform size
guides..." with a structured pino logger call: import pino (or use the existing
nestjs-pino logger if available in this script), create/get a logger instance
(e.g., const logger = pino() or use injected PinoLogger) and call
logger.info('Syncing platform size guides...'); remove the console.log line so
all backend logging uses pino/nestjs-pino instead.
🪄 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: 32aac3f9-d1e7-47a6-bb0f-8d8e3dd5ff7b

📥 Commits

Reviewing files that changed from the base of the PR and between cfe1aac and f00df00.

📒 Files selected for processing (4)
  • apps/backend/src/domains/commerce/product/dto/create-product.dto.ts
  • apps/backend/src/domains/commerce/product/dto/update-product.dto.ts
  • apps/backend/src/domains/commerce/product/product.service.ts
  • apps/backend/src/prisma/seed.ts

Comment thread apps/backend/src/domains/commerce/product/product.service.ts Outdated
Comment thread apps/backend/src/domains/commerce/product/product.service.ts
onerandomdevv
onerandomdevv previously approved these changes May 21, 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