From fe101104cdd50256d4ef5c61e1bf099ed2da68e3 Mon Sep 17 00:00:00 2001
From: nsfisis
Date: Sun, 7 Dec 2025 19:16:48 +0900
Subject: feat(server): add POST /api/sync/push endpoint
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Implement sync push endpoint with Last-Write-Wins conflict resolution.
Includes Zod validation for decks, cards, and review logs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5
---
src/client/pages/StudyPage.tsx | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
(limited to 'src/client/pages/StudyPage.tsx')
diff --git a/src/client/pages/StudyPage.tsx b/src/client/pages/StudyPage.tsx
index 05e9943..c6f8665 100644
--- a/src/client/pages/StudyPage.tsx
+++ b/src/client/pages/StudyPage.tsx
@@ -144,17 +144,14 @@ export function StudyPage() {
throw new ApiClientError("Not authenticated", 401);
}
- const res = await fetch(
- `/api/decks/${deckId}/study/${currentCard.id}`,
- {
- method: "POST",
- headers: {
- ...authHeader,
- "Content-Type": "application/json",
- },
- body: JSON.stringify({ rating, durationMs }),
+ const res = await fetch(`/api/decks/${deckId}/study/${currentCard.id}`, {
+ method: "POST",
+ headers: {
+ ...authHeader,
+ "Content-Type": "application/json",
},
- );
+ body: JSON.stringify({ rating, durationMs }),
+ });
if (!res.ok) {
const errorBody = await res.json().catch(() => ({}));
@@ -312,7 +309,13 @@ export function StudyPage() {
{completedCount}{" "}
card{completedCount !== 1 ? "s" : ""}.
-
+
@@ -336,7 +339,9 @@ export function StudyPage() {
}}
role="button"
tabIndex={0}
- aria-label={isFlipped ? "Card showing answer" : "Click to reveal answer"}
+ aria-label={
+ isFlipped ? "Card showing answer" : "Click to reveal answer"
+ }
style={{
border: "1px solid #ccc",
borderRadius: "8px",
--
cgit v1.2.3-70-g09d2