일기 + AI 무드 캘린더 플랫폼
사용자가 일기를 작성하면 AI 가 공감 메시지 + 그 날의 기분 이모지를 생성한다. 그 이모지는 월별 캘린더 화면에 매핑되어 한 달치 감정을 한눈에 보여준다.
로드맵 · API 명세 · 보안 · 트러블슈팅 · 학습 노트 12 항목 · 운영 Runbook 까지 한 페이지에 검색 가능 (MkDocs Material).
→ 문서 사이트 열기
Controller → Service → Repository → Entity. 컨트롤러에 @AuthenticationPrincipal UUID 자동 주입,
서비스에 소유권 검증 + @Transactional, 엔티티에 명시 메서드 패턴 (setter X).
비동기 AI 응답 흐름 (PR 4-pre 운영 반영): POST /post 가 같은 트랜잭션에 AiResponse(PENDING) row 저장 →
controller 가 commit 후 triggerAsync 호출 → @Async 스레드가 Stub 호출 → DONE/FAILED 전이.
클라이언트는 GET /post/{id}/ai-response 폴링.
@UuidGenerator. 컬럼명 <table>_id. 분산 환경 가정 + ID 추측 방지.
모든 엔티티 created_at / updated_at 자동. JpaAuditingConfig 분리 (슬라이스 테스트 호환).
이모지 (😊) 그대로 저장. 변환 로직 X. 운영 RDS 머지 전 사전 검증.
Post ↔ AiResponse 는 uk_ai_response_post_id UNIQUE. 운영 머지 후 SHOW INDEX 사후 검증 필수.
부팅 시 누락 컬럼/테이블 자동 추가. 인덱스/UNIQUE 보장 X → PR 6 Flyway 도입 시 validate.
setter 없음. Post.update(...) / AiResponse.markDone(...) → 트랜잭션 dirty-checking.
[FE: React+Vite] [BE: Spring Boot 4] [AI: 별도 EC2]
| build | build ^
v aws s3 sync v Docker Hub |
+----------------+ +-----------------+ |
| AWS S3 | | AWS EC2 | <-- SSM --- GitHub
| ap-northeast-1| -- HTTP -->| Amazon Linux | send Actions
| (도쿄) | | ap-northeast-2 | -command (main push)
+----------------+ +-----------------+ |
| JDBC |
v |
+-----------------+ |
| AWS RDS MySQL | |
| utf8mb4 | |
+-----------------+ |
CI: PR → dev → ./gradlew build.
CD: push → main → Docker Hub (latest + :SHA) → AWS SSM 으로 EC2 에서
docker-compose pull && up -d → wait command-executed + health check (swagger 200 polling).
SHA 태그로 응급 롤백 가능.
비밀번호 BCrypt strength 10. Access token 1시간, Claims sub=UUID.
2주 수명. SHA-256 hex 만 DB 저장 — raw 노출 시에도 복원 불가. 사용 시 즉시 revoke + 새 발급 (탈취 노출 창 최소화).
@AuthenticationPrincipal UUID 자동 주입 + Post.isOwnedBy() 검증 → 본인 200 / 타인 403.
app.cors.allowed-origins env 외부화. 와일드카드 * 금지. compose ${VAR:-default} 패턴.
로그인 실패 / refresh 실패 모두 같은 401 메시지. 이메일 존재 여부 노출 X.
모든 값 ${ENV_VAR:기본값} 플레이스홀더. 평문 비밀값 금지 (T-013 사고 이후 정책).
총 27 항목 누적 (T-001 ~ T-027). 작업 중 막힌 지점이 다음 사람의 시작점이 되도록 기록. 가장 큰 사건 셋:
표면: CORS preflight 401. 실제: 컨테이너 restart loop. 원인: SSM agent 죽음 + CD silent fail + springdoc 2.8.3 ↔ Spring Boot 4 비호환 + Post→User FK orphan + @SpringBootTest @Disabled 안전망 부재. 교훈: 표면 증상에서 멈추지 말고 docker ps + docker logs + docker inspect .Created 부터.
워크플로우의 docker compose (스페이스) 가 EC2 에서 unknown sub-command. PR #45 의 wait/verify 가 처음으로 노출 — 옛 CD 들의 자동 deploy 는 한 번도 진짜로 작동한 적이 없었다. SSM 의 send-command silent fail 이 그것을 가렸을 뿐.
사용자가 GitHub UI 에서 머지하는 시점과 Claude 가 인지하는 시점의 갭. 매번 새로운 회색 지대로 재발: PR 생성 → 추가 push → 메타데이터 변경. 규칙을 회색 지대 한정 열거가 아닌 "gh pr 으로 시작하는 거의 모든 명령" 으로 일반화.
AiResponse 1:1 엔티티 + @Async + 폴링 endpoint.ddl-auto: update 한계 영구 해소 + validate 전환.claude-docs/* 통합.