このドキュメントは、StudyTodoの開発における共通ルールとベストプラクティスを定義します。
StudyTodo/
├── apps/
│ ├── web/ # Next.js (Dexie.js)
│ └── mobile/ # Expo React Native (SQLite)
└── packages/
└── shared/ # 共有コード
カテゴリ
例
型定義
Todo, Category, Session, SRSProfile
ビジネスロジック
同期処理、マージロジック、SRS計算
ユーティリティ
日付変換、ID生成、バリデーション
データ変換
mapper (camelCase ⇔ snake_case)
カテゴリ
理由
UIコンポーネント
プラットフォーム固有のスタイルが必要
DB操作
Dexie.js (Web) vs SQLite (Mobile)
認証処理
ストレージ方式が異なる
packages/shared/src/ に実装
packages/shared/src/index.ts にエクスポートを追加
npm run build -w @studytodo/shared でビルド
各アプリから @studytodo/shared としてインポート
保存 : ISO 8601 文字列("2025-01-01T10:00:00.000Z")
操作 : Date オブジェクトに変換して操作
表示 : date-fns を使用してフォーマット
import { parseDate , toISOString , compareDates } from '@studytodo/shared' ;
// パース(無効な値は undefined)
const date = parseDate ( todo . dueDate ) ;
// ISO文字列に変換
const isoString = toISOString ( new Date ( ) ) ;
// 比較(cloud > local なら正の値)
const diff = compareDates ( cloudItem . updatedAt , localItem . updatedAt ) ;
if ( diff > 0 ) {
// クラウドが新しい
}
// ❌ 避けるべき
new Date ( value || 0 ) . getTime ( ) // 無効な値の処理が曖昧
// ✅ 推奨
compareDates ( cloudValue , localValue ) // 共通ユーティリティを使用
ワークスペース
フレームワーク
備考
packages/shared
Vitest
全テスト実行可能
apps/web
Vitest
コンポーネントテスト対応
apps/mobile
Vitest
純粋なロジックテストのみ
src/
├── utils/
│ ├── date.ts
│ └── __tests__/
│ └── date.test.ts # ユニットテスト
└── hooks/
├── useSync.ts
└── __tests__/
└── useSync.test.ts # フックテスト
# 全テスト
npm test
# 個別実行
npm test -w @studytodo/shared
npm test -w @studytodo/web
npm test -w mobile
優先度
対象
例
🔴 高
共有ロジック
mapper, syncCore, date utils
🔴 高
ビジネスロジック
SRS計算、スケジュール範囲計算
🟡 中
データフック
useMobileTodos, useSync
🟢 低
UIコンポーネント
静的な表示のみ
種類
規則
例
コンポーネント
PascalCase
TodoList.tsx, MobileTimerView.tsx
フック
camelCase(useプレフィックス)
useMobileTodos.ts, useSync.ts
ユーティリティ
camelCase
date.ts, mapper.ts
テスト
元ファイル名 + .test
date.test.ts, mapper.test.ts
種類
規則
例
ローカル変数
camelCase
cloudItem, localTodos
定数
UPPER_SNAKE_CASE または camelCase
MAX_RETRIES, allowedFieldsMap
型/インターフェース
PascalCase
Todo, SyncHandlers
try {
await processTableSync ( ...) ;
} catch ( error ) {
console . error ( '[Sync Error]:' , error ) ;
// オフラインキューに追加
await offlineQueue . add ( { ... } ) ;
}
const date = parseDate ( value ) ;
if ( ! date ) {
// 無効な日付として処理
return undefined ;
}
9.1 共有パッケージのエクスポートが見つからない
Module '...' has no exported member '...' エラーが発生する場合:
packages/shared がビルドされているか確認してください。
npm run build -w @studytodo/shared
VS Code等のエディタを再起動するか、TypeScriptサーバを再起動してください。
packages/shared/dist/index.d.ts に対象のエクスポートが含まれているか確認してください。