음성 재생과 운영 배포 정리

This commit is contained in:
Yun Chan 2026-06-28 12:18:20 +09:00
parent 8ed185ce6c
commit ac7db95542
1020 changed files with 46863 additions and 2175 deletions

View file

@ -134,7 +134,50 @@ class RuntimeFallbackPolicyTest(unittest.IsolatedAsyncioTestCase):
self.assertEqual(prefs.voice_preset_id, "soft-young-fem")
async def test_staging_blocks_admin_engine_config_default_when_row_missing(self) -> None:
async def test_prod_blocks_runtime_schema_bootstrap_ddl_when_schema_incomplete(self) -> None:
class IncompleteConn:
async def fetchrow(self, *args, **kwargs):
return {
"has_user_columns": False,
"has_persona_triggers": False,
"has_persona_voice_map": False,
"has_auth_session": False,
"has_preferences": False,
"has_engine_config": False,
"has_session_columns": False,
"has_state_columns": False,
"has_stage_defs": False,
"has_admin_health_event": False,
"has_support_ticket": False,
"has_admin_health_event_policies": False,
"has_support_ticket_policies": False,
"has_session_write_policies": False,
"removed_old_session_policy": False,
"has_turn_write_policies": False,
"removed_old_turn_policy": False,
}
async def execute(self, *args, **kwargs):
raise AssertionError("prod startup must not run owner DDL")
class IncompleteAcquire:
async def __aenter__(self):
return IncompleteConn()
async def __aexit__(self, exc_type, exc, tb):
return None
class IncompletePool:
def acquire(self):
return IncompleteAcquire()
with environment("prod"), patch.object(auth_sessions, "get_pool", return_value=IncompletePool()):
with self.assertRaises(RuntimeError) as caught:
await auth_sessions.ensure_runtime_tables()
self.assertIn("runtime DB schema is incomplete", str(caught.exception))
async def test_staging_uses_env_engine_config_when_row_missing(self) -> None:
class EmptyConfigConn:
async def fetchrow(self, *args, **kwargs):
return None
@ -151,6 +194,19 @@ class RuntimeFallbackPolicyTest(unittest.IsolatedAsyncioTestCase):
return EmptyConfigAcquire()
with environment("staging"), patch.object(admin_routes, "get_pool", return_value=EmptyConfigPool()):
config = await admin_routes._current_engine_config()
self.assertFalse(config.durable)
self.assertEqual(config.source, "runtime_default")
self.assertEqual(config.engine_mode, settings.engine_mode)
self.assertEqual(config.engine_url, settings.engine_url)
async def test_staging_blocks_admin_engine_config_when_db_unavailable(self) -> None:
class BrokenConfigPool:
def acquire(self):
raise RuntimeError("db unavailable")
with environment("staging"), patch.object(admin_routes, "get_pool", return_value=BrokenConfigPool()):
with self.assertRaises(HTTPException) as caught:
await admin_routes._current_engine_config()