Skip to content

feat(api-server): Phase 2 백엔드 API 추가 (B1+B2)#161

Merged
cocoyoon merged 8 commits into
mainfrom
feat/backend-api-additions-phase2
Apr 10, 2026
Merged

feat(api-server): Phase 2 백엔드 API 추가 (B1+B2)#161
cocoyoon merged 8 commits into
mainfrom
feat/backend-api-additions-phase2

Conversation

@cocoyoon
Copy link
Copy Markdown
Member

Summary

  • B1: UserResponse에 ink_credits, style_dna 필드 추가 (엔티티 + DTO)
  • B2: GET /users/me/social-accounts 엔드포인트 신규
    • user_social_accounts SeaORM 엔티티
    • SocialAccountResponse DTO
    • 서비스 함수 + 핸들러 + OpenAPI 등록

남은 Phase 2 항목 (별도 PR)

  • B3: /users/me/stats stub → 실제 구현
  • B5: GET /rankings/artists 트렌딩 아티스트
  • B6-B7: spots/solutions user_id 필터 (profile 서버사이드로 대체 가능)

Test plan

  • cargo check 통과
  • 배포 후 GET /users/me 응답에 ink_credits/style_dna 포함 확인
  • GET /users/me/social-accounts 정상 응답 확인

Part of #160

🤖 Generated with Claude Code

cocoyoon and others added 3 commits April 10, 2026 01:03
- authStore.ts: .from("users") select/update → getMyProfile()/updateMyProfile()
- useImages.ts: Supabase 직접 쿼리 + fallback 제거 → listPosts() REST API
- usePosts.ts: fetchPostWithSpotsAndSolutions → getPost() REST API
- useSolutions.ts: fetchSolutionsFromSupabase fallback → listSolutions() REST API

Part of #158

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- lib/supabase/storage.ts — 정의만 있고 어디서도 import 안 됨
- lib/supabase/queries/debug/posts.ts — 개발용, production 미사용

Part of #158

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ounts 엔드포인트

B1: users 엔티티와 UserResponse에 ink_credits, style_dna 필드 추가
B2: GET /users/me/social-accounts 엔드포인트 신규 추가
  - user_social_accounts 엔티티 추가
  - SocialAccountResponse DTO
  - 서비스 + 핸들러 + OpenAPI 등록

Part of #160

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 Error Error Apr 10, 2026 1:41am

B3: GET /users/me/stats — stub(0) → 실제 posts/comments/likes count SQL 쿼리
B5: GET /rankings/artists — 트렌딩 아티스트 서버 사이드 SQL 집계
  - period: weekly/monthly/all_time
  - limit: 최대 50
  - artist_name별 post_count + 대표 이미지

Part of #160

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- GET /users/me/spots — 유저의 Spot 목록 (post image_url 포함, 페이지네이션)
- GET /users/me/solutions — 유저의 Solution 목록 (active만, 페이지네이션)
- UserSpotItem, UserSolutionItem DTO 추가
- OpenAPI 등록

Part of #160

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 메인 피드 로딩 확인
- Explore 무한스크롤 확인
- 포스트 상세 페이지 확인
- 프로필 페이지 확인
- 백엔드 API health 확인

Part of #158

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cocoyoon and others added 2 commits April 10, 2026 10:33
…queries' into feat/backend-api-additions-phase2
- playwright.config.ts: dotenv 로딩 + api-migration을 chromium-no-auth에서 실행
- api-migration.spec.ts: 비인증 환경에 맞게 테스트 재작성
- 4/4 테스트 통과 확인

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cocoyoon cocoyoon merged commit 8b33c32 into main Apr 10, 2026
2 of 3 checks passed
@cocoyoon cocoyoon deleted the feat/backend-api-additions-phase2 branch April 10, 2026 01:40
@github-project-automation github-project-automation Bot moved this from Todo to Done in decoded-monorepo Apr 10, 2026
cocoyoon added a commit that referenced this pull request Apr 10, 2026
* docs(git): dev→main 브랜치 워크플로우 정립 (#127) (#128)

* 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>

* refactor: 백엔드 배포 환경 파일을 단일 .env.backend.{env}로 통합 (#120)

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: env compose hotfix (Meilisearch 경로 + dev ENV) (#154)

* 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>

* feat(ci): 백엔드 CD 파이프라인 — self-hosted runner 자동 배포 (#155)

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>

* fix(ci): CD workflow에서 .env.backend.prod 복사 스텝 추가 (#156)

runner 작업 디렉토리에 env 파일이 없어 배포 실패.
Mac Mini의 고정 경로에서 checkout 디렉토리로 복사.

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

* fix(ci): ai health check를 docker exec로 변경 (#157)

ai 컨테이너는 포트 10000을 호스트에 publish하지 않아
호스트에서 curl이 실패함. docker exec로 컨테이너 내부에서 체크.

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

* feat(api-server): Phase 2 백엔드 API 추가 (B1+B2) (#161)

* refactor(web): Phase 1 — 클라이언트 Supabase 직접 호출을 백엔드 API로 전환

- authStore.ts: .from("users") select/update → getMyProfile()/updateMyProfile()
- useImages.ts: Supabase 직접 쿼리 + fallback 제거 → listPosts() REST API
- usePosts.ts: fetchPostWithSpotsAndSolutions → getPost() REST API
- useSolutions.ts: fetchSolutionsFromSupabase fallback → listSolutions() REST API

Part of #158

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

* chore(web): 미사용 Supabase 파일 삭제

- lib/supabase/storage.ts — 정의만 있고 어디서도 import 안 됨
- lib/supabase/queries/debug/posts.ts — 개발용, production 미사용

Part of #158

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

* feat(api-server): UserResponse에 ink_credits/style_dna 추가 + social accounts 엔드포인트

B1: users 엔티티와 UserResponse에 ink_credits, style_dna 필드 추가
B2: GET /users/me/social-accounts 엔드포인트 신규 추가
  - user_social_accounts 엔티티 추가
  - SocialAccountResponse DTO
  - 서비스 + 핸들러 + OpenAPI 등록

Part of #160

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

* feat(api-server): B3 user stats 실제 구현 + B5 트렌딩 아티스트 엔드포인트

B3: GET /users/me/stats — stub(0) → 실제 posts/comments/likes count SQL 쿼리
B5: GET /rankings/artists — 트렌딩 아티스트 서버 사이드 SQL 집계
  - period: weekly/monthly/all_time
  - limit: 최대 50
  - artist_name별 post_count + 대표 이미지

Part of #160

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

* feat(api-server): B6 유저 Spots + B7 유저 Solutions 엔드포인트 추가

- GET /users/me/spots — 유저의 Spot 목록 (post image_url 포함, 페이지네이션)
- GET /users/me/solutions — 유저의 Solution 목록 (active만, 페이지네이션)
- UserSpotItem, UserSolutionItem DTO 추가
- OpenAPI 등록

Part of #160

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

* test(web): Supabase→API 마이그레이션 E2E 테스트 추가

- 메인 피드 로딩 확인
- Explore 무한스크롤 확인
- 포스트 상세 페이지 확인
- 프로필 페이지 확인
- 백엔드 API health 확인

Part of #158

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

* test(web): E2E 테스트 수정 — 비인증 환경 대응 + dotenv 로딩

- playwright.config.ts: dotenv 로딩 + api-migration을 chromium-no-auth에서 실행
- api-migration.spec.ts: 비인증 환경에 맞게 테스트 재작성
- 4/4 테스트 통과 확인

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

---------

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

* refactor(web): 클라이언트 Supabase 직접 호출 제거 (Phase 1+3) (#159)

* refactor(web): Phase 1 — 클라이언트 Supabase 직접 호출을 백엔드 API로 전환

- authStore.ts: .from("users") select/update → getMyProfile()/updateMyProfile()
- useImages.ts: Supabase 직접 쿼리 + fallback 제거 → listPosts() REST API
- usePosts.ts: fetchPostWithSpotsAndSolutions → getPost() REST API
- useSolutions.ts: fetchSolutionsFromSupabase fallback → listSolutions() REST API

Part of #158

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

* chore(web): 미사용 Supabase 파일 삭제

- lib/supabase/storage.ts — 정의만 있고 어디서도 import 안 됨
- lib/supabase/queries/debug/posts.ts — 개발용, production 미사용

Part of #158

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

---------

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

* docs: CLAUDE.md에 just hook 초기 설정 안내 추가

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

* style: cargo fmt 적용

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

* test(web): E2E 테스트 커버리지 확대 + pre-push 게이트 (#168)

핵심 사용자 플로우 E2E 테스트 12개 추가 (소비·생성·참여).
API mock 헬퍼, Playwright config 정리, pre-push E2E 게이트, 테스트 문서 작성.

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

* fix(web): ESLint + Prettier 에러 일괄 수정

기존 코드의 prettier formatting, no-explicit-any, no-empty,
no-html-link-for-pages 에러 수정. pre-push hook 통과를 위해 필요.

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

* fix(web): TypeScript 에러 수정 (debug/posts stub + image dimensions 타입)

- debug/posts.ts 클라이언트 쿼리 파일 생성 (기존 import 에러)
- image_width/image_height 타입 assertion 추가 (generated 타입 미반영)

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

---------

Co-authored-by: Kiyori <113906780+thxforall@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cocoyoon added a commit that referenced this pull request Apr 10, 2026
Resolve dev↔main 충돌 (모두 prettier/rustfmt 포맷 차이 또는 dev 신규 기능):
- packages/api-server/src/domains/{rankings,users}/{handlers,service}.rs: 포맷 정렬, 일부 dev 신규 기능
- packages/web/lib/hooks/usePosts.ts, lib/stores/authStore.ts: prettier 포맷
- packages/web/lib/supabase/queries/debug/posts.ts: main에서 삭제 (#161), dev 변경 폐기
- packages/web/playwright.config.ts, tests/api-migration.spec.ts: 포맷

dev 자체 버그 수정 (merge 과정에서 발견):
- src/domains/users/service.rs::get_user_stats — 중복 카운트 로직 제거 (helper fn 호출 후 inline raw SQL이 중복 계산)
- src/openapi.rs — follow_user_handler/unfollow_user_handler/get_follow_status가 #[utoipa::path]인데 paths()에 누락
- src/tests/fixtures.rs::user_model — `ink_credits`/`style_dna` 필드 누락
- src/domains/users/dto.rs (4곳), src/domains/posts/dto_tests.inc::sample_user, src/domains/posts/tests.rs::image_upload_response_serialization — 동일 신규 필드 누락 보강

테스트 보강 (커버리지 65% 게이트 유지):
- follow_user / unfollow_user / check_is_following 단위 + handler 테스트
- get_user_stats / get_user_profile / get_my_profile / get_my_stats 핸들러 not_found 경로
- list_user_spots / list_user_solutions empty 경로

검증:
- cargo test --lib: 999 passed, 0 failed
- cargo clippy -D warnings: clean
- cargo tarpaulin --fail-under 65: 65.45%
- check-migration-sync.sh: DB/코드 일치 (50개)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cocoyoon added a commit that referenced this pull request Apr 10, 2026
PR #161 에서 클라이언트 Supabase 직접 호출 제거 시 `lib/supabase/queries/debug/posts.ts` 가 삭제됐는데, 이를 import 하던 client hook 과 컴포넌트가 정리되지 않아 main 빌드가 실패했습니다.

```
Module not found: Can't resolve '@/lib/supabase/queries/debug/posts'
  at packages/web/lib/hooks/debug/usePosts.ts:11:1
```

debug-only 페이지의 client-side 부분을 제거하고 server component (`fetchLatestPostsServer`) 만 남깁니다:

- delete `packages/web/lib/hooks/debug/usePosts.ts`
- delete `packages/web/app/debug/supabase/posts/PostsClient.tsx`
- `app/debug/supabase/posts/page.tsx` — `<PostsClient />` 참조 제거

검증:
- `bun run generate:api && bun run build` — 빌드 성공 (전 라우트 컴파일)

Co-Authored-By: Claude Opus 4.6 (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.

1 participant