Commit Graph

33 Commits

Author SHA1 Message Date
ttipo 700a100a38 docs: 규칙 문서를 실제 구현에 맞춰 갱신
CI / Frontend (lint · type-check · test) (push) Has been cancelled
CI / Flutter (analyze · test) (push) Has been cancelled
CI / Backend (lint · test · e2e · build) (push) Has been cancelled
CI / 에러 코드 SSOT 동기화 검사 (push) Has been cancelled
규칙과 구현이 어긋나 있던 부분을 바로잡고, 작업하며 발견한 함정을 기록한다.

- 스킬 문서의 "기본 제공 골격" 표를 실제 파일 목록과 일치시킴
- 커밋 전 체크리스트에 테스트 실행·에러 코드 동기화 절차 추가
- 커밋 규칙에 scope·브랜치 전략·PR 규칙 보강
- 새 규칙 파일(api-design, logging)을 CLAUDE.md import 목록에 등록하고,
  규칙 추가 시 등록이 필수라는 메타 규칙 명시
- README 를 현재 구조에 맞게 갱신 (traceId·페이지네이션·에러 코드 SSOT·로컬 개발 명령)

작업 중 실제로 겪은 함정들을 규칙으로 남긴다:
- Windows 에서 npm install 하면 Linux 전용 optional 의존성이 lock 에서 잘려
  Docker 의 npm ci 가 실패한다 → 의존성 변경은 컨테이너 안에서 수행
- --build 만으로는 node_modules 익명 볼륨이 갱신되지 않아
  새 패키지가 컨테이너에 반영되지 않는다 → --renew-anon-volumes 필요
- compose 는 미정의 변수를 빈 문자열로 주입해 Number('')===0 함정이 생긴다
- dev 는 PID 1 이 npm 이라 graceful shutdown 확인은 운영 이미지로 해야 한다
- Redis 는 컨테이너만 떠 있고 사용처가 없다 — 확장 지점임을 명시

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 14:32:23 +09:00
ttipo 258e0e37cc fix(flutter): 디렉터리 구조를 규칙에 맞추고 깨진 테스트 교체
- 공통 위젯 위치를 lib/widgets/ 에서 규칙상 목표인 lib/shared/widgets/ 로 이동
- 기본 생성된 카운터 위젯 테스트가 실제 앱과 맞지 않아 실패 상태였다 —
  앱 렌더링을 검증하는 테스트로 교체

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 14:31:46 +09:00
ttipo dac1603b03 ci: 규칙을 자동으로 강제하는 검사 추가
지금까지 "커밋 전 lint/test 통과"는 문서상의 약속일 뿐 강제되지 않았다.

- CI(GitHub Actions) 추가 — 세 스택의 lint·test·build 와 backend e2e 를 PR 마다 실행.
  error-codes-sync 잡은 sync 를 재실행한 뒤 git diff 로 생성 파일 드리프트를 검사한다.
  레지스트리만 고치고 sync 를 빠뜨리면 클라이언트 사전이 조용히 어긋나기 때문.
- lint 스크립트에 --max-warnings 0 적용. 기존에는 경고가 있어도 통과해
  "Warning 0" 규칙이 사실상 무의미했다. 자동 수정은 lint:fix 로 분리.
- 문서로만 있던 규칙을 린트로 이관:
  any/dynamic 금지, console/print 금지, Vue 인라인 스타일·Options API 금지,
  Dart const 누락·await 누락, HttpException 직접 생성 차단(BusinessException 유도).
- backend 에 @/ 경로 alias 설정 (tsconfig paths + jest moduleNameMapper).
  공통 규칙이 요구하는 절대경로 alias 가 backend 에만 빠져 있었다.
- npm audit 취약점 10건 중 9건 해결.
  남은 multer(high)는 platform-express v12 가 필요해 Nest v11 생태계와 충돌하고,
  파일 업로드 엔드포인트가 없어 도달 경로가 없다 — security.md 에 재검토 조건 기록.
- PR 템플릿 추가.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 14:31:34 +09:00
ttipo e7c00e6f65 fix: 보안 규칙을 어기던 컨테이너·네트워크 설정 수정
security.md 가 금지한다고 적어둔 것을 실제 설정이 어기고 있었다.

- 프론트엔드 운영 컨테이너가 root 로 nginx 를 실행하고 있었다.
  nginx-unprivileged 로 전환하고 포트를 8080 으로 맞춤(비-root 는 1024 미만 바인드 불가).
- dev 오버라이드가 사용하는 빌드 스테이지에도 USER node 적용.
  익명 볼륨이 node 소유로 생성되도록 chown 을 USER 전환 앞에 둔다
  (그렇지 않으면 vite 가 node_modules/.vite 캐시를 쓰지 못한다).
- dev 의 DB/Redis 포트가 0.0.0.0 에 바인딩되어 같은 LAN 에 노출돼 있었다 → 127.0.0.1 로 한정.
- CSP 헤더 추가. 대신 현대 브라우저에서 권장되지 않는 X-XSS-Protection 은 제거.
- CORS 차단 시 Error 를 던져 500(SYS_001)이 되던 것을 헤더 미부여 방식으로 변경.
- 헬스체크가 localhost 를 ::1 로 해석해 항상 실패하던 문제 수정(127.0.0.1 명시).
- graceful shutdown 을 위해 init(tini)과 stop_grace_period 적용.
- *.example 의 실제같은 비밀번호를 placeholder 로 교체하고,
  비어 있던 서비스 env 예시에 안내를 채움.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 14:31:04 +09:00
ttipo bf102d758f feat: 기동·종료·헬스체크 견고성 보강
운영에서 조용히 문제를 일으킬 수 있는 지점들을 정리한다.

- env 검증(fail-fast): 설정이 잘못되면 서버가 뜨지 않는다.
  운영에서 DB_* 누락과 'change-me' 같은 예시 값 배포를 차단하고,
  문제를 하나씩이 아니라 한 번에 모아 보여준다.
  DB_PASSWORD 가 없을 때 'password' 로 조용히 동작하던 폴백도 제거.
- graceful shutdown: SIGTERM 시 요청·커넥션을 정리한 뒤 종료한다.
  종료 로그는 OnApplicationShutdown 훅으로 남긴다 —
  process.on(signal) 로 직접 잡으면 Nest 의 종료 흐름에 간섭해 종료 코드가 달라진다.
- 헬스체크 두 가지 결함 수정:
  pingCheck 기본 타임아웃 1초가 짧아 유휴 커넥션 재연결 시 정상 DB 를 down 으로 오판했고,
  실패 응답이 SYS_001 로 덮여 어느 구성요소가 죽었는지 알 수 없었다.
  모니터링이 읽는 엔드포인트이므로 표준 래퍼·에러 코드에서 제외한다.
- Rate limiting 을 @nestjs/throttler 로 일원화 (express-rate-limit 제거).
  두 리미터가 겹쳐 헤더의 한도와 실제 동작이 어긋나 있었다.
- e2e 를 응답 계약 검증으로 교체. 기존 테스트는 없는 경로를 검사해 이미 실패 상태였다.
- 로깅 규칙(logging.md) 신설 — 레벨 기준·민감정보 마스킹·traceId

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 14:30:29 +09:00
ttipo c5d165275c feat: 응답 계약 정의와 페이지네이션·추적 ID 추가
세 클라이언트가 공유하는 계약 중 정의가 빠져 있던 부분을 채운다.

- 목록 응답 형태를 {items, pageInfo} 로 고정하고 커서/오프셋 쿼리 DTO 제공
- @SkipTransform() 으로 스트림·204 등 래핑하면 안 되는 응답을 제외
- ApiStandardResponse/ApiErrorResponse 로 Swagger 문서를 실응답과 일치시킴
  (컨트롤러는 raw 를 반환하지만 실제 응답은 래핑되어 문서가 어긋나 있었다)
- RequestIdMiddleware 로 모든 요청에 x-request-id 부여
- API 설계 규약(api-design.md) 신설 — REST 경로·쿼리·날짜/ID 표현·버전 관리

또한 .gitignore 의 data/ 패턴이 모든 depth 에 매칭되어
flutter/lib/features/user/data/ 의 소스가 커밋되지 않던 문제를 함께 고친다.
(user_provider.dart 가 import 하는 파일이 저장소에 없어 flutter analyze 가 깨져 있었다)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 14:30:07 +09:00
ttipo f7ea60b8e7 feat: 에러 코드 SSOT 체계 도입
사용자에게 노출되는 실패가 에러 코드 없이 만들어질 수 없도록 구조를 바꾼다.

기존에는 예외 필터가 HTTP 상태로 코드를 추론해 도메인별 에러를 표현할 수 없었고,
세 플랫폼의 에러 사전을 손으로 맞춰야 해서 어긋나기 쉬웠다.

- 코드↔메시지↔HTTP 상태를 error-codes.ts 레지스트리 한 곳으로 통합
- BusinessException 은 에러 코드를 생성자 필수 인자로 받아 코드 누락을 타입으로 차단
- sync:error-codes 스크립트가 프론트·플러터 사전을 자동 생성 (수동 복사 제거)
- 429 전용 코드 REQ_001 추가 (기존에는 "시스템 오류"로 잘못 안내)
- AUTH_002(세션 만료)를 클라이언트에서 실제로 발행하도록 구현
- 응답에 traceId 를 실어 로그와 대조 가능하게 함

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 14:29:15 +09:00
ttipo 3b397b7788 fix: 기존 코드의 타입·린트 정합성 보강 (lint·type-check 통과)
- backend: HttpExceptionFilter status 를 HttpStatus 로 타입 지정(enum 비교),
  TransformInterceptor 를 Observable<T> 로, main.ts expressApp 캐스팅·bootstrap void 처리
- frontend: useApi 의 ErrorCodeLexicon 폴백 타입 보강(noUncheckedIndexedAccess)
- eslint --fix 포맷 정리(user 컨트롤러/서비스, 페이지)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 13:58:02 +09:00
ttipo b35ddfc9c3 feat: 공통 컴포넌트·인증·Riverpod 기초 골격 추가
- frontend: BaseButton 공통 컴포넌트, auth.store(세션 인증)·useAuth(로그인 흐름),
  라우터 가드를 auth.store 와 연동
- flutter: dio_provider(인터셉터 적용 Dio DI), features/user 수직 슬라이스
  (model·repository·provider) 예제

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 13:58:01 +09:00
ttipo 6306160dda refactor: .claude 규칙 체계를 skills·rules 구조로 재편
- 슬래시 커맨드(nestjs/vue3/flutter)를 정식 스킬(.claude/skills)로 전환하고
  docker 스킬을 신설(루트 command.md 이관)
- 공통 규칙을 .claude/rules 로 모듈화(coding-common·response-format·error-codes·
  git-convention·security·env-structure·testing·checklist)하고 CLAUDE.md 에서 @import
- 파일·식별자 네이밍 규약, 테스트 규칙 추가
- .claude/settings.json(권한·환경) 추가
- CLAUDE.md·README.md 참조 갱신, 단독 실행(non-Docker) 안내 정리

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 13:58:01 +09:00
ttipo 49fef58c5f chore: 줄바꿈·에디터 설정 추가 (.gitattributes, .editorconfig)
저장소 줄바꿈을 LF로 정규화하고 에디터 공통 포맷(UTF-8, 2-space)을 정의해
OS·에디터에 따른 불필요한 diff를 방지한다.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 13:58:01 +09:00
ttipo c5896fbdb1 command.md 업데이트 2026-06-22 12:34:10 +09:00
ttipo 5cf52d3beb .env.production.example 업데이트 2026-06-22 12:33:32 +09:00
ttipo 6e0c745f5c docker-compose.dev.yml 업데이트 2026-06-17 18:14:27 +09:00
ttipo 5ffceb3923 fix: swc watch 모드용 chokidar 의존성 추가
@swc/cli가 chokidar를 optional peerDependency로 선언해 자동 설치되지
않아, watch 모드(start:dev)에서 'Cannot find module chokidar'로 실패하던
문제 수정. chokidar를 명시적 devDependency로 추가하고 lockfile 재생성.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 14:30:29 +09:00
ttipo 5d0eb9bd59 fix: backend package-lock.json을 올바른 lockfile로 재생성
package.json을 복사한 가짜 lockfile이라 npm ci가 실패하던 문제 수정.
clean install로 lockfileVersion 3 의존성 트리를 생성해 동기화.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:58:11 +09:00
ttipo 1be0ed0f28 backend/package-lock.json 업데이트 2026-06-16 13:35:32 +09:00
ttipo bc2ff5ea51 backend/package-lock.json 업데이트 2026-06-16 13:35:22 +09:00
ttipo 758a26d8f8 frontend/package-lock.json 추가 2026-06-16 11:48:53 +09:00
ttipo ff7be15948 backend/package-lock.json 업데이트 2026-06-16 11:48:24 +09:00
ttipo d9eba74e95 backend/package-lock.josn 추가 2026-06-16 11:48:17 +09:00
ttipo 6e88c7a21a backend/package-lock.json 삭제 2026-06-16 11:41:21 +09:00
ttipo 745a1d139a frontend/package-lock.json 삭제 2026-06-16 11:41:13 +09:00
ttipo 215477d797 frontend/.env.production.example 업데이트 2026-06-16 11:08:11 +09:00
ttipo fe9d489642 frontend/.env.development.example 업데이트 2026-06-16 11:01:00 +09:00
ttipo 87b104b570 backend/.env.production.example 업데이트 2026-06-16 11:00:47 +09:00
ttipo 37b7d870a9 backend/.env.development.example 업데이트 2026-06-16 11:00:37 +09:00
ttipo 749b5cc342 .env.production.example 업데이트 2026-06-16 11:00:22 +09:00
ttipo c873d17cba .env.development.example 업데이트 2026-06-16 11:00:09 +09:00
ttipo f5a18a52f4 docs: 템플릿 규칙 정비 및 환경변수 예제·README 추가
- CLAUDE.md: 모노레포 개요·표준 응답 포맷·에러 코드 맵(구현 일치)·환경변수 위임 구조(SSOT) 정리
- nestjs/vue3/flutter 규칙을 실제 구현(클래스명, env키, 디렉터리)과 정합화
- 루트 .env 단일 진실 공급원 구조에 맞춰 docker-compose 변수명 정정(BACKEND_API_URL, DB/REDIS_DATA_DIR)
- backend/frontend/flutter 예제 env 추가(루트 위임 반영, 서비스 고유 값만 작성)
- README.md 신규 작성, command.md 범용화, .gitignore에 *.example 재포함 규칙 추가

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 11:14:42 +09:00
ttipo 543d7b85fa .gitignore 업데이트 2026-06-09 16:06:40 +09:00
ttipo c2e970f453 Docker compose 구조 수정 2026-05-28 13:55:30 +09:00
ttipo 4d70b1428a first commit 2026-05-18 11:25:51 +09:00