Rempla plans schedule gifts years -- sometimes decades -- into the future. The catalog is designed from day one to tolerate vendor churn, price drift, and catalog rewrites without ever breaking a customer's original promise.
Most e-commerce catalogs you've used separate the thing customers see from the variants they pick from the vendor-specific fulfillment. Rempla follows the same pattern -- Shopify, Amazon, BigCommerce all work this way -- and uses the separation to survive the long scheduling horizons our plans demand.
Each tier has a distinct job. The boundaries matter: if we blur them, the catalog gets harder to maintain and vendor swaps become risky.
Vendor-agnostic. Carries the name, description, category, and default lead time. No price, no vendor, no SKU lives here.
| Name | "Dozen Red Roses" |
| Category | Flowers |
| Default lead time | 3 days |
| Occasions | Anniversary, Valentine's Day, Just Because |
A selectable option under a product: size, color, configuration. Customers see these on the gift card. Still vendor-agnostic -- still no price.
| Under product | "Dozen Red Roses" |
| Name | "12 stems red" |
| Size | 12 |
| Color | Red |
A specific variant offered by a specific vendor. This is where money, SKUs, and availability live. A single variant can have multiple offers at once.
| Our SKU | REM-000123 |
| Vendor | FTD |
| Vendor SKU | FTD-ROSE-DOZEN |
| Vendor cost | $45.00 |
| List price | $65.00 |
| Status | Active |
| Priority | 10 (higher wins) |
A customer schedules a gift in 2026 to be delivered in 2036. By 2036, the vendor they originally quoted against may be out of business, acquired, or simply retired from our network. We can't tell the customer ten years later that their gift failed because our supplier changed.
|
At Order Creation
Bind to Variant Only
The order records what the customer picked (the variant) and what we promised (the price). It does not lock in a specific vendor. |
At Delivery Time
Pick the Best Live Offer
When a scheduled delivery fires, the system queries the currently-active vendor offers for the variant and picks the winner by priority and availability. |
Retiring a vendor is a status change, not a delete. The vendor row stays, the offers stay (marked Disabled), the historical audit trail is preserved, and any in-flight order simply routes through the next-best active offer for its variant. No bulk order invalidation. No mass customer notification.
Each order item carries a policy for what the system is allowed to do if no offer exists for the original variant at execution time:
| Exact | Same variant only. Fail if unavailable. |
| VariantEquivalent | Admin-curated acceptable replacements. |
| ProductEquivalent | Any variant of the same product is fine. |
| Cancel | Fail cleanly. No substitution ever. |
Vendor prices drift. Marketing photos get retaken. Product descriptions get rewritten. None of that should change what a customer sees on a plan they bought years ago.
When an order is created, the price the customer is quoted is frozen onto the order item. It's honored at delivery execution regardless of what the current vendor offer costs. If vendor pricing rises, the business absorbs the variance. If it drops, the business keeps the margin. The customer never sees the delta.
The order item also captures a snapshot of the product's name, description, and hero image at purchase time. A ten-year-old plan summary shows what the customer originally picked -- not whatever the catalog entry has since been rewritten to say. New purchases always use the live catalog; historical orders always use their snapshot.
Adjacent domains (remembrance plans, the vault, orders) all have legitimate pressure to push their concerns into the catalog. We resist that. The catalog is a descriptive "what can be bought, from whom, at what price" model -- nothing else.
|
Catalog Owns
|
Lives Elsewhere
|
Any future proposal to add PlanId, IsPersonalizable, IsScheduledOnly, RecipientId, VaultBoxSize, or similar plan/vault/order-specific fields to Product, ProductVariant, or VendorOffer should be treated as domain drift and relocated -- not merged.
Categories are the "what type of thing is this?" axis, single-valued per product. Occasions are the "when is this good to give?" axis, many-valued per product. A dozen red roses might carry one category (Flowers) and several occasions (Anniversary, Valentine's Day, Just Because).
|
Categories (seeded, 6)
|
Occasions (seeded, 9)
|
As of April 19, 2026.
Rempla.CoreAddProductCatalog applied to the dev databaseREM-NNNNNN SKUs on insert