diff --git a/docs/map/11-gap-backlog.md b/docs/map/11-gap-backlog.md index 8a10245..d56d2ec 100644 --- a/docs/map/11-gap-backlog.md +++ b/docs/map/11-gap-backlog.md @@ -27,7 +27,7 @@ Legend: `[ ]` open · `[~]` in progress · `[!]` blocked externally · `[x]` res | GAP-REL-09 | Release | 랜딩 사이트가 **재배포되지 않는다**. `deploy` 워크플로가 main push마다 실패한다. 실측 원인(run#66 로그): `site/src/sections/Hero.tsx`가 타이머 ref를 `NodeJS.Timeout`으로 타이핑해 `@types/node` 네임스페이스가 필요했고, 배포 잡은 `npm ci --prefix site`만 하므로 조상 `node_modules`의 hoisted 타입이 없어 `tsc -b`가 `TS2503: Cannot find namespace 'NodeJS'`로 실패한다. 그래서 `https://d3ro.chanpaca.net/release-identity.json`이 404다(공개 버전 검증 불가). | `.forgejo/workflows/deploy-site.yml`, `site/src/sections/Hero.tsx` | `[x]` 2026-09-19: ref를 `ReturnType`으로 바꿔 hoisted 타입 의존을 제거했다(격리 `--typeRoots`로 CI 조건 재현 → 수정 전 TS2503, 수정 후 clean). 같은 수정을 push하자 `deploy` run#67이 사이트 빌드를 통과해 `dist/`를 만들었고, 실패는 다음 단계(Cloudflare)로 이동했다. | | GAP-REL-09b | Release | `d3ro.chanpaca.net`이 404였던 직접 원인: 이 Cloudflare 계정에 Pages 프로젝트 `d3ro`/`d3ro-voice`가 **존재하지 않아** 커스텀 도메인 바인딩이 없었다(빈 본문 404, `cf-ray`만 반환). Pages 커스텀 도메인은 존 DNS CNAME(`d3ro → d3ro.pages.dev`)을 요구하는데 기존 `d3ro` 레코드가 남아 있어 `CNAME record not set`으로 pending에 머물렀고, 로컬 wrangler 자격증명에는 DNS 스코프가 없다(403 Authentication error). `deploy-site.yml`은 `CF_API_TOKEN` 시크릿이 없어 마지막 게시 단계에서도 `exit 1`이다. | `server/cloudflare-site-bridge/`, `.forgejo/workflows/deploy-site.yml`, `docs/map/02-infrastructure.md` | `[x]` 2026-09-19: Pages 프로젝트 `d3ro` 생성 + `site/dist` production 배포(`d3ro.pages.dev` 200, `release-identity.json` = commit `2407f5a` / 1.3.7) + 커스텀 도메인 연결. DNS 없이 도메인을 살리기 위해 Workers 라우트 브리지(`server/cloudflare-site-bridge`, `d3ro.chanpaca.net/*` → Pages 프록시, `npx wrangler deploy`)를 배포 → 라이브 확인: `/`·`/privacy/`·`/terms/`·`/delete-account/` 200, 라이브 번들이 설치 파일명을 `1.3.7`로 계산, `/download.html` → `/#download`. 남은 정리 2건: (1) 대시보드에 CNAME을 추가한 뒤 브리지 워커 삭제, (2) CI 자동 게시를 위해 `CF_API_TOKEN`(Pages/Workers Edit) + `CF_ACCOUNT_ID`=`8e83cc130e7329c160cf2b88d6b4c20a`를 Forgejo 시크릿에 등록. **2026-09-23:** CI `deploy`(deploy-site.yml)는 `CF_API_TOKEN` 부재로 run#71까지 여전히 실패한다. 로컬 인증 wrangler(pages:write)로 `npm run build --prefix site` → release-identity 작성 → `npx wrangler pages deploy site/dist --project-name d3ro --branch main`을 수동 배포했고, 라이브 `https://d3ro.chanpaca.net/release-identity.json`이 commit `5c11ee2` / version `1.5.0`을, 라이브 번들이 설치 파일명 `D3RO-Voice-Setup-1.5.0-x64.exe`를 보고한다. 자동 게시에는 여전히 시크릿 등록이 필요하다. | | GAP-BILL-01 | Billing | 사이트 가격과 서버 청구 금액·결제 진입 URL이 제각각이었다. | `packages/core/src/plan-catalog.ts`, `packages/core/src/web-urls.ts`, `scripts/ci/sync-core-contract.mjs` | `[x]` 2026-09-26 (Wave 3, 88f24d8·b6fe588): 가격·쿼터·공개 URL 정본을 core 두 파일로 합치고 Deno는 생성 사본(`contract:check`). Payple 함수 4종+billing-catalog 운영 재배포(payple-* v9, billing-catalog v5) → 신규·갱신 모두 ₩2,900/₩8,900. 결제 진입은 `/app/billing` 하나. | -| GAP-BILL-02 | Billing | **Payple 정기 갱신이 한 번도 실행되지 않았다.** 갱신 cron(`payple-renew`)이 `.github/workflows`에만 있었는데 GitHub 원격이 없다. 웹 Payple 결제용 `NEXT_PUBLIC_PAYPLE_CLIENT_KEY`는 설정된 적이 없다. | `.forgejo/workflows/payple-renew.yml`, `apps/web/src/components/billing/payple-checkout-button.tsx`, `apps/web/Dockerfile` | `[~]` 2026-09-26: 워크플로 Forgejo 이식(dc43884), `CRON_SECRET` 새로 발급해 Supabase 함수 시크릿·Forgejo 시크릿에 등록, Forgejo `SUPABASE_URL` 등록 — main에 push되면 스케줄이 등록된다. **백로그(사용자 결정):** 웹 Payple 클라이언트 키는 아직 넣지 않는다. Stripe는 쓰지 않고(2026-09-26 저장소에서 제거, GAP-BILL-03), Google Play 가격은 스토어가 정본이라 사이트에 표시하지 않는다. | +| GAP-BILL-02 | Billing | **Payple 정기 갱신이 한 번도 실행되지 않았다.** 갱신 cron(`payple-renew`)이 `.github/workflows`에만 있었는데 GitHub 원격이 없다. 웹 Payple 결제용 `NEXT_PUBLIC_PAYPLE_CLIENT_KEY`는 설정된 적이 없다. | `.forgejo/workflows/payple-renew.yml`, `apps/web/src/components/billing/payple-checkout-button.tsx`, `apps/web/Dockerfile` | `[~]` 2026-09-26: 워크플로 Forgejo 이식(dc43884), `CRON_SECRET` 새로 발급해 Supabase 함수 시크릿·Forgejo 시크릿에 등록, Forgejo `SUPABASE_URL` 등록 — main에 push되면 스케줄이 등록된다. **백로그(사용자 결정, 2026-09-27):** 아직 Payple 계약·계정이 없다. 웹 Payple 클라이언트 키(`NEXT_PUBLIC_PAYPLE_CLIENT_KEY`)는 계약 후 `.env`에 넣고 웹 이미지를 다시 빌드한다. 그 전까지 웹 결제 버튼은 꺼진 상태로 둔다. Stripe는 쓰지 않고(2026-09-26 저장소에서 제거, GAP-BILL-03), Google Play 가격은 스토어가 정본이라 사이트에 표시하지 않는다. | | GAP-BILL-03 | Billing | **Stripe 결제 제거 — 운영 잔여물 정리.** 사용자 결정(2026-09-26)으로 저장소에서 Stripe 코드·설정·테스트를 모두 지웠다(함수 3종, 웹 checkout/portal 버튼, `billing-catalog`의 Stripe 가격 조회, 데스크톱 `CheckoutModal`·`payment:*` IPC, `billingUrl()`의 `success`/`canceled` 복귀 쿼리). 배포된 Supabase 함수와 시크릿은 아직 운영에 남아 있다. 과거 `provider='stripe'` 행·`stripe_*` 컬럼·마이그레이션은 이력 호환으로 유지한다. | `server/supabase/config.toml`, `server/supabase/functions/billing-catalog/index.ts`, `apps/web/src/lib/billing-catalog.ts` | `[ ]` 운영: `supabase functions delete stripe-checkout`·`stripe-portal`·`stripe-webhook`, 시크릿 `STRIPE_SECRET_KEY`·`STRIPE_WEBHOOK_SECRET`·`STRIPE_PRICE_PRO`·`STRIPE_PRICE_PRO_PLUS`·`STRIPE_PRICE_TEAM` unset, Stripe 대시보드 웹훅 엔드포인트 비활성화. `billing-catalog` 재배포는 웹앱 배포보다 먼저(웹 파서가 Stripe 가격을 거부). | | GAP-WEB-01 | Web | 웹앱(`apps/web`)이 공개되지 않았다(배포 경로가 없었음). | `apps/web/Dockerfile`, `docker-compose.nas.yml`, `server/cloudflare-site-bridge` | `[x]` 2026-09-26: `/app` basePath·NAS `d3ro_voice_web`(3002). 터널 `kd-nas` ingress에 `d3ro.chanpaca.net` path `^/app` → NAS 3002를 추가하고 브리지 워커가 `/app`·`/api`·`/health`를 도메인 원본(터널)으로 흘린다(4aadee8). Supabase `site_url`을 `https://d3ro.chanpaca.net/app`으로(기존 localhost:3000), 허용 목록에 `/app/**` 추가. 라이브 `/app/login` 200. 같은 수정으로 9/19부터 끊겨 있던 API(`/api`, 관리자 로그인·stt-proxy)도 복구. | | GAP-OPS-01 | Ops | NAS 운영 compose가 저장소와 어긋나 있었다(JWT 기본값 폴백, 법률 wwwroot 마운트, 필수 변수 4개 누락). | `docker-compose.nas.yml`, NAS `/volume1/docker/d3ro/.env` | `[x]` 2026-09-26: NAS `.env`에 `SUPABASE_URL`·`SUPABASE_SERVICE_ROLE_KEY`(운영 service_role)·`ADMIN_BOOTSTRAP_TOKEN`(신규)·`API_SERVER_URL` 추가, 저장소 compose로 교체 후 `docker compose up -d`. 4개 컨테이너 정상, 백업 `*.before-wave3-20260926`. |