CREATE TABLE import_batches ( id INTEGER PRIMARY KEY AUTOINCREMENT, imported_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, source_path TEXT NOT NULL, source_sha256 TEXT, row_count INTEGER NOT NULL, notes TEXT ); CREATE TABLE sqlite_sequence(name,seq); CREATE TABLE transactions ( id INTEGER PRIMARY KEY AUTOINCREMENT, transaction_id TEXT NOT NULL UNIQUE, status TEXT NOT NULL, asset_class TEXT, instrument_type TEXT, market TEXT, ticker TEXT, name TEXT, side TEXT, order_type TEXT, trade_datetime TEXT, timezone TEXT, trade_date TEXT, financial_year TEXT, settlement_date TEXT, quantity TEXT, price_currency TEXT, price TEXT, gross_currency TEXT, gross_amount TEXT, brokerage_currency TEXT, brokerage_and_gst TEXT, total_currency TEXT, total_cash_amount TEXT, total_cash_amount_aud TEXT, fx_rate_to_aud TEXT, broker TEXT, account TEXT, source_document TEXT, notes TEXT, import_batch_id INTEGER REFERENCES import_batches(id), created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE trade_lots ( id INTEGER PRIMARY KEY AUTOINCREMENT, transaction_id TEXT NOT NULL REFERENCES transactions(transaction_id) ON DELETE CASCADE, lot_id TEXT NOT NULL UNIQUE, asset_class TEXT, ticker TEXT, name TEXT, acquisition_date TEXT, quantity_acquired TEXT, quantity_remaining TEXT, native_currency TEXT, native_cost_base TEXT, aud_cost_base TEXT, broker TEXT, account TEXT, notes TEXT ); CREATE TABLE cash_movements ( id INTEGER PRIMARY KEY AUTOINCREMENT, movement_id TEXT NOT NULL UNIQUE, movement_date TEXT, financial_year TEXT, movement_type TEXT, platform TEXT, account TEXT, currency TEXT, amount TEXT, amount_aud TEXT, related_transaction_id TEXT REFERENCES transactions(transaction_id), source_document TEXT, notes TEXT ); CREATE TABLE fx_rates ( id INTEGER PRIMARY KEY AUTOINCREMENT, fx_id TEXT NOT NULL UNIQUE, rate_date TEXT, from_currency TEXT NOT NULL, to_currency TEXT NOT NULL, rate TEXT NOT NULL, source TEXT, source_document TEXT, notes TEXT ); CREATE TABLE source_documents ( id INTEGER PRIMARY KEY AUTOINCREMENT, path TEXT NOT NULL UNIQUE, doc_type TEXT, sha256 TEXT NOT NULL, size_bytes INTEGER NOT NULL, captured_date TEXT, description TEXT, ocr_text TEXT, notes TEXT, created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE transaction_documents ( transaction_id TEXT NOT NULL REFERENCES transactions(transaction_id) ON DELETE CASCADE, source_document_id INTEGER NOT NULL REFERENCES source_documents(id) ON DELETE CASCADE, relationship TEXT NOT NULL DEFAULT 'evidence', PRIMARY KEY (transaction_id, source_document_id, relationship) ); CREATE TABLE decisions ( id INTEGER PRIMARY KEY AUTOINCREMENT, decision_date TEXT NOT NULL, topic TEXT NOT NULL, decision TEXT NOT NULL, source TEXT, notes TEXT ); CREATE TABLE audit_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, event_time TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, event_type TEXT NOT NULL, entity_type TEXT, entity_id TEXT, details TEXT ); CREATE INDEX idx_transactions_ticker ON transactions(ticker); CREATE INDEX idx_transactions_trade_date ON transactions(trade_date); CREATE INDEX idx_transactions_financial_year ON transactions(financial_year); CREATE INDEX idx_transactions_broker ON transactions(broker); CREATE INDEX idx_lots_ticker ON trade_lots(ticker); CREATE INDEX idx_docs_sha ON source_documents(sha256); CREATE VIEW v_transactions_aud AS SELECT transaction_id, status, financial_year, trade_date, trade_datetime, timezone, asset_class, instrument_type, market, ticker, name, side, quantity, price_currency, price, total_currency, total_cash_amount, total_cash_amount_aud, fx_rate_to_aud, brokerage_and_gst, broker, account, source_document, notes FROM transactions /* v_transactions_aud(transaction_id,status,financial_year,trade_date,trade_datetime,timezone,asset_class,instrument_type,market,ticker,name,side,quantity,price_currency,price,total_currency,total_cash_amount,total_cash_amount_aud,fx_rate_to_aud,brokerage_and_gst,broker,account,source_document,notes) */; CREATE VIEW v_holdings AS SELECT ticker, name, asset_class, instrument_type, market, broker, account, SUM(CASE WHEN lower(side)='buy' THEN CAST(quantity AS REAL) WHEN lower(side)='sell' THEN -CAST(quantity AS REAL) ELSE 0 END) AS quantity, SUM(CASE WHEN lower(side)='buy' THEN CASE WHEN total_cash_amount_aud IS NOT NULL THEN CAST(total_cash_amount_aud AS REAL) WHEN total_currency='AUD' THEN CAST(total_cash_amount AS REAL) ELSE NULL END WHEN lower(side)='sell' THEN CASE WHEN total_cash_amount_aud IS NOT NULL THEN -CAST(total_cash_amount_aud AS REAL) WHEN total_currency='AUD' THEN -CAST(total_cash_amount AS REAL) ELSE NULL END ELSE 0 END) AS aud_cost_base FROM transactions WHERE status='executed' AND ticker IS NOT NULL GROUP BY ticker, name, asset_class, instrument_type, market, broker, account /* v_holdings(ticker,name,asset_class,instrument_type,market,broker,account,quantity,aud_cost_base) */; CREATE VIEW v_financial_year_summary AS SELECT financial_year, asset_class, total_currency, COUNT(*) AS transaction_count, SUM(CAST(total_cash_amount AS REAL)) AS native_total, CASE WHEN SUM(CASE WHEN total_currency!='AUD' AND total_cash_amount_aud IS NULL THEN 1 ELSE 0 END) > 0 THEN NULL ELSE SUM(CASE WHEN total_cash_amount_aud IS NOT NULL THEN CAST(total_cash_amount_aud AS REAL) WHEN total_currency='AUD' THEN CAST(total_cash_amount AS REAL) ELSE NULL END) END AS aud_total FROM transactions GROUP BY financial_year, asset_class, total_currency /* v_financial_year_summary(financial_year,asset_class,total_currency,transaction_count,native_total,aud_total) */;