KG 이니시스 결제에서 통화 스냅샷 이상 시 서버 오류로 새지 않도록 검증 실패/재통보 가능한 응답으로 처리하고, 주문 단위 콜백 락으로 동시 완료 콜백의 중복 후속 처리를 줄입니다.
백엔드 테스트의 통화 스냅샷 fixture도 최신 계약에 맞춰 복구합니다.
Co-Authored-By: Codex <codex@openai.com>
targets 에 명시된 {modules,plugins,templates,lang-packs}/_bundled 가
상위 protected(modules 등)에 걸려 3-way apply 목록에서 제외되던 결함 수정.
targets 가 protected 보다 더 구체적이면 오버라이드해 통과시켜, 코어 업데이트로
번들 확장 갱신 파일(composer.json·vendor-bundle.json 등)이 정상 반영되도록 한다.
자동 발견 폴백의 방어 및 prune 롤백 경로는 불변.
아울러 이슈 템플릿의 사용법 문의 링크를 Discussions 에서 sir.kr Q&A 로 전환.
에서 이커머스 모듈 버전을 1.0.0 → 1.0.1 로 올리며 composer.json version
필드를 변경했으나 vendor-bundle 을 재생성하지 않아, 번들 기록 해시와 실제
composer.json SHA 가 불일치. VendorIntegrityChecker 가 module:update 를 차단.
module:vendor-bundle 로 재생성해 해시를 재동기화하고 무결성 검증을 복구.
7.0.2 번들과 함께 버전이 상향되는 코어(7.0.2), 모듈(board/ecommerce/page 1.0.1),
템플릿(admin_basic/basic 1.0.1) 및 대응 번들 언어팩의 릴리스 날짜를 오늘로 정렬.
이니시스 결제(pay_kginicis 1.0.0)는 기존 출시일(07-01) 유지.
core:update Step 7 이 targets 전체를 무조건 재복사하고 orphan 을 삭제하여
사용자 .htaccess 커스텀 블록·_bundled 커스텀 확장이 소실되던 사고(공개 )를
차단한다. 백업(base)↔_pending(theirs) 3-way md5 비교로 코어가 실제 변경/추가한
파일만 산출해 적용하고, 코어 미변경 파일은 복사·권한·mtime 을 전부 스킵해 현재
디스크 상태(사용자 수정 포함)를 보존한다. 전체 덮어쓰기 + orphan 정리가 필요하면
--prune 으로 opt-in. 백업 부재(--no-backup) 시 base 가 없어 전체 덮어쓰기로 안전
회귀 + 안내를 출력한다.
기존 stale 정리 테스트는 새 기본(증분)에서 orphan 을 삭제하지 않으므로 prune
컨텍스트로 전환했고, 증분 3-way 판정·목록 적용·fallback 단위 테스트와 --prune
커맨드 표면 테스트를 추가했다.
번들 ja 언어팩은 코어 apply_mode 안내 키(g7-core-ja)와 함께, 같은 빌드에서
동기화된 관리자↔유저 크로스링크 라벨(board/ecommerce/admin_basic/basic)의 일본어
번역을 반영하고 각 패키지 버전·CHANGELOG 를 갱신했다.
관리자·유저 화면 왕복 이동 수단을 추가하고, 상품/게시판 URL 식별자를
사람이 읽을 수 있는 값(상품코드/슬러그)으로 전환한다.
크로스 이동 링크 (전부 새 탭):
- 관리자 사이드바 "사이트 보기" + 모바일 드로어 상단 잘림 수정
- 관리자 게시물 조회 ↔ 유저 게시판, 유저 상품 상세 ↔ 관리자 상품 수정
- 유저 화면의 관리자 진입은 is_admin 이 아니라 세부 권한 플래그로 게이트
(게시판 can_access_admin, 상품 can_update)
상품 라우팅 id → product_code:
- Product::resolveRouteBinding(code/id) + 공개 라우트 정규식 확장
- 모든 상품 링크(목록·최근본·검색·장바구니·주문내역·문의내역·관리자) 전환
- 상품 검색을 상품코드·번호 양쪽 조회 가능하게 확장(관리자+통합검색)
게시판 라우팅 board id → slug:
- Board::resolveRouteBinding(slug/id) + 관리자 라우트 slug 전환
- 생성 후 리다이렉트·토글·삭제·수정·add-to-menu·편집기 스코프 전수 정정
- BoardController::addToAdminMenu 를 Board 바인딩으로 정합
검증: 프론트 레이아웃 Vitest 36건 green, 백엔드 회귀 테스트 추가,
g7.dev 라이브 실측(생성/삭제/메뉴추가 slug, 문의내역·검색 상품코드 URL).
설치 시 use_read_db=false 인데도 db_read_host 잔존값으로 read 커넥션을
조립해 5단계 마이그레이션이 실패하던 문제를 수정한다. "read 사용 여부"
판정이 세 지점에서 달랐던 것이 근본 원인으로, use_read_db 플래그를 단일
SSoT 로 통일한다.
- installer-runtime.php: read 블록을 use_read_db 게이트로. 미사용 시 runtime
에 read 키 미생성 → 하류가 write 로 자동 fallback. mergeRuntimeIntoEnv 도
read 부재 시 DB_READ_* 를 빈 값으로 기록(write 복사 제거).
- config/database.php: read env 를 Elvis(?:) fallback 으로 복원. 중첩
env(A, env(B)) 는 DB_READ_* 가 빈 문자열일 때 fallback 이 무력화되므로,
빈 값까지 흡수하는 ?: 를 사용(tinker 실측 확인). 설치 이후 운영 중
DB_READ_* 공란 시에도 SELECT 가 write DB 로 정확히 향하게 한다.
- functions.php / request-handler.php: read 미사용 시 .env DB_READ_* 빈 값
기록 + state.json 잔존 read 필드 제거(2단계 방어).
기존 설치 환경은 .env 에 DB_READ_* 가 이미 채워져 Elvis fallback 미발동 →
동작 불변이라 업그레이드 스텝 불필요(실측 확인).
무관 사전 실패 테스트(beta.7 stale-ENV 복구)는 코어 version 이 beta.7 이
아니면 skip 하도록 가드 헬퍼 추가(프로덕션 한시 가드 전제를 테스트에 반영).
자유형식 제보에서 진단 축(버전/활성 확장/커스텀 자산/환경)이 누락되기 쉬워
G7 전용 이슈 템플릿을 추가한다. bug_report / feature_request / upgrade_issue
+ config.yml(blank 비활성, Discussions·보안신고 링크).
인스톨러 2단계(설치 환경 확인)의 checkDirectoryPermissions 가 storage 를
재귀 스캔하는데, checkSubdirectoriesRecursive 가 깊이 제한 없이 무한 재귀하여
storage/framework/testing 하위에 누적된 수만 개 디렉토리를 전부 순회 → 응답이
8초 이상 지연되던 문제.
쓰기 권한 문제는 트리 상위 얕은 깊이에서 결정되므로(상위 쓰기 가능 시 하위 상속),
재귀에 maxDepth(기본 1) 제한을 추가. 기본값이 있어 호출부는 변경 불필요.
실측: checkDirectoryPermissions 8.4초 → 0.086초.
Composer 실행 모드로 설치할 때 일부 Windows 환경에서 composer 출력의
invalid UTF-8 바이트가 정규화 없이 로그에 저장되어, 진행 상태 응답의
json_encode 가 false 를 반환 → 빈 본문(HTTP 200) → 프론트 파싱 실패로
진행 상황이 표시되지 않던 문제.
- 로그 저장(addLog)에서 mb_scrub 로 항상 유효 UTF-8 보장 (근본)
- composer 스트림 라인 정규화 (SSE/폴링 공통 경계)
- 폴링(state-management)·SSE(progress-emitter) 응답 json_encode 에
JSON_INVALID_UTF8_SUBSTITUTE + false 가드 (양쪽 안전망)
무관 결함 동시 정리: 신규 격리 테스트가 트리거한 BASE_PATH 누수로
깨지던 DeleteDirectoryTest·InstallerWindowsCommandsTest 를 프로젝트 루트
절대경로 앵커로 격리.
공개 이슈 gnuboard/g7 (@kitrio 제보).
코드/테스트 주석에 남아 있던 내부 이슈번호(-14, -15 등)를
규정에 따라 제거하고, 첨부 라우트 주석의 오해 소지 표현을 정정한다.
1.0.1 릴리스 날짜를 2026-07-06 으로 맞춘다.
- Listener/커맨드 주석, Feature/Unit/레이아웃/E2E 테스트 주석
- 시나리오 매니페스트 설명 (audit:allow 지시어는 보존)
- 첨부 라우트: admin 그룹의 오해성 "단일화" 주석 제거,
공개 pages 그룹 각 라우트에 게시판과 동일한 방식·사유를 간결히 명시
(미리보기=공개 이미지, 다운로드=발행 상태 조건부 접근 제어)
- CHANGELOG [1.0.1] 날짜를 2026-07-06 으로 정정
(page 모듈 / basic·admin_basic 템플릿 / 대응 ja 언어팩 3종)
- 로직·동작 변경 없음
목록·상세·등록/수정 화면의 버튼·선택 상자·카드 여백을 시맨틱 클래스로 통일하고,
검수 중 발견한 동작 결함을 함께 수정한다.
- 모바일 검색이 저장소 불일치(_global 저장 ↔ _local 읽기)로 미작동하던 문제 수정
- 폼 취소 이동을 수정=상세 / 등록=목록으로 명시 (기존 navigateBack 안티패턴 제거)
- 검증 에러 박스 제목 색/굵기·하단 여백, 저장 버튼 시맨틱화(spinner 포함)
- 상세: 첨부 기본 열림 + 항목별 구분선, 다크모드 카드 대비 개선,
메타 정보 2열 배치, 카드 헤더 통일(이중 여백·구분선 제거), 실패 토스트 실제 메시지 노출
- 언어 탭이 모바일에서 줄바꿈되도록 반응형 처리
레이아웃 렌더 회귀 테스트 113건 통과 + 취소 이동 E2E spec 추가.
썸네일(<img>)·다운로드(<a>)는 브라우저 직접 GET 이라 토큰을 실을 수 없는데
커밋 d48c684 가 첨부 URL 을 auth:sanctum admin 라우트로 바꿔 401 회귀가 났다.
게시판·이커머스 표준으로 정렬한다.
- 썸네일(preview): 공개 hash 서빙으로 단일화 (발행/미발행 무관 200)
- 다운로드: 공개 hash 라우트 + 권한 게이트(발행=누구나 / 미발행=pages.read 관리자만)
- 프론트 다운로드를 downloadAttachment 핸들러(토큰 fetch→blob)로 전환
- 다운로드 아이콘 arrow-down-tray(FA 미존재) → download
- 사용자 페이지에도 이미지 첨부 썸네일 추가 (관리자 상세와 일관)
- admin 첨부 preview/download 데드 라우트·메서드 제거
- iteration 안 정적 id 를 att_idx 동적 id 로 교정 (위생 정리)
- 페이지 폼 FileUploader 에 onUploadError→toast 연결 (용량/확장자 초과 안내)
- 사용자 템플릿(sirsoft-basic) 개수 초과 시 onUploadError 발화 추가 (silent 무시 방지)
- 개수 초과 문구를 이미지 전용에서 일반 파일 범용 공통 메시지로 통일 (ko/en/ja)
버전 복원 시 발화되는 after_restore 훅을 SeoPageCacheListener가
구독하지 않아, 복원 후에도 검색봇에 복원 전 버전이 계속 노출되던
문제를 수정. 복원은 콘텐츠 변경의 일종이므로 수정/삭제와 동일한
onPageChange 무효화 정책을 재사용.
미발행 페이지는 관리자여도 사용자 화면(/page/{slug})에 접근할 수 없어
발행 전 미리보기가 불가능했다. 페이지 조회 권한(sirsoft-page.pages.read)
보유 관리자는 미발행 페이지를 사용자 화면에서 미리볼 수 있게 하고, 미리보기
화면에 안내 배너를 노출한다. 비로그인·일반 회원은 기존대로 404를 유지한다.
- getPublishedPageBySlug 에 미리보기 허용 플래그 추가 (권한 판정은 컨트롤러)
- 미발행 미리보기 시 첨부 URL 을 admin 컨텍스트로 전환해 첨부까지 미리보기
- page/show.json 에 미발행 미리보기 안내 배너 + ko/en/ja 다국어
- E2E 시드 커맨드 구현 + 커맨드 등록 + 사용자 화면 미리보기 spec
- 페이지 상세 버전 이력의 "변경내역"이 title·content 등 영문 필드명으로
노출되던 문제를 field_labels 다국어 매핑으로 정정 (ko/en/ja)
- sirsoft-page 모듈에 Playwright E2E 인프라를 이커머스와 동일 패턴으로 신설
(config·fixture·seed stub + spec 3건, data-testid 보강 전까지 skip placeholder)
- 출시된 1.0.0 이후 변경이므로 module 1.0.1 bump (3곳+lock 동기화),
ja 언어팩 1.0.1 bump
- 검색 조건 '전체'가 슬러그를 검색하도록 통합하고, 검색 대상을 제목·슬러그로
한정(본문 제외 — UI '제목 또는 슬러그로 검색'과 정합). '제목' 선택 시 제목만 검색.
- 페이지당 표시 개수 기본값을 백엔드도 20으로 통일(화면 표시와 실제 조회 일치).
- 긴 검색어(공백 없는 한글 다수)가 FULLTEXT 토큰 한도를 넘겨 500을 유발하던 문제를
검색어 100자 제한으로 422 처리. 검증 메시지 필드명을 '검색어'로 노출.
페이지 목록 일괄 발행/미발행이 after_publish 훅을 발화하지 않아
활동로그에 발행/미발행이 기록되지 않던 문제를 수정한다.
- bulkChangePublishStatus 를 DB::transaction 내부에서 페이지별로
before_publish -> update -> after_publish 발화하도록 재작성 (per-item 로그)
- 존재하지 않는 id 가 섞이면 전체 롤백 (all-or-nothing)
- 단일 mass UPDATE 전용 bulkUpdatePublished 제거 (dead code, 의존 확장 영향 없음)
- 일괄 발행 성공 응답 메시지의 :count 미치환 정정
(success 의 4번째 인자 messageParams 로 치환 파라미터 전달)
- 회귀 테스트 추가 (훅 발화 횟수/published 인자/롤백/메시지 치환)
- 관리자 첨부 다운로드/미리보기를 admin 라우트 URL로 분기 (미발행 페이지 첨부를 관리자가 열 수 있도록)
- 다중 업로드 시 올린 순서대로 저장 (이커머스 패턴: temp_key 연결 + form.attachments 동기화, 코어/공용 컴포넌트 무수정)
- 수정→등록 전환 시 이전 첨부·제목·슬러그·검증안내 잔존 차단
(initialFiles를 _local.form.attachments에 바인딩 + init_actions에서 form null→기본값 초기화)
- 등록 폼 슬러그 미리보기 {{slug}} 미치환 수정 (빈 슬러그를 못 거르던 ?? → || fallback)
- 페이지 변경 시 상세 SEO 캐시 무효화 URL 패턴을 단수형(/page/{slug})으로 정정
페이지 삭제 후 동일 슬러그로 재생성 시 "이미 사용 중" 오류가 나던 문제 수정.
슬러그 중복 체크(SoftDeletes 스코프로 삭제 행 제외)와 생성 검증(Rule::unique로
삭제 행 포함)이 soft delete를 다르게 취급해 발생. Page/PageAttachment의
SoftDeletes를 제거하고 deleted_at 컬럼을 마이그레이션으로 정리해 두 경로를 정합화.