Skip to content

10-1. 프로젝트 가이드 ​

한 줄 요약: 포트폴리오 프로젝트를 기능 목록이 아니라 문제 정의, 제약, 기술 선택, 측정 결과가 남는 검증 가능한 시스템으로 설계할 수 있다.

학습 목표 ​

  • 포트폴리오 프로젝트 주제를 기술 판단 지점의 밀도로 평가할 수 있다.
  • 기능 요구사항과 비기능 요구사항을 검증 가능한 동작과 제약으로 바꿀 수 있다.
  • 렌더링 전략, 상태 관리, 테스트, 배포 같은 기술 선택을 대안·비용·재검토 조건과 함께 비교할 수 있다.
  • ADR(Architecture Decision Record)을 결정의 근거와 변경 이력으로 작성할 수 있다.
  • 개인 또는 팀 프로젝트의 마일스톤, issue, PR, Definition of Done을 수직 절편 중심으로 설계할 수 있다.

배경: 왜 이것이 존재하는가 ​

Phase 0~9에서는 브라우저, HTTP, JavaScript, TypeScript, React, 도구, Git, 성능, 보안, 렌더링 전략, 설계 패턴의 동작 모델과 판단 기준을 따로 세웠다. Phase 10의 문제는 새로운 API를 더 배우는 것이 아니라, 이 모델을 하나의 프로젝트 판단으로 합치는 것이다.

경력 개발자의 포트폴리오 프로젝트가 약해지는 지점은 대체로 구현 능력 부족이 아니다. 이미 CRUD, 인증, 배포, README 작성은 할 수 있다. 문제는 프로젝트가 "무엇을 만들었다"만 말하고 "어떤 제약에서 무엇을 선택했고, 그 선택이 어떤 증거로 검증되었는가"를 말하지 못하는 데 있다. 채용 담당자는 결과물을 훑고, 동료 개발자는 저장소와 이력을 읽고, 면접관은 선택의 근거를 반박한다. 이 세 독자는 모두 다른 속도로 읽지만 같은 질문을 한다.

text
이 프로젝트는 어떤 문제를 풀었는가?
왜 이 기술 선택이 이 문제에 맞았는가?
그 선택이 실제로 효과가 있었는지 어떻게 확인했는가?
어떤 조건이 바뀌면 결정을 바꿀 것인가?

백엔드 프로젝트에서 RFC, ADR, API contract, migration plan이 운영 가능한 시스템을 만드는 것처럼 프론트엔드 프로젝트에도 의사결정 기록이 필요하다. 차이는 실행 환경이다. 프론트엔드는 사용자의 기기, 브라우저, 네트워크, 입력 장치, 접근성 보조 기술, 보안 정책 위에서 실행된다. 따라서 프로젝트 기획 단계부터 성능 예산, 접근성 흐름, 캐시 신선도, 보안 경계, 브라우저 지원 범위가 기술 선택의 일부가 된다.

핵심 개념 ​

좋은 주제는 기능이 아니라 판단 지점을 가진다 ​

포트폴리오 주제를 고를 때 "게시판", "쇼핑몰", "대시보드" 같은 명사는 충분한 기준이 아니다. 같은 게시판도 정적 목록이면 판단 지점이 적고, 검색·필터·권한·낙관적 업데이트·접근성 요구가 있으면 판단 지점이 많다. 좋은 주제는 기술 선택이 갈리는 지점을 의도적으로 포함한다.

판단 지점드러낼 수 있는 역량관찰 증거
데이터 신선도HTTP 캐시와 애플리케이션 캐시 분리Network waterfall, cache header, 서버 상태 캐시 설정
인증·권한쿠키, 세션, 토큰 저장 위치의 보안 경계Set-Cookie 속성, 권한 오류 플로우, 보안 점검표
검색·필터링URL 상태, 서버 쿼리, 클라이언트 상태 소유권URL 재현성, 요청 수, debounce trace
대용량 목록렌더링 비용과 가상화 판단React Profiler, INP, DOM node 수
오프라인 저장브라우저 저장소와 동기화 충돌 처리IndexedDB/localStorage 선택 근거, 충돌 정책
접근성 흐름시맨틱 마크업, 포커스, 이름 계산키보드 완주 기록, Accessibility tree, Lighthouse/axe
보안 입력 경로XSS, CSRF, 민감 정보 노출 방어sanitizer 정책, CSP, SameSite, 입력 검증 테스트

예를 들어 "영화 검색 앱"은 API를 호출하고 목록을 보여 주는 수준이면 얕다. 그러나 다음 제약을 붙이면 기술 검증 대상이 된다.

md
# 프로젝트 후보: 영화 검색과 감상 목록 관리

## 판단 지점
- 검색어는 URL에 반영되어 공유 가능한 상태여야 한다.
- 검색 결과는 30초 동안 재사용하되, 상세 정보는 사용자가 열 때 최신성을 우선한다.
- 감상 목록은 로그인 없이 IndexedDB에 저장한다.
- 모바일 네트워크에서 첫 검색 결과의 LCP를 2.5초 이하로 유지한다.
- 키보드만으로 검색, 필터, 상세 열기, 저장을 완료할 수 있어야 한다.
- 외부 API 실패, rate limit, 빈 결과를 서로 다른 상태로 보여 준다.

## 제외 범위
- 결제, 소셜 로그인, 추천 알고리즘은 다루지 않는다.
- 실시간 협업 편집은 이 프로젝트의 핵심 문제가 아니다.

이 문서는 기능 수를 늘리라고 말하지 않는다. 오히려 반대다. 주제의 폭은 줄이고, 선택이 갈리는 지점을 깊게 만든다. 포트폴리오 프로젝트는 모든 실서비스 요구를 만족할 필요가 없다. 대신 다루지 않은 영역을 알려진 한계로 명시해야 한다.

요구사항은 "하고 싶은 기능"을 "검증할 동작"으로 바꾼 것이다 ​

기능 목록은 구현 항목을 나열하지만, 요구사항은 성공과 실패를 판정할 기준을 만든다. "검색 기능"은 기능 목록이다. "사용자가 검색어를 입력하고 Enter를 누르면 URL query가 갱신되고, 이전 검색 결과가 있으면 즉시 보여 주며, 새 응답이 도착하면 최신 결과로 교체한다"는 검증 가능한 동작이다.

프로젝트 초기에 다음 문서를 만든다.

md
# 요구사항 문서

## 문제
반복적으로 확인하는 웹 성능 지표와 배포 변경 이력을 한 화면에서 비교하고 싶다.

## 사용자
- 개인 프로젝트를 운영하는 프론트엔드 개발자
- 작은 팀에서 배포 후 성능 회귀를 확인하는 리뷰어

## 핵심 작업
1. 사용자는 프로젝트 URL을 등록한다.
2. 사용자는 배포 버전별 Lighthouse 결과와 주요 변경 PR을 비교한다.
3. 사용자는 LCP/INP/CLS 중 회귀가 생긴 지표를 선택해 관련 trace와 조치 기록을 확인한다.

## 성공 기준
- 등록된 URL의 최근 5개 측정 결과를 한 화면에서 비교할 수 있다.
- 지표가 악화된 배포는 이전 배포와 차이를 볼 수 있다.
- 측정 조건이 없거나 다른 결과는 같은 표에서 직접 비교하지 않는다.

## 비기능 요구사항
- 초기 화면 LCP는 Fast 4G, 4x CPU slowdown 기준 2.5초 이하를 목표로 한다.
- 키보드만으로 프로젝트 등록, 결과 선택, 상세 열기를 수행할 수 있다.
- 외부 API key는 클라이언트 번들에 포함하지 않는다.
- 최신 Chrome, Safari, Firefox의 안정 버전을 지원한다.

## 제외 범위
- 자체 RUM 수집 SDK는 만들지 않는다.
- 다중 사용자 권한 관리는 첫 버전에 포함하지 않는다.

요구사항의 동작 모델은 테스트와 리뷰의 입력이 된다. 성공 기준이 없으면 PR 리뷰는 취향 싸움이 되고, 성능 개선은 Lighthouse 점수 올리기가 되며, 보안 점검은 헤더 체크리스트로 축소된다. 요구사항은 기능을 제한하는 문서이기도 하다. 제외 범위가 명확해야 프로젝트가 포트폴리오 분량 안에서 끝난다.

비기능 요구사항은 기술 선택을 제한하는 계약이다 ​

비기능 요구사항(non-functional requirement)은 "있으면 좋은 품질"이 아니라 선택지를 줄이는 제약이다. 성능 예산이 있으면 렌더링 전략과 번들 크기 판단이 달라지고, 접근성 목표가 있으면 커스텀 위젯 비용이 달라지며, 보안 요구가 있으면 토큰 저장과 서버 경계가 달라진다.

요구프로젝트 문장선택에 미치는 영향무너지는 조건
성능상품 목록 LCP p75 2.5초 이하SSR/SSG, 이미지 최적화, API 위치, CDN 캐시 검토개인화가 강해 HTML 캐시가 어려울 때
접근성주요 플로우 키보드 완주native control 우선, focus management 설계복잡한 drag-and-drop이 핵심일 때
보안API token은 브라우저에 노출하지 않음서버 route, proxy, httpOnly cookie 검토완전 정적 호스팅만 허용될 때
운영PR마다 preview deployment 제공CI/CD, 환경 변수, seed data 정리외부 API 비용이 preview마다 커질 때
호환성Safari 최신 안정 버전 지원Web API Baseline, polyfill, CSS fallback 검토실험적 API가 핵심 가치일 때

성능 요구를 쓸 때는 측정 조건도 같이 쓴다. "빠르다"는 요구가 아니다. 예를 들어 "로컬 MacBook에서 Lighthouse 95점"은 실제 사용자 경험을 대표하지 못한다. "Moto G Power급 모바일 프로파일, Fast 4G, cold cache, /search?q=react 첫 진입 LCP 2.5초 이하를 목표로 하고, field data가 없으므로 lab data의 한계를 README에 명시한다"처럼 조건을 남긴다.

기술 선택은 결론보다 비교 기준이 먼저다 ​

기술 선택의 순서는 다음과 같다.

text
문제와 제약
  → 가능한 선택지
  → 비교 기준
  → 결정
  → 검증 방법
  → 재검토 조건

나쁜 결정문은 결론부터 시작한다.

md
Next.js를 사용한다. SSR이 가능하고 성능이 좋기 때문이다.

좋은 결정문은 비용 모델을 드러낸다.

md
검색 결과 페이지는 공유 가능한 URL, 초기 콘텐츠 노출, 외부 API key 보호가 필요하다.
후보는 React SPA + API proxy, Next.js App Router, 정적 사이트 + serverless function이다.
첫 화면에 검색 결과가 있어야 하고 API key를 숨겨야 하므로 완전 정적 배포만으로는 부족하다.
Next.js App Router를 선택하되, 검색어별 결과는 동적 데이터라 장기 HTML 캐시를 기대하지 않는다.
LCP와 서버 응답 시간이 목표를 넘거나 클라이언트 상호작용 코드가 커지면 RSC 경계를 재검토한다.

기술 비교는 표로 남기면 리뷰하기 쉽다.

선택지얻는 것비용이 프로젝트의 판단
React SPA단순한 정적 배포, 클라이언트 상호작용 구현 용이초기 데이터 로딩이 JS 실행 뒤로 밀림, API key 보호에 별도 서버 필요인증 없는 내부 도구라면 충분하지만 첫 검색 결과 노출 요구와 충돌한다
Next.js App Router서버 데이터 접근, route 단위 렌더링, RSC 경계캐시 계층과 서버/클라이언트 경계 복잡도API key 보호와 초기 콘텐츠 노출이 중요하므로 1차 선택
정적 사이트 + serverless function빌드 산출물 단순, 일부 서버 기능 가능데이터별 렌더링 경계와 캐시 제어를 직접 설계해야 함작은 프로젝트에는 가능하지만 학습 목표인 렌더링 전략 검증이 약해진다

이 표의 목적은 "정답"을 고정하는 것이 아니다. 선택하지 않은 대안이 더 나아지는 조건을 적어야 판단이 성숙해진다. 예를 들어 "사용자별 개인화가 강해 HTML 캐시 이점이 사라지고 상호작용이 대부분이라면 SPA로 단순화한다"는 재검토 조건이다.

ADR은 선택을 반박 가능하게 만드는 변경 이력이다 ​

ADR은 결정의 장식물이 아니다. 결정이 내려진 시점의 맥락을 보존해 나중에 반박하거나 갱신할 수 있게 하는 기록이다. 최소 형식은 다음 정도면 충분하다.

md
# ADR-001. 검색 결과 렌더링 전략으로 Next.js App Router를 사용한다

## 상태
Accepted

## 맥락
- 검색 결과 URL은 공유 가능해야 한다.
- 외부 API key를 클라이언트에 노출하지 않아야 한다.
- 첫 검색 결과의 LCP를 lab 기준 2.5초 이하로 유지하고 싶다.
- 사용자별 개인화는 첫 버전에 없다.

## 선택지
1. React SPA + 별도 API proxy
2. Next.js App Router
3. 정적 사이트 + serverless function

## 결정
Next.js App Router를 사용한다. 검색 결과 page는 서버에서 데이터를 읽고,
상호작용이 필요한 필터와 저장 버튼만 클라이언트 컴포넌트로 분리한다.

## 결과
- API key는 서버 환경 변수에 둔다.
- 초기 HTML에 검색 결과 일부를 포함할 수 있다.
- route segment, fetch cache, RSC payload를 이해해야 하므로 구현 복잡도가 증가한다.

## 검증 방법
- `pnpm build` 후 client bundle에 외부 API SDK가 포함되는지 확인한다.
- Chrome DevTools Performance에서 LCP element와 waterfall을 기록한다.
- Network 패널에서 검색 API 호출이 브라우저에서 직접 나가지 않는지 확인한다.

## 재검토 조건
- 검색 결과가 사용자별로 강하게 개인화되어 서버 렌더링 캐시 이점이 사라진다.
- 클라이언트 컴포넌트 경계가 커져 초기 JS가 목표 예산을 넘는다.
- 배포 플랫폼의 서버 실행 비용이 프로젝트 운영 범위를 넘는다.

상태는 Proposed, Accepted, Superseded 정도면 충분하다. 중요한 것은 재검토 조건이다. 재검토 조건이 없는 ADR은 과거 결정을 영구 진리처럼 만든다. 실제 프로젝트에서는 기술 선택보다 상황 변화가 더 자주 문제를 만든다.

수직 절편은 프로젝트가 실제로 끝나는 단위다 ​

수직 절편(vertical slice)은 데이터, UI, 상태, 오류, 배포 경로가 얇게라도 끝까지 연결된 단위다. "컴포넌트 먼저 전부 만들기", "API client 먼저 만들기"는 레이어 단위 작업이다. 레이어 단위 작업은 병렬화가 쉬워 보이지만, 통합 위험을 마지막에 몰아넣는다.

첫 마일스톤은 다음처럼 잡는다.

md
# Milestone 1. 검색 결과 수직 절편

## 포함
- `/search?q=...` URL에서 검색어를 읽는다.
- 서버 또는 API 계층에서 검색 요청을 수행한다.
- 로딩, 빈 결과, 실패, rate limit 상태를 구분한다.
- 결과 10개를 접근 가능한 목록으로 렌더링한다.
- 키보드로 검색창에서 결과 상세 링크까지 이동할 수 있다.
- preview deployment에서 동작을 확인한다.

## 제외
- 고급 필터
- 정렬 저장
- 사용자 계정
- 추천 결과

## 완료 조건
- typecheck, lint, test, build가 통과한다.
- Network waterfall과 LCP trace를 PR에 첨부한다.
- 관련 ADR 링크를 PR 본문에 포함한다.

이 단위가 중요한 이유는 프론트엔드 결함이 계층 사이에서 자주 발생하기 때문이다. 타입은 맞지만 접근성 이름이 없고, 화면은 보이지만 API 실패 상태가 막혀 있으며, 로컬은 빠르지만 배포 preview에서 환경 변수가 빠져 실패한다. 수직 절편은 이런 통합 위험을 초기에 드러낸다.

협업 규칙은 프로젝트 시작 시점에 비용을 고정한다 ​

팀 프로젝트라면 협업 규칙은 나중에 정리하는 문서가 아니다. 브랜치 전략, PR 크기, 리뷰 기준, merge 조건은 변경 비용을 직접 결정한다. 개인 프로젝트라도 셀프 리뷰와 issue 기록을 남기면 협업 습관을 보여 줄 수 있다.

md
# 작업 규칙

## 브랜치
- `main`은 배포 가능한 상태로 유지한다.
- 기능 작업은 `feature/<issue-number>-<slug>`에서 진행한다.

## PR 크기
- 리뷰 가능한 목표는 300줄 이하의 의미 있는 변경이다.
- 대형 변경은 ADR, 타입 경계, UI 연결, 테스트 추가 PR로 나눈다.

## PR 본문
- 문제와 변경 의도
- 관련 요구사항 또는 ADR
- 검증 방법
- 스크린샷 또는 trace
- 남은 리스크

## Definition of Done
- 주요 happy path와 실패 상태가 동작한다.
- 접근성 이름, 키보드 순서, focus 이동을 확인했다.
- 성능 또는 보안에 영향을 주는 변경은 관찰 증거를 남겼다.
- README 또는 ADR을 갱신해야 하는 변경이면 함께 갱신했다.

개인 프로젝트에서 이 규칙이 과해 보일 수 있다. 그러나 포트폴리오 저장소는 완성된 코드만 보는 공간이 아니다. issue, PR, ADR, commit message가 모두 "어떻게 일하는가"를 보여 준다. 혼자 하더라도 PR 본문 형식의 셀프 리뷰를 남기는 편이 낫다.

실무 관점 ​

선택지는 프로젝트 규모보다 검증 목표로 고른다 ​

포트폴리오 프로젝트는 실서비스보다 작다. 따라서 "실무에서 많이 쓰니까"만으로 기술을 붙이면 과잉 설계가 된다. 반대로 너무 단순한 선택만 하면 앞선 Phase에서 배운 원리를 보여 줄 장면이 사라진다.

선택 영역단순 선택복잡한 선택판단 기준경계 조건
렌더링Vite SPANext.js App Router초기 콘텐츠, SEO, 비밀 값, 캐시 가능성개인화와 상호작용이 대부분이면 SSR 이점이 줄어든다
서버 상태직접 fetchTanStack Query/SWRstale data, 재시도, 무효화, pagination요청이 1~2개면 라이브러리 비용이 더 크다
클라이언트 상태지역 상태Zustand/Redux 등 외부 store공유 범위, 디버깅, undo, persist서버 상태를 전역 store에 복제하면 정합성이 깨진다
스타일링CSS ModulesTailwind/CSS-in-JS팀 규칙, 동적 스타일, 런타임 비용디자인 시스템이 없으면 추상화만 늘 수 있다
테스트수동 검증 + unitcomponent/e2e/visual회귀 위험, 사용자 플로우 중요도flaky e2e가 많으면 신뢰가 떨어진다
배포정적 호스팅serverless/edge/container서버 실행 필요, 캐시, 비용, secret플랫폼 기능에 과하게 결합될 수 있다

좋은 프로젝트는 모든 복잡한 선택을 채택하지 않는다. 오히려 "이 프로젝트의 핵심 검증 목표는 렌더링 전략과 성능이므로 인증은 제외한다"처럼 축을 제한한다.

README와 ADR은 첫 커밋 근처에 있어야 한다 ​

README를 마지막에 쓰면 실제 의사결정의 흔적이 사라진다. 초기에 빈 골격을 만들고, 결정이 생길 때마다 갱신한다.

md
# README 초기 골격

## 문제와 목표

## 주요 사용자 플로우

## 기술 선택 요약
- 렌더링 전략: [ADR-001](./docs/adr/001-rendering.md)
- 상태·데이터 계층: [ADR-002](./docs/adr/002-data-state.md)
- 테스트 전략: [ADR-003](./docs/adr/003-testing.md)

## 로컬 실행

## 검증 명령

## 성능·접근성·보안 점검 로그

## 알려진 한계

이 골격은 프로젝트의 작업 기억이다. 새 기능이 들어올 때 README나 ADR이 갱신되지 않는다면, 변경이 기술 서사에 반영되지 않은 것이다.

측정 로그는 성공뿐 아니라 실패도 남긴다 ​

성능, 접근성, 보안 점검은 결과가 좋을 때만 포트폴리오에 붙이는 스크린샷이 아니다. 실패한 측정은 더 좋은 기술 서사가 된다. 기준선, 가설, 조치, 재측정, 해석을 남긴다.

md
# 측정 로그

## 2026-07-07 검색 결과 LCP 기준선
- 환경: Chrome DevTools, Fast 4G, 4x CPU slowdown, cold cache
- URL: `/search?q=react`
- 결과: LCP 3.4s, LCP element는 첫 번째 결과 카드 이미지
- 가설: 이미지 요청이 JS 실행 뒤에 발견되어 resource load delay가 크다.
- 조치: 이미지 URL을 서버 응답 HTML에 포함하고 `width`/`height`를 제공한다.
- 재측정: LCP 2.6s
- 남은 한계: field data가 없고 외부 이미지 CDN 응답이 흔들린다.

이 로그는 나중에 README, 이력서, 면접 답변의 근거가 된다. "성능을 개선했다"보다 "resource load delay를 줄였고, lab 조건에서 LCP가 3.4s에서 2.6s로 줄었지만 field data는 아직 없다"가 더 신뢰할 수 있다.

더 깊이 ​

의사결정은 코드와 같은 수명주기를 가진다 ​

ADR을 코드 밖의 정적 문서로 보면 금방 낡는다. 의사결정도 코드처럼 변경된다. 새로운 요구사항이 들어오면 기존 ADR의 상태를 Superseded로 바꾸고 새 ADR을 연결한다.

md
# ADR-004. 서버 상태 캐시를 TanStack Query로 전환한다

## 상태
Accepted

## 대체한 결정
- ADR-002. 직접 fetch와 지역 상태로 서버 데이터를 관리한다

## 맥락 변화
- 검색 결과뿐 아니라 즐겨찾기, 상세, 추천 데이터가 추가되었다.
- 같은 데이터가 여러 화면에서 갱신되고 stale 상태가 사용자에게 보이기 시작했다.
- 직접 구현한 재시도와 무효화 코드가 기능마다 중복된다.

이 방식은 "처음부터 틀렸다"는 표현을 피한다. 당시의 제약에서는 단순한 선택이 맞았고, 맥락이 바뀌어 결정도 바뀐 것이다. 면접에서 좋은 방어는 과거 결정을 고집하는 것이 아니라 어떤 조건에서 결정을 갱신하는지 설명하는 것이다.

프로젝트 위험은 기술 부채보다 먼저 식별할 수 있다 ​

기획 단계에서 다음 위험 표를 만들어 두면 구현 중 판단이 빨라진다.

위험신호완화받아들이는 한계
외부 API rate limit429 응답 증가서버 캐시, debounce, 실패 상태실시간성은 포기한다
초기 JS 과다bundle analyzer에서 route chunk 증가RSC 경계 축소, dynamic import복잡한 차트는 상세 화면으로 이동
접근성 누락키보드 trap, 이름 없는 buttonnative control 우선, axe smoke testscreen reader별 차이는 수동 점검 범위를 명시
보안 오판secret이 client bundle에 포함서버 경계, CI secret scan공개 demo data만 사용

위험 표는 프로젝트를 방어적으로 만든다. "완벽하게 막았다"가 아니라 "무엇을 알고 있고, 무엇을 완화했고, 무엇을 한계로 인정했는가"를 보여 준다.

정리 ​

  • 포트폴리오 프로젝트의 깊이는 기능 수가 아니라 기술 판단 지점과 검증 증거에서 나온다.
  • 요구사항은 구현하고 싶은 기능을 검증 가능한 동작과 성공 기준으로 바꾸는 문서다.
  • 비기능 요구사항은 성능, 접근성, 보안, 운영, 호환성 선택지를 제한하는 계약이다.
  • ADR은 결정을 정당화하는 문서가 아니라 나중에 반박하고 갱신할 수 있게 하는 변경 이력이다.
  • 수직 절편은 UI, 데이터, 오류, 접근성, 배포 경로를 초기에 연결해 통합 위험을 드러낸다.

확인 문제 ​

1. 다음 프로젝트 주제는 왜 기술 깊이가 드러나기 어려운가? ​

md
React로 게시판을 만든다.
- 글 목록
- 글 상세
- 글 작성
- 글 수정
- 글 삭제
정답과 해설

기능 목록만 있고 판단 지점이 없다. 데이터 신선도, 권한, 실패 상태, 캐시, 접근성, 성능 예산, 보안 입력 경로, 브라우저 저장소 같은 제약이 없으므로 기술 선택을 비교할 근거가 생기지 않는다. 같은 게시판이라도 "Markdown 입력을 허용하되 XSS를 막는다", "목록 URL 상태를 공유 가능하게 한다", "권한 오류와 낙관적 업데이트 rollback을 처리한다" 같은 제약을 붙이면 검증 가능한 프로젝트가 된다.

2. 다음 ADR에서 빠진 가장 중요한 항목은 무엇인가? ​

md
Next.js를 사용한다.
이유: SSR을 쓰면 SEO와 성능이 좋아진다.
정답과 해설

문제와 제약, 선택지, 비용, 검증 방법, 재검토 조건이 빠졌다. SSR이 항상 성능을 좋게 만드는 것은 아니다. TTFB, hydration, 캐시 가능성, 사용자별 개인화, 서버 비용에 따라 결과가 달라진다. 좋은 ADR은 "왜 SSR이 이 프로젝트의 어떤 제약을 해결하는지", "SPA나 정적 사이트가 왜 덜 맞는지", "어떤 trace로 검증할지", "어떤 조건에서 결정을 바꿀지"를 포함해야 한다.

3. 개인 프로젝트에서도 PR 템플릿이 의미 있는 이유는 무엇인가? ​

정답과 해설

PR 템플릿은 협업 인원이 아니라 변경 검증의 단위를 만든다. 혼자 진행해도 변경 의도, 관련 ADR, 검증 방법, 스크린샷·trace, 남은 리스크를 남기면 나중에 README, 이력서, 면접 답변의 증거가 된다. 또한 수직 절편이 요구사항과 품질 gate를 만족했는지 스스로 리뷰할 수 있다.

참고 자료 ​