zenith-audit-system / src /export_data.py
vinny2005's picture
Initial commit of Zenith
2e5b4a1
Raw
History Blame Contribute Delete
5.47 kB
import os
import sqlite3
import pandas as pd
DB_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "zenith.db")
EXPORT_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "exports")
def export_table_to_csv(conn, table_name):
df = pd.read_sql_query(f"SELECT * FROM {table_name}", conn)
file_path = os.path.join(EXPORT_DIR, f"{table_name}.csv")
df.to_csv(file_path, index=False)
print(f"Exported {len(df)} rows from '{table_name}' table to: {file_path}")
def run_analytical_exports(conn):
print("\nRunning analytical SQL queries and exporting views...")
# 1. SoD Violations
sod_query = """
SELECT fje.entry_id, fje.transaction_date, fje.posted_by, fje.approved_by,
da.account_code, da.account_name, (fje.debit_amount + fje.credit_amount) AS amount,
fje.risk_score, fal.llm_determination, fal.llm_audit_summary
FROM fact_journal_entries fje
JOIN dim_accounts da ON fje.account_key = da.account_key
LEFT JOIN fact_audit_log fal ON fje.entry_id = fal.entry_id
WHERE fje.posted_by = fje.approved_by AND (fje.debit_amount > 0 OR fje.credit_amount > 0)
"""
df_sod = pd.read_sql_query(sod_query, conn)
df_sod.to_csv(os.path.join(EXPORT_DIR, "report_sod_violations.csv"), index=False)
print(f"Exported {len(df_sod)} SoD violations.")
# 2. Split Transactions
split_query = """
WITH daily_postings AS (
SELECT
DATE(transaction_date) AS post_date,
posted_by,
account_key,
COUNT(DISTINCT entry_id) AS split_count,
SUM(debit_amount + credit_amount) AS total_daily_value,
GROUP_CONCAT(entry_id) AS split_entry_ids
FROM fact_journal_entries
WHERE (debit_amount + credit_amount) < 5000.0
AND (debit_amount + credit_amount) > 0
GROUP BY post_date, posted_by, account_key
)
SELECT dp.post_date, dp.posted_by, da.account_code, da.account_name,
dp.split_count, dp.total_daily_value, dp.split_entry_ids
FROM daily_postings dp
JOIN dim_accounts da ON dp.account_key = da.account_key
WHERE dp.split_count >= 3
"""
df_split = pd.read_sql_query(split_query, conn)
df_split.to_csv(os.path.join(EXPORT_DIR, "report_split_transactions.csv"), index=False)
print(f"Exported {len(df_split)} split transaction cohorts.")
# 3. Off-hours Postings
offhours_query = """
SELECT fje.entry_id, fje.transaction_date, fje.posted_by, du.clearance_level,
(fje.debit_amount + fje.credit_amount) AS amount, da.account_name,
STRFTIME('%H', fje.transaction_date) AS posting_hour,
STRFTIME('%w', fje.transaction_date) AS day_of_week
FROM fact_journal_entries fje
JOIN dim_users du ON fje.user_key = du.user_key
JOIN dim_accounts da ON fje.account_key = da.account_key
WHERE du.user_id <> 'usr_admin'
AND (
STRFTIME('%H', fje.transaction_date) < '09'
OR STRFTIME('%H', fje.transaction_date) >= '18'
OR STRFTIME('%w', fje.transaction_date) IN ('0', '6')
)
"""
df_off = pd.read_sql_query(offhours_query, conn)
df_off.to_csv(os.path.join(EXPORT_DIR, "report_offhours_postings.csv"), index=False)
print(f"Exported {len(df_off)} off-hours transaction records.")
# 4. Sentiment Summary Report
sentiment_query = """
SELECT sentiment_label, COUNT(*) as review_count, AVG(confidence_score) as avg_confidence
FROM fact_brand_reviews
GROUP BY sentiment_label
"""
df_sent = pd.read_sql_query(sentiment_query, conn)
df_sent.to_csv(os.path.join(EXPORT_DIR, "report_sentiment_summary.csv"), index=False)
print(f"Exported sentiment summary calculations.")
# 5. Pricing Violations Report
pricing_query = """
SELECT dcr.retailer_name, COUNT(*) as checks_count,
SUM(frp.is_violation) as violation_count,
AVG(frp.price_inflation_pct) as avg_price_inflation
FROM fact_retail_prices frp
JOIN dim_competitor_retailers dcr ON frp.retailer_key = dcr.retailer_key
GROUP BY dcr.retailer_name
"""
df_pr = pd.read_sql_query(pricing_query, conn)
df_pr.to_csv(os.path.join(EXPORT_DIR, "report_pricing_violations.csv"), index=False)
print(f"Exported pricing compliance summary.")
def export_all():
if not os.path.exists(EXPORT_DIR):
os.makedirs(EXPORT_DIR)
print(f"Exporting files to directory: {EXPORT_DIR}")
conn = sqlite3.connect(DB_PATH)
# Standard ledger dimensions
export_table_to_csv(conn, "dim_accounts")
export_table_to_csv(conn, "dim_entities")
export_table_to_csv(conn, "dim_users")
# Brand Sentiment and Competitor Retail dimensions
export_table_to_csv(conn, "dim_sentiment_channels")
export_table_to_csv(conn, "dim_competitor_retailers")
# Fact tables
export_table_to_csv(conn, "fact_journal_entries")
export_table_to_csv(conn, "fact_audit_log")
export_table_to_csv(conn, "fact_brand_reviews")
export_table_to_csv(conn, "fact_retail_prices")
# Reporting views
run_analytical_exports(conn)
conn.close()
print("\nAll database tables successfully exported to CSVs!")
if __name__ == "__main__":
export_all()