Files
Gnuboard7/tests/scenarios/core-gc-schedules.yaml
HeuJung febffb173e fix(core,admin-template): GC 스케줄 허용목록 동기 + 스토리지 잔존물 GC 신설 + 스케줄 모달 저장 회귀 수정
공개 후속 전수 조사의 실작업:
- attachments:prune-orphans 관리자 예약 허용목록 등재 + 가드 테스트 도출 규칙을
 런타임 validator 와 일치 (옵션 포함 키는 영원히 매칭되지 않는 죽은 항목)
- layout-previews:cleanup 을 gc-schedules 가드 구간으로 편입 (+onOneServer)
- storage:prune-leftovers 신설: 중단된 업데이트/설치의 _pending 스테이징·코어 임시·
 vendor 스테이징(3일)과 오래된 백업(30일, 최신 1개 상시 보존), 레거시 browser.log 회수
 — 산출물 누적 + 회수 경로 부재( 동형) 7건 해소
- 언어팩 설치 임시 디렉토리 정리를 finally 로 이동 (설치 성공 시 100% 누수)
- 브라우저 콘솔 로그를 daily(7일) 로테이션으로 전환 (단일 파일 989MB 실측)
- 검수 중 발견한 스케줄 등록/수정 모달 저장 불능 수정 (Form id 부재 + 커스텀
 Select/Toggle 값 미전송) + 동형 재발 차단 audit 룰 2종 신설
2026-08-17 15:17:20 +09:00

111 lines
5.4 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# audit:allow test-scenario-coverage reason: |
# cross product 자동 전개는 audit 실행 환경의 fallback YAML 파서가 nested axes 를 읽지 못해
# 검출되지 않는다(다른 시나리오와 동일 한계). 축 조합은 PHPUnit Feature 테스트
# (CoreScheduleRegistrationTest · DataRetentionCommandsTest)와 모듈 커맨드 테스트가
# 커버하고 green 이다.
feature: 만료 데이터 자동 정리 예약과 예약 시각 기준 (공개이슈 #110)
description: |
수명이 지난 데이터를 정리하는 예약 작업을 등록하고, 예약의 실행 시각 해석 기준을
사이트 설정 시간대로 통일한다.
배경:
- 만료 토큰 정리 커맨드는 있었지만 어디에도 예약되지 않아 행이 영구 누적됐다.
- 정리 코드는 있는데 호출자가 0건인 대상(임시 주문·SEO 통계·예약 이력·본인인증
challenge)이 있었고, 보존 정책이 아예 없는 대상(본인인증 이력·활동 로그·알림
발송 이력)도 있었다.
- `app.timezone` 이 UTC 이고 예약에 시간대 지정이 없어, '새벽 4시' 로 등록해도
한국 기준 낮에 실행됐다. 관리자가 화면에서 등록한 cron 도 같은 결함을 가졌다.
- 이 축의 회귀 테스트가 0건이라 결함군이 무가드로 통과됐다.
적용 지점:
- `routes/console.php` 의 만료 데이터 정리 구획 (일 1회 새벽 배치 + 시간별 1건).
- 신설 코어 커맨드 6종 + 이커머스 모듈 커맨드 1종.
- 시각 기준: 설정 반영부가 `app.schedule_timezone` 을 세팅해 Schedule 인스턴스
전체에 일괄 적용 (이벤트별 지정 방식은 누락이 생겨 채택하지 않음).
- 관리자 등록 예약: 다음 실행 시각 계산도 같은 기준.
axes:
target:
- sanctum_tokens
- password_reset_tokens
- failed_jobs
- job_batches
- notifications
- extension_bundles
- seo_cache_stats
- schedule_histories
- identity_challenges
- identity_logs
- activity_logs
- notification_logs
- ecommerce_temp_orders
row_age: [within_retention, beyond_retention]
schedule_axis: [code_registered, admin_registered]
timezone_setting: [configured, empty]
# 스토리지 잔존물 GC (#120 후속 — storage:prune-leftovers): 대상군 × dry-run × 보존 가드
leftover_target:
- update_staging
- core_temp
- vendor_bundle_staging
- extension_backups
- core_backups
- legacy_browser_log
leftover_mode: [real_delete, dry_run]
leftover_guard: [aged_out, fresh_kept, latest_backup_kept, normal_pending_untouched, idempotent_second_run]
exclusions:
- { target: identity_challenges, row_age: beyond_retention, reason: "상태 전환만 수행하며 삭제하지 않음 — 만료 여부는 expires_at 이 판정" }
- { schedule_axis: admin_registered, target: sanctum_tokens, reason: "관리자 등록 축은 시각 기준만 검증 (대상별 동작은 코드 예약 축이 커버)" }
effects:
- all_gc_commands_are_registered_in_schedule
- gc_commands_run_on_one_server_only
- sanctum_prune_uses_hours_option
- rows_beyond_retention_are_deleted
- rows_within_retention_are_kept
- identity_challenges_transition_without_deletion
- schedule_timezone_follows_site_general_timezone
- schedule_timezone_falls_back_to_app_timezone_when_unset
- app_timezone_stays_utc
- admin_registered_schedule_next_run_uses_same_basis
- new_commands_are_in_schedule_security_allowlist
- new_commands_are_exposed_in_dev_dashboard
- automated_prune_emits_its_own_hooks
- retention_floor_is_owned_by_the_domain_layer
- large_purge_is_split_into_batches
# 스토리지 잔존물 GC (#120 후속)
- aged_leftovers_are_pruned_after_retention
- fresh_leftovers_are_kept
- latest_backup_is_always_kept
- normal_pending_extension_dirs_are_untouched
- dry_run_deletes_nothing
- leftover_prune_is_idempotent
- legacy_browser_log_is_removed
- browser_logs_rotate_daily_with_finite_retention
- successful_install_leaves_no_temp_directory
# E2E axis 없음 (스토리지 잔존물 GC): 브라우저 표면은 dev-dashboard 의 실행 버튼뿐이고
# blade 는 frontend-change-requires-e2e 룰 대상 경로가 아니다. 판정(패턴 매칭·mtime·
# 보존 가드)은 전부 서버측 파일시스템 연산이라 서버측 단위 테스트가 같은 것을 더 촘촘히
# 고정한다. 대시보드 버튼 노출 자체는 CoreScheduleRegistrationTest 가 소스 대조로 단언한다.
test_files:
- tests/Feature/Console/CoreScheduleRegistrationTest.php
- tests/Feature/Console/DataRetentionCommandsTest.php
- tests/Unit/Repositories/DeletesInBatchesTest.php
- tests/Unit/Services/StorageLeftoverPruneServiceTest.php
- tests/Feature/DevTools/BrowserLogRotationTest.php
- tests/Unit/Services/LanguagePack/LanguagePackServiceTest.php
- modules/_bundled/sirsoft-ecommerce/tests/Feature/Console/PruneExpiredTempOrdersCommandTest.php
rules_layer_coverage:
- rule: offset-chunk-mutates-filter
coverage: |
정리는 기본키 배치로 끊어 지운다 — OFFSET 이 개입하지 않으므로 커서가 밀려
미처리 행을 건너뛰는 결함이 성립하지 않는다. 매 회전이 같은 술어를 다시
평가하고, 직전 회전이 지운 만큼 모집단이 줄어든다.
- rule: console-confirm
coverage: 정리 커맨드는 확인 프롬프트가 없는 무인 실행 전용