"""c_concurrency_config_update (03-C §3.13) + c_log_retention_config_update (03-C §3.13.1): the two `v_settings/*` upserts that don't already have a home in a bigger module (c_budget_config_update lives in budget_guardrail.py next to check_budget/list_budget_configs, which it shares state with). Both are singleton config_id='default' rows -- create on first use, update in place after. """ class InvalidParamError(Exception): """INVALID_PARAM -- 03-C §3.13/§3.13.1: value out of range.""" def get_concurrency_config(conn, config_id="default"): row = conn.execute( "SELECT config_id, max_concurrent_goals, updated_at FROM org_concurrency_config WHERE config_id = ?", (config_id,), ).fetchone() if row is None: return None return {"config_id": row[0], "max_concurrent_goals": row[1], "updated_at": row[2]} def upsert_concurrency_config(conn, max_concurrent_goals, updated_by, config_id="default"): """c_concurrency_config_update (03-C §3.13): v_concurrency_settings' submit_save. 02-V §2.11: range 1-50.""" if not (1 <= max_concurrent_goals <= 50): raise InvalidParamError("max_concurrent_goals must be in range 1-50, got {!r}".format(max_concurrent_goals)) exists = conn.execute( "SELECT 1 FROM org_concurrency_config WHERE config_id = ?", (config_id,) ).fetchone() is not None if exists: conn.execute( "UPDATE org_concurrency_config SET max_concurrent_goals = ?, updated_by = ?, " "updated_at = CURRENT_TIMESTAMP WHERE config_id = ?", (max_concurrent_goals, updated_by, config_id), ) else: conn.execute( "INSERT INTO org_concurrency_config (config_id, max_concurrent_goals, updated_by) VALUES (?, ?, ?)", (config_id, max_concurrent_goals, updated_by), ) conn.commit() return get_concurrency_config(conn, config_id) def get_loop_limit_config(conn, config_id): """Work Graph self-planning + loop-back (docs/todo/work-graph-self- planning-and-loop-back-design.md §6): no single 'default' config_id -- callers look up "{org_node}:{node_type}" then "{org_node}:*" then "default", falling back to a hardcoded constant if even "default" is unseeded (same pattern scheduler.py already uses for get_concurrency_config: `config["x"] if config else `).""" row = conn.execute( "SELECT config_id, max_loop_attempts, updated_at FROM work_graph_loop_limit_config WHERE config_id = ?", (config_id,), ).fetchone() if row is None: return None return {"config_id": row[0], "max_loop_attempts": row[1], "updated_at": row[2]} def upsert_loop_limit_config(conn, config_id, max_loop_attempts, updated_by): if max_loop_attempts < 1: raise InvalidParamError("max_loop_attempts must be >= 1, got {!r}".format(max_loop_attempts)) exists = conn.execute( "SELECT 1 FROM work_graph_loop_limit_config WHERE config_id = ?", (config_id,) ).fetchone() is not None if exists: conn.execute( "UPDATE work_graph_loop_limit_config SET max_loop_attempts = ?, updated_by = ?, " "updated_at = CURRENT_TIMESTAMP WHERE config_id = ?", (max_loop_attempts, updated_by, config_id), ) else: conn.execute( "INSERT INTO work_graph_loop_limit_config (config_id, max_loop_attempts, updated_by) VALUES (?, ?, ?)", (config_id, max_loop_attempts, updated_by), ) conn.commit() return get_loop_limit_config(conn, config_id) def get_log_retention_config(conn, config_id="default"): row = conn.execute( "SELECT config_id, retention_days, max_total_size_mb, updated_at FROM log_retention_config " "WHERE config_id = ?", (config_id,), ).fetchone() if row is None: return None return {"config_id": row[0], "retention_days": row[1], "max_total_size_mb": row[2], "updated_at": row[3]} def upsert_log_retention_config(conn, retention_days, updated_by, max_total_size_mb=None, config_id="default"): """c_log_retention_config_update (03-C §3.13.1): v_log_retention_settings' submit_save.""" if retention_days <= 0: raise InvalidParamError("retention_days must be > 0, got {!r}".format(retention_days)) exists = conn.execute( "SELECT 1 FROM log_retention_config WHERE config_id = ?", (config_id,) ).fetchone() is not None if exists: conn.execute( "UPDATE log_retention_config SET retention_days = ?, max_total_size_mb = ?, updated_by = ?, " "updated_at = CURRENT_TIMESTAMP WHERE config_id = ?", (retention_days, max_total_size_mb, updated_by, config_id), ) else: conn.execute( "INSERT INTO log_retention_config (config_id, retention_days, max_total_size_mb, updated_by) " "VALUES (?, ?, ?, ?)", (config_id, retention_days, max_total_size_mb, updated_by), ) conn.commit() return get_log_retention_config(conn, config_id)