Skip to content

02 Architecture

hywznn edited this page Jul 22, 2026 · 4 revisions

백엔드 아키텍처

FOWOCO Server는 Spring Boot 기반의 modular monolith입니다. 한 애플리케이션으로 배포하되 기능별 경계를 지켜 나중에 필요한 부분만 분리할 수 있게 설계합니다.

시스템 구성

flowchart LR
  subgraph USER["사용자 영역"]
    HR["HR / Admin / Viewer"]
    WK["Worker"]
  end

  HR --> RC["React Client"]
  RC -->|"JWT · /api/v1/**"| SB["Spring Boot Server"]
  WK -->|"만료 token · /public/worker-links/**"| SB

  SB --> PG[("PostgreSQL")]
  SB --> ST["Local/S3 FileStorage"]
  SB -->|"S2S · /internal/v1/analyses"| AR["AI Runtime"]
  KP["Pinned Knowledge Bundle"] --> AR
  KP -. "Workflow projection" .-> SB
  AR --> LLM["External LLM / Cloud Endpoint"]

  SB -.-> OBS["Logs · Metrics · Traces"]
  AR -.-> OBS
Loading

중요한 경계는 다음과 같습니다.

  • Server는 AI Runtime만 호출합니다.
  • AI Runtime은 Server DB에 접근하지 않습니다.
  • LLM Provider key는 AI Runtime 배포 환경에 둡니다.
  • Knowledge는 version이 고정된 bundle로 배포합니다.
  • AI 결과는 Server의 HR 승인 규칙을 우회하지 못합니다.

자세한 소유권은 저장소 경계와 계약을 따릅니다.

Server 내부 모듈

모듈 책임 대표 객체
auth 로그인, JWT, Refresh rotation, Role User, RefreshToken
company 사업장 경계와 설정 Company, ActorContext
worker 근로자 기본정보와 근무·체류 정보 Worker
document 문서 유형·상태·유효기간·제출처 WorkerDocument
file 원본 파일 저장 Port와 안전한 접근 FileReference, FileStorage
task 업무카드와 Task Workflow Task, ChecklistItem
approval 승인 요청·승인·반려·무효화 Approval
workerlink 만료되는 근로자 링크·응답·제출 WorkerLink, WorkerResponse
airun AI 요청의 영속 실행·재시도·후보 결정 AiRun, TaskCandidate
aiintegration AI Runtime 내부 HTTP 계약과 장애 격리 AiRuntimeClient
audit 변경 행위의 append-only 기록 AuditEvent
reliability Durable Event, idempotency, 재시작 복구 EventPublication
common 오류 응답, request ID, clock 등 최소 공통 ApiErrorResponse

common에 Domain 로직을 모으지 않습니다. 다른 모듈의 Entity나 Repository를 직접 가져오지 말고 Application Port와 ID로 협력합니다.

요청 처리 계층

Controller
→ Request DTO validation
→ Application Service
→ Domain guard / 상태 전이
→ Repository 또는 외부 Port
→ Response DTO
  • Controller는 HTTP 변환과 입력 형식 검증을 담당합니다.
  • Application Service는 권한·tenant·transaction·use case 순서를 조정합니다.
  • Domain은 허용 상태와 불변식을 지킵니다.
  • Repository는 company_id 범위를 포함해 저장·조회합니다.
  • Adapter는 DB, FileStorage, AI Runtime 같은 외부 구현 세부를 감쌉니다.

자연어 요청의 비동기 흐름

sequenceDiagram
  actor H as HR
  participant C as Client
  participant S as Server
  participant D as PostgreSQL
  participant A as AI Runtime

  H->>C: 자연어 요청 입력
  C->>S: POST /api/v1/ai-runs
  S->>S: 인증·tenant·최소정보·idempotency 검증
  S->>D: AiRun=QUEUED + Event 저장
  S-->>C: 202 Accepted + aiRunId
  S->>A: POST /internal/v1/analyses
  A-->>S: outcome + candidates + version metadata
  S->>S: Schema·핵심값·민감정보 재검증
  S->>D: SUCCEEDED 또는 FAILED 저장
  C->>S: GET /api/v1/ai-runs/{aiRunId}
  S-->>C: 실행상태와 후보
  H->>C: 후보별 확정·폐기
  C->>S: POST .../candidate-decisions
  S->>D: 선택 후보만 DRAFT/NEEDS_INFO Task 생성
Loading

HTTP 연결이 끊겨도 AiRun과 Event가 DB에 남으므로 진행 상태를 다시 조회하고 재시작 뒤 복구할 수 있습니다.

Task 승인과 전달 흐름

sequenceDiagram
  actor H as HR
  participant S as Server
  participant W as Worker Link

  H->>S: Task 정보 보완
  H->>S: 검토 준비·승인 요청
  S->>S: 필수정보·version·Role 검증
  H->>S: 승인
  S->>S: 승인 snapshot + Audit 저장
  H->>S: Worker Link 발급
  S-->>H: 만료 token URL
  W->>S: 안내 확인·응답·문서 제출
  S->>S: Task Activity·Audit·증빙 갱신
  H->>S: 완료
  S->>S: 완료 조건 검증 후 COMPLETED
Loading

업무 핵심값을 수정하면 기존 승인을 무효화하고 다시 승인받게 합니다.

DB와 Transaction

  • PostgreSQL이 운영 기준 DB입니다.
  • JPA Entity 자동 생성 대신 Flyway migration을 사용합니다.
  • 모든 business table은 필요 시 company_id, 생성·수정 시각, optimistic lock version을 가집니다.
  • 중요 상태 변경과 Audit/Event publication은 가능한 한 같은 transaction에 저장합니다.
  • 외부 AI 호출 중 DB transaction을 오래 잡지 않습니다.
  • 원본 파일은 DB blob 대신 FileStorage 뒤에 두고 DB에는 안전한 reference와 metadata를 둡니다.

인증과 tenant

JWT 검증 → ActorContext 생성 → Role 검사 → company_id 범위 조회 → Domain command

Client가 body에 보낸 company_id를 믿지 않습니다. 인증된 Actor의 사업장 범위를 사용하며 목록·상세·수정·파일·AiRun·Audit에 같은 규칙을 적용합니다.

주요 기술 선택

선택 MVP 이유 확장 지점
Spring Boot + JPA 팀 학습비용과 생산성 module 경계 유지
PostgreSQL + Flyway 상태·감사·내구성에 적합 read model·partition 검토
REST + OpenAPI Client 계약이 명확 내부 event 또는 async API
JWT Access + Refresh 사업장 사용자 인증 SSO 필요 시 Adapter 추가
Local/S3 호환 FileStorage MVP와 cloud 전환 모두 지원 malware scan pipeline
AiRuntimeClient Port Fake와 Remote 교체가 쉬움 Agent Router·Canary
Durable DB Event 재시작과 중복에 안전 처리량이 필요할 때 broker 검토

설계 변경 체크

  • 이 로직의 실제 소유 저장소가 맞나요?
  • Task 상태와 AiRun 상태를 섞지 않았나요?
  • tenant 조건이 query와 background handler 모두에 있나요?
  • 승인·증빙·Audit을 우회하는 경로가 없나요?
  • 중복 요청·재시작·동시 수정에 안전한가요?
  • Public OpenAPI 또는 Internal AI contract가 함께 갱신됐나요?
  • 개인정보·token·Prompt가 log/event/metric에 들어가지 않나요?

Architecture 결정을 바꾸면 #23의 ADR에 이유·대안·영향을 남깁니다.

Clone this wiki locally