chore(week2): photo/admin form retrofit + CI + Deploy + retro#31
Merged
Conversation
… 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
.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.
.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회는 여전히 필요)
This was referenced Jun 7, 2026
Merged
peterabcd
added a commit
that referenced
this pull request
Jun 7, 2026
* 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 toc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
2주차 마무리 한 PR. 작은 작업 4개를 commit 단위로 분리, 머지는 한 번.
Closes #5, #22. 사진 폼/admin 폼 retrofit + Week 2 회고는 별도 issue 없음 — 본문 기재.
Commits (review 단위)
1.
fix(forms): SKILL 4.5 retrofit — photo & admin members inline alert + dedupePR #30 에 새로 박은 SKILL §4.5 폼 표준 체크리스트를 이미 있는 폼에 소급 적용.
useActionState+ErrorAlert+SubmitButton. 15MB 초과 / MIME 거부 / 빈 파일 → inline alert.photo-actions.ts,PhotoSection.tsx(server→client),PhotoReplaceButton.tsx(props 통해 부모 action 공유),app/admin/members/actions.ts,_components/PendingMemberActions.tsx(new).2.
chore(ci): typecheck + lint + build on PR/push (#5).github/workflows/ci.yml. PR to dev/main + dev/main push 트리거.pnpm install --frozen-lockfile→db:generate→typecheck→lint→build3.
chore(deploy): GH Actions SSH deploy pipeline (#22).github/workflows/deploy.yml+deploy/README.md의 secret 등록 절차.<target>-<sha7>+<target>(latest 역할). GHA cache 사용.docker compose pull && up -d(project name 으로 staging/prod 격리)staging(자동) /prod(수동 승인 가능)N100_HOST,N100_USER,N100_SSH_KEY4.
docs(retro): Week 2 회고 + Home tocdocs/wiki/Retrospective-Week2.md신설. Home 색인 갱신.Fidelity check (06)
.gjc/specs/week2-wrapup.md) acceptance 1:1 매칭pnpm typecheck/lint/build4 commit 모두 통과 (마지막 회고는 docs 라 skip)docker ps로 컨테이너 갱신 확인.호스트(너) 작업
머지 후:
prodenvironment 보호 추가 — Settings → Environments → "prod" → Required reviewers 본인deploy/README.md§0 참고)다음 PR 후보 (Week 3 진입 시)
v0.1.0태그 — MVP 배포 도장. 코드 변경 X, 사용자 직접.추천: (a) → (b) 순. dogfooding 1회 후 실제로 어색한 부분이 다음 PR 우선순위를 결정.