diff --git a/CLAUDE.md b/CLAUDE.md
index dd08709..7ae7708 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -22,75 +22,6 @@ This is a TypeScript monorepo using a Convex backend and SvelteKit frontend with
- `packages/client/` - SvelteKit frontend with Tauri integration
- `packages/convex/` - Convex backend with database schema and functions
-## Development Commands
-
-### Setup
-
-```bash
-bun install --frozen-lockfile
-```
-
-### Development Servers
-
-```bash
-# Main development (Convex + Web Client)
-bun dev
-
-# All development servers including Storybook
-bun dev:all
-
-# Individual servers
-bun dev:web # Web client at http://localhost:5173
-bun dev:convex # Convex at http://localhost:3210, Dashboard at http://localhost:6790
-bun dev:storybook # Storybook at http://localhost:6006
-bun dev:tauri # Desktop app (conflicts with web client)
-```
-
-### Building and Testing
-
-```bash
-# Build all apps
-bun run --filter=* build
-
-# Run tests
-bun test
-
-# Type checking and linting
-bun check # Runs lint + format + all app checks
-bun check:lint # Biome linting only
-bun check:format # Prettier formatting check only
-
-# Auto-fix
-bun fix # Auto-fix lint + format issues
-bun fix:lint # Biome auto-fix
-bun fix:format # Prettier auto-format
-```
-
-### Convex Operations
-
-```bash
-# Convex CLI commands
-bun convex [command]
-
-# Code generation (run after schema changes)
-bun sync
-```
-
-### Internationalization
-
-```bash
-# Compile i18n messages
-bun paraglide
-```
-
-## Code Architecture
-
-### Svelte Documentation
-
-When working with Svelte code, always reference the latest documentation:
-
-- **Latest Svelte Docs**: https://svelte.dev/llms-small.txt
-
### Frontend (SvelteKit)
- **Routes**: Standard SvelteKit routing in `packages/client/src/routes/`
@@ -100,9 +31,33 @@ When working with Svelte code, always reference the latest documentation:
- `@@` → `../..` (workspace root)
- `$components` → `src/components`
- `~` → `src/`
+ - `@packages/{package}` → monorepo
- **Convex Integration**: Uses `convex-svelte` for reactive queries
- **State Pattern**: Logic components (e.g., TaskList.svelte) separate from presentation (TaskListSkin.svelte)
+### Backend (Convex)
+
+- **Schema**: Defined in `packages/convex/src/convex/schema.ts`
+- **Functions**: Database operations in `packages/convex/src/convex/[feature].ts`
+- **Type Safety**: Auto-generated types from schema shared with frontend via workspace dependency
+
+### Data Flow
+
+1. Convex schema defines database structure
+2. Convex functions provide type-safe CRUD operations
+3. Frontend uses `convex-svelte` hooks for reactive data
+4. Automatic type generation ensures type safety across stack
+
+## Framework - Convex
+
+### Convex の Import について
+
+```ts
+import { api, type Id } from "@packages/convex";
+
+// use api and type Id ...
+```
+
### 注意点: convex-svelte の `useQuery` について
`useQuery` に渡す引数は、関数の形式で渡してください。そうでないと、期待しない動作を引き起こす可能性があります。
@@ -141,60 +96,61 @@ createOrganization.processing; // boolean, use for button disabled state / loadi
createOrganization.error; // string | null, use for error messages
```
-### Backend (Convex)
-
-- **Schema**: Defined in `packages/convex/src/convex/schema.ts`
-- **Functions**: Database operations in `packages/convex/src/convex/[feature].ts`
-- **Type Safety**: Auto-generated types from schema shared with frontend via workspace dependency
-
-### Data Flow
+## Framework - Svelte
-1. Convex schema defines database structure
-2. Convex functions provide type-safe CRUD operations
-3. Frontend uses `convex-svelte` hooks for reactive data
-4. Automatic type generation ensures type safety across stack
+### Syntax
-## Code Quality
+Never use logacy svelte syntax. This project uses Svelte 5 runes mode.
-### Linting and Formatting
+- ❌ FORBIDDEN: `$: reactiveVar = ...` (reactive statements)
+- ❌ FORBIDDEN: `let count = 0` for reactive state
+- ✅ REQUIRED: `let count = $state(0)` for reactive state
+- ✅ REQUIRED: `$effect(() => { ... })` for side effects
+- ✅ REQUIRED: `const sum = $derived(a + b);` for derived variables
+- ✅ REQUIRED: `const sum = $derived.by(() => { if (a + b < 0) return 0; return a + b; );` for derived variables which needs a block.
-- **Biome**: Primary linter with strict rules
-- **Prettier**: Code formatting (Biome formatter disabled)
-- **Lefthook**: Pre-commit hooks for code generation and formatting
+### Svelte Capabilities
-### Special Biome Rules
+- clsx: Svelte has clsx builtin to its class. `
{text}
`
-- Svelte files have relaxed rules for unused variables/imports
-- Convex files exempt from import extension requirements
-- Strict style rules including parameter assignment, const assertions
+- reactive class: Svelte allows defining reactive controller classes inside ".svelte.ts" files for reusability and separation of concerns.
-### Pre-commit Hooks
-
-- Automatic code generation (`bun sync`)
-- Automatic formatting (`bun fix:format`)
+```ts
+// my-controller.svelte.ts
+class MyController {
+ foo = $state(3);
+ bar: number;
+ baz = $derived.by(() => bar + baz); // use derived.by if it needs to be lazy-initialized
+ doubleQux: number;
+ // unless it doesn't change at runtime (e.g. static configuration - initBar in this example),
+ // using getter function is better for reactivity.
+ constructor(initBar: number, props: () => { qux: number }) {
+ this.bar = $state(initBar);
+ this.doubleQux = $derived(props().qux * 2);
+ }
+}
+```
-## Tauri Desktop App
+## Code Quality / Coding Rules
-Tauri integration requires separate development workflow:
+### Common Rules
-```bash
-# Start backend first
-bun dev:convex
+- FILE LENGTH: Prefer short files, 30 ~ 50 lines recommended, 100 lines MAX.
+- CHECK: Always run `bun check` after writing code.
+- DOCUMENTATION: document the behavior (and optionally the expected usage) of the code, not the implementation
-# Then start Tauri (in separate terminal)
-bun dev:tauri
-```
+### Svelte
-Tauri conflicts with the web development server and requires more resources for compilation.
+- NAMING: Name snippets with camelCase instead of PascalCase to avoid confusion with components.
+- ALIAS: Use TypeScript import alias for client code. `import component from "~/features/foo/component.svelte";`
+- STYLING: Don't use style blocks in Svelte components, instead use TailwindCSS and DaisyUI.
+- STYLING: Always prefer using DaisyUI classes, and use minimal Tailwind classes.
+- SEPARATE COMPONENTS: Separate components into smallest pieces for readability.
+- SEPARATE LOGIC: Separate Logic from .svelte files into .svelte.ts files.
+ - .svelte.ts files should handle Calculation / Reactivity, while .svelte files should handle UI changes (e.g. navigation, modal open).
+ - if it has any reusable utility function, it should be separated again into plain .ts files / .svelte.ts
+ - An Ideal import tree would look like this: `UI component [.svelte] -> controller [.svelte.ts] -> processor [.svelte.ts] -> pure logic utility [.ts]`
-## Coding Instructions
+### Convex Rules
-- **🚫 NEVER USE LEGACY SVELTE SYNTAX**: This project uses Svelte 5 runes mode
- - ❌ FORBIDDEN: `$: reactiveVar = ...` (reactive statements)
- - ❌ FORBIDDEN: `let count = 0` for reactive state
- - ✅ REQUIRED: `const reactiveVar = $derived(...)`
- - ✅ REQUIRED: `let count = $state(0)` for reactive state
- - ✅ REQUIRED: `$effect(() => { ... })` for side effects
-- Always prefer using DaisyUI classes, and use minimal Tailwind classes.
-- Separate components into smallest pieces for readability.
-- Name snippets with camelCase instead of PascalCase to avoid confusion with components.
+- AUTHORIZATION: write authorization determinator in `packages/convex/src/convex/perms.ts`
diff --git a/docs/file-upload/implement.md b/docs/file-upload/implement.md
new file mode 100644
index 0000000..17ef079
--- /dev/null
+++ b/docs/file-upload/implement.md
@@ -0,0 +1,198 @@
+# ファイルアップロード機能 設計書
+
+## 概要
+
+Prismチャットアプリケーションにおけるファイルアップロード機能の詳細設計書です。
+
+## システム構成
+
+- **フロントエンド**: SvelteKit (Svelte 5 runes mode)
+- **バックエンド**: Convex (リアルタイムデータベース & API)
+- **ファイルストレージ**: Convex File Storage
+- **認証**: Convex Auth
+
+## 機能要件
+
+### 基本機能
+
+- ✅ チャット内でのファイル添付・アップロード
+- ✅ ドラッグ&ドロップによるファイルアップロード
+- ✅ 複数ファイルの同時アップロード
+- ✅ アップロード進捗表示
+- ✅ ファイルプレビュー(画像)
+- ✅ ファイルダウンロード
+
+### 対応ファイル形式
+
+- **画像**: `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`
+- **文書**: `.pdf`, `.txt`, `.doc`, `.docx`
+- **その他**: 一般的なファイル形式
+
+### 制限事項
+
+- **ファイルサイズ**: 最大 10MB
+- **同時アップロード**: 最大 5ファイル
+- **権限**: Organization/Channel メンバーのみ
+
+## データベース設計
+
+### 新しいテーブル: `files`
+
+```typescript
+files: defineTable({
+ // Convex Storage ID
+ storageId: v.string(),
+ // ファイル情報
+ filename: v.string(),
+ originalFilename: v.string(),
+ mimeType: v.string(),
+ size: v.number(), // bytes
+ // メタデータ
+ uploadedBy: v.id("users"),
+ uploadedAt: v.number(),
+ organizationId: v.id("organizations"),
+ // 画像の場合の追加情報
+ width: v.optional(v.number()),
+ height: v.optional(v.number()),
+})
+ .index("by_organization", ["organizationId"])
+ .index("by_uploader", ["uploadedBy"]);
+```
+
+### 既存テーブル拡張: `messages`
+
+```typescript
+messages: defineTable({
+ channelId: v.id("channels"),
+ content: v.string(),
+ author: v.string(),
+ createdAt: v.number(),
+ parentId: v.optional(v.id("messages")),
+ // 添付ファイル (新規追加)
+ attachments: v.optional(v.array(v.id("files"))),
+}).index("by_channel", ["channelId"]);
+```
+
+## API設計 (Convex)
+
+### Mutations
+
+#### `generateUploadUrl`
+
+アップロード用の署名付きURLを生成します。
+
+#### `saveFileInfo`
+
+アップロード後のファイル情報をデータベースに保存します。
+
+#### `deleteFile`
+
+ファイルを削除します。
+
+### Queries
+
+#### `getFile`
+
+ファイル情報とアクセスURLを取得します。
+
+#### `listFiles`
+
+Organization内のファイル一覧を取得します。
+
+## フロントエンド設計
+
+### コンポーネント構成
+
+#### 1. ファイルアップロードコンポーネント
+
+**Features:**
+
+- ドラッグ&ドロップエリア
+- ファイル選択ボタン
+- 複数ファイル選択
+- アップロード進捗表示
+- バリデーション(サイズ・形式)
+
+#### 2. ファイルのプレビュー表示コンポーネント
+
+**Features:**
+
+- 画像プレビュー
+- ファイル情報表示(名前・サイズ・形式)
+- 削除ボタン
+
+#### 3. メッセージ内の添付ファイル表示コンポーネント
+
+**Features:**
+
+- ファイル情報表示
+- ダウンロードリンク
+- 画像のインラインプレビュー
+
+#### 4. 既存のメッセージ入力コンポーネントを拡張
+
+**追加Features:**
+
+- ファイル添付ボタン
+- 添付ファイル一覧表示
+- 添付ファイル付きメッセージ送信
+
+### アップロードフロー
+
+1. **ファイル選択/ドロップ**
+ - ファイルバリデーション
+ - プレビュー表示
+
+2. **アップロード開始**
+ - `generateUploadUrl` を呼び出し
+ - Convex Storage へファイルアップロード
+ - 進捗表示
+
+3. **メタデータ保存**
+ - `saveFileInfo` を呼び出し
+ - ファイル情報をデータベースに保存
+
+4. **メッセージ送信** (任意)
+ - 添付ファイルIDを含むメッセージを送信
+
+### エラーハンドリング
+
+- **ファイルサイズエラー**: "ファイルサイズが大きすぎます(最大10MB)"
+- **形式エラー**: "サポートされていないファイル形式です"
+- **ネットワークエラー**: "アップロードに失敗しました。再試行してください"
+- **権限エラー**: "ファイルのアップロード権限がありません"
+
+## セキュリティ
+
+### 認証・認可
+
+- **アップロード**: ログインユーザーのみ
+- **アクセス**: Organization メンバーのみ
+- **削除**: アップロード者またはOrganization admin
+
+### ファイル検証
+
+- **MIMEタイプ**: クライアント・サーバー両方で検証
+- **ファイルサイズ**: 10MB制限
+- **ファイル名**: サニタイズ処理
+
+### アクセス制御
+
+- **プライベートURL**: 署名付きURL使用
+- **権限チェック**: ファイルアクセス時に毎回確認
+
+## パフォーマンス最適化
+
+### 表示最適化
+
+- **遅延読み込み**: 画像の lazy loading
+- **サムネイル**: 小さいプレビュー画像生成(将来実装)
+- **キャッシュ**: ファイルURLのキャッシュ
+
+## 将来の拡張予定
+
+- **ファイル管理画面**: Organization内のファイル管理機能
+- **高度なプレビュー**: PDF, 動画のプレビュー
+- **ファイル検索**: ファイル名・メタデータ検索
+- **自動削除**: 古いファイルの自動削除機能
+- **帯域幅最適化**: 画像圧縮・リサイズ機能
diff --git a/package.json b/package.json
index d813b59..0e55884 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
"scripts": {
"dev": "bun run --filter='@packages/{client,convex}' dev",
"dev:all": "(trap 'kill 0' EXIT; bun run dev:convex & bun run dev:web & bun run dev:storybook & wait",
- "dev:web": "bun run --filter=@packages/client dev",
+ "dev:web": "cd packages/client; bun dev",
"dev:convex": "cd packages/convex && bun run dev",
"dev:tauri": "cd packages/client && bun run dev:tauri",
"dev:storybook": "cd packages/client && bun run storybook",
diff --git a/packages/client/src/app.html b/packages/client/src/app.html
index 3b193fc..c808a7f 100644
--- a/packages/client/src/app.html
+++ b/packages/client/src/app.html
@@ -1,15 +1,13 @@
+
+
+
+
+ %sveltekit.head%
+
-
-
-
-
- %sveltekit.head%
-
-
-
- %sveltekit.body%
-
-
-
\ No newline at end of file
+
+ %sveltekit.body%
+
+