o2o-site-AEO/solution/backend/crud/social_crud.py
Mina Choi 11d30bb3d1 [chore] solution,admin,ontology: 코드 주석을 한 줄로 — 히스토리 주석 삭제
여러 줄 주석이 설명보다 경위(예전·실측·지적)를 적고 있어 읽는 사람이 결론을 찾기 어려웠다.

- ts·tsx·js·mjs·css·py 478개: 여러 줄 주석은 첫 문장 한 줄로, 과거형·날짜 문장은 삭제
- 주석 위치는 TypeScript 파서·파이썬 tokenize/ast 로 찾는다 — 문자열 안의 # · /* 는 건드리지 않는다
- eslint·ts·noqa·type: ignore 같은 지시 주석은 그대로 둔다

파이썬 275개 정리 전후 AST 동일, TS 298개 주석 뺀 토큰 동일(빈 JSX 주석 10곳만 차이).
site·frontend·admin tsc, site vitest 105 passed

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 16:05:19 +09:00

68 lines
2.5 KiB
Python

"""승인 CAS와 큐 적재를 같은 트랜잭션으로 묶어 승인 후 잡 유실을 막는다."""
import json
from sqlalchemy import text
from common.database.db_session_manager import DB_SESSION_MNG
from common.database.model.models import place_social_posts as Post
from common.enums import JobType
async def transaction(fn):
return await DB_SESSION_MNG.execute_lambda_write(Post.DBType(), fn)
async def enqueue(s, post_id, job_type):
await s.execute(
text("""INSERT INTO jobs(job_type, payload, dedupe_key, max_attempts)
VALUES (:type, CAST(:payload AS jsonb), :key, 1)
ON CONFLICT (dedupe_key) WHERE status IN (1,2) AND dedupe_key IS NOT NULL DO NOTHING"""),
{
"type": job_type,
"payload": json.dumps({"post_id": str(post_id)}),
"key": f"social:{job_type}:{post_id}",
},
)
await s.execute(text("SELECT pg_notify('web4ai_job', '')"))
async def decide(s, post_id, sha, approve, via):
row = (
await s.execute(
text("""UPDATE place_social_posts
SET status=:status, decided_at=now(), decided_via=:via, updated_at=now()
WHERE post_id=:id AND deleted=false AND status='PENDING_APPROVAL'
AND approval_token_sha=:sha AND approval_expires_at>now()
RETURNING post_id, account_id"""),
{
"status": "APPROVED" if approve else "DECLINED",
"via": via,
"id": post_id,
"sha": sha,
},
)
).first()
if row and approve and row.account_id:
await enqueue(s, post_id, JobType.SOCIAL_POST.value)
return bool(row)
async def sweep():
async def run(s):
await s.execute(
text("""UPDATE place_social_posts SET status='EXPIRED', updated_at=now()
WHERE deleted=false AND status='PENDING_APPROVAL' AND approval_expires_at<=now()""")
)
# POSTING은 외부가 받았을 수 있다.
await s.execute(
text("""UPDATE place_social_posts SET status='UNKNOWN',
last_error='POST_RESULT_UNKNOWN', updated_at=now()
WHERE deleted=false AND status='POSTING' AND updated_at<now()-interval '10 minutes'""")
)
await s.execute(
text("""UPDATE place_social_posts SET status='FAILED',
last_error='DRAFT_INTERRUPTED', updated_at=now()
WHERE deleted=false AND status='DRAFTING' AND updated_at<now()-interval '10 minutes'""")
)
await transaction(run)