# AI ExamGenerator — Public Architecture

이 문서는 AI ExamGenerator의 설계 의도를 설명하기 위한 공개용 아키텍처 개요입니다. 보안과 영업상 중요한 구현 세부사항, 운영 환경 값, 모델 프롬프트는 포함하지 않습니다.

## 1. 전체 흐름

```mermaid
flowchart LR
    U["Teacher / User"] -->|HTTPS| FE["React Web App"]
    FE --> API["FastAPI"]
    API --> DB[(PostgreSQL)]
    API --> Q["Redis / RQ"]
    Q --> W["AI Worker"]
    W --> AI["AI Providers"]
    W --> DOC["PDF / DOCX Renderer"]
    W --> DB
    API --> FE
```

### 요청 계층

- FastAPI는 인증, 세션 생성, 상태 조회와 같은 짧은 요청을 처리합니다.
- 업로드 직후 사용자에게 작업 식별자를 반환하고 긴 AI 처리는 요청 수명과 분리합니다.
- 각 리소스 접근은 소유권을 확인하며, 관리자 기능은 별도 권한으로 제한합니다.

### 작업 계층

- Redis/RQ 워커가 PDF 분석, AI 생성, 검증과 문서 출력을 수행합니다.
- 작업은 재시도 가능해야 하므로 요청 식별자와 상태 전이를 명시적으로 관리합니다.
- 취소 신호와 제한된 타임아웃을 확인해 불필요한 외부 API 호출을 줄입니다.

### 데이터 계층

- PostgreSQL은 사용자, 세션, 문제, 생성 시험지와 크레딧 원장을 관리합니다.
- 금전성 상태 변경은 트랜잭션과 멱등성 키를 사용합니다.
- Redis는 작업 큐, 제한된 캐시, 동시성 제어와 짧은 수명의 상태에 사용합니다.

## 2. AI 파이프라인

```mermaid
flowchart TD
    P["PDF Upload"] --> T["Text Extraction"]
    T --> G{"Extractable?"}
    G -->|No| O["Page Render + OCR/Vision"]
    G -->|Yes| S["Question Structuring"]
    O --> S
    S --> A["Question Analysis"]
    A --> N["Controlled Generation"]
    N --> V["Local + AI Verification"]
    V --> R{"Pass?"}
    R -->|No| F["Repair / Supplemental Generation"]
    F --> V
    R -->|Yes| D["PDF / DOCX"]
```

### 추출

페이지별 텍스트 양과 품질을 확인합니다. 일반 텍스트 추출로 읽기 어려운 페이지는 이미지로 렌더링한 후 OCR/비전 단계로 전환합니다. 두 방식 모두 실패하면 성공으로 위장하지 않고 작업을 실패 처리합니다.

### 생성

원문 문항을 분석한 구조와 사용자 조건을 바탕으로 변형합니다. 생성 요청은 가능한 경우 구조화된 스키마를 사용하고, 문항별 결과가 독립적으로 검증될 수 있도록 유지합니다.

### 검증

검증은 다음과 같은 서로 다른 실패를 구분합니다.

- 정답 불일치
- 원문 또는 지문 재창작
- 선택지 중복·유사도 이상
- 수학 유형·난이도 관계 불일치
- 필요한 도형 및 이미지 누락
- 파싱 불가 또는 불완전한 응답

모든 문항이 같은 비용의 검증을 거치지는 않습니다. 로컬 검사와 이전 단계 결과를 활용해 위험도가 높은 문항에 더 많은 검증 비용을 사용합니다.

### 부분 실패 복구

청크 전체를 무한히 다시 생성하는 대신 실패한 문항을 좁혀 repair하고, 그래도 실패하면 제한된 보충 생성을 시도합니다. 최종적으로 품질 기준을 통과하지 못한 문항은 상태에 반영합니다.

## 3. 크레딧과 멱등성

AI 작업은 네트워크 재시도, 큐 재실행, 사용자의 중복 클릭 때문에 같은 의도가 여러 번 도착할 수 있습니다.

따라서 크레딧 시스템은 다음 원칙을 따릅니다.

1. 요청 식별자를 기준으로 동일 차감이 반복되지 않습니다.
2. 차감과 원장 기록은 하나의 트랜잭션 경계에 있습니다.
3. 환불도 원래 작업과 연결된 멱등 이벤트입니다.
4. 작업 상태가 불명확할 때 임의로 성공 처리하지 않습니다.
5. 외부 결제 알림은 위조와 중복 수신을 가정합니다.
6. 비용이 먼저 발생하고 차감은 나중에 확정되는 작업은, 확정 전 잔액을 미리 예약해 동시 요청이 같은 잔액을 중복으로 통과시키지 못하게 합니다.

구체적인 테이블, 키 형식과 결제사 연동 구현은 공개 저장소에 포함하지 않습니다.

## 4. 결정적 도형 렌더링

수학 문제의 그래프나 도형을 생성 모델이 자유 형식 SVG로 직접 출력하면 다음 문제가 생깁니다.

- 실행마다 모양이 달라질 수 있음
- 화면과 PDF 결과가 다를 수 있음
- 안전하지 않은 SVG 속성이 포함될 수 있음
- 수식 문자열을 실행하는 구현은 코드 실행 위험을 만들 수 있음

AI ExamGenerator는 제한된 **figure specification**을 사용합니다.

```json
{
  "type": "function_plot",
  "viewport": { "xMin": -3, "xMax": 3, "yMin": -2, "yMax": 4 },
  "curves": [
    { "expression": "x^3 - 3*x + 1", "style": "primary" }
  ],
  "showAxes": true
}
```

애플리케이션은 허용된 필드와 범위를 검증하고, 자체 수식 파서로 표현식을 처리해 결정적인 SVG를 생성합니다. 임의 코드 실행 함수는 사용하지 않습니다. SVG는 허용 목록과 정화 단계를 거친 후 화면과 출력물에서 사용됩니다.

## 5. 관측성과 비용 제어

AI 응답 속도와 품질은 고정되어 있지 않습니다. 운영 판단을 위해 역할별로 다음 정보를 수집합니다.

- 호출 latency와 상태
- 재시도 횟수와 실패 유형
- 입력/출력 크기의 근사치
- 캐시 적중 여부
- 요청 문항 수와 최종 생성 문항 수
- 단계별 wall-clock 시간

이 메트릭은 개별 사용자의 원문을 그대로 기록하지 않는 방향으로 설계합니다. 모델 선택과 검증 강도는 플랜 정책과 운영 결과를 바탕으로 조정합니다.

## 6. 배포 구조

```mermaid
flowchart TB
    Internet --> N["Nginx"]
    N --> Static["Static Frontend"]
    N --> API["FastAPI Processes"]
    API --> DB[(PostgreSQL)]
    API --> Redis[(Redis)]
    Redis --> Workers["RQ Worker Pools"]
    Workers --> AI["External AI APIs"]
    Workers --> Renderer["Document Renderer"]
```

API 프로세스와 무거운 워커를 분리해 AI 작업 포화가 일반 페이지와 상태 조회를 직접 막지 않도록 합니다. 정적 자산과 보호된 결과물 전달 경로도 API 계산 경로와 구분합니다.

## 7. 공개 문서의 한계

본 문서는 포트폴리오 목적의 고수준 설명입니다. 공격 표면을 넓힐 수 있는 다음 정보는 생략했습니다.

- 운영 서버와 네트워크 식별 정보
- Nginx/systemd 전체 설정
- JWT, 웹훅, 저장소 토큰 형식
- 프롬프트와 모델 폴백 상세값
- 관리자 엔드포인트와 내부 데이터 구조
- 실제 사용자 데이터와 운영 로그

공개 범위에 대한 자세한 기준은 [PUBLIC_SCOPE.md](PUBLIC_SCOPE.md)를 확인해 주세요.
