Skip to content

test(api): 백엔드 테스트 커버리지 10% → 65.64% 확대#179

Merged
cocoyoon merged 9 commits into
devfrom
test/backend-coverage-65-percent
Apr 10, 2026
Merged

test(api): 백엔드 테스트 커버리지 10% → 65.64% 확대#179
cocoyoon merged 9 commits into
devfrom
test/backend-coverage-65-percent

Conversation

@cocoyoon
Copy link
Copy Markdown
Member

Summary

  • packages/api-server 테스트 커버리지를 10% → 65.64% 까지 확대 (+607 tests, 총 985개 lib 테스트)
  • scripts/pre-push.sh tarpaulin 임계값을 10% → 65% 로 상향
  • SeaORM mock feature 도입 + AppState.dbArc<DatabaseConnection> 으로 전환하여 단위 테스트에서 DB 의존 로직까지 커버

기존 백엔드 lib 테스트는 주로 DTO 직렬화 스모크 테스트 수준이라 서비스/핸들러 로직의 회귀를 단위 테스트로 잡지 못했습니다. cargo test --lib가 실제 비즈니스 로직을 거의 실행하지 않는 상태였어서, DB 의존 함수까지 mock으로 검증 가능하도록 인프라부터 다시 세팅했습니다.

핵심 변경

테스트 인프라

  • Cargo.toml: SeaORM mock feature 활성화 (dev-dependencies)
  • AppState.db: DatabaseConnectionArc<DatabaseConnection>
    • SeaORM mock feature는 DatabaseConnectionClone derive를 제거하므로, Arc 래핑으로 cheap clone 지원
    • 호출부 174곳의 &state.dbstate.db.as_ref() 일괄 변환
    • BackendGrpcService, SynonymManager, upsert_solution_embedding 시그니처도 Arc<DatabaseConnection> 기반으로 정리
  • src/tests/fixtures.rs 신규: 엔티티 팩토리 (post/user/spot/solution/comment/badge/curation/... 등) + count_row(n) 헬퍼 (SeaORM PaginatorTrait::count mocking)
  • src/tests/helpers.rs 확장: test_config, test_app_state, empty_mock_db, mock_db_with_query_results, mock_user, mock_admin_user

테스트 추가 (+607, 총 985개)

  • 도메인 서비스/핸들러: posts, users, solutions, rankings, feed, votes, spots, comments, badges, categories, subcategories, earnings, post_magazines, post_likes, saved_posts, reports, search
  • Admin: dashboard, curations, badges, synonyms, magazine_sessions, editorial_candidates
  • Batch: badge_check, trending_calc, rank_update, retry_failed_items, click_aggregation, search_reindex, scheduler
  • Services: storage/config, affiliate/config, search/synonym_manager, embedding/sync, decoded_ai_grpc/client, backend_grpc/server (0% → 커버)
  • Middleware: auth (User 구조체)
  • Core: error.rs, config.rs (AppConfig::from_env 전 경로), handlers.rs (/health 0% → 커버), utils/jwt.rs

빌드/CI

  • scripts/pre-push.sh: TARPAULIN_FAIL_UNDER 기본값 1065
  • src/tests/architecture.rs::migration_no_duplicate_sequence: 기존 dev 에 merge된 m20260402_000001_add prefix 중복을 KNOWN_DUPLICATES 로 허용 (seaql_migrations 레코드와 호환 유지)
  • scripts/check-migration-sync.sh: 6자리 순번이 없는 레거시 파일명(m20260409_add_image_dimensions)도 수용하도록 regex 완화

로컬 CI 검증 결과 (scripts/pre-push.sh 전 단계 통과)

단계 상태
1. cargo fmt --check
2. cargo clippy -D warnings (migration, entity, decoded-api)
3. cargo test --lib 985 passed, 0 failed
4. cargo deny check
5. cargo tarpaulin --fail-under 65 65.64% (4,978 / 7,584 lines)
6. check-migration-sync.sh ✅ "DB와 코드 마이그레이션 목록 일치 (50개)"

커버리지 진행 스냅샷

Milestone 커버리지 테스트 수
Before 10.00% 378
20% 목표 20.75% 558
30% 목표 37.43% 685
40% 목표 46.46% 767
50% 목표 56.08% 863
60% 목표 64.97% 963
최종 (65% 게이트) 65.64% 985

Test plan

  • cargo fmt --check
  • cargo clippy -p migration -p entity -p decoded-api --all-targets -- -D warnings
  • cargo test --lib — 985 passed
  • cargo tarpaulin --lib --exclude-files 'src/entities/*' --fail-under 65 — 65.64%
  • DATABASE_URL=... bash packages/api-server/scripts/check-migration-sync.sh — DB/코드 일치
  • SKIP_FE_CI=1 DATABASE_URL=... bash scripts/git-pre-push.sh — 전체 로컬 CI 통과
  • CI (GitHub Actions) 에서 동일 단계 재확인

Notes

  • AppState.db 타입 변경은 기존 핸들러/서비스 호출부 174곳을 state.db.as_ref() 로 바꾸는 mechanical 패치입니다. SeaORM 쿼리 동작에는 변화 없습니다.
  • migration_no_duplicate_sequenceKNOWN_DUPLICATES 는 이미 dev 에 배포된 레거시 충돌을 수용하기 위한 임시 조치입니다. 이후 신규 중복은 계속 차단됩니다.
  • 기존 tests/integration_*.rs&state.db 사용부도 동일 패턴으로 업데이트했습니다 (일부 파일은 여전히 #[ignore] 상태이므로 실 DB 필요).

🤖 Generated with Claude Code

thxforall and others added 9 commits April 9, 2026 16:05
* fix(web): solution 이미지 미표시 수정 (#97) (#98)

* fix(web): use Supabase direct query for solutions instead of Rust proxy

- Replace listSolutions (Orval REST → Rust backend) with direct Supabase
  query in useAllSolutionsForSpots hook
- Make API_BASE_URL optional in server-env.ts to prevent module crash
  when Rust backend is not configured

Fixes #97

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(web): enrich hero posts with spots/solutions data

Hero posts were created with items: [] since the Supabase fallback was
added. Now fetches spots+solutions for hero posts server-side so item
overlay markers appear when a hero card is focused.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(web): Korean search fallback + published filter in search (#102)

- Trigger Supabase fallback when backend returns empty results for
  non-empty query (enables synonym expansion for Korean→English)
- Add post_magazines inner join + created_with_solutions filter to
  search fallback to match browse mode behavior

Fixes #99

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(git): dev→main 브랜치 워크플로우 정립 (#127)

- GIT-WORKFLOW.md에 브랜치 전략 섹션 추가 (feature→dev→main)
- 긴급 hotfix 예외 플로우 문서화
- CLAUDE.md git workflow 요약 업데이트

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
release: Phase 2 — Auth 안정화, Image Dimensions, 한글 검색 개선
release: Phase 2 batch 2 — Try posts, code review fixes, CI notifications
api-server/.env.{env} + ai-server/.{env}.env 2개 파일을
루트 .env.backend.{env} 1개로 통합하여 관리 포인트를 줄임.

- .env.backend.example 추가 (통합 템플릿)
- docker-compose 3개 (dev/staging/prod) env_file 경로 통합
- deploy-backend.sh env 파일 체크 단순화
- 충돌 키 LOG_FORMAT은 compose environment에서 서비스별 오버라이드

Closes #118

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Meilisearch 에러 메시지 경로 수정 + dev compose ENV 오버라이드 추가

- docker-compose.prod.yml: MEILISEARCH_MASTER_KEY 에러 메시지에서
  옛 경로(packages/api-server/.env.prod) → .env.backend.prod로 수정
- docker-compose.yml: dev api 서비스에 ENV=development 명시하여
  .env.backend.example 복사 시 production 모드로 뜨는 문제 방지

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: staging Meilisearch MEILI_ENV를 production으로 변경

staging에서 MEILI_ENV=development로 되어있던 것을 production으로 수정.
Meilisearch는 development/production 두 모드만 지원.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
main 머지 시 Mac Mini self-hosted runner에서 자동 배포:
- path filter: api-server, ai-server, deploy script 변경 시 트리거
- workflow_dispatch로 수동 배포 지원
- 롤백: 빌드 전 :prev 태깅, 실패 시 자동 복원
- health check: api(:8080) + ai(:10000) 최대 5분 대기
- Telegram 알림 (성공/실패)

Closes #119

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
runner 작업 디렉토리에 env 파일이 없어 배포 실패.
Mac Mini의 고정 경로에서 checkout 디렉토리로 복사.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ai 컨테이너는 포트 10000을 호스트에 publish하지 않아
호스트에서 curl이 실패함. docker exec로 컨테이너 내부에서 체크.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 985개 lib 테스트 (기존 378 → +607개)
- tarpaulin 기준 65% 설정 (scripts/pre-push.sh)
- SeaORM `mock` feature 활성화 + `AppState.db`를 `Arc<DatabaseConnection>`으로 전환
- 모든 `&state.db` → `state.db.as_ref()` 일괄 적용 (mock feature 호환)
- 테스트 인프라 확장: `src/tests/fixtures.rs` (엔티티 팩토리), 확장된 `helpers.rs`
- 도메인/서비스/핸들러/배치/미들웨어 전반에 MockDatabase 기반 단위 테스트 추가
- architecture::migration_no_duplicate_sequence: 기존 merge된 중복 prefix 허용 (KNOWN_DUPLICATES)
- check-migration-sync.sh: 6자리 순번 없는 레거시 파일명도 수용하도록 regex 완화

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
decoded-app Ready Ready Preview, Comment Apr 10, 2026 5:48am

@cocoyoon cocoyoon self-assigned this Apr 10, 2026
@cocoyoon cocoyoon moved this from Todo to Done in decoded-monorepo Apr 10, 2026
@cocoyoon cocoyoon merged commit 0b4c05d into dev Apr 10, 2026
5 checks passed
thxforall added a commit that referenced this pull request Apr 30, 2026
- Epic #170의 P1~P3 재배열 대신 P0 인프라 스프린트 신설
- 발견: CI에 E2E job 없음 / "80%"는 테스트 개수 기준 vanity metric / auth regression umbrella 부재
- 1주 스프린트(04-24~04-30): GitHub Actions e2e.yml + CI secret 주입 + baseline 측정 + 커버리지 재정의 + auth safety net 이슈 #179 생성
- mutation-covered critical flows / total critical flows 공식으로 재정의, baseline ~12% (2/17)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
thxforall added a commit that referenced this pull request Apr 30, 2026
- 12개 태스크로 분해 (feature branch → workflow → secrets → PR → baseline → docs → umbrella 이슈 → retro → merge)
- 각 태스크는 2-5분 단위 step, 실제 명령어와 완성된 파일 내용 포함
- Task 4 (secret 주입)는 유저 수행 구간으로 명시 — agent는 명령어 준비만
- Task 10 새 이슈 번호 #179 가정, 실제 ID 다르면 spec 문서 업데이트 스텝 포함

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants