Move 39 documentation files from top-level docs/ into each module's docs/ folder, accessible via symlinks from docs/modules/. Create data-model.md files for 10 modules with full schema documentation. Replace originals with redirect stubs. Remove empty guide stubs. Modules migrated: tenancy, billing, loyalty, marketplace, orders, messaging, cms, catalog, inventory, hosting, prospecting. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
663 lines
17 KiB
Markdown
663 lines
17 KiB
Markdown
# OMS Feature Implementation Plan
|
|
|
|
## Overview
|
|
|
|
Transform Orion into a **"Lightweight OMS for Letzshop Sellers"** by building the missing features that justify the tier pricing structure.
|
|
|
|
**Goal:** Ship Essential tier quickly, then build Professional differentiators, then Business features.
|
|
|
|
## Design Decisions (Confirmed)
|
|
|
|
| Decision | Choice |
|
|
|----------|--------|
|
|
| Phase 1 scope | Invoicing + Tier Limits together |
|
|
| PDF library | WeasyPrint (HTML/CSS to PDF) |
|
|
| Invoice style | Simple & Clean (minimal design) |
|
|
|
|
---
|
|
|
|
## Current State Summary
|
|
|
|
### Already Production-Ready
|
|
- Multi-tenant architecture (Merchant → Store hierarchy)
|
|
- Letzshop order sync, confirmation, tracking
|
|
- Inventory management with locations and reservations
|
|
- Unified Order model (direct + marketplace)
|
|
- Customer model with pre-calculated stats (total_orders, total_spent)
|
|
- Team management + RBAC
|
|
- CSV export patterns (products)
|
|
|
|
### Needs to be Built
|
|
| Feature | Tier Impact | Priority |
|
|
|---------|-------------|----------|
|
|
| Basic LU Invoice (PDF) | Essential | P0 |
|
|
| Tier limits enforcement | Essential | P0 |
|
|
| Store VAT Settings | Professional | P1 |
|
|
| EU VAT Invoice | Professional | P1 |
|
|
| Incoming Stock / PO | Professional | P1 |
|
|
| Customer CSV Export | Professional | P1 |
|
|
| Multi-store view | Business | P2 |
|
|
| Accounting export | Business | P2 |
|
|
|
|
---
|
|
|
|
## Phase 1: Essential Tier (Target: 1 week)
|
|
|
|
**Goal:** Launch Essential (€49) with basic invoicing and tier enforcement.
|
|
|
|
### Step 1.1: Store Invoice Settings (1 day)
|
|
|
|
**Create model for store billing details:**
|
|
|
|
```
|
|
models/database/store_invoice_settings.py
|
|
```
|
|
|
|
Fields:
|
|
- `store_id` (FK, unique - one-to-one)
|
|
- `merchant_name` (legal name for invoices)
|
|
- `merchant_address`, `merchant_city`, `merchant_postal_code`, `merchant_country`
|
|
- `vat_number` (e.g., "LU12345678")
|
|
- `invoice_prefix` (default "INV")
|
|
- `invoice_next_number` (auto-increment)
|
|
- `payment_terms` (optional text)
|
|
- `bank_details` (optional IBAN etc.)
|
|
- `footer_text` (optional)
|
|
|
|
**Pattern to follow:** `models/database/letzshop.py` (StoreLetzshopCredentials)
|
|
|
|
**Files to create/modify:**
|
|
- `models/database/store_invoice_settings.py` (new)
|
|
- `models/database/__init__.py` (add import)
|
|
- `models/database/store.py` (add relationship)
|
|
- `models/schema/invoice.py` (new - Pydantic schemas)
|
|
- `alembic/versions/xxx_add_store_invoice_settings.py` (migration)
|
|
|
|
---
|
|
|
|
### Step 1.2: Basic Invoice Model (0.5 day)
|
|
|
|
**Create invoice storage:**
|
|
|
|
```
|
|
models/database/invoice.py
|
|
```
|
|
|
|
Fields:
|
|
- `id`, `store_id` (FK)
|
|
- `order_id` (FK, nullable - for manual invoices later)
|
|
- `invoice_number` (unique per store)
|
|
- `invoice_date`
|
|
- `seller_details` (JSONB snapshot)
|
|
- `buyer_details` (JSONB snapshot)
|
|
- `line_items` (JSONB snapshot)
|
|
- `subtotal_cents`, `vat_rate`, `vat_amount_cents`, `total_cents`
|
|
- `currency` (default EUR)
|
|
- `status` (draft, issued, paid, cancelled)
|
|
- `pdf_generated_at`, `pdf_path` (optional)
|
|
|
|
**Files to create/modify:**
|
|
- `models/database/invoice.py` (new)
|
|
- `models/database/__init__.py` (add import)
|
|
- `alembic/versions/xxx_add_invoices_table.py` (migration)
|
|
|
|
---
|
|
|
|
### Step 1.3: Invoice Service - Basic LU Only (1 day)
|
|
|
|
**Create service for invoice generation:**
|
|
|
|
```
|
|
app/services/invoice_service.py
|
|
```
|
|
|
|
Methods:
|
|
- `create_invoice_from_order(order_id, store_id)` - Generate invoice from order
|
|
- `get_invoice(invoice_id, store_id)` - Retrieve invoice
|
|
- `list_invoices(store_id, skip, limit)` - List store invoices
|
|
- `_generate_invoice_number(settings)` - Auto-increment number
|
|
- `_snapshot_seller(settings)` - Capture store details
|
|
- `_snapshot_buyer(order)` - Capture customer details
|
|
- `_calculate_totals(order)` - Calculate with LU VAT (17%)
|
|
|
|
**For Essential tier:** Fixed 17% Luxembourg VAT only. EU VAT comes in Professional.
|
|
|
|
**Files to create:**
|
|
- `app/services/invoice_service.py` (new)
|
|
|
|
---
|
|
|
|
### Step 1.4: PDF Generation (1.5 days)
|
|
|
|
**Add WeasyPrint dependency and create PDF service:**
|
|
|
|
```
|
|
app/services/invoice_pdf_service.py
|
|
```
|
|
|
|
Methods:
|
|
- `generate_pdf(invoice)` - Returns PDF bytes
|
|
- `_render_html(invoice)` - Jinja2 template rendering
|
|
|
|
**Template:**
|
|
```
|
|
app/templates/invoices/invoice.html
|
|
```
|
|
|
|
Simple, clean invoice layout:
|
|
- Seller details (top left)
|
|
- Buyer details (top right)
|
|
- Invoice number + date
|
|
- Line items table
|
|
- Totals with VAT breakdown
|
|
- Footer (payment terms, bank details)
|
|
|
|
**Files to create/modify:**
|
|
- `requirements.txt` (add weasyprint)
|
|
- `app/services/invoice_pdf_service.py` (new)
|
|
- `app/templates/invoices/invoice.html` (new)
|
|
- `app/templates/invoices/invoice.css` (new, optional)
|
|
|
|
---
|
|
|
|
### Step 1.5: Invoice API Endpoints (0.5 day)
|
|
|
|
**Create store invoice endpoints:**
|
|
|
|
```
|
|
app/api/v1/store/invoices.py
|
|
```
|
|
|
|
Endpoints:
|
|
- `POST /orders/{order_id}/invoice` - Generate invoice for order
|
|
- `GET /invoices` - List invoices
|
|
- `GET /invoices/{invoice_id}` - Get invoice details
|
|
- `GET /invoices/{invoice_id}/pdf` - Download PDF
|
|
|
|
**Files to create/modify:**
|
|
- `app/api/v1/store/invoices.py` (new)
|
|
- `app/api/v1/store/__init__.py` (add router)
|
|
|
|
---
|
|
|
|
### Step 1.6: Invoice Settings UI (0.5 day)
|
|
|
|
**Add invoice settings to store settings page:**
|
|
|
|
Modify existing store settings template to add "Invoice Settings" section:
|
|
- Merchant name, address fields
|
|
- VAT number
|
|
- Invoice prefix
|
|
- Payment terms
|
|
- Bank details
|
|
|
|
**Files to modify:**
|
|
- `app/templates/store/settings.html` (add section)
|
|
- `static/store/js/settings.js` (add handlers)
|
|
- `app/api/v1/store/settings.py` (add endpoints if needed)
|
|
|
|
---
|
|
|
|
### Step 1.7: Order Detail - Invoice Button (0.5 day)
|
|
|
|
**Add "Generate Invoice" / "Download Invoice" button to order detail:**
|
|
|
|
- If no invoice: Show "Generate Invoice" button
|
|
- If invoice exists: Show "Download Invoice" link
|
|
|
|
**Files to modify:**
|
|
- `app/templates/store/order-detail.html` (add button)
|
|
- `static/store/js/order-detail.js` (add handler)
|
|
|
|
---
|
|
|
|
### Step 1.8: Tier Limits Enforcement (1 day)
|
|
|
|
**Create tier/subscription model:**
|
|
|
|
```
|
|
models/database/store_subscription.py
|
|
```
|
|
|
|
Fields:
|
|
- `store_id` (FK, unique)
|
|
- `tier` (essential, professional, business)
|
|
- `orders_this_month` (counter, reset monthly)
|
|
- `period_start`, `period_end`
|
|
- `is_active`
|
|
|
|
**Create limits service:**
|
|
|
|
```
|
|
app/services/tier_limits_service.py
|
|
```
|
|
|
|
Methods:
|
|
- `check_order_limit(store_id)` - Returns (allowed: bool, remaining: int)
|
|
- `increment_order_count(store_id)` - Called when order synced
|
|
- `get_tier_limits(tier)` - Returns limit config
|
|
- `reset_monthly_counters()` - Cron job
|
|
|
|
**Tier limits:**
|
|
| Tier | Orders/month | Products |
|
|
|------|--------------|----------|
|
|
| Essential | 100 | 200 |
|
|
| Professional | 500 | Unlimited |
|
|
| Business | Unlimited | Unlimited |
|
|
|
|
**Integration points:**
|
|
- `order_service.py` - Check limit before creating order
|
|
- Letzshop sync - Check limit before importing
|
|
|
|
**Files to create/modify:**
|
|
- `models/database/store_subscription.py` (new)
|
|
- `app/services/tier_limits_service.py` (new)
|
|
- `app/services/order_service.py` (add limit check)
|
|
- `app/services/letzshop/order_service.py` (add limit check)
|
|
|
|
---
|
|
|
|
## Phase 2: Professional Tier (Target: 2 weeks)
|
|
|
|
**Goal:** Build the differentiating features that justify €99/month.
|
|
|
|
### Step 2.1: EU VAT Rates Table (0.5 day)
|
|
|
|
**Create VAT rates reference table:**
|
|
|
|
```
|
|
models/database/eu_vat_rates.py
|
|
```
|
|
|
|
Fields:
|
|
- `country_code` (LU, DE, FR, etc.)
|
|
- `country_name`
|
|
- `standard_rate` (decimal)
|
|
- `reduced_rate_1`, `reduced_rate_2` (optional)
|
|
- `effective_from`, `effective_until`
|
|
|
|
**Seed with current EU rates (27 countries).**
|
|
|
|
**Files to create:**
|
|
- `models/database/eu_vat_rates.py` (new)
|
|
- `alembic/versions/xxx_add_eu_vat_rates.py` (migration + seed)
|
|
|
|
---
|
|
|
|
### Step 2.2: Enhanced Store VAT Settings (0.5 day)
|
|
|
|
**Add OSS fields to StoreInvoiceSettings:**
|
|
|
|
- `is_oss_registered` (boolean)
|
|
- `oss_registration_country` (if different from merchant country)
|
|
|
|
**Files to modify:**
|
|
- `models/database/store_invoice_settings.py` (add fields)
|
|
- `alembic/versions/xxx_add_oss_fields.py` (migration)
|
|
|
|
---
|
|
|
|
### Step 2.3: VAT Service (1 day)
|
|
|
|
**Create VAT calculation service:**
|
|
|
|
```
|
|
app/services/vat_service.py
|
|
```
|
|
|
|
Methods:
|
|
- `get_vat_rate(country_code, as_of_date)` - Lookup rate
|
|
- `determine_vat_regime(seller_country, buyer_country, buyer_vat_number, is_oss)` - Returns (regime, rate)
|
|
- `validate_vat_number(vat_number)` - Format check (VIES integration later)
|
|
|
|
**VAT Decision Logic:**
|
|
1. B2B with valid VAT number → Reverse charge (0%)
|
|
2. Domestic sale → Domestic VAT
|
|
3. Cross-border + OSS registered → Destination VAT
|
|
4. Cross-border + under threshold → Origin VAT
|
|
|
|
**Files to create:**
|
|
- `app/services/vat_service.py` (new)
|
|
|
|
---
|
|
|
|
### Step 2.4: Enhanced Invoice Service (1 day)
|
|
|
|
**Upgrade invoice service for EU VAT:**
|
|
|
|
- Add `vat_regime` field to invoice (domestic, oss, reverse_charge, origin)
|
|
- Add `destination_country` field
|
|
- Use VATService to calculate correct rate
|
|
- Update invoice template for regime-specific text
|
|
|
|
**Files to modify:**
|
|
- `models/database/invoice.py` (add fields)
|
|
- `app/services/invoice_service.py` (use VATService)
|
|
- `app/templates/invoices/invoice.html` (add regime text)
|
|
- `alembic/versions/xxx_add_vat_regime_to_invoices.py`
|
|
|
|
---
|
|
|
|
### Step 2.5: Purchase Order Model (1 day)
|
|
|
|
**Create purchase order tracking:**
|
|
|
|
```
|
|
models/database/purchase_order.py
|
|
```
|
|
|
|
**PurchaseOrder:**
|
|
- `id`, `store_id` (FK)
|
|
- `po_number` (auto-generated)
|
|
- `supplier_name` (free text for now)
|
|
- `status` (draft, ordered, partial, received, cancelled)
|
|
- `order_date`, `expected_date`
|
|
- `notes`
|
|
|
|
**PurchaseOrderItem:**
|
|
- `purchase_order_id` (FK)
|
|
- `product_id` (FK)
|
|
- `quantity_ordered`
|
|
- `quantity_received`
|
|
- `unit_cost_cents` (optional)
|
|
|
|
**Files to create:**
|
|
- `models/database/purchase_order.py` (new)
|
|
- `models/database/__init__.py` (add import)
|
|
- `models/schema/purchase_order.py` (new)
|
|
- `alembic/versions/xxx_add_purchase_orders.py`
|
|
|
|
---
|
|
|
|
### Step 2.6: Purchase Order Service (1 day)
|
|
|
|
**Create PO management service:**
|
|
|
|
```
|
|
app/services/purchase_order_service.py
|
|
```
|
|
|
|
Methods:
|
|
- `create_purchase_order(store_id, data)` - Create PO
|
|
- `add_item(po_id, product_id, quantity)` - Add line item
|
|
- `receive_items(po_id, items)` - Mark items received, update inventory
|
|
- `get_incoming_stock(store_id)` - Summary of pending stock
|
|
- `list_purchase_orders(store_id, status, skip, limit)`
|
|
|
|
**Integration:** When items received → call `inventory_service.adjust_inventory()`
|
|
|
|
**Files to create:**
|
|
- `app/services/purchase_order_service.py` (new)
|
|
|
|
---
|
|
|
|
### Step 2.7: Purchase Order UI (1.5 days)
|
|
|
|
**Create PO management page:**
|
|
|
|
```
|
|
app/templates/store/purchase-orders.html
|
|
```
|
|
|
|
Features:
|
|
- List POs with status
|
|
- Create new PO (select products, quantities, expected date)
|
|
- Receive items (partial or full)
|
|
- View incoming stock summary
|
|
|
|
**Inventory page enhancement:**
|
|
- Show "On Order" column in inventory list
|
|
- Query: SUM of quantity_ordered - quantity_received for pending POs
|
|
|
|
**Files to create/modify:**
|
|
- `app/templates/store/purchase-orders.html` (new)
|
|
- `static/store/js/purchase-orders.js` (new)
|
|
- `app/api/v1/store/purchase_orders.py` (new endpoints)
|
|
- `app/routes/store_pages.py` (add route)
|
|
- `app/templates/store/partials/sidebar.html` (add menu item)
|
|
- `app/templates/store/inventory.html` (add On Order column)
|
|
|
|
---
|
|
|
|
### Step 2.8: Customer Export Service (1 day)
|
|
|
|
**Create customer export functionality:**
|
|
|
|
```
|
|
app/services/customer_export_service.py
|
|
```
|
|
|
|
Methods:
|
|
- `export_customers_csv(store_id, filters)` - Returns CSV string
|
|
|
|
**CSV Columns:**
|
|
- email, first_name, last_name, phone
|
|
- customer_number
|
|
- total_orders, total_spent, avg_order_value
|
|
- first_order_date, last_order_date
|
|
- preferred_language
|
|
- marketing_consent
|
|
- tags (if we add tagging)
|
|
|
|
**Files to create:**
|
|
- `app/services/customer_export_service.py` (new)
|
|
|
|
---
|
|
|
|
### Step 2.9: Customer Export API + UI (0.5 day)
|
|
|
|
**Add export endpoint:**
|
|
|
|
```
|
|
GET /api/v1/store/customers/export?format=csv
|
|
```
|
|
|
|
**Add export button to customers page:**
|
|
- "Export to CSV" button
|
|
- Downloads file directly
|
|
|
|
**Files to modify:**
|
|
- `app/api/v1/store/customers.py` (add export endpoint)
|
|
- `app/templates/store/customers.html` (add button)
|
|
|
|
---
|
|
|
|
## Phase 3: Business Tier (Target: 1-2 weeks)
|
|
|
|
**Goal:** Build features for teams and high-volume operations.
|
|
|
|
### Step 3.1: Multi-Store Consolidated View (2 days)
|
|
|
|
**For merchants with multiple Letzshop accounts:**
|
|
|
|
**New page:**
|
|
```
|
|
app/templates/store/multi-store-dashboard.html
|
|
```
|
|
|
|
Features:
|
|
- See all store accounts under same merchant
|
|
- Consolidated order count, revenue
|
|
- Switch between store contexts
|
|
- Unified reporting
|
|
|
|
**Requires:** Merchant-level authentication context (already exists via Merchant → Store relationship)
|
|
|
|
**Files to create/modify:**
|
|
- `app/templates/store/multi-store-dashboard.html` (new)
|
|
- `app/services/multi_store_service.py` (new)
|
|
- `app/api/v1/store/multi_store.py` (new)
|
|
|
|
---
|
|
|
|
### Step 3.2: Accounting Export (1 day)
|
|
|
|
**Export invoices in accounting-friendly formats:**
|
|
|
|
```
|
|
app/services/accounting_export_service.py
|
|
```
|
|
|
|
Methods:
|
|
- `export_invoices_csv(store_id, date_from, date_to)` - Simple CSV
|
|
- `export_invoices_xml(store_id, date_from, date_to)` - For accounting software
|
|
|
|
**CSV format for accountants:**
|
|
- invoice_number, invoice_date
|
|
- customer_name, customer_vat
|
|
- subtotal, vat_rate, vat_amount, total
|
|
- currency, status
|
|
|
|
**Files to create:**
|
|
- `app/services/accounting_export_service.py` (new)
|
|
- `app/api/v1/store/accounting.py` (new endpoints)
|
|
|
|
---
|
|
|
|
### Step 3.3: API Access Documentation (1 day)
|
|
|
|
**If not already documented, create API documentation page:**
|
|
|
|
- Document existing store API endpoints
|
|
- Add rate limiting for API tier
|
|
- Generate API keys for stores
|
|
|
|
**Files to create/modify:**
|
|
- `docs/api/store-api.md` (documentation)
|
|
- `app/services/api_key_service.py` (if needed)
|
|
|
|
---
|
|
|
|
## Implementation Order Summary
|
|
|
|
### Week 1: Essential Tier
|
|
| Day | Task | Deliverable |
|
|
|-----|------|-------------|
|
|
| 1 | Step 1.1 | Store Invoice Settings model |
|
|
| 1 | Step 1.2 | Invoice model |
|
|
| 2 | Step 1.3 | Invoice Service (LU only) |
|
|
| 3-4 | Step 1.4 | PDF Generation |
|
|
| 4 | Step 1.5 | Invoice API |
|
|
| 5 | Step 1.6 | Invoice Settings UI |
|
|
| 5 | Step 1.7 | Order Detail button |
|
|
|
|
### Week 2: Tier Limits + EU VAT Start
|
|
| Day | Task | Deliverable |
|
|
|-----|------|-------------|
|
|
| 1 | Step 1.8 | Tier limits enforcement |
|
|
| 2 | Step 2.1 | EU VAT rates table |
|
|
| 2 | Step 2.2 | OSS fields |
|
|
| 3 | Step 2.3 | VAT Service |
|
|
| 4 | Step 2.4 | Enhanced Invoice Service |
|
|
| 5 | Testing | End-to-end invoice testing |
|
|
|
|
### Week 3: Purchase Orders + Customer Export
|
|
| Day | Task | Deliverable |
|
|
|-----|------|-------------|
|
|
| 1 | Step 2.5 | Purchase Order model |
|
|
| 2 | Step 2.6 | Purchase Order service |
|
|
| 3-4 | Step 2.7 | Purchase Order UI |
|
|
| 5 | Step 2.8-2.9 | Customer Export |
|
|
|
|
### Week 4: Business Tier
|
|
| Day | Task | Deliverable |
|
|
|-----|------|-------------|
|
|
| 1-2 | Step 3.1 | Multi-store view |
|
|
| 3 | Step 3.2 | Accounting export |
|
|
| 4 | Step 3.3 | API documentation |
|
|
| 5 | Testing + Polish | Full testing |
|
|
|
|
---
|
|
|
|
## Key Files Reference
|
|
|
|
### Models to Create
|
|
- `models/database/store_invoice_settings.py`
|
|
- `models/database/invoice.py`
|
|
- `models/database/eu_vat_rates.py`
|
|
- `models/database/store_subscription.py`
|
|
- `models/database/purchase_order.py`
|
|
|
|
### Services to Create
|
|
- `app/services/invoice_service.py`
|
|
- `app/services/invoice_pdf_service.py`
|
|
- `app/services/vat_service.py`
|
|
- `app/services/tier_limits_service.py`
|
|
- `app/services/purchase_order_service.py`
|
|
- `app/services/customer_export_service.py`
|
|
- `app/services/accounting_export_service.py`
|
|
|
|
### Templates to Create
|
|
- `app/templates/invoices/invoice.html`
|
|
- `app/templates/store/purchase-orders.html`
|
|
|
|
### Existing Files to Modify
|
|
- `models/database/__init__.py`
|
|
- `models/database/store.py`
|
|
- `app/services/order_service.py`
|
|
- `app/templates/store/settings.html`
|
|
- `app/templates/store/order-detail.html`
|
|
- `app/templates/store/inventory.html`
|
|
- `app/templates/store/customers.html`
|
|
- `requirements.txt`
|
|
|
|
---
|
|
|
|
## Dependencies to Add
|
|
|
|
```
|
|
# requirements.txt
|
|
weasyprint>=60.0
|
|
```
|
|
|
|
**Note:** WeasyPrint requires system dependencies:
|
|
- `libpango-1.0-0`
|
|
- `libpangocairo-1.0-0`
|
|
- `libgdk-pixbuf2.0-0`
|
|
|
|
Add to Dockerfile if deploying via Docker.
|
|
|
|
---
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Tests
|
|
- `tests/unit/services/test_invoice_service.py`
|
|
- `tests/unit/services/test_vat_service.py`
|
|
- `tests/unit/services/test_tier_limits_service.py`
|
|
- `tests/unit/services/test_purchase_order_service.py`
|
|
|
|
### Integration Tests
|
|
- `tests/integration/api/v1/store/test_invoices.py`
|
|
- `tests/integration/api/v1/store/test_purchase_orders.py`
|
|
|
|
### Manual Testing
|
|
- Generate invoice for LU customer
|
|
- Generate invoice for DE customer (OSS)
|
|
- Generate invoice for B2B with VAT number (reverse charge)
|
|
- Create PO, receive items, verify inventory update
|
|
- Export customers CSV, import to Mailchimp
|
|
|
|
---
|
|
|
|
## Success Criteria
|
|
|
|
### Essential Tier Ready When:
|
|
- [ ] Can generate PDF invoice from order (LU VAT)
|
|
- [ ] Invoice settings page works
|
|
- [ ] Order detail shows invoice button
|
|
- [ ] Tier limits enforced on order sync
|
|
|
|
### Professional Tier Ready When:
|
|
- [ ] EU VAT calculated correctly by destination
|
|
- [ ] OSS regime supported
|
|
- [ ] Reverse charge for B2B supported
|
|
- [ ] Purchase orders can be created and received
|
|
- [ ] Incoming stock shows in inventory
|
|
- [ ] Customer export to CSV works
|
|
|
|
### Business Tier Ready When:
|
|
- [ ] Multi-store dashboard works
|
|
- [ ] Accounting export works
|
|
- [ ] API access documented
|