Releases: beyondwin/ReadMates
Releases · beyondwin/ReadMates
Release list
ReadMates v2.3.0
Highlights
- 플랫폼 운영 지휘대:
/admin/today를 클럽 readiness·domain·첫 호스트, 알림 실패·backlog, AI failed/stale job, 회차 마감 위험을 하나의 내구 운영 케이스 queue와 inspector로 처리하는 command center로 전환했습니다. Desktop은 queue와 상세를 함께 제공하고 mobile은 목록 → 상세 → 목록 흐름을 사용하며, source 일부 장애가 나도 확인 가능한 case는 계속 처리할 수 있습니다. - 안전한 로그인·오류 복구: OAuth 시작·callback의 HTML navigation 실패를 public-safe한
/auth/error화면으로 모으고, 상태별 안내와 검증된 상대 복귀 경로를 제공합니다. 공통 route error도 같은 editorial hierarchy와 구체적인 다음 행동을 사용합니다. - 멤버·호스트 모바일 완성도: 내 공간의 최근 독서 기록과 호스트 AI 기본값 도구를 더 조밀하고 읽기 쉽게 정리했습니다. 호스트 모바일 대시보드와 세션 편집기는 핵심 행동, 현재 세션 metadata, 다섯 편집 탭을 좁은 화면에서도 겹침 없이 사용할 수 있도록 다듬었습니다.
Changed
- 운영 케이스 lifecycle과 권한: case는
OPEN,ACKNOWLEDGED,SNOOZED,RESOLVED상태와 optimistic version, immutable event history를 가집니다. 운영 화면의 활성 건수는RESOLVED를 제외한 모든 상태를 포함합니다. OWNER와 OPERATOR만 acknowledge·최대 7일 snooze·resolve 검증을 실행하고 SUPPORT는 safe projection만 읽습니다. Resolve는 exact source identity가 authoritative하게 사라진 경우에만 성공하며 active·부분 조회·source unavailable은 fail closed합니다. - 운영 shell과 안전 경계: admin 탐색을 Command·Operations·Review 업무 그룹과 compact source status로 정리했습니다. Case API는 allowlist summary, aggregate impact, freshness와 canonical detail link만 제공하며 기존 club publication, notification replay, AI recovery, support grant mutation route를 변경하지 않고 범용 execute endpoint도 추가하지 않습니다.
- 운영 케이스 API:
GET /api/admin/operations/cases, case 상세와 acknowledge·snooze·resolve action을 추가했습니다. 목록은 state·severity·source·assignee filter와 opaque cursor를 사용하고 mutation은 exact expected version을 요구합니다. - 게스트 노트 범위: 공개 노트 feed의 optional
sessionIdquery를 backend와 frontend가 함께 사용해 선택한 회차의 질문·서평만 pagination합니다. 회차 선택과 cursor cache는 club·session별로 분리되며 선택하지 않은 기존 전체 feed contract는 유지합니다. - 반응형 작업 밀도: 멤버 최근 독서 행은 날짜·회차·책 정보와 기록 action의 위계를 맞췄고, 호스트 AI 기본값은 별도 설명 card 대신 compact 운영 도구로 정리했습니다. 모바일 호스트 화면은 현재 세션 CTA, 운영 항목, 예정 세션 흐름을 중복 없이 배치하며 세션 편집 metadata와 section tab은 320px 폭까지 축약 label과 fallback wrapping을 사용합니다.
Fixed
- OAuth/BFF navigation 오류: 잘못된 provider route, upstream 4xx/5xx, network failure를 HTML 문서 탐색에서는
no-store오류 화면으로 전환하고 non-HTML 요청은 기존 public-safe JSON 오류 contract를 유지합니다. 오류 kind와returnTo는 allowlist·same-origin 상대 경로로 제한하고 recursive/auth/error복귀를 거절합니다. - 릴리스 의존성 보안: 전이 의존성
brace-expansion을 DoS 수정 버전5.0.9,nanoid를 zero-size custom generator 무한 반복 수정 버전3.3.17로 강제해 HIGH audit 경고를 제거했습니다. - 긴 검토 label, guest feedback 잠금 dialog, 멤버 홈 간격과 최근 기록 action 정렬을 다듬고, 선택한 guest note session이 route layout 전환 뒤에도 유지되도록 했습니다.
Database
- Flyway V47:
admin_operation_cases, immutableadmin_operation_case_events, one-row-per-sourceadmin_operation_source_status를 additive하게 추가합니다. Source identity unique key, lifecycle/severity check, optimistic version과 source freshness를 영속화하며 private content나 provider raw error를 저장하지 않습니다. Migration rollback 대신 V47 schema를 보존한 compatible image 또는 forward-fix를 사용합니다.
Deployment Notes
- Annotated
v2.3.0tag에서Deploy Server Image가 scan한 digest를 같은 release tag로 promote한 뒤 OCI backend를 먼저 배포합니다. Spring startup Flyway가 V47까지 적용되고/internal/health, anonymous BFF auth, guest note feed와 admin operations authorization이 정상인 경우에만 같은v2.3.0tag의 Cloudflare Pages frontend를 배포합니다. - V47은 forward-only입니다. 실패 시 migration을 되돌리거나 이미 발행한 tag를 이동하지 않고 V47 schema와 호환되는 이전 image 또는 새 patch forward-fix를 사용합니다. Runtime env rendering, host-write client contract와 provider activation policy는 바뀌지 않으므로
sync-configmutation은 필요하지 않습니다. - Production smoke는 public app/auth, OAuth start/error navigation, guest selected-session note read와 OWNER/OPERATOR/SUPPORT의 admin operations read/denied 경계를 read-only 또는 no-send 방식으로 확인합니다. 실제 Google OAuth 완료, AI provider 호출, 이메일 발송, 실제 member/admin mutation은 별도 승인 없이 실행하지 않습니다.
Verification
- Release candidate gate: repository-pinned
pnpm@11.13.1로 frontend lint, 274 files / 2,153 tests와 coverage(84.50% statements, 79.63% branches, 84.30% functions, 85.25% lines), production build와 Zod fixture freshness를 확인했습니다. - Server evidence: PR quality gate에서 unit 1,091 tests(1 skipped)와 architecture 28 tests가 통과했고, MySQL/Testcontainers integration 872 tests가 통과했습니다.
- Browser/design evidence: Chromium E2E 146/146이 통과했습니다. 모바일 세션 편집기의 5개 탭이 의도대로 viewport 안에 들어가는 계약과 어긋난 기존 overflow 기대값을 수정한 뒤 해당 focused E2E 1/1과 전체 suite를 다시 확인했습니다.
- Release safety:
pnpm audit --audit-level high0건, deploy workflow contract, AI production config, public release candidate/gitleaks와 Prometheus/Tempo/Grafana/Alertmanager 검증이 통과했습니다.
ReadMates v2.2.0
Changed
- 멤버 공간 UI 밀도: 참석 명단을 화면 폭에 따라 데스크톱 8열·중간 5열·소형 모바일 4열로 정리하고, 프로필 아바타의 서정 이름을 그림 아래 캡션으로 배치했습니다. 누적 성취는 모임·완독·질문·서평 숫자를 한 번씩 읽는
독서 여정 장부와 단일기록 보기동선으로 다듬고, 알림 설정은 중복 상단 문구와 저장 버튼 아래 마지막 경계선을 제거했으며 데스크톱 홈 바로가기 두 행의 구분선을 행 너비에 맞췄습니다. - 통합 멤버 프로필 편집:
/app/me의 읽기 전용 프로필 요약에서 표시 이름과 book-club 아바타를 하나의 adaptive dialog/bottom sheet로 함께 편집합니다. 로컬 아바타 catalog를 30개 key로 정리하고, 저장은 선택한 클럽 membership의 두 필드를PUT /api/me/profile한 번으로 원자적으로 반영해 전역 계정 메뉴, 멤버·호스트 roster와 공개 기록 identity가 같은 값을 읽습니다. - 둘러보기 사용자도 정식 멤버와 같은 홈·세션·노트·아카이브·기록 화면을 사용하며, 입력 영역은 읽기 전용으로 비활성화되고 피드백 문서는 정식 멤버에게만 열리도록 정리했습니다.
- 전역 활자 가독성: Pretendard 단일 서체 안에서 제목·본문·보조 정보의 위계를 정리하고, 실제 표시 텍스트의 크기 하한을 12px로 보호하며, 모바일과 좁은 화면에서 본문 행간과 운영 보드의 단일 열 가독성을 강화했습니다. Pretendard 가변 웹폰트를 앱에 자체 번들링하고 모든 CT baseline 갱신을 Docker renderer로 고정해 macOS/Linux 폴백 차이도 제거했습니다.
- 프론트 성능 예산: 세션 편집기의 AI 기록 도구를 필요할 때만 로드하도록 분리하고, 반복적인 웹폰트 unicode-range 선언이 포함된 전역 CSS는 gzip 전송 크기로 하드 게이트하면서 raw 크기도 보고서에 함께 남기도록 조정했습니다.
- 기본 로그인 진입: 별도 복귀 경로가 없는
/login도 읽는사이 클럽의둘러보기와멤버로 시작을 제공해 공개 화면과 같은 선택지를 유지합니다. 명시된 안전한returnTo는 기본값보다 우선하며, 오류 복구와 안전하지 않은 외부 복귀 경로는 암묵적인 클럽 가입 문맥을 만들지 않습니다.
Fixed
- 릴리즈 전 CI·의존성 보안 하드닝: 로컬 Google OAuth stack fixture의 ShellCheck 경고를 제거해 Scripts CI blocker를 닫고, frontend를 React Router
8.3.0의react-router/react-router/dompackage split으로 전환했습니다. Workspace override는brace-expansion 5.0.8,postcss 8.5.25이상을 강제하며 active source/test/config가 제거된react-router-domwrapper를 다시 참조하지 못하도록 architecture test를 추가했습니다. - 호스트 모바일 대시보드의 현재 세션 여백과 3열 운영 수치를 복구하고, 처리 항목·예정 세션 행동을 더 명확한 단일 primary action 흐름으로 정돈했습니다.
- Google 로그인 복구: 종료된 멤버십 또는 Google 인증 실패 뒤에는 다른 Google 계정을 명시적으로 선택해 다시 로그인할 수 있습니다. 카카오톡 인앱 브라우저에서는 외부 브라우저 안내와 로그인 주소 복사를 제공하며, 안전한 멤버 복귀 경로와 기존 OAuth·세션 보안 경계는 유지합니다. 로컬 dev-login은 명시적으로 활성화된 Google OAuth 설정이 없으면 깨진 provider 링크를 노출하지 않고, macOS Keychain의 localhost 전용 credential을 backend에만 주입하는 공개 저장소 안전 실행 경로를 제공합니다.
One-command local OAuth stack + redacted smoke verifier로 기존 서비스 보존 상태에서 localhost 기반 Google login 회귀 점검을 반복 가능하게 했습니다. - 게스트 read/cache 경계: guest browse 응답은 항상
no-store이며 Pages BFF가No-Store와Private같은 혼합 대소문자 Cache-Control directive도 cache 금지로 해석합니다. Guest cursor는 다른 club에서 재사용할 수 없고 429는 boundedRetry-After와 복구 가능한 공개 오류 UI를 유지합니다. - 세션 만료 복구: 보호 API의 기본 401 login redirect를 유지하면서, 이미 성공한 current/archive/notes read와 작성 중 current-session mutation만 명시적으로 in-place recovery를 사용합니다. Read는 exact public resource가 다시 확인될 때만 게스트 전환을 제공하고 write는 입력을 보존한 채 재로그인만 허용합니다.
Highlights
- 로그인 없는 게스트 앱: 공개 클럽의
/clubs/:slug/app/**에서 현재·예정 세션, 노트, 아카이브와 회차 상세를 로그인 없이 둘러볼 수 있습니다. 개인 공간은 preview로, 설정·알림·피드백은 정식 멤버 전용 안내로 보여주고 호스트 route와 모든 write를 차단합니다. - 반응형 계정·내 공간·북클럽 아바타: 모바일과 데스크톱에서 계정 접근과 호스트 공간 전환을 명시적으로 구분하고, 알림·계정 설정에 고정된
내 공간상위 동선을 제공합니다. 멤버 식별은 외부 프로필 사진 대신 privacy-safe 로컬 book-club 아바타 30종을 사용하며, 미사용 아바타 우선 자동 배정 후에도 멤버가내 공간의 통합 편집기에서 표시 이름과 함께 변경할 수 있습니다. 내 공간·편집기·내비게이션·멤버 목록·작성자 표시는 역할별 의미 크기로 정규화되고, 선택기는 30개 이름을 항상 보이면서 현재 선택을 체크 배지 없이 테두리와 절제된 배경으로 구분하고 키보드 focus outline을 별도로 유지합니다.
Deployment Notes
Deploy Server Image는 push와 manual dispatch 모두 exactvMAJOR.MINOR.PATCHannotated tag를 checkout하고 tag commit과HEAD가 일치해야 build를 시작합니다. Trivy가 검사한 digest와 같은 digest만 release tag로 promote하며, repository checker가 CI·pre-push·public release candidate에서 이 계약을 fail closed로 검증합니다. 이 source 변경 자체는 workflow dispatch, image publish, OCI/Cloudflare 배포를 실행하지 않습니다.- 배포 전 최근 DB backup과 backend readiness 기준을 확인합니다. V43과 V44는 수정하지 않으며, forward-only V46이 모든 기존 membership의 avatar key를 30-key 집합으로 한 번 다시 쓰고 named check constraint를 새 집합으로 교체합니다.
- 같은 release tag의 새 backend를 먼저 배포해 Flyway V45 guest exposure와 V46 avatar catalog, backend health가 모두 정상임을 확인한 뒤에만 새 frontend를 배포합니다.
PUT /api/me/profile은 현재 club membership의 표시 이름과 avatar key를 한 transaction에서 교체하며,PATCH /api/me/profile과PATCH /api/me/avatar는 cached old client를 위한 제한된 호환성 window로 남습니다. Cached old client가 제거된 key를 보내면AVATAR_KEY_INVALID를 받을 수 있습니다. - 배포 후에는 현재 club의 atomic profile 변경과
/api/app/me·/api/auth/me재조회, 다른 club 격리, 허용된 public author avatar 표시를 smoke하고 권한과LEFT/anonymous masking이 유지되는지 확인합니다. 실제 member data나 private identifier는 공개 release evidence에 기록하지 않으며, 운영 배포의 공개 가능한 완료 증거는 같은 태그의 GitHub Release에 기록합니다. - Rollback은 V45/V46이 바꾼 schema와 이미 migration된 data를 보존합니다. Migration을 되돌리지 않고 V45/V46과 호환되는 server/frontend image로 전환하거나 새 forward-fix release를 발행합니다.
Changed
- 독립 exposure 모델: app access의 canonical field를
sessions.access_scope(HOST_ONLY|GUEST_READABLE), public marketing placement를public_session_publications.site_visibility(HIDDEN|PUBLIC_RECORD)로 분리했습니다. 기존visibility와is_public은 rolling deploy/rollback을 위해 한 릴리즈 dual-write하고 새 host UI와 API는 canonical field를 사용합니다. - 공개 진입과 target-club join: 공개 홈·소개·기록·회차와 scoped login에
둘러보기와멤버로 시작을 제공합니다.멤버로 시작은 서명된 exact raw scoped return path와 같은ACTIVE + PUBLICclub에서만VIEWERmembership을 만들며 기존 membership과 초대 흐름을 우선·보존합니다. - OAuth 가입 의도·CI 재실행 경계: target-club
VIEWER생성은 same-origin JSON POST가 발급한 만료·1회용 의도를 실제 OAuthstate에 결합한 경우에만 수행합니다. 역순 multi-tab callback은 성공·실패와 예상 밖 처리 예외에서도 소비한 state만 정리하고 session ID를 정확히 한 번 회전해 나머지 pending flow를 보존합니다. Provider 취소와 인지된 도메인 오류는 유효한 기존 앱 세션을 유지하고 서버가 invalid/stale로 확인한 cookie만 만료합니다. rawinviteToken이 있으면 blank·malformed도 join보다 우선합니다. 서버 PR gate는 stale Gradle 산출물에 의존하지 않도록--no-build-cache --rerun-tasks check를 실행하므로, 로컬 반복 실행도 전체 품질 검사를 새로 수행합니다. - Guest-safe records: guest DTO는 참석자 표시 이름, RSVP·실제 참석 상태, 질문의
draftThought, 작성자 이름이 붙은 질문·서평을 허용합니다. Membership/account ID, email/account name, 정확한 장소, 접속 URL·비밀번호, 읽은 분량, 피드백 본문은 제외합니다. 새 한줄평·장문 서평은 guest-readable record에 공개되며 기존 private/session 예외 row는 일괄 재작성하지 않습니다.
Database
- Flyway V43–V44:
memberships.avatar_key를 추가해 클럽 membership의 로컬 아바타를 영속화하고, 후속 migration에서 초기 catalog를 확장·재배정했습니다. 두 migration은 이미 배포된 적 없는 이번 릴리즈의 순차 schema history이며 수정하거나 합치지 않습니다. - Flyway V45:
sessions.access_scope와public_session_publications.site_visibility를 additive하게 추가하고 기존 member/public exposure를 canonical 두 축으로 backfill합니다. Compatibility column은 이번 릴리즈에서 제거하지 않으며 rollback은 V45 schema를 보존한 호환 image 또는 forward-fix를 사용합니다. - Flyway V46: 모든 기존 membership을 최종 30-key book-club avatar catalog로 결정적으로 재배정하고
memberships_avatar_key_check를 같은 집합으로 교체합니다. V43/V44를 수정하지 않으며 rollback은 V46 schema와 이미 변환된 key를 보존합니다.
Deployment Notes
- V45를 포함한 backend를 먼저 배포해 Flyway와 dual-write를 활성화한 뒤 같은 commit의 Pages Functions/frontend를 배포합니다. 한 릴리즈 동안 old
{visibility}request와 compatibility read/write를 유지하고, 다음 릴리즈에서 old frontend가 남지 않았다는 운영 증거를 확인한 뒤 별도 migration으로 제거합니다. - Production smoke는 anonymous public/guest reads, exact scoped OAuth start marker, viewer/member/host route 경계, guest 429/no-store를 확인합니다. Live Google OAuth 완료, 실제 이메일, AI provider 호출과 production data mutation은 별도 승인 없이 실행하지 않습니다.
Verification
- Release candidate gate: repository-pinned
pnpm@11.13.1로 frontend lint, 265 files / 2,049 tests와 coverage(83.68% statements, 78.88% branches, 83.72% functions, 84.54% lines), production build와 Zod fixture freshness를 확인했습니다. - Server evidence: PR quality gate에서 unit 1,024 tests(1 skipped)와 architecture 26 tests가 통과했고, MySQL/Testcontainers integration 839 tests가 통과했습니다.
- Browser/design evidence: 격리된 backend/frontend 포트로 Chromium E2E 136/136, Docker Playwright component tests 55/55, design system 14/14와 design docs 2/2가 통과했습니다.
- Release safety: deploy workflow contract self-tests/current check, ShellCheck/actionlint, pnpm HIGH audit 0건, public release candidate/gitleaks, AI production config와 Prometheus/Tempo/Grafana/Alertmanager 검증이 통과했습니다.
Production deployment
- Server image workflow 30756834917 passed exact-tag verification, server quality gates, ARM64 build, Trivy HIGH/CRITICAL scan, and same-digest promotion.
- OCI backend is running
v2.2.0at the promoted digest with healthUP, zero restarts, and Flyway schema version 46 applied successfully. - Frontend workflow 30757194408 deployed the same tag to Cloudflare Pages after backend health succeeded.
- Production marker, OAuth redirect URI, public app, anonymous auth, and guest browse/no-store smoke checks passed. No live AI-provider call, email send, or private-member mutation was executed.
ReadMates v2.0.1
Fixed
- 서버 이미지 release scan blocker:
v2.0.0scan candidate에서 Trivy가 발견한 수정 가능한 HIGH 6건을 제거했습니다. Runtime classpath의com.fasterxml.jackson.core:jackson-core를2.21.4, Netty 전체를4.2.16.Final로 정렬해 Jackson async parser와 Netty compression/HTTP/HTTP3 취약 버전이 release image에 포함되지 않게 했습니다.
Deployment Notes
v2.0.0source tag의Deploy Server Image는 scan candidate를 만들었지만 Trivy에서 차단되어 GHCRv2.0.0release image tag로 승격되지 않았습니다. 따라서sync-config, OCI backend promotion, Cloudflare Pages frontend 배포와 GitHub Release 생성은 시작하지 않았습니다.v2.0.1은 같은 v2 기능과 V37–V42 migration을 포함한 forward-fix release입니다.v2.0.1서버 이미지 scan/promote → production config sync → OCI backend/Flyway/health →Deploy Front(release_tag=v2.0.1)→ production smoke 순서를 사용합니다.
Verification
- Runtime dependency resolution:
com.fasterxml.jackson.core:jackson-core 2.21.4,tools.jackson.core:jackson-core 3.1.4, Netty compression/HTTP/HTTP34.2.16.Final. ./scripts/server-ci-check.shpassed.- Local
linux/arm64release image build passed, and Trivy0.70.0HIGH/CRITICAL scan reported zero findings for both Ubuntu packages and application JARs. ./scripts/pre-push-check.sh --full --releasepassed, including 1,536 frontend tests, server quality and Testcontainers integration gates, public candidate/gitleaks, 92 Playwright E2E tests, and observability configuration validation.
ReadMates v1.17.3
Highlights
- 공개 기록 화면의 좁은 viewport metadata가 서로 겹치지 않고 읽히며, 로컬 개발 환경의 frontend observability가 운영과 같은 BFF 경로 계약을 사용합니다.
- OCI 앱 배포가 같은 Compose project/network의 관측 서비스를 보존하고, CI와 pre-push가 같은 agent guidance 및 server quality 계약을 검증합니다.
Changed
- Agent guidance contract: CI와 pre-push가 agent router, active guide link, canonical server/Corepack command, instruction-chain size, release-checklist size, Graphify local-state exclusion, public-safety invariants를 하나의 저장소 검사기로 검증하며, server quality gate는
./scripts/server-ci-check.sh로 통일되었습니다. - Release bypass evidence: solo-admin 또는 incident branch-protection bypass는 공개 안전 템플릿, 생략 검증, 후속 owner/deadline, closure evidence를 갖춘 release bypass ledger 절차를 따릅니다.
Fixed
- Local frontend observability BFF parity: the Vite dev proxy now maps
/api/bff/observability/frontend-eventsto Spring's/api/observability/frontend-eventswhile preserving the production browser contract and the existing general/api/bff/api/**rewrite, preventing route navigation from emitting telemetry 403 noise locally. - Responsive public record metadata: 좁은 화면에서 공개 기록의 날짜와 작성자 metadata가 겹치지 않도록 줄바꿈 가능한 레이아웃과 회귀 검증을 추가했습니다.
- OCI Compose backend deploy: 앱 stack 시작 경로에서
--remove-orphans를 제거해 같은 Compose project/network에 붙은 Prometheus/Grafana/Alertmanager가 백엔드 배포 중 orphan으로 삭제되지 않게 했습니다. - Frontend tooling security: Lighthouse의 Sentry runtime을 OpenTelemetry 2.x를 지원하는
@sentry/node10.x 계열로 맞추고@opentelemetry/core를 patched 2.8.0 이상으로 해석해 Dependabot moderate advisoryGHSA-8988-4f7v-96qf를 닫으면서 runtime import 호환성도 유지합니다. - Public release coverage: 새 root product contract인
PRODUCT.md와 기존ops/tree가 clean public release candidate의 명시적 top-level coverage fixture 및 gitleaks scan 범위에 포함됩니다.
Deployment Notes
v1.17.2위 patch release입니다. Spring application source, public API contract, DB migration, OAuth scope, auth cookie, BFF secret, runtime secret 변경은 없습니다.- Annotated tag
v1.17.3을 발행해Deploy Front와Deploy Server Image를 같은 commit에서 실행합니다. Cloudflare Pages 배포와 GHCR image scan/promote가 모두 성공한 뒤 OCI Compose backend를ghcr.io/<owner>/<repo>/readmates-server:v1.17.3으로 올립니다. - OCI promotion은 업데이트된
05-deploy-compose-stack.sh를 사용해 app stack만 새 image tag로 전환하고, 같은 Compose project/network의 Prometheus/Grafana/Alertmanager는 유지해야 합니다. DB migration은 없으므로 Flyway schema 변화는 기대하지 않습니다. - 배포 후 Cloudflare Pages app, anonymous BFF auth, OAuth redirect, production integration smoke, Spring
/internal/health, post-deploy watch를 확인합니다. 실제 운영 host, credential, member data, smoke 전문은 Git에 기록하지 않습니다.
Verification
- Full local release gate (2026-07-12):
./scripts/pre-push-check.sh --full --releasepassed. It covered the agent guidance contract, frontend lint, 167 frontend test files with 1,315 tests and coverage (81.82% statements, 77.8% branches, 82.44% functions, 82.53% lines), production build, Zod fixture freshness, backendcheck, Testcontainers integration lane, 70 Playwright E2E tests, public release candidate build/gitleaks scan, Prometheus rules/config, and Alertmanager config. - Dependency safety (2026-07-12):
pnpm audit --jsonreported zero known vulnerabilities, and the Lighthouse package-context Sentry runtime regression test passed with the patched dependency graph. - Public release safety (2026-07-12): the generated
.tmp/public-release-candidatepassed./scripts/public-release-check.shwith no gitleaks findings.
Release bypass
- Classification: POLICY_MISMATCH
- Release/commit:
v1.17.3release commit - Reason: solo-admin repository with no available non-author reviewer for the accumulated CI contract change; all executable release gates run locally before direct
mainpublication. - Affected high-control surfaces:
.github/workflows/ci.yml,scripts/pre-push-check.sh,scripts/server-ci-check.sh, and the OCI Compose deploy helper/unit. - Checks completed:
./scripts/pre-push-check.sh --full --releaseand its frontend, backend, E2E, integration, observability-config, and public-release safety lanes. - Checks skipped or failed: none before publication.
- Follow-up owner and deadline: repository operator, 2026-07-19, confirm the tag-triggered workflows, OCI promotion, production smoke, and whether branch protection should require the CI workflow.
- Closure evidence: GitHub Release
v1.17.3, tag-triggered workflow runs, and the sanitized final deployment report.
ReadMates v1.17.2
Fixed
- frontend observability beacon upload: browser telemetry now sends the
sendBeaconpayload as anapplication/jsonBlob, preventing/api/bff/observability/frontend-eventsfrom rejecting valid frontend event batches with415 Unsupported Media Type.
Deployment Notes
- Patch release over
v1.17.1for a frontend telemetry transport regression. No server API contract, Pages Functions route behavior, DB migration, OAuth scope, auth cookie, runtime secret, or production config change is included. - Publish
v1.17.2, confirm tag-triggeredDeploy FrontandDeploy Server Imageworkflows, then run browser-facing production smoke. The OCI backend can be promoted to the same image tag for version alignment, but the frontend fix does not require a server schema or API cutover.
Verification
- Local frontend gates (2026-07-05):
npx --yes corepack@0.35.0 pnpm --dir front lint,npx --yes corepack@0.35.0 pnpm --dir front test -- frontend-observability-client --reporter=dot,npx --yes corepack@0.35.0 pnpm --dir front test --reporter=dot, andnpx --yes corepack@0.35.0 pnpm --dir front buildpassed. - Local release safety (2026-07-05):
./scripts/build-public-release-candidate.shand./scripts/public-release-check.sh .tmp/public-release-candidatepassed. - Full local release gate (2026-07-05):
./scripts/pre-push-check.sh --releasepassed, including frontend lint, frontend coverage (165 files, 1311 tests), frontend build, zod fixture export/diff, backend check, public release candidate build, and public release check with gitleaks no leaks.
ReadMates v1.17.1
Fixed
- Server image publication: release Docker images no longer run
apt-getduringlinux/arm64Buildx publication. The Java 25 Temurin Jammy image now keeps the same JRE baseline, creates the runtime user without package-manager mutation, and uses the checked-in/app/bin/readmates-http-gethelper for container-internal health/readiness calls. - OCI Compose health probes: production compose health checks, deploy smoke, post-deploy watch, and collect diagnostics now call the image-owned HTTP helper instead of assuming
curlis installed inside the server container.
Deployment Notes
- Patch release over
v1.17.0because thev1.17.0tag-triggeredDeploy Server Imageworkflow passed Gradle quality gates but failed during the Buildx image layer. No application API, DB migration, frontend route, BFF/auth, OAuth scope, auth cookie, runtime secret, or production config change is included. - Publish
v1.17.1, confirmDeploy FrontandDeploy Server Imagefor the same tag, then promote OCI Compose backend toghcr.io/<owner>/<repo>/readmates-server:v1.17.1.
Verification
- Local helper and script gates (2026-07-05):
server/docker/readmates-http-getwas verified against a local HTTP server for 2xx success and 404 failure behavior;bash -n server/docker/readmates-http-get deploy/oci/05-deploy-compose-stack.sh deploy/oci/watch-compose-post-deploy.sh deploy/oci/readmates-collect.sh,shellcheck server/docker/readmates-http-get deploy/oci/05-deploy-compose-stack.sh deploy/oci/watch-compose-post-deploy.sh deploy/oci/readmates-collect.sh, targetedgit diff --check, and targeted deploy-doccurlassumption scan passed. - Local backend and image gates (2026-07-05):
./server/gradlew -p server clean check bootJar,docker build --platform linux/arm64 --no-cache -t readmates-server:v1.17.1-arm64-local -f server/Dockerfile.release server, image sanity check for Java 25 plus/app/bin/readmates-http-get, and local Trivy0.70.0HIGH/CRITICAL scan passed with 0 Ubuntu and Java findings. Local amd64 image reproduction was skipped because this machine's Docker installation lacks the Buildx plugin and the legacy builder reused the arm64 platform cache incorrectly; the release workflow remainslinux/arm64. - Full local release gate (2026-07-05):
./scripts/pre-push-check.sh --releasepassed, including frontend lint, frontend coverage (165 files, 1311 tests), frontend build, zod fixture export/diff, backend check, public release candidate build, and public release check with gitleaks no leaks. - Graphify discovery was used for release impact orientation and pointed back to CHANGELOG, release readiness, OCI backend, compose stack, release publish runbook, and deploy docs surfaces.
ReadMates v1.17.0
Highlights
- Java 25 production runtime: backend build, test, release image, CI, and OCI deploy paths now run on Java 25 with Kotlin 2.4.0, keeping local and GitHub Actions runtime expectations aligned.
- Release-tooling parity: frontend, deploy, pre-push, and Playwright CT paths now activate the repo-pinned
pnpm@10.33.0through Corepack, reducing local/CI drift before production tags are pushed. - Host server-state boundary cleanup: host members and invitations now keep query ownership in route/data actions, closing the remaining frontend boundary exceptions without changing server APIs.
Changed
- Backend Gradle toolchains, GitHub Actions Java setup, Docker runtime images, legacy OCI VM setup, and active development/deploy docs now use Java 25 LTS with Kotlin 2.4.0 bytecode targeting Java 25.
- CI/deploy and pre-push package-manager setup now activate the root
packageManagerthrough Corepack. The pinned frontend package manager remainspnpm@10.33.0. - Playwright component visual-regression Docker commands now run through a shared helper that activates the repo-defined pnpm with Corepack, verifies the container pnpm version, and isolates CT
node_modulesin Docker volumes so the host install is not rewritten by Linux optional dependencies. - Host members and invitations route/data actions now own query refresh and action handoff, while host UI components receive canonical state from route-owned data.
Fixed
- Host server-state boundary: host members and invitations now keep query ownership in route/data actions, removing the remaining frontend boundary exceptions without changing the server API, BFF/auth behavior, DB migrations, deploy workflow, or route URLs.
- Backend Java 25 runtime: backend Gradle toolchains, GitHub Actions setup-java jobs, Docker runtime images, legacy OCI VM setup, and active development/deploy docs now use Java 25 LTS with Kotlin 2.4.0 bytecode targeting Java 25.
- pre-push pnpm parity: pre-push checks now run frontend commands through
pnpm@10.33.0, matching CI and avoiding local failures when another pnpm major version is first onPATH. - Tooling: CI/deploy and pre-push package-manager setup now activate the root
packageManagerthrough Corepack, reducing pnpm version drift between local checks and GitHub Actions. - CT Docker Corepack path: Playwright component visual-regression Docker commands now run through a shared helper that activates the repo-defined pnpm with Corepack, verifies the container pnpm version, and isolates CT
node_modulesin Docker volumes so the host install is not rewritten by Linux optional dependencies.
Deployment Notes
- Minor release because the backend production runtime and release image baseline move to Java 25. No Flyway migration is included.
- Public API contracts, Pages Functions BFF/auth behavior, OAuth scopes, auth cookie format, runtime secret format, route URLs, and deploy workflow triggers are unchanged.
- Push
main, push annotated tagv1.17.0, confirmDeploy FrontandDeploy Server Imageworkflows for the same tag, then promote OCI Compose backend toghcr.io/<owner>/<repo>/readmates-server:v1.17.0. Deploy Server Imagemust pass the Trivy HIGH/CRITICAL scan before OCI promotion. The backend promotion should be followed by/internal/health, BFF auth, OAuth redirect, and production smoke checks.
Verification
- Local script and public-safety gates (2026-07-05):
bash -n scripts/*.sh deploy/oci/*.sh,shellcheck scripts/*.sh deploy/oci/*.sh,bash scripts/aigen-pii-check.sh,git diff --check -- . ':(exclude)docs/superpowers/**',./scripts/build-public-release-candidate.sh, and./scripts/public-release-check.sh .tmp/public-release-candidatepassed; gitleaks reported no leaks in the public release candidate. - Local frontend and design gates (2026-07-05):
npx --yes corepack@0.35.0 pnpm --dir front lint,npx --yes corepack@0.35.0 pnpm --dir front test:coverage(165 files, 1311 tests),npx --yes corepack@0.35.0 pnpm --dir front build,npx --yes corepack@0.35.0 pnpm --dir front zod:export-fixturesplus fixture diff check,npx --yes corepack@0.35.0 pnpm --dir front test:e2e(68 Playwright tests),npx --yes corepack@0.35.0 pnpm --dir front test:ct:docker(7 CT tests), andnpx --yes corepack@0.35.0 pnpm design:checkpassed. - Local backend and release-image gates (2026-07-05):
./server/gradlew -p server clean check bootJar,./server/gradlew -p server unitTest integrationTest architectureTest --rerun-tasks,./server/gradlew -p server bootJar,docker build -t readmates-server:v1.17.0-local -f server/Dockerfile.release server, anddocker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:0.70.0 image --severity HIGH,CRITICAL --ignore-unfixed --scanners vuln readmates-server:v1.17.0-localpassed with 0 Ubuntu and Java HIGH/CRITICAL findings. - Graphify discovery was used for release impact orientation and confirmed the touched release/docs/host boundary surfaces;
graphify-out/remains ignored and is not a release artifact. - Skipped before tag push: tag-triggered
Deploy Front, tag-triggeredDeploy Server Image, OCI Compose backend promotion, GitHub Release publication, production OAuth/provider-console checks, and post-deploy smoke. These require pushedmain/tag or production operator access and are the next release-operation steps.
ReadMates v1.16.3
v1.16.3
Patch release for OCI observability deployment hardening after the frontend observability rollout.
Fixed
- Suppress macOS metadata/xattr noise when archiving Prometheus and Grafana assets for the VM.
- Use a Prometheus config without Alertmanager targets when the partial stack intentionally deploys only Prometheus and Grafana.
- Restart Prometheus after config updates so target changes are applied immediately.
- Reset and verify Grafana admin credentials against the persisted Grafana database during deployment.
- Extend the observability bootstrap/runbook and release-readiness docs with the partial-stack behavior and Grafana credential check.
Verification
- main CI passed for commit
d20465ca. - Deploy Front passed for tag
v1.16.3. - Deploy Server Image passed for tag
v1.16.3; promoted server image digestsha256:8746e8774b13f1b8943885f7455f2dbf4a8ff0e1499c67f22c6d17519fb7532d. - OCI backend promoted to
v1.16.3; post-deploy health, BFF auth, OAuth redirect, Pages marker, and recent-error watch passed. - OCI Prometheus/Grafana partial stack redeployed successfully.
- Production frontend observability smoke returned
202withaccepted:3,dropped:0. - Prometheus targets
prometheus-selfandreadmates-serverwereup. - Prometheus showed route-load, API-failure, and runtime-error frontend metrics from the smoke event.
- Grafana health returned
database: ok; authenticated dashboard search foundFrontend Runtime.
Known remaining operational gap
- Alertmanager/SMTP alert delivery is still intentionally not enabled because production SMTP credentials have not been provided.
ReadMates v1.16.2
v1.16.2
Patch release for production frontend observability intake.
Fixed
- Allow trusted Pages BFF frontend observability POSTs through Spring Security without member-session auth or CSRF, while preserving the BFF secret and allowed-origin boundary.
- Forward browser
Origin/Refererfrom the Pages BFF telemetry endpoint to the API so production origin validation has the expected context.
Verification
- Deploy Front: passed for tag
v1.16.2. - Deploy Server Image: passed for tag
v1.16.2; promoted server image digestsha256:00722c8f4c14eafe8b5f2d24544d0412e722b18bbc531bbfb08aef19c4fbb450. - OCI backend promoted to
v1.16.2; post-deploy health and BFF/OAuth/Page marker watches passed. - Production frontend observability smoke returned
202withaccepted:3,dropped:0. - Production Prometheus scraped frontend route/API/runtime smoke metrics.
Superseded by v1.16.3
- OCI Prometheus/Grafana deploy helper hardening shipped in
v1.16.3.
ReadMates v1.16.0
Highlights
- frontend observability v2: Browser route-load, runtime-error, and API-failure signals now flow through a same-origin BFF telemetry endpoint into Spring Micrometer metrics and Grafana docs, using normalized route patterns and low-cardinality labels only.
- production observability bootstrap: OCI compose observability provisioning now has production-shaped Grafana/Prometheus wiring, public-safe dummy env fallbacks, and release/runbook closure so operators can verify dashboards and rules without committing private deployment state.
- platform admin workspace switcher: 플랫폼 관리자 헤더에서 현재 계정의 멤버/호스트 워크스페이스로 이동하는
내 공간메뉴를 사용할 수 있고, 다른 계정 로그인은 현재 BFF 세션 정리 후 admin return path로 돌아갑니다.
Added
- Frontend runtime telemetry records SPA route load duration, route-boundary/runtime errors, and frontend-observed API failures through
/api/bff/observability/frontend-events. - Spring records the new frontend telemetry as
readmates.frontend.*Micrometer metrics and exposes SLO catalog entries for frontend route-load p95 and runtime error ratio. - Grafana dashboard source
ops/grafana/dashboards/frontend-runtime.jsontracks route load p95, runtime errors, API failures, and dropped frontend telemetry. - OCI observability deployment helpers now include Grafana provisioning and Prometheus datasource/dashboard wiring for the committed dashboard set.
- Platform admin shell UI now shows a workspace switcher for returning to member or host workspaces from admin context.
Changed
- Frontend API failure handling now emits safe observability events after
ReadmatesApiErrorconversion without exposing raw URLs, query strings, request/response bodies, cookies, tokens, emails, user identifiers, stack traces, club slugs, or deployment identifiers. - The BFF telemetry sanitizer forwards safe dropped-event reasons to Spring so invalid browser telemetry increments
readmates.frontend.observability.droppedinstead of being silently lost at the edge. - Observability runbooks, dashboard docs, metrics catalog, SLO docs, and release-readiness notes now distinguish local provisioning evidence from production scrape/dashboard evidence.
Deployment Notes
- Minor release. No Flyway migration is included.
- Server runtime code changed for additive frontend observability intake and Micrometer metrics. Deploy the backend image after
Deploy Server Imagepromotesghcr.io/<owner>/<repo>/readmates-server:v1.16.0. - Frontend runtime and Pages Functions changed.
Deploy Frontmust succeed for tagv1.16.0before final browser-facing smoke is considered complete. - Public API product contracts, OAuth scopes, auth cookie format, BFF secret format, and deployment workflow triggers are unchanged. The new telemetry endpoint is a fail-open same-origin side path.
- Completion order: push
main, push annotated tagv1.16.0, confirmDeploy FrontandDeploy Server Image, promote OCI Compose backend to the same image tag, create the GitHub Release, then run sanitized BFF/OAuth/frontend-observability smoke checks and production dashboard scrape checks.
Verification
- Local merged-main verification (2026-06-30):
git diff --check -- front server ops docs CHANGELOG.md,npx --yes pnpm@10.33.0 --dir front lint,npx --yes pnpm@10.33.0 --dir front test,npx --yes pnpm@10.33.0 --dir front build,npx --yes pnpm@10.33.0 --dir front test:e2e,./server/gradlew -p server check architectureTest,./scripts/lint-grafana-dashboards.sh,./scripts/validate-prometheus-rules.sh,./scripts/build-public-release-candidate.sh, and./scripts/public-release-check.sh .tmp/public-release-candidatepassed. - Focused observability verification (2026-06-30): frontend observability client/contracts/BFF tests, route observability tests,
ReadmatesApiErrorAPI-failure tests, Spring frontend observability controller/service/metrics tests, SLO catalog docs consistency, Grafana dashboard lint, Prometheus rule validation, and preview Lighthouse public smoke passed. - Public safety: clean public release candidate passed gitleaks and scanner checks. Telemetry labels are normalized route patterns, enum-like API groups, status classes, safe error codes, severity, navigation type, result, and allowlisted dropped reasons only.
- Skipped before tag push: tag-triggered
Deploy Front, tag-triggeredDeploy Server Image, OCI Compose backend promotion, GitHub Release publication, production scrape/dashboard data confirmation, external synthetic monitor setup, production OAuth/provider-console checks, and post-deploy smoke. These require pushedmain/tag or production operator access and are release-operation evidence after publication.