3 changed files with 238 additions and 9 deletions
@ -1,12 +1,67 @@ |
|||||||
OTB Billing Design |
# OTB Billing Design Notes |
||||||
|
|
||||||
Purpose: |
## Current Version |
||||||
Track invoices and payments for OutsideTheBox services. |
0.0.2 |
||||||
|
|
||||||
Payment types: |
## Purpose |
||||||
|
OTB Billing is the billing and payment tracking component for OutsideTheBox. |
||||||
|
|
||||||
|
It is intended to: |
||||||
|
- track clients |
||||||
|
- track services |
||||||
|
- issue invoices |
||||||
|
- record payments |
||||||
|
- support bookkeeping visibility |
||||||
|
- integrate with outsidethedb while keeping billing records logically separate |
||||||
|
|
||||||
|
## Supported payment directions |
||||||
- Square |
- Square |
||||||
- Interac e-transfer |
- Interac e-Transfer |
||||||
- crypto |
- Crypto |
||||||
|
|
||||||
|
## Multi-currency design |
||||||
|
The schema supports multi-currency from day one. |
||||||
|
|
||||||
|
Current intended currencies: |
||||||
|
- CAD |
||||||
|
- ETHO |
||||||
|
- EGAZ |
||||||
|
- ALT |
||||||
|
|
||||||
|
### Rule |
||||||
|
Store both: |
||||||
|
- actual payment currency and amount |
||||||
|
- CAD-equivalent snapshot when relevant |
||||||
|
|
||||||
|
Example: |
||||||
|
- payment_currency = EGAZ |
||||||
|
- payment_amount = 12.50000000 |
||||||
|
- cad_value_at_payment = 47.82 |
||||||
|
|
||||||
|
This keeps both crypto-native records and bookkeeping-friendly reporting. |
||||||
|
|
||||||
|
## Core tables |
||||||
|
- clients |
||||||
|
- services |
||||||
|
- invoices |
||||||
|
- invoice_items |
||||||
|
- payments |
||||||
|
- audit_log |
||||||
|
|
||||||
|
## Relationship flow |
||||||
|
client -> service -> invoice -> invoice_items -> payment |
||||||
|
|
||||||
|
## Notes |
||||||
|
- services are linked to clients |
||||||
|
- invoices are linked to clients and optionally to services |
||||||
|
- invoice items can optionally reference services |
||||||
|
- payments reference both invoice and client |
||||||
|
- audit_log provides change history for future accountability and troubleshooting |
||||||
|
|
||||||
Integration: |
## Planned future additions |
||||||
Will communicate with outsidethedb for service status. |
- recurring invoice generation |
||||||
|
- reminders / overdue handling |
||||||
|
- dashboard counts |
||||||
|
- service suspension workflow |
||||||
|
- integration hooks to outsidethedb |
||||||
|
- client verification records |
||||||
|
|||||||
@ -0,0 +1,174 @@ |
|||||||
|
CREATE DATABASE IF NOT EXISTS otb_billing |
||||||
|
CHARACTER SET utf8mb4 |
||||||
|
COLLATE utf8mb4_unicode_ci; |
||||||
|
|
||||||
|
USE otb_billing; |
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS=0; |
||||||
|
|
||||||
|
DROP TABLE IF EXISTS audit_log; |
||||||
|
DROP TABLE IF EXISTS payments; |
||||||
|
DROP TABLE IF EXISTS invoice_items; |
||||||
|
DROP TABLE IF EXISTS invoices; |
||||||
|
DROP TABLE IF EXISTS services; |
||||||
|
DROP TABLE IF EXISTS clients; |
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS=1; |
||||||
|
|
||||||
|
CREATE TABLE clients ( |
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT, |
||||||
|
client_code VARCHAR(50) NOT NULL, |
||||||
|
company_name VARCHAR(255) NOT NULL, |
||||||
|
contact_name VARCHAR(255) DEFAULT NULL, |
||||||
|
email VARCHAR(255) DEFAULT NULL, |
||||||
|
phone VARCHAR(50) DEFAULT NULL, |
||||||
|
status ENUM('lead','active','inactive','suspended') NOT NULL DEFAULT 'active', |
||||||
|
notes TEXT DEFAULT NULL, |
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, |
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, |
||||||
|
PRIMARY KEY (id), |
||||||
|
UNIQUE KEY uq_clients_client_code (client_code), |
||||||
|
KEY idx_clients_company_name (company_name), |
||||||
|
KEY idx_clients_status (status) |
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; |
||||||
|
|
||||||
|
CREATE TABLE services ( |
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT, |
||||||
|
client_id INT UNSIGNED NOT NULL, |
||||||
|
service_code VARCHAR(50) NOT NULL, |
||||||
|
service_name VARCHAR(255) NOT NULL, |
||||||
|
service_type ENUM('hosting','rpc','explorer','node','ipfs','consulting','other') NOT NULL DEFAULT 'other', |
||||||
|
billing_cycle ENUM('one_time','monthly','quarterly','yearly','manual') NOT NULL DEFAULT 'monthly', |
||||||
|
status ENUM('pending','active','suspended','cancelled') NOT NULL DEFAULT 'pending', |
||||||
|
currency_code VARCHAR(16) NOT NULL DEFAULT 'CAD', |
||||||
|
recurring_amount DECIMAL(18,8) NOT NULL DEFAULT 0.00000000, |
||||||
|
start_date DATE DEFAULT NULL, |
||||||
|
end_date DATE DEFAULT NULL, |
||||||
|
description TEXT DEFAULT NULL, |
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, |
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, |
||||||
|
PRIMARY KEY (id), |
||||||
|
UNIQUE KEY uq_services_service_code (service_code), |
||||||
|
KEY idx_services_client_id (client_id), |
||||||
|
KEY idx_services_status (status), |
||||||
|
CONSTRAINT fk_services_client |
||||||
|
FOREIGN KEY (client_id) REFERENCES clients(id) |
||||||
|
ON DELETE RESTRICT |
||||||
|
ON UPDATE CASCADE |
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; |
||||||
|
|
||||||
|
CREATE TABLE invoices ( |
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT, |
||||||
|
client_id INT UNSIGNED NOT NULL, |
||||||
|
service_id INT UNSIGNED DEFAULT NULL, |
||||||
|
invoice_number VARCHAR(50) NOT NULL, |
||||||
|
currency_code VARCHAR(16) NOT NULL DEFAULT 'CAD', |
||||||
|
subtotal_amount DECIMAL(18,8) NOT NULL DEFAULT 0.00000000, |
||||||
|
tax_amount DECIMAL(18,8) NOT NULL DEFAULT 0.00000000, |
||||||
|
total_amount DECIMAL(18,8) NOT NULL DEFAULT 0.00000000, |
||||||
|
amount_paid DECIMAL(18,8) NOT NULL DEFAULT 0.00000000, |
||||||
|
status ENUM('draft','pending','paid','partial','overdue','cancelled') NOT NULL DEFAULT 'draft', |
||||||
|
issued_at DATETIME DEFAULT NULL, |
||||||
|
due_at DATETIME DEFAULT NULL, |
||||||
|
paid_at DATETIME DEFAULT NULL, |
||||||
|
notes TEXT DEFAULT NULL, |
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, |
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, |
||||||
|
PRIMARY KEY (id), |
||||||
|
UNIQUE KEY uq_invoices_invoice_number (invoice_number), |
||||||
|
KEY idx_invoices_client_id (client_id), |
||||||
|
KEY idx_invoices_service_id (service_id), |
||||||
|
KEY idx_invoices_status (status), |
||||||
|
KEY idx_invoices_due_at (due_at), |
||||||
|
CONSTRAINT fk_invoices_client |
||||||
|
FOREIGN KEY (client_id) REFERENCES clients(id) |
||||||
|
ON DELETE RESTRICT |
||||||
|
ON UPDATE CASCADE, |
||||||
|
CONSTRAINT fk_invoices_service |
||||||
|
FOREIGN KEY (service_id) REFERENCES services(id) |
||||||
|
ON DELETE SET NULL |
||||||
|
ON UPDATE CASCADE |
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; |
||||||
|
|
||||||
|
CREATE TABLE invoice_items ( |
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT, |
||||||
|
invoice_id INT UNSIGNED NOT NULL, |
||||||
|
line_number INT UNSIGNED NOT NULL DEFAULT 1, |
||||||
|
item_type ENUM('service','setup','credit','discount','manual','other') NOT NULL DEFAULT 'service', |
||||||
|
description VARCHAR(255) NOT NULL, |
||||||
|
quantity DECIMAL(18,4) NOT NULL DEFAULT 1.0000, |
||||||
|
unit_amount DECIMAL(18,8) NOT NULL DEFAULT 0.00000000, |
||||||
|
line_total DECIMAL(18,8) NOT NULL DEFAULT 0.00000000, |
||||||
|
currency_code VARCHAR(16) NOT NULL DEFAULT 'CAD', |
||||||
|
service_id INT UNSIGNED DEFAULT NULL, |
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, |
||||||
|
PRIMARY KEY (id), |
||||||
|
KEY idx_invoice_items_invoice_id (invoice_id), |
||||||
|
KEY idx_invoice_items_service_id (service_id), |
||||||
|
CONSTRAINT fk_invoice_items_invoice |
||||||
|
FOREIGN KEY (invoice_id) REFERENCES invoices(id) |
||||||
|
ON DELETE CASCADE |
||||||
|
ON UPDATE CASCADE, |
||||||
|
CONSTRAINT fk_invoice_items_service |
||||||
|
FOREIGN KEY (service_id) REFERENCES services(id) |
||||||
|
ON DELETE SET NULL |
||||||
|
ON UPDATE CASCADE |
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; |
||||||
|
|
||||||
|
CREATE TABLE payments ( |
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT, |
||||||
|
invoice_id INT UNSIGNED NOT NULL, |
||||||
|
client_id INT UNSIGNED NOT NULL, |
||||||
|
payment_method ENUM( |
||||||
|
'square', |
||||||
|
'etransfer', |
||||||
|
'crypto_etho', |
||||||
|
'crypto_egaz', |
||||||
|
'crypto_alt', |
||||||
|
'cash', |
||||||
|
'other' |
||||||
|
) NOT NULL, |
||||||
|
payment_currency VARCHAR(16) NOT NULL, |
||||||
|
payment_amount DECIMAL(18,8) NOT NULL DEFAULT 0.00000000, |
||||||
|
cad_value_at_payment DECIMAL(18,8) DEFAULT NULL, |
||||||
|
exchange_rate_note VARCHAR(255) DEFAULT NULL, |
||||||
|
reference VARCHAR(255) DEFAULT NULL, |
||||||
|
sender_name VARCHAR(255) DEFAULT NULL, |
||||||
|
txid VARCHAR(255) DEFAULT NULL, |
||||||
|
wallet_address VARCHAR(255) DEFAULT NULL, |
||||||
|
confirmations INT UNSIGNED DEFAULT NULL, |
||||||
|
confirmation_required INT UNSIGNED DEFAULT NULL, |
||||||
|
payment_status ENUM('pending','confirmed','failed','reversed') NOT NULL DEFAULT 'confirmed', |
||||||
|
received_at DATETIME DEFAULT NULL, |
||||||
|
notes TEXT DEFAULT NULL, |
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, |
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, |
||||||
|
PRIMARY KEY (id), |
||||||
|
KEY idx_payments_invoice_id (invoice_id), |
||||||
|
KEY idx_payments_client_id (client_id), |
||||||
|
KEY idx_payments_method (payment_method), |
||||||
|
KEY idx_payments_status (payment_status), |
||||||
|
KEY idx_payments_txid (txid), |
||||||
|
CONSTRAINT fk_payments_invoice |
||||||
|
FOREIGN KEY (invoice_id) REFERENCES invoices(id) |
||||||
|
ON DELETE RESTRICT |
||||||
|
ON UPDATE CASCADE, |
||||||
|
CONSTRAINT fk_payments_client |
||||||
|
FOREIGN KEY (client_id) REFERENCES clients(id) |
||||||
|
ON DELETE RESTRICT |
||||||
|
ON UPDATE CASCADE |
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; |
||||||
|
|
||||||
|
CREATE TABLE audit_log ( |
||||||
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, |
||||||
|
entity_type ENUM('client','service','invoice','payment','system') NOT NULL, |
||||||
|
entity_id INT UNSIGNED DEFAULT NULL, |
||||||
|
action VARCHAR(100) NOT NULL, |
||||||
|
actor VARCHAR(100) NOT NULL DEFAULT 'system', |
||||||
|
details TEXT DEFAULT NULL, |
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, |
||||||
|
PRIMARY KEY (id), |
||||||
|
KEY idx_audit_entity (entity_type, entity_id), |
||||||
|
KEY idx_audit_action (action), |
||||||
|
KEY idx_audit_created_at (created_at) |
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; |
||||||
Loading…
Reference in new issue