Commit ed7e758
committed
chore(week2): photo/admin form retrofit + CI + Deploy + retro (#31)
* fix(forms): SKILL 4.5 retrofit — photo & admin members inline alert + dedupe
PR #30 에 박은 폼 표준 체크리스트(SKILL.md §4.5)를 이미 있는 폼에 소급 적용.
Photo upload (app/sessions/[id]/photo-actions.ts + PhotoSection.tsx):
- uploadSessionPhoto / removeSessionPhoto 시그니처를 useActionState 패턴
((prev, formData) => Promise<{ ok, error? }>) 으로 변경.
- 검증 실패 (15MB 초과 / MIME 거부 / 빈 파일 / 세션 id 불량) 시 throw 대신
명시적 PhotoResult.error 반환.
- PhotoSection 을 server → client component 로 (useActionState).
- 업로드/교체/삭제 모두 SubmitButton (useFormStatus) — pending 중 disabled
+ 라벨 교체.
- 사진 우측 [교체] 버튼은 부모의 useActionState formAction 을 props 로 받음
→ alert/pending 상태가 한 곳에서 관리됨.
Admin members (app/admin/members/actions.ts + page.tsx + _components):
- approveUser / rejectUser 시그니처 동일 패턴.
- 'cannot approve/reject self' 를 throw 대신 inline alert 메시지로.
- 페이지 (server component) 가 PendingMemberActions (client) 를 행마다 렌더.
- 두 버튼 ([승인]/[거절]) 이 같은 row 의 alert 영역 공유.
검증된 회귀 항목:
- 사진 업로드 [올리기] 빠른 더블 클릭 → 첫 클릭 후 button disabled.
- 본인 [승인] 시도 → '본인은 본인을 승인할 수 없습니다.' alert, 페이지 그대로.
- 빌드 9 → 10 routes, /sessions/[id] +1.2kB (client form 추가분).
Spec: .gjc/specs/week2-wrapup.md §1
* chore(ci): typecheck + lint + build on PR/push (#5)
.github/workflows/ci.yml — PR to dev/main 과 dev/main push 에서 동작.
Jobs:
- Setup Node 22 + pnpm 11.5.1 (lockfile 의 packageManager 와 일치)
- pnpm store 캐시 (lockfile hash 기반)
- .next/cache 캐시 (ts/tsx hash 기반)
- pnpm install --frozen-lockfile (lockfile drift 차단)
- pnpm db:generate (postinstall 보강)
- typecheck → lint → build 직렬
- build env: dummy 값 주입 (auth/db url 필요)
Concurrency: 같은 ref 의 새 push 가 들어오면 이전 run 취소.
Timeout: 10분.
브랜치 보호 (Settings → Branches) 설정으로 'check' 통과 강제는 호스트(나)
가 main, dev 두 곳에 별도 등록 — 코드 변경 X.
* chore(deploy): GH Actions SSH deploy pipeline (#22)
.github/workflows/deploy.yml + deploy/README.md secret 등록 절차.
Workflow:
- trigger: push to dev (→ staging), main (→ prod), 또는 workflow_dispatch
- build job: Docker Buildx + GHCR (ghcr.io) push, GHA cache 사용
태그: '<target>-<sha7>' + '<target>' (latest 역할)
- deploy job: appleboy/ssh-action 으로 N100 접속,
docker compose pull && up -d (project name 으로 staging/prod 분리)
- concurrency: 같은 ref 의 동시 배포 금지
- environment: GitHub Environments 의 'staging' / 'prod' 사용 (prod 는
수동 승인 가능)
- Sanity check 단계: secret 누락 시 명시적 에러로 즉시 실패
필요 secrets (사용자 직접 등록):
- N100_HOST / N100_USER / N100_SSH_KEY
- GITHUB_TOKEN 은 자동 (GHCR push 권한 위해 permissions.packages: write)
deploy/README.md:
- '0. CI/CD 사용 시' 섹션 신설 — secret 등록 절차, SSH key 생성, prod
environment 보호.
- 기존 '1. 첫 배포 (수동)' 은 'CI/CD 우회/디버깅' 으로 강등 (호스트 init
1회는 여전히 필요)
* docs(retro): Week 2 회고 + Home toc1 parent ecb765d commit ed7e758
12 files changed
Lines changed: 653 additions & 99 deletions
File tree
- .github/workflows
- .gjc/specs
- app
- admin/members
- _components
- sessions/[id]
- _components
- deploy
- docs/wiki
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
0 commit comments