# /home/Autopartes/pos/services/audit.py """Audit logging service. INSERT-only, never update or delete.""" from flask import g def log_action(conn, action, entity_type=None, entity_id=None, old_value=None, new_value=None): """Insert an audit log entry using the current request context. Args: conn: psycopg2 connection to the tenant DB action: SALE, CANCEL, PRICE_CHANGE, STOCK_ADJUST, LOGIN, DISCOUNT, etc. entity_type: 'sale', 'inventory', 'customer', 'employee', etc. entity_id: ID of the affected entity old_value: dict of previous values (or None) new_value: dict of new values (or None) """ import json cur = conn.cursor() cur.execute(""" INSERT INTO audit_log (employee_id, action, entity_type, entity_id, old_value, new_value, device_id, ip_address, branch_id) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) """, ( getattr(g, 'employee_id', None), action, entity_type, entity_id, json.dumps(old_value) if old_value else None, json.dumps(new_value) if new_value else None, getattr(g, 'device_id', None), _get_client_ip(), getattr(g, 'branch_id', None), )) # Don't commit here — let the caller control the transaction def _get_client_ip(): """Get client IP, handling proxies.""" from flask import request if request.headers.get('X-Forwarded-For'): return request.headers['X-Forwarded-For'].split(',')[0].strip() return request.remote_addr