Skip to content

[fix/MAT-524] 필기 자동저장 race 로 인한 백엔드 빈 PUT 회귀 fix#312

Open
b0nsu wants to merge 2 commits intofix/mat-349-handwriting-api-cache-strategyfrom
fix/mat-524-autosave-data-loss
Open

[fix/MAT-524] 필기 자동저장 race 로 인한 백엔드 빈 PUT 회귀 fix#312
b0nsu wants to merge 2 commits intofix/mat-349-handwriting-api-cache-strategyfrom
fix/mat-524-autosave-data-loss

Conversation

@b0nsu
Copy link
Copy Markdown
Collaborator

@b0nsu b0nsu commented May 4, 2026

Summary

handwriting autosave race 봉쇄. 빠른 탭 전환 시 빈 PUT 으로 백엔드 데이터를 덮어쓰던 regression 해결.

Stacked on PR #288 (MAT-349) — base: `fix/mat-349-handwriting-api-cache-strategy`

Linear

Changes

  • race 가드 ref 3개 (`appliedScrapIdRef`, `pendingLoadRef`, `needsSaveRef`) — 데이터 적용 전 PUT 차단
  • pure helper (`evaluateFlush`, `canMark`) 매니저 inline — race 가드 dispatch
  • autosave fire-and-forget / 명시 flush `mutateAsync` + 5s timeout (silent, 실패 시 toast)
  • decode 실패 시 전화면 에러 + PUT 차단
  • `key={drawing-canvas-${scrapId}}` 제거, 매니저 imperative reset
  • canvas mount: callback ref + boolean state (drawing.tsx `useImperativeHandle` deps 없는 문제 우회)

Testing

  • `pnpm typecheck` / `pnpm lint` 통과
  • 시뮬레이터 (수동): 탭 A→B→A 빠른 전환, cold load + 재진입, AppState bg flush, 빈 스크랩

Risk / Impact

  • 영향 범위: ScrapDetailScreen 필기 자동저장
  • 검증: 탭 A→B→A→C→A 빠른 전환 5회 반복 시 A의 그림이 사라지지 않는지
  • 배포 유의: silent flush (저장 진행 중 UI 표시 없음, 실패 시 toast). spec AC-4.2 약화 — 디자이너 컨펌 후 follow-up 가능

Follow-ups

  • MAT-542 — base64 wrapping 제거 (서버 합의 필요)
  • MAT-543 — autosave debounce + stroke count limit
  • useImperativeHandle deps 안정화 — PR [feat/MAT-364] 캔버스 통합 #306 (MAT-364) fold

Screenshots / Video

(필요 시)

@linear
Copy link
Copy Markdown

linear Bot commented May 4, 2026

@vercel
Copy link
Copy Markdown

vercel Bot commented May 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pointer-admin Ready Ready Preview, Comment May 5, 2026 3:40am

@b0nsu b0nsu changed the title [fix/MAT-524] staleTime: Infinity 도입으로 인한 필기 데이터 유실 (autosave regression) [fix/MAT-524] staleTime: Infinity 도입으로 인한 필기 데이터 유실 May 4, 2026
@b0nsu b0nsu changed the base branch from develop to fix/mat-349-handwriting-api-cache-strategy May 4, 2026 15:26
- race 가드 ref 3개 (appliedScrapIdRef, pendingLoadRef, needsSaveRef) — 데이터 적용 전 PUT 차단
- pure helper (evaluateFlush, canMark) 매니저 inline — race 가드 dispatch
- autosave fire-and-forget / 명시 flush mutateAsync + 5s timeout (silent, 실패 시 toast)
- decode 실패 시 전화면 에러 + PUT 차단
- key={drawing-canvas-\${scrapId}} 제거, 매니저 imperative reset
- canvas mount: callback ref + boolean state (drawing.tsx useImperativeHandle deps 없는 문제 우회)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a regression where introducing staleTime: Infinity caused a handwriting autosave race, leading to empty PUT requests overwriting existing backend handwriting data during fast tab/scrap switching in ScrapDetailScreen.

Changes:

  • Reworked handwriting autosave to guard against pre-load PUTs using screen-scoped refs (appliedScrapIdRef, pendingLoadRef, needsSaveRef) and explicit flushPending() semantics.
  • Removed DrawingCanvas remount-by-key and moved canvas reset/attachment into the handwriting manager via an imperative callback ref.
  • Added a decode-failure UI state that blocks saving and forces an explicit back navigation.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
apps/native/src/features/student/scrap/screens/ScrapDetailScreen.tsx Switches to the new handwriting manager API (flush + canvas ref callback), adds decode error screen, and removes key-based canvas remounting.
apps/native/src/features/student/scrap/hooks/useHandwritingManager.ts Implements race-guarded load/apply, autosave interval, explicit flush with timeout, and local mutation/cache updates for handwriting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/native/src/features/student/scrap/hooks/useHandwritingManager.ts Outdated
Comment thread apps/native/src/features/student/scrap/hooks/useHandwritingManager.ts Outdated
Comment thread apps/native/src/features/student/scrap/hooks/useHandwritingManager.ts Outdated
Comment thread apps/native/src/features/student/scrap/hooks/useHandwritingManager.ts Outdated
- flushPending Promise<boolean> → Promise<void> (호출부 ok 가드 3곳 제거)
- autosave fire-and-forget 실패 시 needsSaveRef 복구 — 다음 interval 에 재시도
- 자동저장 토스트 제거, 명시 flush 토스트만 유지 (이중 토스트 방지)
- inline useMutation 제거, useUpdateHandwriting 재사용

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@b0nsu b0nsu changed the title [fix/MAT-524] staleTime: Infinity 도입으로 인한 필기 데이터 유실 [fix/MAT-524] 필기 자동저장 race 로 인한 백엔드 빈 PUT 회귀 fix May 5, 2026
b0nsu added a commit that referenced this pull request May 5, 2026
5초 autosave 메인 스레드 4단계 직렬화(stringify → encodeURIComponent
→ unescape → btoa)를 1단계(JSON.stringify)로 축소.

handwritingEncoder
- canonicalize: Stroke / Point / TextItem 의 키 순서를 명시 재구성하여
  byte-stable JSON 출력 보장 (동일 입력 → 동일 출력).
- decodeHandwritingData: 응답 객체만 받는 단일 시그니처. dataJson 우선,
  없으면 data(base64) fallback, 둘 다 없으면 빈값. 옛 strokes-only
  배열 형식 호환 유지.

useHandwritingManager
- PUT body 를 { dataJson } 으로 (data 미포함) — 자연 마이그레이션.
- 응답 분기를 decodeHandwritingData(handwritingData) 로 단순화.

Stacked on PR #312 — base: fix/mat-524-autosave-data-loss.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants