feat: 운영 안정성과 세션 음성 경험 개선
This commit is contained in:
parent
facc4ad2d9
commit
c788343467
95 changed files with 8431 additions and 1785 deletions
|
|
@ -346,7 +346,12 @@ async def _runtime_tables_ready(conn) -> bool:
|
|||
to_regclass('app.persona_voice_map') IS NOT NULL AS has_persona_voice_map,
|
||||
to_regclass('app.auth_session') IS NOT NULL AS has_auth_session,
|
||||
to_regclass('app.user_preferences') IS NOT NULL AS has_preferences,
|
||||
to_regclass('app.admin_engine_config') IS NOT NULL AS has_engine_config,
|
||||
EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = 'app'
|
||||
AND table_name = 'admin_engine_config'
|
||||
AND column_name = 'reasoning_effort'
|
||||
) AS has_engine_config,
|
||||
EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = 'app'
|
||||
|
|
@ -650,11 +655,18 @@ async def ensure_runtime_tables() -> None:
|
|||
engine_mode TEXT NOT NULL,
|
||||
engine_url TEXT NOT NULL,
|
||||
model TEXT NOT NULL,
|
||||
reasoning_effort TEXT,
|
||||
updated_by TEXT,
|
||||
updated_at TIMESTAMPTZ
|
||||
)
|
||||
"""
|
||||
)
|
||||
await conn.execute(
|
||||
"""
|
||||
ALTER TABLE app.admin_engine_config
|
||||
ADD COLUMN IF NOT EXISTS reasoning_effort TEXT
|
||||
"""
|
||||
)
|
||||
await conn.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS app.admin_health_event (
|
||||
|
|
@ -1226,6 +1238,15 @@ async def upsert_managed_user(data: ManagedUserUpsertInput) -> ManagedUser:
|
|||
normalized_email = _normalize_email(data.email)
|
||||
normalized_external_id = _normalize_external_id(data.external_id, normalized_email)
|
||||
manual_external_id = f"email:{normalized_email}"
|
||||
desired_admin_access = (
|
||||
data.admin_access
|
||||
if data.admin_access is not None
|
||||
else (
|
||||
True
|
||||
if has_admin_access(normalized_email, data.role, False)
|
||||
else None
|
||||
)
|
||||
)
|
||||
desired_account_status = data.account_status or _initial_account_status(
|
||||
email=normalized_email,
|
||||
external_id=normalized_external_id,
|
||||
|
|
@ -1242,6 +1263,10 @@ async def upsert_managed_user(data: ManagedUserUpsertInput) -> ManagedUser:
|
|||
display_name = COALESCE(NULLIF(display_name, ''), $3),
|
||||
cohort = COALESCE(cohort, $4),
|
||||
affiliation = COALESCE(NULLIF(affiliation, ''), $5),
|
||||
admin_access = CASE
|
||||
WHEN $7::boolean IS NULL THEN admin_access
|
||||
ELSE $7::boolean
|
||||
END,
|
||||
last_seen_at = now(),
|
||||
updated_at = now()
|
||||
WHERE user_id = (
|
||||
|
|
@ -1293,6 +1318,7 @@ async def upsert_managed_user(data: ManagedUserUpsertInput) -> ManagedUser:
|
|||
_cohort_value(data.cohort_ids),
|
||||
data.affiliation or DEFAULT_AFFILIATION,
|
||||
manual_external_id,
|
||||
desired_admin_access,
|
||||
)
|
||||
if row is not None:
|
||||
user = _managed_user_from_row(row)
|
||||
|
|
@ -1314,13 +1340,13 @@ async def upsert_managed_user(data: ManagedUserUpsertInput) -> ManagedUser:
|
|||
last_seen_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, COALESCE($9, false), $5, $6, $8, now(), now())
|
||||
VALUES ($1, $2, $3, $4, COALESCE($9::boolean, false), $5, $6, $8, now(), now())
|
||||
ON CONFLICT (external_id) DO UPDATE SET
|
||||
email = EXCLUDED.email,
|
||||
display_name = COALESCE(NULLIF(EXCLUDED.display_name, ''), app.app_user.display_name),
|
||||
role = EXCLUDED.role,
|
||||
admin_access = CASE
|
||||
WHEN $9 IS NULL THEN app.app_user.admin_access
|
||||
WHEN $9::boolean IS NULL THEN app.app_user.admin_access
|
||||
ELSE EXCLUDED.admin_access
|
||||
END,
|
||||
cohort = COALESCE(EXCLUDED.cohort, app.app_user.cohort),
|
||||
|
|
@ -1369,7 +1395,7 @@ async def upsert_managed_user(data: ManagedUserUpsertInput) -> ManagedUser:
|
|||
data.affiliation or DEFAULT_AFFILIATION,
|
||||
data.reactivate,
|
||||
desired_account_status,
|
||||
data.admin_access,
|
||||
desired_admin_access,
|
||||
)
|
||||
if row is None:
|
||||
_inactive_emails.add(normalized_email)
|
||||
|
|
@ -1382,6 +1408,8 @@ async def upsert_managed_user(data: ManagedUserUpsertInput) -> ManagedUser:
|
|||
except InactiveUserError:
|
||||
raise
|
||||
except Exception:
|
||||
if not runtime_fallback_allowed():
|
||||
logger.exception("managed user persistence failed")
|
||||
require_runtime_fallback_allowed("managed user")
|
||||
current = _users.get(data.user_id or "") or _users.get(
|
||||
_email_index.get(normalized_email, "")
|
||||
|
|
@ -1405,7 +1433,7 @@ async def upsert_managed_user(data: ManagedUserUpsertInput) -> ManagedUser:
|
|||
email=normalized_email,
|
||||
display_name=data.display_name,
|
||||
role=data.role,
|
||||
admin_access=data.admin_access,
|
||||
admin_access=desired_admin_access,
|
||||
account_status=fallback_account_status,
|
||||
cohort_ids=data.cohort_ids,
|
||||
user_id=fallback_uid,
|
||||
|
|
@ -2008,24 +2036,42 @@ async def get_session(raw_sid: str | None) -> SessionUser | None:
|
|||
key,
|
||||
)
|
||||
if row is not None:
|
||||
app_role = _app_role(row["role"])
|
||||
stored_admin_access = bool(
|
||||
_row_value(row, "admin_access", False)
|
||||
)
|
||||
effective_admin_access = has_admin_access(
|
||||
row["email"],
|
||||
app_role,
|
||||
stored_admin_access,
|
||||
)
|
||||
await conn.execute(
|
||||
"UPDATE app.auth_session SET last_seen_at = now() WHERE sid_hash = $1",
|
||||
key,
|
||||
)
|
||||
await conn.execute(
|
||||
"UPDATE app.app_user SET last_seen_at = now() WHERE user_id = $1",
|
||||
"""
|
||||
UPDATE app.app_user SET
|
||||
last_seen_at = now(),
|
||||
admin_access = CASE
|
||||
WHEN $2 THEN TRUE
|
||||
ELSE admin_access
|
||||
END,
|
||||
updated_at = CASE
|
||||
WHEN $2 AND NOT admin_access THEN now()
|
||||
ELSE updated_at
|
||||
END
|
||||
WHERE user_id = $1
|
||||
""",
|
||||
row["user_id"],
|
||||
effective_admin_access,
|
||||
)
|
||||
return SessionUser(
|
||||
user_id=str(row["user_id"]),
|
||||
email=row["email"],
|
||||
display_name=row["display_name"],
|
||||
role=_app_role(row["role"]),
|
||||
admin_access=has_admin_access(
|
||||
row["email"],
|
||||
_app_role(row["role"]),
|
||||
bool(_row_value(row, "admin_access", False)),
|
||||
),
|
||||
role=app_role,
|
||||
admin_access=effective_admin_access,
|
||||
super_admin=is_super_admin_email(row["email"]),
|
||||
account_status=_account_status(row["account_status"]),
|
||||
cohort_ids=_cohort_ids(row["cohort"]),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue