| Age | Commit message (Collapse) | Author |
|
Switch deckAtom, cardsByDeckAtomFamily, noteTypesAtom, and studyDataAtom
to a stale-while-revalidate pattern: read from IndexedDB synchronously,
trigger sync in the background, and refetch on sync_complete. When local
is empty, await a single bootstrap pull before deciding there's no data.
Add study-builder to assemble StudyCards from LocalCard + Note + NoteType
+ field values, replacing the server /study endpoint dependency. The
study session can now run end-to-end offline.
Disable submit on all write modals when offline since writes still
require the server. Add a "Showing cached data" hint to the sync status
indicator. Drop cacheStudyCards (cards arrive via regular sync pull now)
and update page tests to reflect that lists no longer refresh by hitting
the GET API.
|
|
Move FSRS scheduling to a shared module so the client can compute next
card state without contacting the server. StudyPage now writes the
updated card and review log straight to IndexedDB and lets the existing
sync engine push them on reconnect, instead of POSTing to
/api/decks/:deckId/study/:cardId. Online sessions still trigger a sync
immediately so server-side aggregates stay fresh; offline sessions
accumulate in pendingCountAtom until the next online tick.
The legacy study POST route is preserved for backwards compatibility.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
Previously when the session expired, the API client cleared tokens but
the UI displayed "Invalid or expired token" instead of redirecting to
the login page. The root cause was that isAuthenticatedAtom was derived
from userAtom only as a re-evaluation trigger, while the actual value
came from apiClient.isAuthenticated(). On page reload userAtom is null,
so setting it to null on session expiry did not trigger a re-render and
ProtectedRoute never redirected.
Make userAtom (persisted via atomWithStorage) the single source of truth
for auth state, derive isAuthenticatedAtom from it, drop the redundant
apiClient.isAuthenticated(), and explicitly navigate to /login on
session expiry. Also trigger session expiry when a 401 comes back with
no refresh token available.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
Allow each deck to specify a default note type that is auto-selected
when creating new notes. Includes DB schema migration, server API
updates, sync layer support, and UI for editing the default in the
deck settings modal.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
Add totalCardCount and reviewCardCount to deck API responses and
display a progress bar on the home page for each deck with cards.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
Card and StudyCard interfaces used generic number for state, causing
type errors when indexing Record<CardStateType, ...> maps. Also adds
missing FSRS fields to client Card interface to match API response.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
Add newCardCount alongside Total and Due stats in the deck detail view,
queried from cards with state=New via a new countNewCards repository method.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
REVIEW_CARDS_LIMIT(復習カード80枚制限)とnewCardsPerDay(1日の新規カード制限)
を削除し、期日が来たすべてのカードを制限なく返すように変更。
削除した主な要素:
- REVIEW_CARDS_LIMIT定数とカード取得時のlimitパラメータ
- newCardsPerDayフィールド(DB schema, 型定義, Zod schema, sync, CRDT)
- countDueNewCards, countDueReviewCards, findDueNewCardsForStudy,
findDueReviewCardsForStudy(CardRepository)
- countTodayNewCardReviews(ReviewLogRepository)
- デッキルートからのReviewLogRepository依存
https://claude.ai/code/session_018hrEJ9vg3RPoeAPyEc17gS
|
|
Shuffle order is now fixed within a study day by seeding mulberry32
with the study day boundary timestamp (3:00 AM rollover).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
Replace built-in jotai atomFamily with jotai-family package for better
parameter-based atom family support.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
Replace custom createReloadableAtom/createReloadableAtomFamily with
atomWithSuspenseQuery from jotai-tanstack-query, leveraging TanStack
Query's built-in caching, invalidation, and Suspense support.
- Add @tanstack/query-core and jotai-tanstack-query dependencies
- Create shared QueryClient instance (src/client/queryClient.ts)
- Migrate all data atoms (decks, cards, study, noteTypes) to atomWithSuspenseQuery
- Update page components to use .data destructuring and queryClient.invalidateQueries()
- Update all test files to use QueryClient for data hydration
- Remove src/client/atoms/utils.ts (no longer needed)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
Display a badge with the number of cards due for study today next to
each deck name on the home page. The count is fetched along with deck
data from the API to minimize additional network requests.
|
|
Replace AuthProvider and SyncProvider with Jotai atoms for more granular
state management and better performance. This migration:
- Creates atoms for auth, sync, decks, cards, noteTypes, and study state
- Uses atomFamily for parameterized state (e.g., cards by deckId)
- Introduces StoreInitializer component for subscription initialization
- Updates all components and pages to use useAtomValue/useSetAtom
- Updates all tests to use Jotai Provider with createStore pattern
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|