create-saas-starter-workspace 0.1.13 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/workspace/.claude/skills/web-launch/SKILL.md +1 -1
- package/dist/workspace/web/.github/workflows/smoke.yml +37 -0
- package/dist/workspace/web/AGENTS.md +2 -1
- package/dist/workspace/web/app/api/health/route.ts +9 -0
- package/dist/workspace/web/docs/ENVIRONMENTS.md +1 -0
- package/package.json +1 -1
|
@@ -61,4 +61,4 @@ prod `db push`(5)와 repo를 public으로 전환할 때(진단 4)만 Owner confi
|
|
|
61
61
|
|
|
62
62
|
## 검증
|
|
63
63
|
|
|
64
|
-
성공은
|
|
64
|
+
성공은 넷이 모두 참일 때다: 첫 배포가 **실제 prod 도메인으로 LIVE**이고, 그 도메인이 prod Supabase Auth redirect에 반영돼 있고(7), **배포후 스모크(`.github/workflows/smoke.yml`)가 헬스체크 엔드포인트 `/api/health` 200을 확인하고**, 보안 진단을 통과하며 `pnpm run doctor`가 클라우드 연결을 ✓로 확인한다.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Smoke (post-deploy)
|
|
2
|
+
|
|
3
|
+
# 배포후 스모크 테스트. CI(ci.yml)는 빌드까지만 본다 — 이 워크플로는 "배포된 운영 주소가
|
|
4
|
+
# 실제로 응답하나"를 메운다. Vercel이 prod 배포를 끝내면 GitHub deployment_status가 success로
|
|
5
|
+
# 갱신되고, 그때 그 배포 주소의 헬스체크 엔드포인트(/api/health)가 200인지 확인한다.
|
|
6
|
+
# 빌드·배포는 성공해도 런타임(env 누락·잘못된 설정)이 깨지면 여기서 빨간불이 뜬다.
|
|
7
|
+
# v1은 헬스체크 1건이고, 기능이 붙으면 핵심 흐름(로그인→글쓰기→표시) e2e로 자란다.
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
deployment_status: {}
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
smoke:
|
|
17
|
+
# production 배포가 success일 때만 돈다(preview·실패·기타 환경은 건너뛴다).
|
|
18
|
+
if: >
|
|
19
|
+
github.event.deployment_status.state == 'success' &&
|
|
20
|
+
contains(github.event.deployment_status.environment, 'Production')
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- name: 헬스체크 (배포된 운영 주소가 200인가)
|
|
24
|
+
env:
|
|
25
|
+
URL: ${{ github.event.deployment_status.target_url || github.event.deployment_status.environment_url }}
|
|
26
|
+
run: |
|
|
27
|
+
if [ -z "$URL" ]; then echo "deployment_status 이벤트에 배포 주소가 없습니다."; exit 1; fi
|
|
28
|
+
echo "smoke target: ${URL%/}/api/health"
|
|
29
|
+
# 배포 직후 콜드스타트 여유: 최대 5회(10초 간격) 재시도, 200이면 통과.
|
|
30
|
+
for i in 1 2 3 4 5; do
|
|
31
|
+
code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 20 "${URL%/}/api/health" || echo 000)
|
|
32
|
+
echo "attempt $i: HTTP $code"
|
|
33
|
+
if [ "$code" = "200" ]; then echo "OK: 운영 주소가 살아 있습니다."; exit 0; fi
|
|
34
|
+
sleep 10
|
|
35
|
+
done
|
|
36
|
+
echo "FAIL: 운영 주소가 200을 돌려주지 않습니다 (${URL%/}/api/health). 배포는 됐지만 런타임이 깨졌을 수 있습니다."
|
|
37
|
+
exit 1
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
2. `/probe <아이디어>` — 적응형 인터뷰로 요구사항 도출
|
|
15
15
|
3. `/sketch` — shadcn과 프로젝트 디자인 컨벤션 기반 시안
|
|
16
16
|
4. TDD 개발 — Vitest 테스트 작성, 통과, 커밋을 반복
|
|
17
|
-
5. `git push` 전 로컬 전수 점검(typecheck·lint·test·build) → push → CI 통과 시 Vercel 자동 배포
|
|
17
|
+
5. `git push` 전 로컬 전수 점검(typecheck·lint·test·build) → push → CI 통과 시 Vercel 자동 배포 → 배포후 스모크(`smoke.yml`)가 운영 주소 헬스체크 `/api/health` 200 확인
|
|
18
18
|
|
|
19
19
|
`.vercel/`이 없으면 `/web-launch`를 먼저 실행한다. 의존성·CLI 로그인은 설치 스크립트와 `pnpm run doctor`가 챙긴다.
|
|
20
20
|
|
|
@@ -66,6 +66,7 @@ Owner가 직접(CLI 미지원, AI는 안내만): 카드 결제, 도메인 DNS
|
|
|
66
66
|
app/ # Next.js 라우트만 (page·layout·route handler)
|
|
67
67
|
├── sketch/<feature>/ # /sketch 임시 시안 — 채택안만 남기고 정리
|
|
68
68
|
├── api/cron/<job>/ # cron route handler
|
|
69
|
+
├── api/health/ # 헬스체크 엔드포인트 (배포후 스모크가 점검)
|
|
69
70
|
└── <route>/_components/ # 라우트 전용 UI (underscore = private)
|
|
70
71
|
features/<feature>/ # 도메인 모듈 (자기완결)
|
|
71
72
|
├── components/ # 이 기능 전용 UI
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// 헬스체크 엔드포인트. 배포된 운영 주소가 살아 있는지 확인하는 가벼운 라우트다.
|
|
2
|
+
// 배포후 스모크 테스트(`.github/workflows/smoke.yml`)가 이 엔드포인트를 호출해 200인지 점검한다.
|
|
3
|
+
// 빌드·배포는 성공했지만 런타임이 깨진 경우(env 누락·잘못된 설정 등)를 잡는다. CI는 빌드까지만 본다.
|
|
4
|
+
// DB·외부 호출 없이 프로세스가 떠서 응답하는지(liveness)만 본다. 캐시되면 안 되므로 동적.
|
|
5
|
+
export const dynamic = "force-dynamic";
|
|
6
|
+
|
|
7
|
+
export function GET() {
|
|
8
|
+
return Response.json({ status: "ok" });
|
|
9
|
+
}
|
package/package.json
CHANGED