diff --git a/planning/20_Domain_Consignment.md b/planning/20_Domain_Consignment.md new file mode 100644 index 0000000..7a411d1 --- /dev/null +++ b/planning/20_Domain_Consignment.md @@ -0,0 +1,212 @@ +Forte — Music Store Management Platform + +Domain Design: Consignment + +Version 1.0 | Draft + + + +# 1. Overview + +The Consignment domain manages inventory that is owned by a third party (the consignor) and sold on their behalf by the store. The store earns a commission on each sale and owes the consignor the remainder. Consignment is common in music retail — individuals and local dealers bring in used instruments, vintage gear, or specialty items for the store to sell. + +Consignment items appear in the regular product catalog and POS — customers do not see any difference between store-owned and consignment inventory. The distinction is purely internal for accounting, commission tracking, and consignor settlement. + + + +# 2. Core Concepts + +## 2.1 Consignor + +A consignor is the person or business who owns the item. They are represented as an `account` in the system — they may also be a customer who buys from the store. Using the account entity means consignors have payment info on file for settlement payouts. + +## 2.2 Consignment Detail + +A `consignment_detail` record links a product to its consignor and defines the commission terms. If a product has a consignment_detail, it is consignment inventory. If not, it is store-owned. + +## 2.3 Commission + +The store's cut of a consignment sale. Defined as a percentage on the consignment_detail record. Example: 30% commission means the store keeps 30% of the sale price, the consignor receives 70%. + +## 2.4 Minimum Price + +Consignors may set a floor price below which the item cannot be sold without their approval. Stored on consignment_detail. POS enforces this — if a staff member attempts to sell below min price, the system warns and requires override. + +## 2.5 Settlement + +Periodic payout to the consignor for their sold items. Typically monthly. The store reviews all consignment sales for the period, deducts commission, and pays the consignor the balance. + + + +# 3. Database Schema + +## 3.1 consignment_detail + +Extension table on product — one record per consignment product. + +Column | Type | Notes +id | uuid PK | +product_id | uuid FK → product | The consignment item +company_id | uuid FK → company | Tenant scoping +consignor_account_id | uuid FK → account | Who owns the item +commission_percent | numeric(5,2) | Store's cut — e.g. 30.00 = 30% +min_price | numeric(10,2) | Nullable — floor price set by consignor +agreement_date | date | When consignment agreement was made +notes | text | Terms, special conditions +is_active | boolean | False when item returned to consignor unsold +created_at | timestamptz | + +## 3.2 consignment_settlement + +Records each payout to a consignor. Groups all consignment sales for a period. + +Column | Type | Notes +id | uuid PK | +company_id | uuid FK | +consignor_account_id | uuid FK → account | +period_start | date | Settlement period start +period_end | date | Settlement period end +total_sales | numeric(10,2) | Sum of sale prices for period +total_commission | numeric(10,2) | Store's cut +total_payout | numeric(10,2) | Amount owed to consignor (sales - commission) +status | enum | pending, paid, cancelled +paid_date | date | When consignor was paid +paid_via | varchar | check, ach, cash, account_credit +notes | text | +created_by | uuid FK | Employee who created settlement +created_at | timestamptz | + +## 3.3 consignment_settlement_line + +Individual sold items included in a settlement. + +Column | Type | Notes +id | uuid PK | +settlement_id | uuid FK → consignment_settlement | +product_id | uuid FK → product | +transaction_id | uuid FK → transaction | The sale transaction +sale_price | numeric(10,2) | What it sold for +commission_amount | numeric(10,2) | Store's cut on this item +consignor_amount | numeric(10,2) | Consignor's payout on this item +sold_date | date | +created_at | timestamptz | + + + +# 4. Consignment Lifecycle + +Status | Description +intake | Item received from consignor — product created, consignment_detail linked, inventory_unit created with status 'available' +listed | Item is in the catalog and available for sale at POS +sold | Item sold — commission calculated, included in next settlement +settled | Consignor has been paid for the item +returned | Item returned to consignor unsold — consignment_detail.is_active set to false, inventory_unit retired +expired | Agreement period ended without sale — store contacts consignor to pick up or renew + + + +# 5. Key Workflows + +## 5.1 Consignment Intake + +- Consignor brings item to store (or store picks up) +- Staff creates account for consignor if not existing +- Staff creates product entry for the item (serialized, with description, photos) +- Staff creates consignment_detail — links product to consignor account, sets commission %, min price +- inventory_unit created with status 'available' +- Consignment agreement printed or emailed — includes item description, commission terms, min price, store contact + +## 5.2 Consignment Sale + +- Item sold at POS like any other product +- POS checks for consignment_detail on the product +- If min_price set and sale price < min_price → warning, requires manager override +- Transaction recorded normally +- Consignment sale flagged for inclusion in next settlement +- Journal entry differs from regular sale — see Accounting section + +## 5.3 Settlement + +- Manager runs settlement report for a period (e.g. monthly) +- System groups all consignment sales by consignor for the period +- For each consignor: total sales, total commission, total payout +- Manager reviews and approves settlement +- Settlement record created with line items +- Consignor paid via check, ACH, cash, or account credit +- Settlement marked paid with date and method + +## 5.4 Unsold Item Return + +- Consignor requests item back, or agreement expires +- Staff updates consignment_detail.is_active = false +- inventory_unit.status set to 'retired' +- Product deactivated (is_active = false) +- No financial transaction — item was never store property + + + +# 6. POS Integration + +- Consignment items appear in product search and catalog like any other item +- No visual distinction to customers +- Staff sees a "Consignment" badge on the product detail in POS +- Min price enforced — POS blocks sale below min_price without override +- Discounts on consignment items: commission calculated on actual sale price (after discount), not list price +- Receipt shows the item like any other product — no consignment info visible to customer + + + +# 7. Accounting — Journal Entry Differences + +Consignment sales produce different journal entries than regular sales because the store never owned the inventory. + +## 7.1 Regular Sale (Store-Owned) + +Debit | Credit | Notes +Cash/Stripe Clearing | Sales Revenue | Full sale price is revenue +COGS | Inventory | Cost of item removed from inventory + +## 7.2 Consignment Sale + +Debit | Credit | Notes +Cash/Stripe Clearing | Consignment Payable | Consignor's portion — liability until settled +Cash/Stripe Clearing | Commission Income | Store's commission — this is your revenue +(no COGS entry) | (no inventory entry) | Store never owned the item — no cost basis + +## 7.3 Consignment Settlement (Paying Consignor) + +Debit | Credit | Notes +Consignment Payable | Cash/Bank | Liability cleared when consignor is paid + +### New Chart of Accounts Entries Needed + +Code | Account Name | Type | Notes +2500 | Consignment Payable | Liability | Amounts owed to consignors for sold items +4600 | Commission Income — Consignment | Revenue | Store's commission on consignment sales + + + +# 8. Reporting + +Report | Description +Consignment inventory | All active consignment items — consignor, list price, days listed +Consignment sales by period | Items sold, sale price, commission, consignor payout +Unsettled consignment | Sold items not yet included in a settlement — amounts owed +Settlement history | Past settlements by consignor — dates, amounts, payment method +Commission analysis | Commission earned by period — identifies how much consignment contributes to revenue +Aging report | Consignment items listed for X days without selling — candidates for return or price reduction +Consignor statement | Per-consignor report — items listed, items sold, commission, payouts — printable/emailable + + + +# 9. Business Rules + +- Consignment items are always serialized (each is a unique item with a consignment_detail) +- Commission calculated on actual sale price after discounts, not list price +- Min price enforced at POS — override requires manager role +- Consignor cannot be paid until settlement is approved by manager +- Settlement cannot include items from future dates +- Returned items generate no financial transaction — no revenue, no COGS +- Consignment_detail is soft-deleted (is_active = false), never hard deleted — preserves history +- Consignor account follows same rules as any account — soft-delete only, financial history retained +- Price reductions on consignment items should notify consignor (future: notification system)