전 저장소 리팩터링과 SSOT 정비
This commit is contained in:
parent
14ecbd4e7d
commit
3dfddcac6f
173 changed files with 19679 additions and 6952 deletions
|
|
@ -8,7 +8,7 @@ import re
|
|||
import uuid
|
||||
from typing import Annotated, Any, Literal
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Response, status
|
||||
from fastapi import APIRouter, Depends, File, Form, HTTPException, Response, UploadFile, status
|
||||
|
||||
from ..db import acquire
|
||||
from ..deps import CurrentPrincipal, Principal, Role, require_role
|
||||
|
|
@ -52,6 +52,7 @@ from ..persona_read_model import (
|
|||
from ..engine_client import EngineError, EngineMessage, GenerateRequest, engine_client
|
||||
from ..services import rag
|
||||
from ..services.guardrail import mask_pii
|
||||
from ..services.tabular_ingest import TabularIngestError, extract_tabular_text
|
||||
|
||||
router = APIRouter(prefix="/personas", tags=["personas"])
|
||||
TeacherOrAdmin = Annotated[Principal, Depends(require_role(Role.TEACHER, Role.ADMIN))]
|
||||
|
|
@ -555,6 +556,42 @@ async def create_persona_source_route(
|
|||
return await _register_persona_source_document(request, principal)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/sources/upload",
|
||||
response_model=PersonaSourceDocumentResponse,
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
)
|
||||
async def upload_persona_source_route(
|
||||
principal: TeacherOrAdmin,
|
||||
file: UploadFile = File(...),
|
||||
source_kind: PersonaSourceKind = Form("mixed_notes"),
|
||||
title: str | None = Form(None),
|
||||
source_note: str = Form(""),
|
||||
) -> PersonaSourceDocumentResponse:
|
||||
"""자유 양식 엑셀/CSV 업로드 → 텍스트 변환 → 기존 source 등록 경로 재사용 (P4).
|
||||
|
||||
업로드 원본 바이트는 이 핸들러 메모리에서만 파싱하고 저장하지 않는다(원본 파기).
|
||||
파생 텍스트만 기존 마스킹·hash-only 증거·sanitized chunk 경로로 등록된다.
|
||||
"""
|
||||
_ensure_teacher_or_admin(principal)
|
||||
data = await file.read()
|
||||
try:
|
||||
text = extract_tabular_text(filename=file.filename or "", data=data)
|
||||
except TabularIngestError as exc:
|
||||
raise HTTPException(status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(exc)) from exc
|
||||
finally:
|
||||
# 원본 바이트 참조를 즉시 놓는다 — 파생 텍스트 외에는 남기지 않는다.
|
||||
del data
|
||||
request = PersonaSourceDocumentRequest(
|
||||
filename=(file.filename or "uploaded-table.xlsx")[:240],
|
||||
source_kind=source_kind,
|
||||
text=text,
|
||||
title=(title or None),
|
||||
source_note=source_note[:800],
|
||||
)
|
||||
return await _register_persona_source_document(request, principal)
|
||||
|
||||
|
||||
@router.post("/drafts/generate", response_model=PersonaDraftGenerateResponse)
|
||||
async def generate_persona_draft_route(
|
||||
request: PersonaDraftGenerateRequest,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue