Files
mercadodevida/work/artifacts/F-019/architect.md
2026-08-17 22:23:10 +02:00

1.5 KiB

Architect — F-019 Promotions v1

Feature

F-019 adds server-side promo code validation and discount calculation. Discounts are recalculated from current cart totals and never trusted from the client.

Design

Module boundaries

Create project/src/modules/promotions/ with domain/application/infrastructure/api/tests. Promotions owns promo definitions and validation. Cart receives a public PromotionServicePort from the composition root and stores only the selected promo code, not discount amounts.

Data model

Add migration 014_promotions.js:

  • promotions_promotions: code, type (percent, fixed_amount), value, validity window, usage_limit, usage_count, active, timestamps.
  • Add promo_code text to cart_carts.

Rules

  • Percent discounts are basis points over current cart total.
  • Fixed amount discounts are cents and capped at current cart total.
  • Validity checks: active, starts_at <= now, ends_at >= now, usage_count < usage_limit when limit exists.
  • No stacking in v1: one promo code per cart.
  • Client discount fields are stripped/ignored by cart schemas.

API

  • Admin POST /promotions creates promo codes.
  • Public/authenticated cart endpoint POST /cart/promo-code stores a code after server validation.
  • GET /cart recalculates discount through PromotionService.

Acceptance trace

  • Valid promo: cart read applies recalculated server discount.
  • Expired/exhausted: applying code returns HTTP 422 reason.
  • Client discount ignored: schemas strip discount fields and cart stores no discount amount.