weekly
요약. weekly: 자율 개선 회차 17회, 릴리즈 10건. 최근 릴리즈 v0.296.0 (자산 1개). 건강 B
- 17회차
- 1프로젝트
- 10배포 준비 완료
- 0릴리즈 진행 중
- 2병합 완료
- 1검토 대기
- 1검증 실패
- 3변경 없음
- 0실행 오류
- $68.05비용
- 3시간 59분에이전트 시간
현황
- 저장소
- https://github.com/hkjang/weekly
- 마지막 회차
- 2026-09-11 10:23 KST — 🚀 릴리즈 merged PR #13, released v0.296.0
- 최근 릴리즈
- v0.296.0 — released · 자산 1개 (이전 v0.295.0: 1개) 전체 릴리즈 →
회차 이력
| 일시 | 프로젝트 | 결과 |
|---|---|---|
| 2026-09-11 10:23 | weekly | 배포 준비 완료 merged PR #13, released v0.296.0 |
| 2026-09-10 17:24 | weekly | 배포 준비 완료 merged PR #12, released v0.295.0 |
| 2026-09-10 08:59 | weekly | 검증 실패 verify failed: build artifacts committed |
| 2026-09-09 12:42 | weekly | 변경 없음 no change |
| 2026-09-09 03:59 | weekly | 배포 준비 완료 merged PR #11, released v0.294.0 |
| 2026-09-08 22:50 | weekly | 검토 대기 CI timeout, PR open PR #10 |
| 2026-09-07 09:46 | weekly | 배포 준비 완료 release-only, released v0.290.0 |
| 2026-09-07 05:52 | weekly | 병합 완료 merged PR #9, release blocked (secrets) |
| 2026-09-06 20:53 | weekly | 변경 없음 no change |
| 2026-09-05 10:00 | weekly | 변경 없음 no change |
| 2026-09-04 21:15 | weekly | 배포 준비 완료 merged PR #8, released v0.289.0 |
| 2026-09-04 02:53 | weekly | 병합 완료 merged PR #7, release missing |
| 2026-09-03 19:17 | weekly | 배포 준비 완료 merged PR #6, released v0.286.0 |
| 2026-09-03 11:28 | weekly | 배포 준비 완료 merged PR #5, released v0.285.0 |
| 2026-09-03 06:06 | weekly | 배포 준비 완료 merged PR #4, released v0.284.0 |
| 2026-09-03 00:01 | weekly | 배포 준비 완료 merged PR #3, released v0.283.0 |
| 2026-09-02 17:27 | weekly | 배포 준비 완료 merged PR #2, released v0.282.0 |
비용·사용량
| 시각 | 프로젝트 | 단계 | 시간 | 턴 | 비용 | 토큰 입력/출력 | 종료 |
|---|---|---|---|---|---|---|---|
| 10:09 | weekly | 릴리즈 | 22분 | 43 | $3.16 | 3.5M / 19K | success |
| 09:39 | weekly | review | 3분 | 28 | $2.15 | 2.1M / 12K | success |
| 09:33 | weekly | 개선 | 25분 | 99 | $11.12 | 13.7M / 81K | success |
| 17:10 | weekly | 릴리즈 | 5분 | 28 | $1.29 | 1.1M / 10K | success |
| 16:47 | weekly | review | 6분 | 52 | $2.46 | 2.5M / 20K | success |
| 16:40 | weekly | 개선 | 42분 | 80 | $5.85 | 7.2M / 40K | success |
| 08:59 | weekly | 개선 | 9분 | 57 | $4.46 | 4.9M / 34K | success |
| 12:42 | weekly | 개선 | 11분 | 82 | $6.46 | 7.9M / 46K | success |
| 03:44 | weekly | 릴리즈 | 1분 | 8 | $1.92 | 529K / 3K | success |
| 03:21 | weekly | review | 3분 | 17 | $1.14 | 743K / 12K | success |
| 03:16 | weekly | 개선 | 17분 | 65 | $6.02 | 7.0M / 43K | success |
| 22:31 | weekly | review | 4분 | 26 | $1.06 | 959K / 9K | success |
| 22:26 | weekly | 개선 | 16분 | 60 | $5.39 | 5.8M / 39K | success |
| 09:31 | weekly | 릴리즈 | 12분 | 18 | $0.99 | 641K / 10K | success |
| 05:52 | weekly | 릴리즈 | 4분 | 38 | $1.91 | 1.8M / 15K | success |
| 05:33 | weekly | review | 8분 | 25 | $1.36 | 1.0M / 17K | success |
| 05:24 | weekly | 개선 | 25분 | 86 | $6.47 | 8.0M / 47K | success |
| 20:53 | weekly | 개선 | 25분 | 67 | $4.84 | 5.6M / 34K | success |
아이디어 백로그 — 대기 13 / 전체 14
| 아이디어 | 가치/위험/크기 | 상태 | 메모 | 갱신 |
|---|---|---|---|---|
| 완료 숨기기가 담당자별 완료율을 전원 0% 로 만들고 다 끝낸 달을 '계획 없음' 이라고 말합니다 | 3/1/S | 대기 | 2026-09-11 재확인: 이 트리(v0.295.0)의 scheduleGrid.byAssignee 는 여전히 (tasks, meId) 한 벌만 받고 emptyBoardText 가 없음 — 원장의 2026-09-10 1회차 PR 이 아직 머지되지 않음. 머지되면 done 으로, 아니면 창 전체(tasks)와 그릴 줄(visible)을 따로 들도록 고침 | 2026-09-11 |
| listScheduleTasks 에 상한이 없고 /api/v1/schedule 이 scale-check PATHS 에 없습니다 | 3/2/M | 대기 | 2026-09-11 재확인: 이 트리(main=v0.295.0)에 여전히 scheduleRowLimit 없음. 원장의 2026-09-09 2회차 PR 이 아직 머지되지 않았음. 착수 전에 존재부터 확인. 상한만 걸면 달력 뒤쪽이 잘려 '일정 없음' 과 구별되지 않으므로 요약의 창 전체 집계와 truncated 표시가 함께 가야 함 | 2026-09-11 |
| failstate-check 의 화면 목록이 손으로 관리돼 새 화면이 조용히 빠집니다 | 2/1/S | 대기 | a11y-check PAGES · failstate-check SCREENS · scale-check PATHS 세 곳이 서로를 모름. router.ts 의 pageNames 와 맞춰 보는 시험이 자리. 이번 회차의 guide-captures.py 도 화면 목록을 손으로 듦(네 번째) | 2026-09-11 |
| 월 격자의 하루 칸이 담는 줄 수에 상한이 없습니다 | 2/2/S | 대기 | tasksOnDay 가 전부 돌려주고 month-cell 이 모두 그림. 'n건 더' 로 접되 어디서 펴 볼지(주 보기로 보내기 / 칸 안에서 펴기) 정해야 함 | 2026-09-11 |
| 월 격자는 이웃 달의 며칠까지 조회하므로 요약 숫자가 '이 달' 보다 큽니다 | 2/2/S | 대기 | gridRange 가 8/30~10/3 을 보내고 요약은 그 창 전체를 셈. 회색 칸을 세는 것이 맞는지부터 정해야 함 | 2026-09-11 |
| analyticsOrganizations 의 제출 CTE 는 날짜 범위로, 기대건은 격자 주로 셉니다 | 2/2/S | 대기 | admin_analytics.go:205-237. 창 가장자리 한 주에 한정된 오차 | 2026-09-11 |
| 키워드 분석의 두 창(collectTerms)도 week_start BETWEEN 이라 전환 주가 옆 창으로 넘어갑니다 | 2/2/S | 대기 | 이전 기간 대비 증감이 한 주만큼 밀려 보일 수 있는지 확인 | 2026-09-11 |
| summarizeWorkItem 의 AgeWeeks·SilentWeeks 가 7일 등간격을 전제합니다 | 2/2/S | 대기 | workitems.go:382. 옮긴 폭과 빠진 주가 겹치면 침묵 주 수가 한 주 어긋남. 옳은 규칙부터 정해야 함 | 2026-09-11 |
| 겹침 규칙에서는 옛 격자의 보고서 한 건이 새 격자의 두 주를 면제합니다 | 2/2/M | 대기 | v0.290.0 의 weekIsOwed 겹침 성질. '가장 많이 겹치는 한 주' 규칙과 견줄 자리 | 2026-09-11 |
| 가이드 캡처가 CI 에서 다시 찍히지 않아 화면이 바뀌면 그림이 조용히 낡습니다 | 2/2/M | 대기 | release-check 또는 별도 워크플로에 씨 뿌린 배포 + guide-captures.py + md2pdf 를 붙이고, 캡처가 문서와 어긋나면(파일 없음/미사용) 실패하게. Playwright 경로가 지금은 Naviq 의 node_modules 를 빌려 씀 | 2026-09-11 |
| 상황판 담당자 선택 목록이 report-inclusions 를 재사용합니다 | 1/1/S | 대기 | 서브트리 밖·비활성 담당자의 줄을 열면 select 이 '본인' 을 보여 줌(표시만 틀림). withAssignee 가 있으니 '창이 든 담당자가 목록에 없으면 선택지를 하나 만든다' 가 자리 | 2026-09-11 |
| 업무 인사이트 캡처가 씨앗 데이터에 중복이 없어 빈 결과입니다 | 1/1/S | 대기 | seed-scale.sql 에 조직 간 유사 제목 한 쌍을 넣으면 '중복 의심' 이 채워짐. 단, 유사도 검사 비용을 다시 재야 함(씨앗 머리말의 교훈) | 2026-09-11 |
| issueoutcome.go 의 r.week_start < $2 가 전환 주에 같은 주 보고서를 이전 결과로 셉니다 | 1/2/S | 대기 | weekEndedBefore 로 바꿀 자리인지 확인 | 2026-09-11 |
| 캠페인 guides-2026-09: 사용자·관리자 가이드를 실제 화면 캡처가 든 완성본으로 | 4/1/M | 완료 | scripts/guide-captures.py 로 27장 캡처, 두 가이드를 표준 구성으로 다시 씀, PDF 는 공용 md2pdf.mjs. 커밋 8dd58e5 | 2026-09-11 |
원장 (에이전트가 남긴 기록)
2026-09-02
- 선택: 주 시작 요일 변경 후 이미 제출한 팀원에게 작성 권고 메일이 가는 버그 수정 (가치 4 / 위험 2 / 작업량 M)
- 결과: 성공 — PR https://github.com/hkjang/weekly/pull/1 (예산 $3 소진으로 에이전트가 원장을 못 남겨 러너가 대신 기록)
- 요약: queueTeamReminders/reminderStillWanted 가 week_start 정확일치로 묻던 것을 weekCoveringDays(기간 겹침)로 통일. 회귀 테스트 2개 추가. 저장소 루트에 잘못 들어온 middleware.go 사본 파일 삭제. WEEKLY_TEST_POSTGRES_DSN 으로 실제 DB 테스트 통과 확인.
- 보류 아이디어: (기록 전 예산 소진)
- 릴리즈: v0.281.0 (2026-09-02)
2026-09-02 (2회차)
- 선택: 주 격자가 옮겨진 전환 주에 작성 화면이 기존 보고서를 열지 못하는 버그 수정 (가치 4 / 위험 1 / 작업량 S)
- 결과: 성공
- 요약:
currentReport(GET /api/v1/reports/current)가week_start정확일치로만 찾아, 주 시작 요일 변경 후 전환 주에는 작성자의 보고서가 화면에서 사라지고 그 자리의 빈 편집기가 저장 때마다 409 REPORT_PERIOD_OVERLAPS 만 돌려줬습니다(weekIsFree 는 이미 기간 겹침으로 막고 있었으므로 두 화면이 서로 다른 규칙을 쓰던 셈). 조회를weekCoveringDays로 통일하고 회귀 테스트 1개(currentweekgrid_test.go, guards: currentReport/weekCoveringDays)를 추가했습니다. 검증: 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...통과,go vet, guard-check(1개 도달), mutation-check(전부 캐치), modal-close/version/openapi-check 통과, frontend lint·build·test(121개) 통과. 수정 전 코드에서 새 테스트가 실패하는 것도 확인했습니다. - 보류 아이디어:
- 격자 이동 후
runAutomaticCloneForUser의 원본 조회가week-7정확일치라 자동 복제가 한 주 조용히 건너뜁니다 (가치 3 / 위험 2 / 작업량 S) buildMailMessage의 From 표시이름이 순수 ASCII면 인코딩되지 않아,·<가 든 이름이 From 헤더를 깨뜨립니다 (가치 2 / 위험 1 / 작업량 S)currentIncludedMaterials도 같은 전환 주 문제를 갖는지 확인 (가치 2 / 위험 2 / 작업량 S)outlookForDueDate의 AT_RISK 문구가 low==high 일 때 최근 속도를 빼고 전체 평균만 말합니다 (가치 1 / 위험 1 / 작업량 S)
- 격자 이동 후
- 릴리즈: v0.282.0 (2026-09-02)
2026-09-02 (3회차)
- 선택: 주 격자가 옮겨진 전환 주에 포함한 팀원 주간보고가 “미작성”으로 보이는 버그 수정 (가치 4 / 위험 1 / 작업량 S)
- 결과: 성공
- 요약:
includedMaterialsFor가 팀원 보고서를report.week_start=$2::date정확일치로만 붙여, 주 시작 요일 변경 후 전환 주에는 이미 작성한(그리고 weekIsFree 때문에 새 날짜로 다시 쓸 수도 없는) 팀원이 보고서 없음으로 돌아왔습니다. PPTX 는 그것을 이름 옆 “주간보고 미작성 / 해당 주차 주간보고가 없습니다” 로 바꿔 경영 보고 자리에 올립니다. 조회를weekCoveringDays기준 LATERAL 조인(겹치는 것 중week_start DESC하나)으로 바꿔 currentReport·weekIsFree 와 규칙을 통일했고,currentIncludedMaterials와loadReport두 경로가 같은 함수를 쓰므로 한 번에 고쳐집니다. 회귀 테스트 1개(currentweekgrid_test.go, guards: includedMaterialsFor/weekCoveringDays)를 추가했고, 안 쓴 주가 다른 주 보고서로 채워지지 않는 것도 같이 확인합니다. 검증: 수정 전 코드에서 새 테스트가 실패하는 것을 확인 → 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과,go vet, guard-check(새 가드가 두 대상 모두 도달), modal-close/version/openapi-check 통과, frontend lint·build·test(121개) 통과. mutation-check 잔존 변이 4건은 모두 기존 권한 분기(294·333·334행)로 예산 초과로 건너뛴 기존 가드가 담당하며 이번 변경분이 아닙니다. backup-check 는 로컬에 psql 이 없어 건너뛰었습니다(CI 에서 실행). - 보류 아이디어:
- 격자 이동 후
runAutomaticCloneForUser의 원본 조회가week-7정확일치라 자동 복제가 한 주 조용히 건너뜁니다 (가치 3 / 위험 2 / 작업량 S) buildMailMessage의 From 표시이름이 순수 ASCII면 인코딩되지 않아,·<가 든 이름이 From 헤더를 깨뜨립니다 (가치 2 / 위험 1 / 작업량 S)meeting.go의 지난주 조회(AddDate(0,0,-7))도 같은 전환 주 정확일치 문제를 갖는지 확인 (가치 2 / 위험 2 / 작업량 S)outlookForDueDate의 AT_RISK 문구가 low==high 일 때 최근 속도를 빼고 전체 평균만 말합니다 (가치 1 / 위험 1 / 작업량 S)
- 격자 이동 후
- 릴리즈: v0.283.0 (2026-09-02)
2026-09-03
- 선택: 주 격자를 옮긴 다음 주에 지난주 자동 복제가 조용히 건너뛰던 버그 수정 (가치 3 / 위험 2 / 작업량 S)
- 결과: 성공
- 요약:
runAutomaticCloneForUser는 이번 주 충돌은 이미 날짜 겹침으로 묻고 있었는데 원본만week-7정확일치로 찾아, 주 시작 요일을 바꾼 다음 주에는 작성자가 이어 쓰던 전환 주 보고서(옛 격자 날짜)를 못 찾고 그 주를 processed 로 표시한 뒤 초안을 만들지 않았습니다. 원본 조회를weekCoveringDays겹침 +week_start DESC LIMIT 1로 바꿔 두 반쪽의 규칙을 통일했고, 회귀 테스트 1개(currentweekgrid_test.go, guards: runAutomaticCloneForUser/weekCoveringDays)를 더했습니다. 전환 주 자체에는 겹치는 보고서가 있으므로 여전히 복제하지 않는다는 것도 같은 테스트가 확인합니다. 관리자 안내서의 “정확히 한 주 전 보고서” 문장과 자동화 표를 제품에 맞게 고치고 HTML·PDF 를 다시 만들었습니다. 검증: 수정 전 코드에서 새 테스트가 실패하는 것을 확인 → 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과,go vet, guard-check 279개 도달, version·openapi·modal-close 검사 통과, frontend lint·build·test(121개) 통과. mutation-check 는 새 가드에서 잔존 변이 3건(287·304·330행)인데 모두 이번에 바꾸지 않은 “쓸 것이 없는” 분기(설정 꺼짐/이미 처리/커밋 생략)이고, 바꾼 조회 경로의 변이 3건은 모두 잡혔습니다. backup-check 는 로컬에 psql 이 없어 건너뛰었습니다(CI 에서 실행). - 보류 아이디어:
buildMailMessage의 From 표시이름이 순수 ASCII면 인코딩되지 않아,·<가 든 이름이 From 헤더를 깨뜨립니다 (가치 2 / 위험 1 / 작업량 S)- 전환 주에는
previousWeekPlan이week_start < target로 물어 작성자가 지금 쓰고 있는 그 보고서를 “지난주 계획” 으로 되돌려 줍니다 (가치 3 / 위험 2 / 작업량 S) meeting.go의 지난주 조회(weekBefore)도 같은 전환 주 정확일치 문제를 갖는지 확인 (가치 2 / 위험 2 / 작업량 S)outlookForDueDate의 AT_RISK 문구가 low==high 일 때 최근 속도를 빼고 전체 평균만 말합니다 (가치 1 / 위험 1 / 작업량 S)
- 릴리즈: v0.284.0 (2026-09-03)
2026-09-03 (2회차)
- 선택: 전환 주에
previousWeekPlan이 지금 쓰고 있는 보고서를 “지난주 계획”으로 되돌려 주던 버그 수정 (가치 3 / 위험 2 / 작업량 S) - 결과: 성공
- 요약: 작성 화면 옆 “지난주 계획” 패널이
week_start < target로 물어, 주 시작 요일을 바꾼 전환 주에는 작성자가 이어 쓰는 바로 그 보고서(옛 격자의 이른 날짜)를 지난주 계획으로 돌려줬습니다 — 눈앞의 업무가 자기 자신과 짝지어지고, 이미 100% 로 보고한 것까지 아직 남은 일로 다시 제안됩니다. 정작 한 주 전 계획은 한 줄 아래에 있어 닿지 않았습니다. “이전”을 날짜가 이른 것이 아니라 이번 주가 시작하기 전에 일곱 날이 끝난 것으로 바꾸고(weekCoveringDays의 나머지 반쪽인weekEndedBefore를weekstart.go에 추가), 회귀 테스트 1개(currentweekgrid_test.go, guards: previousWeekPlan/weekEndedBefore)를 더했습니다. 이 끝점에는 그동안 통합 테스트가 하나도 없었습니다. 검증: 수정 전 코드에서 새 테스트가 실패하는 것을 확인 → 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과,go vet, guard-check(두 대상 모두 도달), version·openapi·modal-close 검사 통과, frontend lint·build·test(121개, 두 시간대) 통과. mutation-check 는 바꾼 조회 경로의 변이를 모두 잡았고 잔존 1건은 이번에 건드리지 않은weekStart질의 인자 파싱의 400 분기(80행)입니다. backup-check 는 로컬에 psql 이 없어 건너뛰었습니다(CI 에서 실행). - 보류 아이디어:
buildMailMessage의 From 표시이름이 순수 ASCII면 인코딩되지 않아,·<가 든 이름이 From 헤더를 깨뜨립니다 (가치 2 / 위험 1 / 작업량 S)meeting.go의 지난주 조회(weekBefore)도 같은 전환 주 정확일치 문제를 갖는지 확인 (가치 2 / 위험 2 / 작업량 S)issueoutcome.go의r.week_start < $2도 전환 주에 같은 주 보고서를 “이전 결과”로 셈하는지 확인 (가치 2 / 위험 2 / 작업량 S)previousWeekPlan의weekStart질의 인자 파싱 400 분기에 가드가 없습니다 (가치 1 / 위험 1 / 작업량 S)outlookForDueDate의 AT_RISK 문구가 low==high 일 때 최근 속도를 빼고 전체 평균만 말합니다 (가치 1 / 위험 1 / 작업량 S)
- 릴리즈: v0.285.0 (2026-09-03)
2026-09-03 (3회차)
- 선택: 보내는 이름에 쉼표·꺾쇠가 들어가면 메일 From 헤더가 깨지던 버그 수정 (가치 3 / 위험 1 / 작업량 S)
- 결과: 성공
- 요약:
buildMailMessage는 보내는 이름(mail.from_name)을mime.BEncoding.Encode로 감싸고 있었는데, 그 함수는 순수 ASCII 를 그대로 돌려줍니다 — 옳은 동작이지만, 그래서 영문 이름은 관리자가 적은 그대로 From 에 실리고 RFC 5322 는 쉼표를 주소의 끝으로 읽습니다.Weekly, Inc.는 보낸사람이Weekly하나인 주소 목록이 되고, 꺾쇠가 든 이름은 자기 angle-addr 를 스스로 달아 진짜 보내는 주소를 두 번째 주소로 남깁니다. 한글 이름만 쓰던 배포에서는 전부 base64 안에 들어가 보이지 않던 결함입니다. 인코딩이 필요하면 지금처럼 인코딩하고, 아니면 RFC 5322 특수문자가 든 이름만 따옴표 문자열(\·"이스케이프)로 쓰는mailDisplayName을 더했고, 빈칸만 남은 설정 칸은 지운 것과 같게 다룹니다. 회귀 테스트 2개(mailsendername_test.go) — 이름 8종을 실제로net/mail로 다시 읽어 보낸사람이 한 명인지·주소가 그대로인지·이름이 그대로 도착하는지 봅니다. 검증: 수정 전 코드에서 새 테스트가 4가지 이름에 대해 실패하는 것을 확인 → 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과,go vet,gofmt, guard-check –changed(19개 모두 도달; 처음엔 빈 이름 가드가mailDisplayName에 닿지 않는다고 잡아 가드 목록을 바로잡았습니다), version·openapi·modal-close 검사 통과, frontend lint·build·test(121개) 통과. mutation-check –changed 잔존 변이 3건은 모두 이번에 건드리지 않은mailMessageID(166·172행)이고, 바꾼 경로의 변이는 모두 잡혔습니다. backup-check 는 로컬에 psql 이 없어 건너뛰었습니다(CI 에서 실행). 한 가지 사고: mutation-check 가 아직 돌고 있는 동안 커밋하는 바람에 그 순간 소스에 얹혀 있던 변이(mailMessageID166행의&&→||)가 커밋에 딸려 들어갔습니다. 발견 즉시 amend 로 걷어 내고go vet·go test를 다시 돌려 확인했습니다 — mutation-check 가 끝나기 전에는git add를 하지 말 것. - 보류 아이디어:
meeting.go의snapshotFor가 주차를 정확일치로 찾아, 격자를 옮긴 전환 주에는 회의 자료가 통째로 비어 보입니다 (가치 3 / 위험 3 / 작업량 M)issueoutcome.go의r.week_start < $2도 전환 주에 같은 주 보고서를 “이전 결과”로 셈하는지 확인 (가치 1 / 위험 2 / 작업량 S)previousWeekPlan의weekStart질의 인자 파싱 400 분기에 가드가 없습니다 (가치 1 / 위험 1 / 작업량 S)mailMessageID의 도메인 추출(@위치·randfail) 분기에 잔존 변이 3건이 있습니다 (가치 1 / 위험 1 / 작업량 S)outlookForDueDate의 AT_RISK 문구가 low==high 일 때 최근 속도를 빼고 전체 평균만 말합니다 (가치 1 / 위험 1 / 작업량 S)
- 릴리즈: v0.286.0 (2026-09-03)
2026-09-04
- 선택: 주 격자를 옮긴 전환 주에 분석 화면이 그 주의 보고서를 세지 못하던 버그 수정 (가치 3 / 위험 2 / 작업량 S)
- 결과: 성공
- 요약:
analyticsOverviewContext는 제출률·상태별 분포·미해결 이슈·평균 진행률을 모두week_start정확일치로 물었습니다. 주차 시작 요일을 바꾸면 격자만 옮겨지고 보고서는 그 자리에 남으므로, 전환되는 한 주 동안 팀이 이미 쓴 보고서는 같은 7일을 다른 날짜로 덮습니다 — 그래서 팀장의 분석 화면은 모두가 보고한 주를 제출률 0%, 빈 상태 분포, 이슈 0건, 진행률 0 으로 답했고weekIsFree때문에 누가 다시 써서 되살릴 수도 없었습니다. 같은 함수를 MCP 주간 요약도 읽으므로 화면 없이 숫자만 받는 AI 클라이언트에게는 이상함을 알아챌 자리조차 없었습니다. 세 질의를weekCoveringDays겹침으로 바꾸고 사람마다DISTINCT ON으로 한 건만 세도록 묶어, 한 화면의 네 숫자가 서로 다른 사람들을 설명하지 않게 했습니다. 회귀 테스트 1개(currentweekgrid_test.go, guards: analyticsOverviewContext/weekCoveringDays)를 더했고, 다른 조직 사람을 한 명 두어 날짜를 기간으로 넓히면서 보이는 사람까지 넓히지 않았는지도 봅니다. 검증: 수정 전 코드에서 새 테스트가 네 숫자 모두에서 실패하는 것을 확인 → 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과,go vet,gofmt, guard-check –changed(20개 도달), version·openapi·modal-close 검사 통과, frontend lint·build·test(121개) 통과. mutation-check –changed 의 첫 회차에서 이슈·진행률 질의의 조직 필터를 지우는 변이가 살아남아 그 다른 조직 사람을 시험에 더했고, 그 변이를 손으로 다시 넣어 이제 실패하는 것을 확인했습니다. 커밋 뒤 다시 돌린 mutation-check 에서는 바꾼 함수의 변이 6건이 모두 잡혔고(3건은 다른 시험이 잡는 기존 조직 분기), 잔존 변이 3건은 이번에 건드리지 않은runAutomaticCloneForUser(287·304·330행)입니다. backup-check 는 로컬에 psql 이 없어 건너뛰었습니다(CI 에서 실행). 커밋은 mutation-check 가 돌지 않는 동안에만 했습니다. - 보류 아이디어:
meeting.go의snapshotFor가 주차를 정확일치로 찾아, 격자를 옮긴 전환 주에는 회의 자료가 통째로 비어 보입니다 (가치 3 / 위험 3 / 작업량 M)analyticsParticipation(r.week_start BETWEEN)과weekIsOwed의 주별 격자도 전환 주를 미제출로 세는지 확인 (가치 3 / 위험 3 / 작업량 M)issueoutcome.go의r.week_start < $2도 전환 주에 같은 주 보고서를 “이전 결과”로 셈하는지 확인 (가치 1 / 위험 2 / 작업량 S)mailMessageID의 도메인 추출(@위치·randfail) 분기에 잔존 변이 3건이 있습니다 (가치 1 / 위험 1 / 작업량 S)outlookForDueDate의 AT_RISK 문구가 low==high 일 때 최근 속도를 빼고 전체 평균만 말합니다 (가치 1 / 위험 1 / 작업량 S)
- 릴리즈: v0.287.0 (2026-09-04)
2026-09-04 (2회차)
- 선택: 주 격자를 옮긴 전환 주에 회의 안건과 주간 변화 요약이 그 주의 보고서를 읽지 못하던 버그 수정 (가치 3 / 위험 2 / 작업량 M)
- 결과: 성공
- 요약:
snapshotFor는 스냅샷을WeekStart == week로 골랐고 지난주는weekBefore(week)정확일치였습니다. 요일을 바꾸면 격자만 옮겨지고 보고서는 그 자리에 남으므로, 전환 주의 회의 자료가 통째로 비었습니다 — “논의할 것이 없다” 가 아니라 업무 0건·인원 0명·이슈 0건, 팀 전원이 보고를 마친 주에 나오는 화면입니다. 그다음 주에는 반대로 비교 대상을 못 찾아 몇 달째 이어지던 업무가신규·재개로 올라왔습니다. 회의 모드와 주간 변화 요약이classifyWeeklyChange를 공유하므로 둘이 함께 틀렸습니다. SQL 쪽weekCoveringDays·weekEndedBefore와 같은 규칙을 Go 에서 묻는snapshotFor(겹침, 둘이면 늦은week_start)·snapshotPrior(바로 앞 7일에 끝난 것)로 바꾸고,신규판정의item.FirstWeek == week를== current.WeekStart로 고쳤습니다. 비교 창을 한 주로 묶은 이유는 “지난주에 없었다” 가재개판정의 근거이기 때문입니다 — 여기를 다 열면 다섯 주 전 업무가 평범한진척이 됩니다. 회귀 시험 2개(weeklychange_test.go8가지,meeting_test.go; guards: classifyWeeklyChange/snapshotFor/snapshotPrior, buildMeeting). 검증: 수정 전 코드에서 전환 주 2건·다음 주 2건이ABSENT·ABSENT·RESUMED·ABSENT로 실패하고 회의 안건은 0건인 것을 확인 → 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과,go vet,gofmt, guard-check(세 가드 모두 도달), version·openapi·modal-close 통과, frontend lint·build·test(121개) 통과. mutation-check 첫 회차에서snapshotFor·snapshotPrior의 겹침 동점 처리(늦은 것 고르기) 변이가 살아남아 격자가 뒤로 옮겨진 사례 2개를 더했고, 이제 두 함수의 변이 12건이 모두 잡힙니다.classifyWeeklyChange의 정체 경계 변이(StallWeeks는 넘어야 하는 수가 아니라 세는 수)는 아무 시험도 잡지 못했는데, 모든 분기를 이미 걸어 보던 기존TestClassifyWeeklyChange에 가드 표시가 없어 변이 검사가 세지 않고 있었습니다 — 표시를 달고 경계 사례를 하나 더해 닫았습니다. 커밋은 mutation-check 가 돌지 않는 동안에만 했습니다. backup-check 는 로컬에 psql 이 없어 건너뛰었습니다(CI 에서 실행). - 보류 아이디어:
analyticsParticipation(r.week_start BETWEEN)과weekIsOwed의 주별 격자도 전환 주를 미제출로 세는지 확인 (가치 3 / 위험 3 / 작업량 M)issueoutcome.go의r.week_start < $2도 전환 주에 같은 주 보고서를 “이전 결과”로 셈하는지 확인 (가치 1 / 위험 2 / 작업량 S)mailMessageID의 도메인 추출(@위치·randfail) 분기에 잔존 변이 3건이 있습니다 (가치 1 / 위험 1 / 작업량 S)summarizeWorkItem의AgeWeeks·SilentWeeks도 7일 등간격을 전제하므로 격자를 옮긴 주가 한 주 더 세지는지 확인 (가치 2 / 위험 2 / 작업량 S)outlookForDueDate의 AT_RISK 문구가 low==high 일 때 최근 속도를 빼고 전체 평균만 말합니다 (가치 1 / 위험 1 / 작업량 S)
- 릴리즈: v0.289.0 (2026-09-04)
- 릴리즈: v0.289.0 (2026-09-04)
2026-09-07
- 선택: 주 격자를 옮겨도 참여 분석이 이미 낸 보고서를 세도록 고침 (가치 4 / 위험 2 / 작업량 M)
- 결과: 성공
- 요약:
analyticsParticipation의 두 반쪽이 모두week_start정확일치였습니다. 제출률 추이는 보고서를 자기week_start로 묶고 화면은 그 행을 격자에서 찾으므로, 주차 시작 요일을 바꾼 뒤에는 그 전에 쓰인 어떤 보고서도 어느 행에도 실리지 않습니다 — 지금까지 고쳐 온 일곱 자리와 달리 전환 주 하나가 아니라 창에 담긴 12주 전부가, 매주 보고한 팀에게 제출률 0% 로 보입니다. 미제출자 명단은 같은 질문을 뒤집은 것(NOT EXISTS ... week_start=week.day)이라 같은 답을 냈습니다: 전원이, 자기가 보고한 모든 주에 대해 밀린 사람으로 이름이 오르고 그 명단은 독촉의 근거가 됩니다. 전환 주는weekIsFree가 두 번째 보고서를 막으니 다시 써서 지울 수도 없는 미제출이었습니다. 추세를generate_series격자에서 만들고 각 행이 그 7일을 덮는 보고서를 세도록weekCoveringDaysOf(placeholder 대신 날짜 식을 받는weekCoveringDays의 형제)로 바꾸되, 옮긴 격자의 한 주가 옛 격자의 두 주와 겹치므로 사람마다DISTINCT ON으로 한 건만 골라 제출률이 100% 를 넘지 않게 했습니다.weekIsOwed의NOT EXISTS도 같은 겹침으로 바꿔 미제출 판정이weekIsFree의 거절과 같은 말을 합니다. 정시·지각은 보고서 자신의 주차 마감으로 재는 지금이 옳다고 정하고(작성자가 실제로 지켜야 했던 마감) 관리자 안내서에 그렇게 적었습니다. 검증: 수정 전 코드에서 새 시험이 세 주의 제출 건수·미제출자 명단·미제출자 수 다섯 곳에서 실패하는 것을 확인 → 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과(138s),go vet,gofmt, guard-check –changed(28개 도달, 새 가드는 analyticsParticipation 71%/weekCoveringDaysOf 100%), version·openapi·modal-close 검사 통과, frontend lint·build·test(121개) 통과. mutation-check –changed 는 MUTATION_RESULT. backup-check 는 로컬에 psql 이 없어 건너뛰었습니다(CI 에서 실행). 커밋은 mutation-check 가 돌지 않는 동안에만 했습니다. v0.290.0 으로 냈습니다(아홉 곳 버전, 릴리즈 본문, 로드맵 기록, 관리자 안내서 문단과 세 안내서 생성물). -
보류 아이디어: analyticsOrganizations 의 제출 CTE 는 날짜 범위, 기대건은 격자 주라 창 가장자리에서 어긋납니다 (2/2/S) · 키워드 분석의 두 창(collectTerms)도
week_start BETWEEN이라 전환 주가 옆 창으로 넘어갑니다 (2/2/S) ·summarizeWorkItem의 AgeWeeks·SilentWeeks 가 7일 등간격을 전제합니다 (2/2/S) · MCPweekly_reports_search의 weekStart 필터가 정확일치라 같은 응답 안의weekly_submission_overview와 다른 답을 합니다 (2/2/S) · 겹침 규칙에서는 옛 격자의 보고서 한 건이 새 격자의 두 주를 면제하므로 ‘가장 많이 겹치는 한 주’ 규칙과 견줄 자리가 남습니다 (2/2/M) - 릴리즈: v0.290.0 (2026-09-07, run 2026-09-07-091911-weekly-release)
2026-09-08
- 선택: 주 격자를 옮긴 주에 MCP 보고서 검색이 그 주의 보고서를 찾지 못하던 버그 수정 (가치 3 / 위험 2 / 작업량 S)
- 결과: 성공
- 요약:
weekly_reports_search의weekStart필터만 아직r.week_start정확일치로 남아 있었습니다(mcp.go:524). 주차 시작 요일을 바꾸면 격자만 옮겨지고 보고서는 그 자리에 남으므로 전환되는 한 주에 대해 이 도구는 빈 목록을 돌려줬고, 같은 도구 묶음의weekly_submission_overview는 v0.287.0 부터 겹침으로 세므로 AI 클라이언트가 한 응답 안에서 “이 주에 1명이 제출했습니다” 를 듣고 그 주의 보고서를 물어 아무것도 받지 못하는 자기모순이 났습니다 — 어느 쪽이 틀렸는지 가릴 단서가 payload 에 없고, 모델이 시도할 만한 복구(없는 보고서 채워 넣기)는weekIsFree가 거절합니다. 필터를weekCoveringDays겹침으로 바꿨고(세는 질의와 읽는 질의가 같은where를 쓰므로total도 목록과 같은 질문에 답합니다), 도구 스키마의weekStart설명과 docs/MCP.md 한 문단에 그 규칙을 적었습니다. 회귀 시험 1개(currentweekgrid_test.go, guards: mcpSearchReports/weekCoveringDays)는 두 도구를 나란히 불러 제출 인원과 검색 결과가 같은 주를 말하는지 보고, 아무도 쓰지 않은 다음 주가 여전히 비어 있는지도 봅니다. 그 과정에서 기존TestMCPSearchReturnsOnlyTheCallersOwnOrganisation이 인자를weekStart가 아니라week로 보내 주차 필터를 한 번도 걸어 보지 않았다는 것이 드러나 이름을 바로잡았습니다. 검증: 수정 전 질의로 되돌려 새 시험이 실패(이 주의 보고 [])하는 것을 확인 → 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과(141s),go vet,gofmt, guard-check –changed(40개 모두 도달, 새 가드는 mcpSearchReports 76%/weekCoveringDays 100%), openapi·modal-close·version·paging 검사 통과. mutation-check –test 는 6건 중 5건을 새 시험이 잡았고 남은 1건(515행 조직 범위 분기!=→==)은 다른 시험이 잡아 exit 0 입니다. 프런트엔드는 손대지 않아 lint·build·test 는 돌리지 않았고, backup-check 는 로컬에 psql 이 없어 건너뛰었습니다(CI 에서 실행). 커밋은 mutation-check 가 돌지 않는 동안에만 했습니다. - 보류 아이디어: analyticsOrganizations 의 제출 CTE 는 날짜 범위, 기대건은 격자 주라 창 가장자리에서 어긋납니다 (2/2/S) · 상황판 편집이 workItemId 를 담지 않아 업무 링크를 조용히 끊습니다 (2/1/S) · listScheduleTasks 에 상한이 없어 최대 366일 × 부서 전원이 한 응답에 실립니다 (3/2/M) · 상황판 담당자 선택 목록이 report-inclusions 를 재사용해 그 밖의 담당자를 본인으로 보여 줍니다 (2/1/S) · 키워드 분석의 두 창(collectTerms)도
week_start BETWEEN이라 전환 주가 옆 창으로 넘어갑니다 (2/2/S)
2026-09-09
- 선택: 상황판을 읽지 못한 것을 “이번 달 계획 없음” 으로 그리던 버그 수정 (가치 3 / 위험 1 / 작업량 S)
- 결과: 성공
- 요약: 업무 상황판의 네 보기가
board없이도 그려졌습니다 — 첫 읽기가 실패하면 벽에 42칸짜리 빈 달력이 걸리고 목록·담당자 보기는 “이 기간에 등록된 업무 일정이 없습니다”, 주 보기는 일곱 칸 모두 “일정 없음” 이라고 말합니다. 이 판은 사무실 벽에 거는 것이라 지나가며 보는 사람에게 그것은 부서가 이번 달에 아무것도 계획하지 않았다는 문장이고, 의심할 자리가 없습니다. 더 나쁜 것은 창을 옮기다 실패했을 때로, 실패가 앞의 판을 그대로 두므로 다음 달로 넘어가다 실패하면 지난달 줄이 이번 달 제목 아래 남고부서 전체를 끄다 실패하면 남의 줄이 본인 것으로 남습니다 — 오래된 것이 아니라 화면이 묻지 않은 질문에 답하는 것입니다.scheduleGrid.ts에boardAfterFailure(창 from·to·scope 가 다르면 버리고, 같으면 벽에 걸린 것을 지킨다 — 전체화면은 1분마다 다시 읽으므로 한 번 실패에 벽을 비우는 것은 1분 된 판보다 나쁩니다)를 더하고, 네 보기를 읽힌 판에만 그리게 했습니다.failstate-check.py의 화면 목록에도schedule을 더했습니다 —a11y-check.py의 PAGES 에는 있었는데 이쪽에는 빠져 있어, 새 화면이 검사에서 조용히 사라져 있었습니다. 검증: 수정 전 코드에서 새 시험(SchedulePage.test.tsx)이month-cell42칸을 그리며 실패하는 것을 확인 → frontend lint(tsc -b)·build·test 141개가 두 시간대(Asia/Seoul, America/New_York) 모두 통과(새 시험 7개: 순수 함수 4 + 화면 3), 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과(132.9s),go vet ./..., paging·modal-close·openapi·version 검사 통과. Go 는 손대지 않아 guard-check·mutation-check 는 돌리지 않았고(대상 변경 없음), failstate-check 자체는 배포와 브라우저가 필요해 이 세션에서 실행하지 못했습니다(CI·수동 점검에서 실행). 빌드 산출물(frontend/dist,node_modules)은.gitignore에 있어 커밋에 들어가지 않았습니다. -
보류 아이디어: listScheduleTasks 에 상한이 없고
/api/v1/schedule이 scale-check 목록에도 없습니다 (3/2/M) · failstate-check 의 화면 목록이 손으로 관리돼 새 화면이 조용히 빠집니다 (2/1/S) · 월 격자가 이웃 달 며칠까지 조회해 요약 숫자가 “이 달” 보다 큽니다 (2/2/S) · 상황판 편집이 workItemId 를 담지 않아 업무 링크를 조용히 끊습니다 (2/1/S) - 릴리즈: v0.294.0 (2026-09-09, run 2026-09-09-030109-weekly-improve)
2026-09-09
- 선택: 상황판 한 번 읽기에 상한을 걸고, 요약이 돌려준 행이 아니라 기간 전체를 세게 함 (가치 3 / 위험 2 / 작업량 M)
- 결과: 성공
- 요약:
listScheduleTasks에는 상한이 없었습니다 — 기간은 최대 366일, 범위는 부서 서브트리 전체이고 관리자의 TEAM 은 전 조직입니다. 그 한 응답을 요청하는 화면은 전체화면일 때 1분마다 스스로 다시 읽습니다. 상한만 거는 것은 없느니만 못했을 자리입니다: 달력은 순위를 매길 수 없으므로 잘리는 쪽이 기간의 뒤쪽이고, 그러면 그 달의 마지막 며칠이 그냥 줄 없는 날이 되어 “그 주에는 일정이 없다” 와 구별되지 않습니다. 그리고 상단 요약은 돌려준 행을 Go 에서 세고 있었으므로, 잘린 순간 지연·오늘·긴급이 모두 0 이 됩니다 — 벽에 걸린 판이 “지연 없음, 긴급 없음” 이라고 말하는 것이 정확히 이 기능이 막으려던 문장입니다. 그래서 세 가지를 함께 했습니다:scheduleRowLimit(2000) 상한, 요약을 창 전체에 대한 집계 질의(scheduleBoardSummary,count(*) FILTER로 완료·지연·오늘·긴급·인원을 기존 분기와 같은 순서로)로 옮기기, 그리고 잘렸을 때truncated·limit으로 응답이 말하고 화면이 “전체 n건 가운데 앞의 m건만 그렸습니다 · 기간을 좁혀 보십시오” 를 띄우기. 완료율도 화면의 줄이 아니라 요약에서 재도록donePercent로 옮겨, 상단 여섯 숫자가 모두 같은 창의 같은 집계에서 나오게 했습니다. 겸해서/api/v1/schedule을scale-check.py의 조회 경로에 더했습니다 — 부서와 기간 양쪽으로 자라는 유일한 읽기가 규모 검사에서 통째로 빠져 있었습니다. 상황판은 팀원도scope=TEAM으로 읽는 공유 계획이므로reachable()의scope=TEAM예외에 걸리지 않도록SHARED_TEAM을 두어, 가장 자주 여는 역할에서도 재게 했습니다. 검증: 수정 전 동작(요약을 페이지에서 세기)을 되돌려 새 시험이overdue:0 today:0 urgent:0 people:1 total:2000으로 실패하는 것을 확인 → 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과(129.9s),go vet,gofmt, guard-check –changed(19개 모두 도달, 새 가드는scheduleBoardSummary100% /listScheduleTasks63%), openapi·modal-close·paging·version 검사 통과, frontend lint(tsc -b)·build·test 145개 통과(새 시험 4개). mutation-check 는--test로 새 가드 시험만 돌렸고 MUTATION_RESULT. 커밋은 mutation-check 가 끝난 뒤에 했습니다. backup-check 는 로컬에 psql 이 없어 건너뛰었습니다(CI 에서 실행). 빌드 산출물(frontend/dist,node_modules)은.gitignore에 있어 커밋에 들어가지 않았습니다. - 보류 아이디어:
/api/v1/schedule이 authz-check 의 권한 스윕에도 빠져 있습니다 — 읽기 범위를 일부러 넓힌 유일한 화면입니다 (3/1/S) · 완료 숨기기를 켜면 담당자별 완료율이 전원 0% 로 그려집니다 (2/1/S) · 월 격자의 하루 칸이 담는 줄 수에 상한이 없어 한 날에 몰리면 나머지 칸을 밀어냅니다 (2/2/S) · 상황판 편집이 workItemId 를 담지 않아 업무 링크를 조용히 끊습니다 (2/1/S) · 월 격자가 이웃 달 며칠까지 조회해 요약 숫자가 “이 달” 보다 큽니다 (2/2/S)
2026-09-10
- 선택: 완료 숨기기가 상황판에 시키던 거짓말 두 가지 수정 (가치 3 / 위험 1 / 작업량 S)
- 결과: 성공
- 요약: 담당자 보기는
byAssignee(tasks, …)에 이미 걸러진 목록을 넘기고doneRatio(lane.tasks)로 완료율을 냈습니다 —완료 숨기기를 켜면 레인에 완료 줄이 하나도 남지 않으므로 모든 사람이 언제나0/n · 0%, 막대는 0 이었습니다. 끝낸 일을 감췄더니 아무도 아무것도 끝내지 못한 것으로 그려지는 것이고, 벽에 걸린 판이 사람 이름 옆에서 하는 말이라 더 나쁩니다. 같은 필터가 만들던 두 번째 거짓말도 함께 고쳤습니다: 그 기간의 일을 모두 끝내면 목록·담당자 보기가이 기간에 등록된 업무 일정이 없습니다, 주 보기의 각 칸이일정 없음이라고 말했습니다 — 계획이 없는 달과 계획을 다 끝낸 달은 정반대인데 같은 문장이었고, 그것은 v0.294.0 이 “읽지 못한 것을 ‘계획 없음’ 으로 그리지 않는다” 로 막은 바로 그 문장입니다.byAssignee가 사람의 창 전체(tasks)와 그릴 줄(visible)을 따로 들도록 바꿔 막대와n/m은 창 전체로 재고 줄만 걸렀으며, 다 끝낸 사람의 레인은0%로 남기지 않고 판에서 내립니다(그것이완료 숨기기가 하겠다고 한 일입니다). 비어 있는 이유는emptyBoardText·emptyDayText가모두 완료와없습니다로 구분합니다. 검증: 이전 동작(걸러진 목록으로 레인을 만들고 빈 화면은 늘 ‘없습니다’)을 되돌려 새 시험 2개가[2] ≠ [1,2]·0% ≠ 50%·'없습니다' 에 '모두 완료' 없음으로 실패하는 것을 확인 → frontend lint(tsc -b)·build·test 144개가 두 시간대(Asia/Seoul, America/New_York) 모두 통과(새 시험 3개), 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과,go vet ./..., modal-close·paging·openapi·version 검사 통과. Go 는 손대지 않아 guard-check·mutation-check 는 돌리지 않았고(대상 변경 없음), a11y·failstate 검사는 배포와 브라우저가 필요해 이 세션에서 실행하지 못했습니다(CI·수동 점검에서 실행). 사용자 안내서의 상황판 절에 “감추는 것은 줄뿐” 한 줄을 더하고 HTML·PDF 를 다시 생성했습니다. 빌드 산출물(frontend/dist,node_modules)은.gitignore에 있어 커밋에 들어가지 않았습니다. - 보류 아이디어:
updateScheduleTask에 시험이 하나도 없습니다 — 쓰기 넷 중 전체 치환 계약을 가진 하나만 비어 있습니다 (3/1/S) · 상황판 편집이workItemId를 담지 않아 업무 링크를 조용히 끊습니다 (2/1/S) ·listScheduleTasks에 상한이 없고/api/v1/schedule이 scale-check PATHS 에 없습니다 — 원장의 2026-09-09 2회차 작업이 이 체크아웃(main=v0.294.0)에는 없으니 착수 전에scheduleRowLimit존재부터 확인 (3/2/M) · 월 격자의 하루 칸이 담는 줄 수에 상한이 없어 한 날에 몰리면 나머지 칸을 밀어냅니다 (2/2/S) · 월 격자가 이웃 달 며칠까지 조회해 요약 숫자가 ‘이 달’ 보다 큽니다 (2/2/S) · [기각]/api/v1/schedule이 authz-check 스윕에 빠졌다는 지난 회차 메모는 전제가 틀렸습니다 — authz-check.py 에는 경로 목록이 없고internal/app/*.go의 403 거부를 전부 자동으로 훑습니다
2026-09-10
- 선택: 상황판 편집이 업무 링크를 조용히 끊던 결함과, 시험이 하나도 없던 updateScheduleTask (가치 3 / 위험 1 / 작업량 S)
- 결과: 성공
- 요약: 상황판의 수정은 PUT 이고 PUT 은 줄 전체를 보낸 것으로 갈아 끼우는데, 편집 창은 읽어 온 줄에서
workItemId를 담지 않았고 저장도 보내지 않았습니다 — 제목의 오타 하나를 고치면 그 줄이 가리키던 업무가 사라졌고, 링크는 어느 보기에도 그려지지 않으므로 고치는 사람에게는 단서조차 없고 판은 고치기 전과 똑같아 보입니다. 창이 값을 들고 다니게 해 고치지 않은 것은 고쳐지지 않게 했고, 담당자를 바꿀 때만 링크를 함께 내려놓습니다(링크는 담당자 본인의 업무만 가리킬 수 있어 서버가WORK_ITEM_NOT_OWNED로 거절하므로, 보이지도 않는 값 때문에 저장이 실패하는 것보다 넘길 때 놓는 쪽이 낫습니다). 편집 창이 드는 줄(ScheduleDraft)과 저장이 보내는 것(scheduleBody·draftOf·withAssignee)을scheduleGrid의 순수 함수로 옮겨 시험이 직접 물을 수 있게 했습니다. 겸해서 쓰기 넷 가운데 유일하게 시험이 없던updateScheduleTask에 가드 시험 2개(scheduleedit_test.go)를 더해 두 계약을 적었습니다: 보낸 것은 남고 보내지 않은 것은 지워진다(업무 링크 포함, 남의 업무·없는 업무는 400), 그리고 체크할 수 있는 사람만 고쳐 쓰되 조직 범위로 재는 것은 ‘옮기는 것’ 뿐이다 — 등록한 사람은 그 줄이 남에게 넘어간 뒤에도 고칠 수 있습니다. openapi 의 PUT 에도 전체 치환 계약을 적었습니다. 검증: 프런트는 이전 동작(창이 링크를 담지 않음)으로 되돌려 새 시험 3개가 모두 실패하는 것을 확인했고, Go 는 UPDATE 의input.WorkItemID를 nil 로 바꾼 변이가 실패하는 것을 확인 → 실제 DB(WEEKLY_TEST_POSTGRES_DSN)로go test ./...전체 통과(132.7s),go vet,gofmt, guard-check –changed(22개 모두 도달, 새 가드는 updateScheduleTask 71% / scheduleWorkItemAllowed 79% / authorizeScheduleTask 67%), openapi·modal-close·paging·version 검사 통과, frontend lint(tsc -b)·build·test 144개가 두 시간대(Asia/Seoul, America/New_York) 모두 통과(새 시험 3개). mutation-check –test 는 첫 회차에서assignee != owner && assignee != p.ID의&&→||변이가 아무 시험에도 잡히지 않아, ‘등록한 사람이 넘어간 줄을 고친다’ 사례를 두 번째 시험에 더해 닫았습니다 — 지금은 두 시험 26건이 모두 잡히고 exit 0 입니다. 커밋은 mutation-check 가 끝난 뒤에 했습니다. backup-check 는 로컬에 psql 이 없어 건너뛰었고(CI 에서 실행), a11y·failstate 검사는 배포와 브라우저가 필요해 이 세션에서 실행하지 못했습니다. 빌드 산출물(frontend/dist,node_modules)은.gitignore에 있어 커밋에 들어가지 않았습니다. -
보류 아이디어:
listScheduleTasks에 상한이 없고/api/v1/schedule이 scale-check PATHS 에 없습니다 — 이 체크아웃(main=v0.294.0)에 아직scheduleRowLimit이 없으니 착수 전에 존재부터 확인 (3/2/M) · 완료 숨기기를 켜면 담당자별 완료율이 전원 0% 로 그려지고, 다 끝낸 달이 ‘계획 없음’ 과 같은 문장을 씁니다 — 원장의 2026-09-10 1회차 작업이 이 트리에 없습니다 (3/1/S) · 월 격자의 하루 칸이 담는 줄 수에 상한이 없어 한 날에 몰리면 나머지 칸을 밀어냅니다 (2/2/S) · 월 격자가 이웃 달 며칠까지 조회해 요약 숫자가 ‘이 달’ 보다 큽니다 (2/2/S) · failstate-check·a11y-check·scale-check 의 화면 목록 세 개가 손으로 관리돼 서로를 모릅니다 (2/1/S) - 릴리즈: v0.295.0 (2026-09-10, run 2026-09-10-160122-weekly-improve)
2026-09-11
- 선택: 캠페인 guides-2026-09 — 사용자·관리자 가이드를 실제 화면 캡처가 든 완성본으로 다시 씀 (가치 4 / 위험 1 / 작업량 M)
- 결과: 성공
- 요약: 두 가이드는 있었지만 그림이 한 장도 없었고 구성도 GUIDE-STANDARD.md 순서가 아니었습니다. 릴리즈 이미지와 같은 내용물(alpine + 정적 바이너리)을
docker run으로 띄우고seed-scale.sql을 넣은 뒤, 새scripts/guide-captures.py(a11y-check 와 같은 Playwright 래퍼)가 팀원 u1·팀장 u225·관리자로 로그인해 headless Chrome 1440×900 으로 27장을 찍어docs/assets/guide/에 놓았습니다 — 상황판은 팀장이 API 로 7줄을 만들어 빈 달력을 피하고 끝나면 지우며, 대상·계정은WEEKLY_GUIDE_*전용 변수로만 받고 루프백이 아니면 멈추고, 전역 설정은 읽기만 합니다. 캡처에 제품 UI 의 예시 이메일(hkjang@koreacb.com)이 찍혀 그 문자열을 AdminPage·README·CONFLUENCE.md 에서hong@example.com으로 바꾸고 다시 빌드해 찍었습니다. USER_GUIDE.md 는 처음 5분 → 화면별(14개 화면, 20장) → 자주 하는 작업(기존 문단 이관) → 막혔을 때(코드의 실제 문구 17개) → 용어로, ADMIN_GUIDE.md 는 구성 요소 → 설치(docker load → compose → readyz) → 설정(config.go 의 환경 변수 5개 전수 표 + 관리자 화면 카드 10개) → 계정과 권한 → 운영 → 장애 대응(로그 문구 그대로) → 보안으로 다시 썼고, 문서에 적은 API 11개는 app.go 에서 메서드까지 확인했습니다. 옛 문서가 주장하던 “관리자 전체 키 즉시 폐기” 는 라우트가 없어 뺐고(사용자 개인 설정의모든 키 회전으로 고침), 원장에는 있으나 이 트리에는 없는 상황판 잘림 안내도 싣지 않았습니다. PDF 는 공용md2pdf.mjs로 굽고(26·17쪽, 표지·표·그림 확인),render-docs.py는 두 가이드에 대해 그림을 지원하는 HTML 만 만들고 PDF 는 건너뛰게 해 정본이 둘이 되지 않게 했습니다. 검증: version-check 통과(아홉 곳 0.295.0), frontend lint(tsc -b) 통과, checksdoc 시험 통과, 27장이 모두 문서에 쓰임, 스크립트에 비밀번호 글자 없음, 빌드 산출물(dist/,cmd/weekly/web/index.html)은 커밋에서 뺐습니다. 캡처용 postgres·앱 컨테이너와 네트워크는 끝나고 지웠습니다. -
보류 아이디어: 월 격자의 하루 칸이 담는 줄 수에 상한이 없어 한 날에 몰리면 나머지 칸을 밀어냅니다 (2/2/S) · 월 격자가 이웃 달 며칠까지 조회해 요약 숫자가 ‘이 달’ 보다 큽니다 (2/2/S) · failstate-check·a11y-check·scale-check 의 화면 목록 세 개가 손으로 관리돼 서로를 모릅니다 (2/1/S) · 가이드 캡처가 CI 에서 다시 찍히지 않아 화면이 바뀌면 그림이 조용히 낡습니다 — release-check 에 guide-captures 를 붙일 자리 (2/2/M) · 업무 인사이트 캡처가 씨앗 데이터에 중복이 없어 빈 결과입니다 — seed-scale 에 조직 간 유사 제목 한 쌍을 넣으면 채워집니다 (1/1/S)
- 릴리즈: v0.296.0 (2026-09-11, run 2026-09-11-091112-weekly-improve)