Alibrown commited on
Commit
5f96287
·
verified ·
1 Parent(s): a045e10

Update app/db_sync.py

Browse files
Files changed (1) hide show
  1. app/db_sync.py +38 -0
app/db_sync.py CHANGED
@@ -294,6 +294,44 @@ def is_ready() -> bool:
294
  return _initialized and _db_path is not None
295
 
296
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
  # =============================================================================
298
  # Direct execution guard
299
  # =============================================================================
 
294
  return _initialized and _db_path is not None
295
 
296
 
297
+ # =============================================================================
298
+ # SECTION 6 — PostgreSQL Bridge (Guardian-injected, optional)
299
+ # =============================================================================
300
+ _psql_writer = None
301
+
302
+
303
+ def set_psql_writer(writer_fn) -> None:
304
+ """
305
+ Receives execute_secured_query callable from Guardian via app.py.
306
+ Called once in start_application() if db_service is available.
307
+ app/* never imports postgresql.py directly — this is the only bridge.
308
+ """
309
+ global _psql_writer
310
+ _psql_writer = writer_fn
311
+ logger.info("PostgreSQL writer registered.")
312
+
313
+
314
+ async def persist(table: str, data: dict) -> None:
315
+ """
316
+ Write data from app/* to PostgreSQL via Guardian-injected writer.
317
+ Called by tools.py for provider_type = 'persist'.
318
+ Graceful degradation: raises RuntimeError if no DB configured.
319
+
320
+ Args:
321
+ table: Target PostgreSQL table name.
322
+ data: Dict to persist — stored as JSONB column 'payload'.
323
+ """
324
+ if not _psql_writer:
325
+ raise RuntimeError("No PostgreSQL writer — DATABASE_URL not configured.")
326
+
327
+ from datetime import datetime, timezone
328
+ now = datetime.now(timezone.utc).isoformat()
329
+
330
+ sql = f"INSERT INTO {table} (payload, created_at) VALUES ($1::jsonb, $2)"
331
+ await _psql_writer(sql, json.dumps(data), now, fetch_method="execute")
332
+ logger.info(f"Persisted to PostgreSQL table '{table}'.")
333
+
334
+
335
  # =============================================================================
336
  # Direct execution guard
337
  # =============================================================================