API 적용 최초 배포
Deploy feedback demo / deploy (push) Failing after 4m26s

This commit is contained in:
root
2026-09-01 17:12:46 +09:00
parent badf5f2c81
commit aaddfc7bfc
44 changed files with 1331 additions and 867 deletions
+6 -2
View File
@@ -265,8 +265,12 @@ async def create_ticket(
]
request_payload = TicketCreateRequest(
workspace_code=workspace_code,
requester_id=str(form.get("requester_id") or ""),
requester_tenant_id=str(form.get("requester_tenant_id") or ""),
# Multipart writers do not send requester identity fields. Use
# the verified SSO principal before Pydantic validates the
# required fields; applying model_copy afterwards is too late
# because empty values fail min_length validation first.
requester_id=principal.user_id,
requester_tenant_id=principal.tenant_id,
requester_contact=str(form.get("requester_contact") or ""),
title=str(form.get("title") or ""),
description=str(form.get("description") or ""),
+3
View File
@@ -41,6 +41,9 @@ class Settings(BaseSettings):
jwt_secret: str = ""
admin_candidate_tenant_id: str = ""
initial_super_admin_phone_number: str = ""
# Users without an explicit workspace role receive END_USER access to
# this public feedback workspace.
default_support_workspace_code: str = "EGBIM_DEMO"
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
+1
View File
@@ -72,6 +72,7 @@ class WorkspaceFormField(BaseModel):
label: str
field_type: str
required: bool = False
options: list[dict[str, str | int]] = Field(default_factory=list)
class WorkspaceFormTemplateResponse(BaseModel):
@@ -9,6 +9,7 @@ from app.db.models import (
UserWorkspaceAccess,
Workspace,
)
from app.core.config import settings
class AccessService:
@@ -36,19 +37,25 @@ class AccessService:
@staticmethod
def default_user_workspace_code(db: Session) -> str | None:
"""Return the first active ABC project workspace.
"""Return the configured public feedback workspace.
The old Q&A_Platform seed workspace must not determine the first SSO
redirect after ABC projects are synchronized.
Users without an explicit role assignment receive END_USER access to
this workspace. A configured code prevents old seed data or a newly
created project from changing the public writer target.
"""
return db.execute(
configured_code = settings.default_support_workspace_code.strip()
query = (
select(Workspace.workspace_code)
.where(
Workspace.is_active.is_(True),
Workspace.workspace_type == "SOFTWARE_APP",
)
.order_by(Workspace.id.asc()),
).scalar()
)
if configured_code:
query = query.where(Workspace.workspace_code == configured_code)
else:
query = query.order_by(Workspace.id.asc())
return db.execute(query).scalar()
@staticmethod
def _upsert_support_user(
@@ -39,6 +39,11 @@ from app.schemas.ticket import (
SEOUL_TIMEZONE = ZoneInfo("Asia/Seoul")
QNA_CATEGORY_CODES = {"ERROR_QNA", "IMPROVEMENT_QNA", "GENERAL_QNA"}
QNA_CATEGORY_OPTIONS = [
{"id": 1, "key": "ERROR_QNA", "name": "오류 문의"},
{"id": 2, "key": "IMPROVEMENT_QNA", "name": "개선 문의"},
{"id": 3, "key": "GENERAL_QNA", "name": "일반 문의"},
]
access_service = AccessService()
@@ -84,6 +89,20 @@ class TicketService:
def get_workspace_form_template(self, db: Session, workspace_code: str) -> WorkspaceFormTemplateResponse:
workspace = self._get_workspace_by_code(db, workspace_code, raise_not_found=False)
qna_fields = [
WorkspaceFormField(
field_code="category",
label="구분",
field_type="select",
required=True,
options=QNA_CATEGORY_OPTIONS,
),
WorkspaceFormField(field_code="title", label="제목", field_type="text", required=True),
WorkspaceFormField(field_code="description", label="내용", field_type="textarea", required=True),
WorkspaceFormField(field_code="ip_address", label="사용자 IP 주소", field_type="text"),
WorkspaceFormField(field_code="mac_address", label="MAC 주소", field_type="text"),
]
templates = {
"INTRA_BOOK_REQUEST": WorkspaceFormTemplateResponse(
workspace_code="INTRA_BOOK_REQUEST",
@@ -113,6 +132,12 @@ class TicketService:
WorkspaceFormField(field_code="expected_result", label="기대 결과", field_type="textarea"),
],
),
"EGBIM_DEMO": WorkspaceFormTemplateResponse(
workspace_code="EGBIM_DEMO",
workspace_name=workspace.workspace_name if workspace else "EGBIM_DEMO",
requires_approval=False,
fields=qna_fields,
),
}
return templates.get(
@@ -1910,7 +1935,7 @@ class TicketService:
if not normalized or normalized == "GENERAL":
return self._default_category_code(workspace_code)
if workspace_code == "Q&A_Platform" and normalized not in QNA_CATEGORY_CODES:
if workspace_code in {"Q&A_Platform", "EGBIM_DEMO"} and normalized not in QNA_CATEGORY_CODES:
return "GENERAL_QNA"
return normalized