feat: 관리자 알림 설정 페이지 추가
Some checks failed
Build and Push Images / build-backend (push) Has been cancelled

This commit is contained in:
qorgh529
2026-04-27 20:17:13 +09:00
parent fc12243b1d
commit c24a2696db
2 changed files with 156 additions and 0 deletions

View File

@@ -79,6 +79,11 @@ def init_db():
webpage_id INTEGER REFERENCES webpages(id) ON DELETE CASCADE,
PRIMARY KEY (user_id, webpage_id)
);
CREATE TABLE IF NOT EXISTS notify_config (
key VARCHAR(100) PRIMARY KEY,
value TEXT NOT NULL,
updated_at TIMESTAMP DEFAULT NOW()
);
""")
# 컬럼 추가 (기존 DB 마이그레이션)
for col, definition in [
@@ -420,6 +425,68 @@ def update_user_pages(user_id: int, data: AccessUpdate, token=Depends(require_ad
conn.commit()
return {"ok": True}
# ─── Admin: 알림 설정 ────────────────────────────────────
class NotifyConfig(BaseModel):
discord_webhook_url: Optional[str] = ""
gmail_user: Optional[str] = ""
gmail_app_password: Optional[str] = ""
alert_email_to: Optional[str] = ""
def get_notify_config_from_db(conn) -> dict:
"""DB에서 알림 설정 조회, 없으면 환경변수 fallback"""
cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
cur.execute("SELECT key, value FROM notify_config")
rows = cur.fetchall()
db_config = {r["key"]: r["value"] for r in rows}
return {
"discord_webhook_url": db_config.get("discord_webhook_url", os.getenv("DISCORD_WEBHOOK_URL", "")),
"gmail_user": db_config.get("gmail_user", os.getenv("GMAIL_USER", "")),
"gmail_app_password": db_config.get("gmail_app_password", os.getenv("GMAIL_APP_PASSWORD", "")),
"alert_email_to": db_config.get("alert_email_to", os.getenv("ALERT_EMAIL_TO", "")),
}
@app.get("/api/admin/notify-config")
def get_notify_config(token=Depends(require_admin), conn=Depends(get_db)):
cfg = get_notify_config_from_db(conn)
# 비밀번호는 설정 여부만 반환 (보안)
return {
"discord_webhook_url": cfg["discord_webhook_url"],
"gmail_user": cfg["gmail_user"],
"gmail_app_password": "••••••••" if cfg["gmail_app_password"] else "",
"alert_email_to": cfg["alert_email_to"],
}
@app.put("/api/admin/notify-config")
def save_notify_config(data: NotifyConfig, token=Depends(require_admin), conn=Depends(get_db)):
cur = conn.cursor()
fields = {
"discord_webhook_url": data.discord_webhook_url,
"gmail_user": data.gmail_user,
"alert_email_to": data.alert_email_to,
}
# 비밀번호가 마스킹값이면 업데이트 안 함
if data.gmail_app_password and data.gmail_app_password != "••••••••":
fields["gmail_app_password"] = data.gmail_app_password
for key, value in fields.items():
if value is not None:
cur.execute("""
INSERT INTO notify_config (key, value, updated_at)
VALUES (%s, %s, NOW())
ON CONFLICT (key) DO UPDATE SET value=EXCLUDED.value, updated_at=NOW()
""", (key, value))
conn.commit()
# notifier 모듈 환경변수 동적 업데이트
import notifier
cfg = get_notify_config_from_db(conn)
notifier.DISCORD_WEBHOOK_URL = cfg["discord_webhook_url"]
notifier.GMAIL_USER = cfg["gmail_user"]
notifier.GMAIL_APP_PASSWORD = cfg["gmail_app_password"]
notifier.ALERT_EMAIL_TO = cfg["alert_email_to"]
return {"ok": True}
@app.get("/api/admin/notify-test")
async def notify_test(token=Depends(require_admin)):
# Discord + Gmail (Pod 이상/복구 테스트)