Phase 1 — Overview
Phase 1 builds the billing catalog — the foundation that every future billing action (invoicing, payment, entitlement grants, ad consumption) will read from. Before we can issue a single invoice, we need three things in place: who is selling, what is being sold, and at what price in which market.
Why we're building this
Right now, ad campaigns run without real billing. Credits are neither reserved nor consumed in a structured way. When we enable billing:
- We need to know who the seller of record is on each invoice — a legal entity registered in that market (Singapore or Indonesia), with its own tax regime and invoice number sequence.
- We need a structured product catalog so prices are not hard-coded in application logic. A product (
SP-CREDITS-100) and its price (SGD 1,000 + 9% GST) must be stored as data, not constants. - We need market-specific pricing from day one. Singapore charges 9% GST; Indonesia charges 11% PPN. The same product may have different prices in each market. A price row that captures currency, tax code, and active dates makes this manageable.
Without this catalog in place, Phase 2 (invoicing) cannot be built. That makes Phase 1 the prerequisite for everything billing-related.
Goal
Deliver the three Billing catalog tables and the Team Portal admin screens to manage them, so that:
- An admin can set up Jod's legal entities for the markets we operate in.
- An admin can define what products we sell and what they cost in each market.
- These records are ready to be referenced when we start issuing invoices.
High-level domain diagram
The diagram shows how Phase 1 fits into the bigger picture: the admin manages the three catalog tables (green), and those tables are referenced downstream by invoice creation, entitlement grants, and eventually ad credit consumption — all in future phases (grey, dashed).
What gets built
Admin can manage legal entities
- Create a new legal entity — name, registration number, country, tax regime, invoice prefix.
- Browse all legal entities.
- View a single legal entity.
- Update a legal entity's mutable details (registered address, Xero mapping). Core identity fields (
legal_name,registration_number,tax_regime,default_currency,invoice_number_prefix) are locked after creation. - Deactivate a legal entity when Jod exits a market. Deactivation is irreversible — no new invoices or prices can reference an inactive entity.
Example: Setting up Jod Pte. Ltd. (Singapore) with SG-INV- as the invoice prefix and sg_gst as the tax regime.
Admin can manage products
- Create a new product — SKU, name, what entitlement it grants, and how many units per purchase.
- Browse all products, with an active/inactive filter.
- View a product's details.
- Update a product's description or display name.
- Activate or deactivate a product (soft enable/disable for the catalog).
Example: Creating SP-CREDITS-100 — a package of 100 placement credits — and deactivating it during a price revision without deleting any historical data.
Admin can manage product prices
- Create a new price row — which product, which legal entity, which country, what currency, what tax code, what price.
- Browse all prices for a product.
- View a single price row.
- End-date a price row (set
active_until) before creating a replacement to manage price transitions cleanly. - Discard a price row that has not yet been referenced by any invoice (soft-delete — row is kept for audit but removed from active-price queries).
Example: Adding a Singapore price for SP-CREDITS-100: SGD 1,000 at 9% GST (SR tax code), active from a specific date.