o2o-site-AEO/solution/backend/router/v1/ops/protocol.py
Mina Choi 46b74b310b [feat] solution/backend,frontend: 개발자 전용 사이트관리·유저관리 — 조회 전용 경량 화면
admin 앱을 새 메뉴로 키우려면 새 도메인이 필요해서, solution 앱에 DEVELOPER 게이트 하나로 얹었다.
메뉴 문자열은 사장님 번들에도 실리지만 데이터 접근은 백엔드 게이트가 막는다.

- router/v1/ops: GET /v1/ops/sites · /v1/ops/users (RequireDeveloper)
- services/ops_service.py, crud/site_crud.list_all_sites, crud/user_crud.list_users
- frontend: OpsSitesPage · OpsUsersPage, AppShell 에 role===DEVELOPER 일 때만 두 줄
- api/generated: orval 코드젠 결과

프론트 tsc·eslint 통과, openapi 코드젠 성공. DB 조회는 미검증(DEVLOG 2026-09-23)

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

54 lines
1.6 KiB
Python

import uuid
from datetime import datetime
from typing import Optional
from common.enums import AuthProvider, PlaceCategory, PlaceStatus, SiteStatus, UserRole, UserStatus
from common.models.gmodel import Res_PageProtocol, WebPacketProtocol
class OpsSiteData(WebPacketProtocol):
"""전 계정 사이트 목록의 한 줄 — 사업장(place) + 사이트(site) + 소유자.
★ MySiteData(내 사이트 목록)와 같은 모양에 소유자 식별자만 얹었다 — 화면이 다를 뿐 값의 뜻은 같다."""
place_id: uuid.UUID
name: str
category: PlaceCategory
place_status: PlaceStatus
created_at: Optional[datetime] = None
site_id: Optional[uuid.UUID] = None
status: Optional[SiteStatus] = None
domain: Optional[str] = None
published_at: Optional[datetime] = None
thumbnail_url: Optional[str] = None
needs_rebuild: bool = False
owner_login_id: str
owner_email: Optional[str] = None
owner_name: Optional[str] = None
class Res_OpsSites(Res_PageProtocol):
sites: list[OpsSiteData] = []
class OpsUserData(WebPacketProtocol):
"""전 계정 목록의 한 줄. ★ role 은 항상 USER/OWNER 다 — 개발자 계정은 서비스가 걸러낸다."""
user_id: uuid.UUID
login_id: str
name: Optional[str] = None
email: Optional[str] = None
contact_number: Optional[str] = None
role: UserRole
status: UserStatus
provider: AuthProvider
created_at: Optional[datetime] = None
last_accessed_at: Optional[datetime] = None
place_count: int = 0
class Res_OpsUsers(Res_PageProtocol):
users: list[OpsUserData] = []