Files
lunarfront-app/planning/20_Domain_Consignment.md
Ryan Moon 9400828f62 Rename Forte to LunarFront, generalize for any small business
Rebrand from Forte (music-store-specific) to LunarFront (any small business):
- Package namespace @forte/* → @lunarfront/*
- Database forte/forte_test → lunarfront/lunarfront_test
- Docker containers, volumes, connection strings
- UI branding, localStorage keys, test emails
- All documentation and planning docs

Generalize music-specific terminology:
- instrumentDescription → itemDescription
- instrumentCount → itemCount
- instrumentType → itemCategory (on service templates)
- New migration 0027_generalize_terminology for column renames
- Seed data updated with generic examples
- RBAC descriptions updated
2026-03-30 08:51:54 -05:00

213 lines
8.7 KiB
Markdown

LunarFront — Small Business 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)