Skip to content

06 Local Development

hywznn edited this page Jul 23, 2026 · 4 revisions

로컬 개발 가이드

현재 상태

#3 개발 기반은 PR #22로 완료됐습니다. 현재 main에서 Gradle Wrapper 실행 권한, Spring Security, Swagger, Flyway, 공통 오류, request_id, profile, H2/PostgreSQL test, CI를 사용할 수 있습니다.

Health와 Auth API는 main에 구현돼 있습니다. Approval·Audit은 PR #37, Task Workflow는 stacked PR #39에서 리뷰 중이므로 현재 checkout한 branch의 Swagger와 PR 상태를 함께 확인하세요.

5분 실행

준비물

  • Git
  • JDK 17
  • 첫 Gradle dependency download를 위한 internet
git clone https://github.com/fowoco/server.git
cd server
./gradlew clean test
./gradlew bootRun

새 terminal에서 확인합니다.

curl http://localhost:8080/health

정상 응답은 OK입니다.

  • Swagger UI: http://localhost:8080/swagger-ui.html
  • OpenAPI JSON: http://localhost:8080/v3/api-docs
  • H2 Console(local 전용): http://localhost:8080/h2-console

기본 profile은 local이며 memory H2를 사용합니다. 서버를 다시 실행하면 local data가 초기화되고 Flyway migration이 다시 적용됩니다. local server는 H2 Console 보호를 위해 기본적으로 127.0.0.1에 bind합니다.

PostgreSQL dev profile

먼저 local PostgreSQL에 fowoco database를 준비합니다. Docker Compose는 #9에서 표준화할 예정이므로 현재는 팀의 local PostgreSQL 방법을 사용합니다.

export DB_URL=jdbc:postgresql://localhost:5432/fowoco
export DB_USERNAME=postgres
export DB_PASSWORD='로컬 전용 값'
export SPRING_PROFILES_ACTIVE=dev
./gradlew bootRun

.env.example은 필요한 변수 이름을 보여주는 문서이며 Spring Boot가 자동으로 읽지 않습니다. shell 또는 IDE run configuration에 값을 등록합니다.

Workflow Catalog projection

local/test는 저장소의 src/main/resources/workflow/catalog-projection.local.json을 자동으로 읽습니다. 이는 fowoco/knowledge 0.2.0 DRAFT의 개발용 projection이며 원본 Workflow Catalog가 아닙니다.

prod에서는 Knowledge release pipeline이 만든 RELEASED projection을 배포하고 위치를 지정해야 합니다.

export WORKFLOW_CATALOG_LOCATION=file:/app/config/catalog-projection.json

운영에서 DRAFT projection을 지정하면 Server는 시작을 거부합니다. Task에는 생성 당시 workflow_idworkflow_catalog_version이 저장되므로 기존 Task의 기준이 몰래 바뀌지 않습니다.

Profile

Profile DB 용도 주의
local memory H2 + Flyway 빠른 개발·Swagger PostgreSQL 전용 동작을 보장하지 않음
test test별 H2 빠른 자동 test domain 통합은 PostgreSQL test도 필요
dev PostgreSQL local 통합 개발 DB 환경변수 필요
prod PostgreSQL 배포 Swagger/H2 Console 비활성, CORS 값 필수

JPA는 모든 profile에서 ddl-auto: validate입니다. schema 변경은 Entity 자동 생성이 아니라 src/main/resources/db/migration의 Flyway SQL로 관리합니다.

Security의 현재 동작

  • /health, Swagger/OpenAPI, local H2 Console만 공개합니다.
  • /api/v1/auth/login, Refresh cookie rotation, logout, /auth/me가 구현돼 있습니다.
  • 보호 API는 JWT의 user_id, company_id, roles로 ActorContext를 만들고 Repository도 같은 Company로 제한합니다.
  • VIEWER는 조회만 가능하고 쓰기는 ADMIN, HR만 가능합니다.
  • Refresh Token은 HttpOnly same-site cookie를 사용합니다. SameSite=None은 CSRF 또는 신뢰 Origin 검증 전까지 사용하지 않습니다.

Client 주소가 기본 http://localhost:3000, http://localhost:5173과 다르면 CORS_ALLOWED_ORIGINS에 쉼표로 등록합니다. prod에서는 이 값이 없으면 시작하지 않게 유지합니다.

AI Runtime 개발 상태

Server는 모델 Provider를 직접 선택하지 않습니다. #8과 #24에서는 다음 두 구현만 둡니다.

구현 환경 원칙
FakeAiRuntimeClient unit/API integration 외부 network 없이 결정적 후보 반환
RemoteAiRuntimeClient local 통합·staging·demo 별도 AI Runtime의 Internal API 호출

개발 모드는 다음처럼 나눕니다.

  1. Server 단독 개발: Fake client로 인증·Task·승인·AiRun을 빠르게 개발합니다.
  2. 통합 개발: Server와 AI Runtime을 함께 실행해 Internal Contract를 검증합니다.
  3. 모델 실험: fowoco/ai 저장소에서 LM Studio 또는 외부 Provider를 비교합니다.

Fake는 test fixture이지 실제 장애 fallback이 아닙니다. 장애를 성공으로 위장하지 않습니다. Provider API key와 Prompt 파일은 Server 저장소에 두지 않습니다.

Test 층

Test 목적 의존성
Unit 상태 전이·검증·fingerprint·error mapping 없음
Repository JPA·tenant query·unique/optimistic lock Testcontainers PostgreSQL
API integration 인증·권한·HTTP·idempotency Fake AI + PostgreSQL
AI Runtime contract Internal HTTP·Structured Output·timeout Fake server 또는 별도 smoke 환경
Recovery process restart·event replay·duplicate delivery PostgreSQL
E2E 대표 사용자·실패 흐름 배포 환경

일반 PR CI는 유료 외부 LLM을 호출하지 않습니다.

Branch·Commit·PR 규칙

작업 시작:

git switch main
git pull --ff-only
git switch -c feat/23-architecture-adr

권장 branch 예시:

feat/4-auth-multitenancy
feat/24-async-ai-run
fix/7-worker-link-expiry
docs/23-architecture-adr
  • 한 PR은 가능하면 한 Issue를 해결합니다.
  • PR 제목은 팀 규칙대로 한국어로 작성하되 AI Run, Workflow, JWT, class/API 이름 같은 기술 식별자를 억지로 번역하지 않습니다.
  • Commit은 Conventional Commits 형식을 사용합니다. type(scope)는 영문으로 두고 설명은 한국어로 작성하되 기술 식별자는 그대로 사용합니다.
feat(ai): 비동기 AI Run lifecycle 저장
fix(workflow): 승인 버전 불일치 전이 차단
test(event): restart recovery scenario 추가
docs(wiki): reliable execution contract 정리

PR 본문에는 변경 이유·검증·보안 영향·rollback과 Closes #번호를 적습니다.

Secret과 실제 데이터

commit하지 않는 것:

  • .env, LLM API key, JWT secret, DB password
  • Worker Link 원본 token과 Authorization header
  • 실제 근로자 개인정보가 든 seed·log·screenshot
  • AI Runtime·Provider request/response 전문과 Prompt 원문

실수로 commit했다면 file만 지우지 말고 key/token을 즉시 폐기·rotation하고 팀에 알립니다.

자주 생기는 문제

./gradlew: permission denied

현재 main에는 실행 권한이 반영돼 있습니다. 오래된 branch라면 git fetch origin 후 최신 main과 비교하세요. 임시로 bash gradlew에 의존해 권한 문제를 숨기지 않습니다.

Java version 오류

java -version

JDK 17이 선택됐는지 확인합니다.

DB/Flyway 실패

  • SPRING_PROFILES_ACTIVE와 DB URL
  • PostgreSQL process/container 상태
  • 사용자·database 권한
  • Flyway version 순서와 checksum
  • Entity와 migration 불일치

flywayClean으로 공유 DB를 지우지 않습니다.

401/403

보호 API는 Authorization: Bearer <access_token>이 없으면 401, 같은 사업장이나 역할 조건이 맞지 않으면 403/404가 정상입니다. /health, 로그인, local Swagger가 접근 가능한지부터 확인합니다.

AI 요청 실패

AI 기능이 아직 구현 전인지 #8/#24 상태를 먼저 확인합니다. 구현 후에는 AI Runtime readiness, Internal API timeout/circuit, request_id/trace_id, AiRun error_code를 확인합니다. Provider 내부 오류는 AI Runtime에서 확인하며 key 값은 어느 쪽에서도 출력하지 않습니다.

관련 이슈

Clone this wiki locally