Skip to content

fix: allow access to app even if first sync fails#29

Merged
Shunseii merged 4 commits intomainfrom
feat/improve-scheduling-option-formatting
Dec 27, 2025
Merged

fix: allow access to app even if first sync fails#29
Shunseii merged 4 commits intomainfrom
feat/improve-scheduling-option-formatting

Conversation

@Shunseii
Copy link
Copy Markdown
Owner

@Shunseii Shunseii commented Dec 27, 2025

Summary by CodeRabbit

  • New Features

    • Flashcard grading now displays localized, direction-aware interval labels for each grade option.
    • Added comprehensive date and time utility constants for common durations.
  • Bug Fixes

    • Error messages now correctly display cause details only when present.
    • Database synchronization failures are now non-fatal; app continues with local data.
  • Refactor

    • Reorganized core utilities into modular external packages for improved maintainability.

✏️ Tip: You can customize this high-level summary in your review settings.

@Shunseii Shunseii self-assigned this Dec 27, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 27, 2025

📝 Walkthrough

Walkthrough

This PR refactors the codebase to externalize core utilities into workspace packages (@bahar/db-operations, @bahar/result, @bahar/search), removes local implementations, updates all dependent imports, adds date constants and utilities, enhances flashcard grading UI with pre-computed interval labels, removes tracedFetch, and adjusts error handling for remote database sync failures.

Changes

Cohort / File(s) Summary
Workspace Dependencies
apps/web/package.json
Added three workspace dependencies: @bahar/db-operations, @bahar/result, @bahar/search
Result Type Migration
apps/web/src/lib/result.ts
Module deleted; Result type, ok/err factories, tryCatch, and safeJsonParse removed (migrated to @bahar/result)
DB Operations Import Updates
apps/web/src/lib/db/index.ts, apps/web/src/lib/db/export/index.ts, apps/web/src/lib/db/operations/dictionary-entries.ts, apps/web/src/lib/db/operations/flashcards.ts
Updated imports to use @bahar/result and @bahar/db-operations; replaced convertRawDictionaryEntryToSelectDictionaryEntry calls with convertRawDictionaryEntryToSelect
DB Utils Removal
apps/web/src/lib/db/utils.ts
Module deleted; ConvertDictionaryEntryError type, buildSelectWithNestedJson, DICTIONARY_ENTRY_COLUMNS, and convertRawDictionaryEntryToSelectDictionaryEntry removed (migrated)
Search Module Refactoring
apps/web/src/lib/search/index.ts
Replaced ORM integration from createOramaDb/insertMultiple to createDictionaryDatabase/insertDocuments; removed legacy diacritics-based highlighting and related helpers
Orama Tokenizer Removal
apps/web/src/lib/search/orama-tokenizer.ts
Module deleted; OramaLanguage type, arabicTokenizer, multiLanguageTokenizer, and related normalization logic removed
Search Import Update
apps/web/src/components/search/Highlight.tsx
Updated import path for highlightWithDiacritics from "@/lib/search" to "@bahar/search"
Date Constants & Utilities
apps/web/src/lib/date/constants.ts, apps/web/src/lib/date/index.ts
New module with 20+ time-related constants (DAYS_IN_WEEK, MILLISECONDS_IN_*, etc.); new intlFormatDistance function for human-readable temporal distance formatting
Flashcard Grading UI
apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx, GradeOption.tsx, utils.ts
Added locale derivation from text direction; new formatScheduleOptions function computes interval labels per rating; GradeOption prop signature changed from due/now Date props to intervalLabel: string; added rendering guard for schedulingCards and intervalLabels
Cleanup & Error Handling
apps/web/src/lib/fetch.ts, apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx, apps/web/src/routes/_authorized-layout/route.tsx, apps/web/src/components/errors/ErrorMessage.tsx
Removed tracedFetch function; removed unused tracedFetch import; removed debug console.log; converted turso_remote_sync_failed from fatal to non-fatal error; added guard for error.cause rendering
Polyfill Cleanup
packages/db-operations/package.json, packages/db-operations/src/utils.ts
Removed react-native-get-random-values dependency; removed associated import

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 A hopping refactor brings delight,
Local modules fly to packages bright,
Interval labels computed with grace,
Flashcards redesigned at a faster pace,
Workspace powers unite the whole crate! 🚀

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title directly addresses the main objective: allowing access to the app when the first sync fails, which aligns with the core error handling changes in the PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/improve-scheduling-option-formatting

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Dec 27, 2025

Deploying bahar with  Cloudflare Pages  Cloudflare Pages

Latest commit: f087007
Status: ✅  Deploy successful!
Preview URL: https://d436d7bf.bahar-5xu.pages.dev
Branch Preview URL: https://feat-improve-scheduling-opti.bahar-5xu.pages.dev

View logs

@Shunseii Shunseii force-pushed the feat/improve-scheduling-option-formatting branch from 26cd618 to 1342caf Compare December 27, 2025 05:46
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Dec 27, 2025

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bahar-marketing f087007 Commit Preview URL Dec 27 2025, 07:01 AM

Base automatically changed from chore/migrate-to-bun-runtime to main December 27, 2025 05:56
@Shunseii Shunseii force-pushed the main branch 2 times, most recently from 67faeb6 to 39ec453 Compare December 27, 2025 06:37
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (6)
apps/web/src/lib/search/index.ts (2)

33-33: Consider using the exported BATCH_SIZE constant.

The BATCH_SIZE is hardcoded as 100 in both hydrateOramaDb and rehydrateOramaDb. However, @bahar/db-operations exports a BATCH_SIZE constant set to 500. Consider importing and using this constant for consistency across the codebase, or document why a different batch size is needed for Orama operations.

🔎 Proposed fix
+import { safeJsonParse, BATCH_SIZE } from "@bahar/db-operations";
-import { safeJsonParse } from "@bahar/db-operations";

 export const hydrateOramaDb = async () => {
   if (isOramaHydrated) return ok({ skippedCount: 0 });
 
-  const BATCH_SIZE = 100;
   const db = await ensureDb();

And similarly for rehydrateOramaDb:

 export const rehydrateOramaDb = async () => {
-  const BATCH_SIZE = 100;
   const db = await ensureDb();

Also applies to: 179-179


139-143: Remove unnecessary type casts.

The type casts oramaDb as DictionaryOrama and newOramaDb as DictionaryOrama are unnecessary. Since createDictionaryDatabase() returns DictionaryOrama, TypeScript should correctly infer the type. If the cast is needed due to a type mismatch, consider adding an explicit type annotation to the variable declaration instead.

🔎 Proposed fix

For hydrateOramaDb:

       if (dictionaryEntries.length > 0) {
         await insertDocuments(
-          oramaDb as DictionaryOrama,
+          oramaDb,
           dictionaryEntries,
           BATCH_SIZE,
         );

For rehydrateOramaDb:

       if (dictionaryEntries.length > 0) {
         await insertDocuments(
-          newOramaDb as DictionaryOrama,
+          newOramaDb,
           dictionaryEntries,
           BATCH_SIZE,
         );

If type errors occur, add explicit type annotations:

-let oramaDb = createDictionaryDatabase();
+let oramaDb: DictionaryOrama = createDictionaryDatabase();

Also applies to: 218-222

apps/web/src/components/errors/ErrorMessage.tsx (1)

117-124: Good defensive rendering improvement.

Adding the error.cause guard prevents displaying an empty "Cause:" field when no cause exists. The fragment wrapper on lines 118-123 is unnecessary for a single child but doesn't impact functionality.

🔎 Optional: Remove unnecessary fragment
               {isDisplayError && error.cause && (
-                <>
-                  <ErrorDetailField
-                    fieldName={<Trans>Cause:</Trans>}
-                    detail={error.cause}
-                  />
-                </>
+                <ErrorDetailField
+                  fieldName={<Trans>Cause:</Trans>}
+                  detail={error.cause}
+                />
               )}
apps/web/src/lib/date/index.ts (1)

142-146: Side-effect assignment inside condition reduces readability.

The assignment value = differenceInCalendarDays(laterDate, earlierDate) inside the condition is a code smell that makes the logic harder to follow.

🔎 Suggested refactor
-    } else if (
-      Math.abs(diffInSeconds) < SECONDS_IN_WEEK &&
-      (value = differenceInCalendarDays(laterDate, earlierDate)) &&
-      Math.abs(value) < 7
-    ) {
-      unit = "day";
+    } else if (Math.abs(diffInSeconds) < SECONDS_IN_WEEK) {
+      value = differenceInCalendarDays(laterDate, earlierDate);
+      if (Math.abs(value) < 7) {
+        unit = "day";
+      } else {
+        value = differenceInCalendarWeeks(laterDate, earlierDate);
+        unit = "week";
+      }
apps/web/src/components/features/flashcards/FlashcardDrawer/utils.ts (1)

60-66: Consider explicit initialization instead of type assertion.

The empty object with as Record<...> could lead to runtime issues if grades array is ever modified. A safer approach:

🔎 Suggested refactor
-  const results: Record<
-    ReviewRating,
-    { label: string; unit: IntlFormatDistanceUnit }
-  > = {} as Record<
-    ReviewRating,
-    { label: string; unit: IntlFormatDistanceUnit }
-  >;
+  const results = new Map<ReviewRating, { label: string; unit: IntlFormatDistanceUnit }>();

   for (const grade of grades) {
-    results[grade] = formatInterval({ due: dates[grade], now, locale });
+    results.set(grade, formatInterval({ due: dates[grade], now, locale }));
   }

Or initialize with all keys upfront if preferring object syntax.

apps/web/src/lib/date/constants.ts (1)

112-127: Minor inconsistency in MINUTES_IN_ constants.*

MINUTES_IN_YEAR (525600) assumes exactly 365 days, and MINUTES_IN_MONTH (43200) assumes exactly 30 days. This differs from SECONDS_IN_YEAR and SECONDS_IN_MONTH which use DAYS_IN_YEAR = 365.2425 for precision.

This is likely intentional for simplicity, but worth documenting if these constants are used interchangeably with the more precise SECONDS_IN_* variants.

🔎 Optional: derive from DAYS_IN_YEAR for consistency
-export const MINUTES_IN_YEAR = 525600;
+export const MINUTES_IN_YEAR = DAYS_IN_YEAR * 24 * 60; // ~525949.8

-export const MINUTES_IN_MONTH = 43200;
+export const MINUTES_IN_MONTH = MINUTES_IN_YEAR / 12; // ~43829.15
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 39ec453 and f087007.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (21)
  • apps/web/package.json
  • apps/web/src/components/errors/ErrorMessage.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/utils.ts
  • apps/web/src/components/search/Highlight.tsx
  • apps/web/src/lib/date/constants.ts
  • apps/web/src/lib/date/index.ts
  • apps/web/src/lib/db/export/index.ts
  • apps/web/src/lib/db/index.ts
  • apps/web/src/lib/db/operations/dictionary-entries.ts
  • apps/web/src/lib/db/operations/flashcards.ts
  • apps/web/src/lib/db/utils.ts
  • apps/web/src/lib/fetch.ts
  • apps/web/src/lib/result.ts
  • apps/web/src/lib/search/index.ts
  • apps/web/src/lib/search/orama-tokenizer.ts
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/routes/_authorized-layout/route.tsx
  • packages/db-operations/package.json
  • packages/db-operations/src/utils.ts
💤 Files with no reviewable changes (5)
  • apps/web/src/lib/fetch.ts
  • packages/db-operations/src/utils.ts
  • apps/web/src/lib/result.ts
  • apps/web/src/lib/search/orama-tokenizer.ts
  • apps/web/src/lib/db/utils.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript with strict typing across entire codebase; do not use any type unless absolutely necessary
Use DisplayError class for user-friendly error messages and Result<T, E> type for explicit error handling with Rust-like pattern
Use Drizzle ORM for database operations across all database interactions

Files:

  • apps/web/src/components/search/Highlight.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • apps/web/src/lib/date/index.ts
  • apps/web/src/lib/db/index.ts
  • apps/web/src/components/errors/ErrorMessage.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/lib/db/export/index.ts
  • apps/web/src/lib/date/constants.ts
  • apps/web/src/lib/db/operations/dictionary-entries.ts
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/lib/db/operations/flashcards.ts
  • apps/web/src/components/features/flashcards/FlashcardDrawer/utils.ts
  • apps/web/src/routes/_authorized-layout/route.tsx
  • apps/web/src/lib/search/index.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Write self-documenting code and avoid overuse of comments
Error handling with try/catch blocks and structured error types
Component naming: use PascalCase for components, camelCase for functions/variables

Files:

  • apps/web/src/components/search/Highlight.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • apps/web/src/lib/date/index.ts
  • apps/web/src/lib/db/index.ts
  • apps/web/src/components/errors/ErrorMessage.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/lib/db/export/index.ts
  • apps/web/src/lib/date/constants.ts
  • apps/web/src/lib/db/operations/dictionary-entries.ts
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/lib/db/operations/flashcards.ts
  • apps/web/src/components/features/flashcards/FlashcardDrawer/utils.ts
  • apps/web/src/routes/_authorized-layout/route.tsx
  • apps/web/src/lib/search/index.ts
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,jsx}: React components use functional style with hooks
Prefer using Jotai atoms over React Context
State management: use Tanstack Query for async state and Jotai for atomic state

Files:

  • apps/web/src/components/search/Highlight.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • apps/web/src/components/errors/ErrorMessage.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/routes/_authorized-layout/route.tsx
apps/web/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/web/**/*.{tsx,jsx}: Web app uses Shadcn/UI components and Tailwind CSS v4 for styling; use the cn() utility function for combining and conditionally applying Tailwind classes
Web app uses Tanstack Router for client-side routing

Files:

  • apps/web/src/components/search/Highlight.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • apps/web/src/components/errors/ErrorMessage.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/routes/_authorized-layout/route.tsx
🧠 Learnings (16)
📚 Learning: 2025-11-27T23:01:26.752Z
Learnt from: Shunseii
Repo: Shunseii/bahar PR: 24
File: packages/drizzle-user-db-schemas/package.json:1-20
Timestamp: 2025-11-27T23:01:26.752Z
Learning: drizzle-zod0.5.1 has peer dependencies of "zod": "*" (accepts any version) and "drizzle-orm": ">=0.23.13". The zod wildcard peer dependency means any zod version is compatible with drizzle-zod0.5.1.

Applied to files:

  • packages/db-operations/package.json
📚 Learning: 2025-12-27T05:56:33.043Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-27T05:56:33.043Z
Learning: Applies to **/*.{tsx,jsx} : Prefer using Jotai atoms over React Context

Applied to files:

  • apps/web/src/components/search/Highlight.tsx
📚 Learning: 2025-12-27T05:56:33.043Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-27T05:56:33.043Z
Learning: Applies to **/*.{tsx,jsx} : State management: use Tanstack Query for async state and Jotai for atomic state

Applied to files:

  • apps/web/src/components/search/Highlight.tsx
📚 Learning: 2025-11-27T06:02:25.941Z
Learnt from: Shunseii
Repo: Shunseii/bahar PR: 24
File: apps/web/src/components/features/decks/DeckDialogContent.tsx:195-201
Timestamp: 2025-11-27T06:02:25.941Z
Learning: In apps/web/src/components/features/decks/DeckDialogContent.tsx, the backend API calls (trpc.decks.create and trpc.decks.update) are temporary and planned to be removed after migration is complete.

Applied to files:

  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/lib/db/operations/flashcards.ts
  • apps/web/src/routes/_authorized-layout/route.tsx
📚 Learning: 2025-12-27T05:56:33.043Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-27T05:56:33.043Z
Learning: Applies to **/*.{tsx,jsx} : React components use functional style with hooks

Applied to files:

  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
📚 Learning: 2025-12-25T22:07:07.504Z
Learnt from: Shunseii
Repo: Shunseii/bahar PR: 27
File: apps/api/src/db/schema/auth.ts:34-36
Timestamp: 2025-12-25T22:07:07.504Z
Learning: Files in apps/api/src/db/schema/auth.ts are auto-generated by better-auth and should not be manually modified as changes will be overwritten. Any schema issues should be tested and reported upstream to better-auth.

Applied to files:

  • apps/web/src/lib/db/index.ts
  • apps/web/src/routes/_authorized-layout/route.tsx
📚 Learning: 2025-12-27T05:56:33.044Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-27T05:56:33.044Z
Learning: Applies to **/*.{ts,tsx} : Use Drizzle ORM for database operations across all database interactions

Applied to files:

  • apps/web/src/lib/db/index.ts
  • apps/web/src/lib/search/index.ts
📚 Learning: 2025-12-27T05:56:33.044Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-27T05:56:33.044Z
Learning: Applies to **/*.{ts,tsx} : Use `DisplayError` class for user-friendly error messages and `Result<T, E>` type for explicit error handling with Rust-like pattern

Applied to files:

  • apps/web/src/components/errors/ErrorMessage.tsx
📚 Learning: 2025-12-27T05:56:33.044Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-27T05:56:33.044Z
Learning: Applies to apps/web/**/*.{tsx,jsx} : Web app uses Tanstack Router for client-side routing

Applied to files:

  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/routes/_authorized-layout/route.tsx
📚 Learning: 2025-12-27T05:56:33.043Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-27T05:56:33.043Z
Learning: Applies to apps/web/**/*.{tsx,jsx} : Web app uses Shadcn/UI components and Tailwind CSS v4 for styling; use the `cn()` utility function for combining and conditionally applying Tailwind classes

Applied to files:

  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
📚 Learning: 2025-12-27T05:56:33.043Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-27T05:56:33.043Z
Learning: Applies to apps/mobile/**/*.{tsx,jsx} : Mobile app uses UniWind (Tailwind for React Native) with Tailwind CSS v4

Applied to files:

  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
📚 Learning: 2025-12-27T05:56:33.043Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-27T05:56:33.043Z
Learning: Applies to apps/mobile/**/*.{tsx,jsx} : Mobile app uses Expo with file-based routing (Expo Router)

Applied to files:

  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
📚 Learning: 2025-12-27T05:56:33.044Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-27T05:56:33.044Z
Learning: Orama search engine is client-side WASM with multi-language support (Arabic and English), indexed from local database on app initialization, featuring stemming, stopwords, and quantized positional search (QPS)

Applied to files:

  • apps/web/src/lib/search/index.ts
📚 Learning: 2025-11-27T06:51:53.688Z
Learnt from: Shunseii
Repo: Shunseii/bahar PR: 24
File: apps/web/src/lib/search/orama-tokenizer.ts:31-31
Timestamp: 2025-11-27T06:51:53.688Z
Learning: In Orama (search library), custom tokenizers must include a `normalizationCache: Map<string, string>` property as part of the required tokenizer interface, even if not explicitly used in the tokenize method implementation. This is part of Orama's documented API contract for custom tokenizers.

Applied to files:

  • apps/web/src/lib/search/index.ts
📚 Learning: 2025-11-27T06:48:31.996Z
Learnt from: Shunseii
Repo: Shunseii/bahar PR: 24
File: apps/web/src/hooks/db/index.ts:59-60
Timestamp: 2025-11-27T06:48:31.996Z
Learning: In the Bahar project, Orama methods (insert, update, remove, search) are synchronous by default since no async plugins are being used. Orama v3.0.0+ core methods are sync; they only become async when specific plugins like plugin-embeddings are added. Do not suggest awaiting Orama operations unless async plugins are confirmed to be in use.

Applied to files:

  • apps/web/src/lib/search/index.ts
📚 Learning: 2025-11-27T06:48:57.365Z
Learnt from: Shunseii
Repo: Shunseii/bahar PR: 24
File: apps/web/src/hooks/db/index.ts:84-85
Timestamp: 2025-11-27T06:48:57.365Z
Learning: In the Orama search library, core operations like insert(), remove(), and update() are synchronous by default. They only become asynchronous when specific plugins (e.g., embedding generators) or Orama Cloud features are used. Don't suggest awaiting these operations unless async plugins are confirmed to be in use.

Applied to files:

  • apps/web/src/lib/search/index.ts
🧬 Code graph analysis (5)
apps/web/src/lib/date/index.ts (1)
apps/web/src/lib/date/constants.ts (7)
  • SECONDS_IN_MINUTE (168-168)
  • SECONDS_IN_HOUR (161-161)
  • SECONDS_IN_DAY (175-175)
  • SECONDS_IN_WEEK (182-182)
  • SECONDS_IN_MONTH (196-196)
  • SECONDS_IN_QUARTER (203-203)
  • SECONDS_IN_YEAR (189-189)
apps/web/src/components/errors/ErrorMessage.tsx (1)
apps/web/src/lib/error.ts (1)
  • error (42-44)
apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx (2)
apps/web/src/lib/db/import/index.ts (3)
  • batchArray (69-73)
  • createImportStatements (11-11)
  • createImportStatements (37-46)
apps/web/src/lib/db/import/v1/index.ts (1)
  • createImportStatements (14-77)
apps/web/src/lib/db/operations/dictionary-entries.ts (2)
packages/db-operations/src/index.ts (1)
  • convertRawDictionaryEntryToSelect (29-29)
packages/db-operations/src/converters.ts (1)
  • convertRawDictionaryEntryToSelect (55-124)
apps/web/src/lib/search/index.ts (5)
packages/search/src/database.ts (2)
  • createDictionaryDatabase (41-50)
  • insertDocuments (55-61)
packages/search/src/index.ts (3)
  • createDictionaryDatabase (33-33)
  • insertDocuments (34-34)
  • DictionaryOrama (29-29)
packages/db-operations/src/constants.ts (1)
  • BATCH_SIZE (36-36)
apps/mobile/src/lib/search/index.ts (1)
  • rehydrateOramaDb (57-112)
apps/web/src/lib/db/index.ts (1)
  • ensureDb (33-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Cloudflare Pages
  • GitHub Check: Workers Builds: bahar-marketing
🔇 Additional comments (16)
apps/web/src/lib/db/operations/flashcards.ts (2)

14-16: LGTM: Import refactoring aligns with workspace package consolidation.

The migration from local ../utils to the workspace package @bahar/db-operations improves code organization and reusability. Keeping DICTIONARY_ENTRY_COLUMNS and the conversion function together ensures consistency.


133-159: LGTM: Function call updated correctly.

The call to convertRawDictionaryEntryToSelect maintains the same usage pattern and error handling logic. TypeScript type checking ensures signature compatibility, and the Result-based error handling with Sentry logging remains intact.

apps/web/src/components/search/Highlight.tsx (1)

1-16: LGTM!

The import path update to @bahar/search aligns with the workspace package externalization. The component correctly uses Jotai for atomic state, memoization for performance, and DOMPurify for XSS protection.

apps/web/src/lib/db/index.ts (2)

4-4: LGTM on import update.

Import path correctly migrated to the workspace package @bahar/result.


154-166: The review comment is incorrect. The PR objective is already met by the current code.

The turso_remote_sync_failed error is explicitly handled in the route's beforeLoad (lines 287-289 in _authorized-layout/route.tsx), where it breaks without throwing, allowing the app to continue. The Route does not return ok(null) from _initDbInternal because the current design is better: it returns the Result with error details, and callers decide how to handle it. This allows different call sites to handle sync failures differently, while in this case the route handler specifically allows continuation for sync failures to permit offline-first usage with the local database.

apps/web/src/lib/db/export/index.ts (1)

6-10: LGTM!

Import paths correctly updated to workspace packages, and the function call renamed to match the new @bahar/db-operations API. Error handling logic remains intact.

Also applies to: 25-25

apps/web/src/lib/db/operations/dictionary-entries.ts (2)

8-11: LGTM!

Import correctly updated to @bahar/db-operations.


37-41: LGTM!

All four usages of convertRawDictionaryEntryToSelect are consistently updated to use the new function name from @bahar/db-operations. Error handling pattern remains correct throughout.

Also applies to: 132-136, 246-250, 281-285

apps/web/package.json (1)

14-17: LGTM!

New workspace dependencies correctly added to support the externalized utilities. The workspace:* protocol is appropriate for internal packages.

apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx (2)

271-273: LGTM!

Formatting change only. The spread of the generator into an array is correct for batch processing.


284-285: LGTM!

Cosmetic formatting changes that improve readability. No functional impact.

Also applies to: 387-397

packages/db-operations/package.json (1)

19-21: LGTM!

The cleanup of dependencies looks appropriate. nanoid is actively used in src/utils.ts and keeping it as the only runtime dependency aligns with the package's purpose.

apps/web/src/routes/_authorized-layout/route.tsx (1)

296-299: LGTM! Graceful degradation for remote sync failures.

The change correctly allows users to continue using the app with the local database when the initial remote sync fails. The error is still captured in Sentry (lines 233-240), ensuring visibility for debugging while not blocking the user experience.

apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx (1)

17-28: LGTM! Clean simplification of props interface.

Moving the interval formatting logic out of this component improves separation of concerns. The component is now a pure presentation component that receives a pre-computed label string.

apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx (1)

146-162: LGTM! Well-structured interval label computation.

The memoization correctly depends on schedulingCards, now, and locale. The guard at line 436 ensures grade options only render when labels are available.

One consideration: the locale derivation (line 147) is limited to Arabic (ar-u-nu-arab) for RTL and English (en) otherwise. If additional RTL languages (e.g., Hebrew, Persian) are added in the future, this logic may need to be revisited.

apps/web/src/lib/date/constants.ts (1)

1-16: Well-documented constants module.

The JSDoc documentation is thorough and follows date-fns conventions. Good use of derived constants (e.g., SECONDS_IN_DAY = SECONDS_IN_HOUR * 24) to avoid magic numbers and ensure consistency.

Comment thread apps/web/src/lib/date/index.ts
Comment thread apps/web/src/lib/date/index.ts
@Shunseii Shunseii merged commit 395b134 into main Dec 27, 2025
3 checks passed
@Shunseii Shunseii deleted the feat/improve-scheduling-option-formatting branch December 27, 2025 07:14
This was referenced Apr 2, 2026
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.

1 participant