Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
181 commits
Select commit Hold shift + click to select a range
28f744a
chore: 不要スキルの削除(create-pr, doc-update, resume-plan, save-plan)
yn1323 Mar 23, 2026
944571e
chore: commitスキルの追加(自動コミット分割)
yn1323 Mar 23, 2026
88f1857
docs: CLAUDE.mdの説明充実・自動生成ファイルの注意事項追加
yn1323 Mar 23, 2026
1d431c5
fix: 充足度の数値表示がグリッドラインとずれる問題を修正
yn1323 Mar 23, 2026
18e5877
chore: discussスキルの追加
yn1323 Mar 23, 2026
5be8797
docs: ShiftFormデザインガイド・デザインファイルの追加
yn1323 Mar 23, 2026
3067dc7
refactor: ShiftForm DailyViewの消しゴムモード削除・空状態ガイド追加
yn1323 Mar 23, 2026
6ca564c
chore: Claude Code権限設定の更新・discussスキルの改善
yn1323 Mar 23, 2026
9cacbbd
docs: ShiftForm情報設計プランの追加
yn1323 Mar 23, 2026
3b41eb5
refactor: undo/redo・toolMode・scrollDragの廃止とPositionToolbar簡素化
yn1323 Mar 24, 2026
8e7ec64
feat: ポジション間ギャップの休憩ストライプ表示
yn1323 Mar 24, 2026
72cb6e3
feat: ピーク帯設定・充足度アラート・DateTabsバッジの追加
yn1323 Mar 24, 2026
3f692bc
feat: StaffEditModalの参照専用モード追加
yn1323 Mar 24, 2026
8019c45
chore: 実装ルールの追加
yn1323 Mar 24, 2026
3ea4ef9
fix: ShiftFormのドラッグ操作時にカーソルがcrosshairに変わる挙動を削除
yn1323 Mar 24, 2026
3ad799d
feat: ポジションバーのホバーカーソルとPopoverの時間順ソートを追加
yn1323 Mar 24, 2026
d99278e
fix: ドラッグ操作後の同一ポジション隣接セグメントが統合されない問題を修正
yn1323 Mar 24, 2026
b40e956
chore: SummaryFooterRowのラベルを「出勤数」から「人数」に変更
yn1323 Mar 24, 2026
66fb1ac
fix: ポジション色バーのホバー時にcursor: pointerが表示されない問題を修正
yn1323 Mar 24, 2026
801b4ba
feat: ShiftForm日別ビューのUI改善(二重テキスト削除・ホバー強化・時刻ラベル視認性・タブ強調)
yn1323 Mar 24, 2026
cfb1b73
feat: ShiftFormのUI全体改善(充足度バー未着手グレー化・一覧ビュートーンダウン・ガイドバーアニメーション・ツールバー背景色)
yn1323 Mar 24, 2026
c321351
feat: ShiftFormのビュー切替とポジション選択を統合ツールバーに集約
yn1323 Mar 24, 2026
789fc00
docs: CLAUDE.mdのデザインセクションをdoc/design/構成に更新
yn1323 Mar 24, 2026
9e1a626
f
yn1323 Mar 24, 2026
6b39dab
f
yn1323 Mar 24, 2026
57d2a86
chore: v2のConvexバックエンドを削除・スキーマ簡素化
yn1323 Mar 25, 2026
0b6f132
docs: v3プロダクト定義書・Convexアーキテクチャ規約の追加
yn1323 Mar 25, 2026
f23ed87
chore: v2の不要コードを一括削除
yn1323 Mar 25, 2026
951b747
refactor: v3に向けたコード簡素化(ShiftForm・テンプレート・ルーティング)
yn1323 Mar 25, 2026
6192434
feat: ダッシュボードページの追加
yn1323 Mar 25, 2026
4802afe
refactor: ShiftFormのドラッグ操作・SP版シフト編集を簡素化
yn1323 Mar 25, 2026
91d6b39
docs: v3再構築に向けた旧ドキュメントの一括削除
yn1323 Mar 25, 2026
e83ae7a
docs: ARCHITECTURE.md・INDEX.mdを現在のコードベース実態に合わせて更新
yn1323 Mar 25, 2026
b88783f
docs: プロダクト定義書の追加
yn1323 Mar 25, 2026
3786d28
docs: プロダクト定義書のファイル名に日付プレフィックスを付与
yn1323 Mar 25, 2026
d12bae5
docs: 情報設計書の追加
yn1323 Mar 25, 2026
94785ea
doc
yn1323 Mar 26, 2026
1375882
chore: Chakra UIテーマ設定ファイルの追加
yn1323 Mar 26, 2026
0127a22
docs: デザイン関連ファイルをdesign/ディレクトリに整理
yn1323 Mar 26, 2026
a581583
docs: system.penにリユーザブルコンポーネントとインデックスを追加
yn1323 Mar 26, 2026
6bcde91
docs: CLAUDE.mdにペルソナとレイアウトルールを追加
yn1323 Mar 26, 2026
0a5161a
docs: デザインファイルのリネームとダッシュボード画面の追加
yn1323 Mar 26, 2026
110c105
docs: デザインインデックスのSP画面ID追加とContentWrapperコンポーネント定義
yn1323 Mar 26, 2026
c682b14
feat: ContentWrapperテンプレートコンポーネントの作成
yn1323 Mar 26, 2026
a2f07ed
feat: ダッシュボード画面の実装(モックデータ版)
yn1323 Mar 26, 2026
0aca3ef
feat: BottomSheetにアクションボタン(送信・キャンセル)を追加
yn1323 Mar 26, 2026
9e28d82
feat: ダッシュボード画面のUI改善
yn1323 Mar 26, 2026
cb0c192
chore: CLAUDE.mdの実装ルール説明を更新
yn1323 Mar 26, 2026
7dbc0e1
feat: BottomSheetデザインにアクションボタン(送信・キャンセル)を追加
yn1323 Mar 27, 2026
621c1c1
feat: ダッシュボード画面のSPデザインを追加
yn1323 Mar 27, 2026
09e2eb8
chore: concurrentlyを導入しdev:allスクリプトを追加
yn1323 Mar 27, 2026
2267d04
docs: セキュリティ・認証設計書を追加し関連ドキュメントを更新
yn1323 Mar 27, 2026
2a678a0
docs: シフトボードのUX設計書とデザインファイルを追加
yn1323 Mar 27, 2026
e0e0562
docs: シフトボードのPC/SPデザインデータを追加
yn1323 Mar 27, 2026
d42bd1b
feat: シフトボード画面の実装(モックデータ版)
yn1323 Mar 27, 2026
e954de5
fix: 日別ビューの1列目(スタッフ名・ヘッダー)が改行される問題を修正
yn1323 Mar 27, 2026
372cf7a
fix: シフトボードの送付済み表示によるレイアウトシフトを修正しToast位置を中央上部に変更
yn1323 Mar 28, 2026
82d3e6a
chore: CLAUDE.mdにフロントエンド実装ルールを追加
yn1323 Mar 28, 2026
c446298
chore: CLAUDE.mdのフロントエンド実装ルールを整理
yn1323 Mar 28, 2026
3c0ad5f
chore: statusLineにコンテキスト使用率と5hセッション使用率を表示
yn1323 Mar 28, 2026
d69b064
feat: スタッフ複数人同時登録フォームの実装
yn1323 Mar 28, 2026
7583161
fix: RecruitmentCardのSP表示でボタン・テキストが折り返される問題を修正
yn1323 Mar 28, 2026
f8c38e6
docs: スタッフ登録Route A/B方針をプロダクト定義・情報設計書に追記
yn1323 Mar 28, 2026
21f4c59
chore: ダッシュボードのデザインデータ更新(スタッフ複数登録モーダル)
yn1323 Mar 28, 2026
72cf652
chore: statusLineにモデル名と5hセッションリセット時刻を追加
yn1323 Mar 28, 2026
af10335
docs: 店舗情報と初回セットアップ設計プランを追加
claude Mar 28, 2026
82199c0
docs: 店舗情報と初回セットアップ設計プランを追加 (#271)
yn1323 Mar 28, 2026
67011f2
feat: Convexスキーマ定義(ダッシュボード・シフトボード・店舗セットアップ)
claude Mar 28, 2026
eaf724b
Merge pull request #272 from yn1323/claude/design-store-shift-db-OgDVW
yn1323 Mar 28, 2026
21406f9
convex/CLAUDE.md にセキュリティガイドを追記
claude Mar 28, 2026
c18b9be
Merge pull request #273 from yn1323/claude/convex-security-guide-Bw6vf
yn1323 Mar 28, 2026
c4f6692
feat: 初回セットアップ ステッパーモーダルのデザイン追加(PC/SP)
yn1323 Mar 28, 2026
81b6992
docs: designIndex.mdに初回セットアップモーダルのフレームIDを追加
yn1323 Mar 28, 2026
6d76d6f
docs: designIndex更新ルールの強調を追記
yn1323 Mar 28, 2026
27f069b
chore: convex-testテスト環境のセットアップ
yn1323 Mar 28, 2026
d64ed52
docs: convex/CLAUDE.mdにテストセクションを追記
yn1323 Mar 28, 2026
b324f41
feat: 初回セットアップモーダルの実装(react-hook-form + Zod)
yn1323 Mar 28, 2026
4bcc65f
docs: フォームのルール(react-hook-form + zodResolver)を追記
yn1323 Mar 28, 2026
afa2a8c
refactor: Dialog/BottomSheetにformIdプロップを追加
yn1323 Mar 28, 2026
7fb886e
feat: CreateRecruitmentFormにreact-hook-form + zodを導入
yn1323 Mar 28, 2026
b0ec77d
refactor: AddStaffFormをreact-hook-form + zodに移行
yn1323 Mar 28, 2026
210f38f
refactor: DashboardContentのフォーム連携をformId方式に変更
yn1323 Mar 28, 2026
36e1efd
docs: フォームのSubmitボタンは常にEnabledにするルールを追記
yn1323 Mar 28, 2026
af3650a
fix: AddStaffFormのバリデーション改善(email union型、refineで最低1名必須)
yn1323 Mar 28, 2026
b17d63d
fix: 日付入力のプレースホルダー表示改善とエラー位置修正
yn1323 Mar 28, 2026
8bd02a2
refactor: DashboardContentからAddStaffFormの状態リフトアップを削除
yn1323 Mar 28, 2026
12bdbe7
chore: ダッシュボードデザインからWelcomeTextを削除
yn1323 Mar 28, 2026
ea56d75
refactor: AddStaffFormのバリデーションをZodネイティブに改善
yn1323 Mar 28, 2026
8067209
feat: 名前入力時にメールアドレスを必須にするバリデーション追加
yn1323 Mar 28, 2026
ce64558
fix: AddStaffFormのエラー表示時のレイアウトシフトを防止
yn1323 Mar 28, 2026
511a9fb
refactor: Zodバリデーションスキーマをconvex/に移動しフロント・バックエンド共有化
yn1323 Mar 28, 2026
b4a03ba
docs: CLAUDE.mdにZodスキーマ共有ルールを追加
yn1323 Mar 28, 2026
ab81b1d
fix: SetupModalの閉じるボタンが表示されない問題を修正
yn1323 Mar 28, 2026
c03db1c
fix: 募集がないときに「新しい募集を作成」ボタンでもSetupモーダルを開くように修正
yn1323 Mar 28, 2026
becb0f8
chore: Convex AI filesとスキルの追加
yn1323 Mar 28, 2026
2613a76
docs: 実装プロンプトとCLAUDE.mdの更新
yn1323 Mar 28, 2026
7e71e07
feat: Convex認証ラッパーとダッシュボードAPI実装
yn1323 Mar 28, 2026
1141f24
feat: ダッシュボードUIをConvexバックエンドに接続
yn1323 Mar 28, 2026
86d2fe4
chore: テストヘルパーのリネーム残ファイルを削除
yn1323 Mar 28, 2026
9e42f4e
docs: SetupModalリファクタの実装計画とCLAUDE.md更新
yn1323 Mar 28, 2026
302a7d1
chore: Convex全テーブルクリア用mutationとdifitスクリプト追加
yn1323 Mar 28, 2026
93fae32
fix: 募集作成フォームの締切日を開始日の前日までに制約
yn1323 Mar 28, 2026
ba36f7b
feat: SetupModalを店舗情報+管理者登録の強制2ステップに改善
yn1323 Mar 28, 2026
1d5df79
refactor: 締切日max計算のマジックナンバーをDate APIに置換
yn1323 Mar 28, 2026
1924569
chore: Biomeスキーマバージョンを2.3.10に更新
yn1323 Mar 28, 2026
2584d87
feat: SetupModal Step2のデザインを管理者情報登録フォームに変更
yn1323 Mar 28, 2026
24866dc
refactor: 認証済みレイアウトの背景色削除とページ遷移アニメーション追加
yn1323 Mar 28, 2026
a6fe1ba
feat: SideMenu/BottomMenuをHeaderに置換
yn1323 Mar 28, 2026
4fdf005
chore: ステータスラインに7日間レート制限表示を追加
yn1323 Mar 28, 2026
62d4fe8
chore: ステータスラインの7日間リセット日時に曜日表示を追加
yn1323 Mar 28, 2026
8b7434f
refactor: シフトボードのレイアウトをフルワイド化し固定要素を除去
yn1323 Mar 29, 2026
80434dc
refactor: DateCardのスタッフ表示上限を撤廃し全員表示に変更
yn1323 Mar 29, 2026
bc14c84
refactor: DateCardのstaffCount変数を除去しworkingStaffs.lengthに統一
yn1323 Mar 29, 2026
c0249e2
design: system.lib.penにHeader追加しshiftboard全画面にヘッダーを統一
yn1323 Mar 29, 2026
d0836f4
refactor: ShiftBoardヘッダーの型共通化とTitleTemplate適用
yn1323 Mar 29, 2026
b13c86a
docs: シフトボードヘッダー再構成のプランドキュメントを追加
yn1323 Mar 29, 2026
e118fe2
design: シフトボードヘッダーをツールバー構成に再構成
yn1323 Mar 29, 2026
0ecebaa
refactor: viewModeのcontrolled props対応(Write-Through Atomパターン)
yn1323 Mar 29, 2026
b8a7be2
refactor: ShiftBoardヘッダーをツールバー構成にコード実装
yn1323 Mar 29, 2026
03f574c
fix: ShiftEditSheet・DateCardのcolorPaletteをtealに統一
yn1323 Mar 29, 2026
6df1475
test: ShiftFormサブコンポーネントのStorybook追加(ビュー単位+SPモーダル)
yn1323 Mar 29, 2026
855b827
feat: ShiftEditSheetに確定ボタン追加とシフト未設定時の時刻セレクト空欄化
yn1323 Mar 29, 2026
95860b4
fix
yn1323 Mar 29, 2026
5cbe482
refactor: シフト表示からポジション名・色を除去し時間のみの表示に簡素化
yn1323 Mar 29, 2026
a517099
feat: Toast表示時間2秒・閉じるボタン常時表示・エラー時は自動非表示無効
yn1323 Mar 29, 2026
47dbee8
refactor: 休憩ポジションのマジックストリングをBREAK_POSITION定数に統一
yn1323 Mar 29, 2026
f2f5f8a
refactor: BottomSheetヘッダーの戻るボタン有無で条件分岐を明確化
yn1323 Mar 29, 2026
f61fa52
refactor: SPDailyViewのopenedFromAddSheetをrefからstateに変更
yn1323 Mar 29, 2026
0b45b81
feat: OverviewViewのShiftEditSheetにもStaffAddSheetへの戻るボタンを追加
yn1323 Mar 29, 2026
1b2c8c3
refactor: ShiftEditSheetの不要import・コメント削除とフォーマット修正
yn1323 Mar 29, 2026
401205e
refactor: PC版ShiftPopoverのポジション表示簡素化とShiftDetailPopover削除
yn1323 Mar 29, 2026
2ddef67
fix: ShiftEditSheetでスタッフ切り替え時にフォーム値がリセットされない問題を修正
yn1323 Mar 29, 2026
6c9ecc2
feat: ShiftBoardのConvex統合(query/mutation作成とフロント接続)
yn1323 Mar 29, 2026
65fe1c7
refactor: ShiftBoardのラベルを「確定」から「送信」に変更
yn1323 Mar 29, 2026
a580c40
feat: ShiftBoard mutationにビジネスロジックバリデーションを追加
yn1323 Mar 29, 2026
81920c8
refactor: showErrorToastをtoaster.tsxに共通化
yn1323 Mar 29, 2026
181154c
fix: dateUtils統一によるTZずれ修正とshopId誤り修正
yn1323 Mar 29, 2026
89af2fc
docs: CLAUDE.mdに日付操作ルールを追加
yn1323 Mar 29, 2026
bd53a26
design: シフトボードのラベルを「確定」から「送信」に変更
yn1323 Mar 29, 2026
a7c84c4
refactor: RootContentWrapper追加とdashboardのレイアウト統一
yn1323 Mar 29, 2026
c0f61ec
design: スタッフ向けシフト閲覧・リンク再発行画面のモック作成
yn1323 Mar 30, 2026
ad21f01
feat: メール通知・マジックリンク認証のバックエンド実装
yn1323 Mar 30, 2026
47a82fa
feat: スタッフ向けシフト閲覧・再発行ページの実装
yn1323 Mar 30, 2026
658e89f
docs: メール通知・マジックリンク設計書の追加
yn1323 Mar 30, 2026
97b6bc0
feat: スタッフ向けシフト閲覧画面にShiftForm(読み取り専用)を統合
yn1323 Mar 30, 2026
ef17020
refactor: FullPageSpinnerとStaffLayoutを共通コンポーネントとして抽出
yn1323 Mar 30, 2026
464531d
fix: lint
yn1323 Mar 30, 2026
8a2bfc5
fix: del footerInfo
yn1323 Mar 30, 2026
78ff46b
fix: shiftBoardテストのlint警告とUnhandled Rejectionを修正
yn1323 Mar 31, 2026
74d6cb3
fix: readOnly時にシフト希望情報を非表示にする
yn1323 Mar 31, 2026
23c28a2
feat: シフト確定メール再送時の件名・本文をシフト変更通知に変更
yn1323 Mar 31, 2026
1f853a0
docs: E2Eテスト規約と方針ドキュメントの追加
yn1323 Mar 31, 2026
a883553
docs: CLAUDE.mdのドキュメントセクションにE2E規約の参照を追加
yn1323 Mar 31, 2026
5d2a2b6
feat: 初回シフト確定シナリオのE2Eテスト実装
yn1323 Mar 31, 2026
e62f0f8
docs: CLAUDE.mdにlint warning修正ルールを追加
yn1323 Mar 31, 2026
ff2f83d
Merge branch 'develop' of github.com:yn1323/yps-crispy-carnival into …
yn1323 Mar 31, 2026
7842323
fix: zip
yn1323 Mar 31, 2026
66b1dfe
fix
yn1323 Mar 31, 2026
3fc171d
fix: pipeline
yn1323 Mar 31, 2026
b1ef424
fix:disconnect storybook and convex
yn1323 Mar 31, 2026
389a26e
fix: storybook
yn1323 Mar 31, 2026
993f0a1
fix
yn1323 Mar 31, 2026
c7b1433
fix: StorybookのClerk依存をモック化してChromatic対応
yn1323 Mar 31, 2026
f4836dc
Revert "fix"
yn1323 Mar 31, 2026
f77cdf7
fix
yn1323 Mar 31, 2026
0386c6d
fix: Playwright CI actionの高速化(不要なセットアップ削除・キャッシュ改善)
yn1323 Mar 31, 2026
f2a0ab6
fix: Playwright CIのレポートパスを環境変数化・インデント修正
yn1323 Apr 5, 2026
889ab51
chore: CI設定・E2Eファイルのフォーマット修正
yn1323 Apr 5, 2026
22278cc
f
yn1323 Apr 5, 2026
19712fc
chore: Playwright CIから不要なフォント・環境変数ステップを削除
yn1323 Apr 5, 2026
a7a8f1b
fix
yn1323 Apr 5, 2026
3a2eb09
yn1323 Apr 5, 2026
a0fbf27
fix
yn1323 Apr 5, 2026
1e565d7
f
yn1323 Apr 5, 2026
c415bf8
fix
yn1323 Apr 5, 2026
8a203ee
fix
yn1323 Apr 5, 2026
2d038cf
f
yn1323 Apr 5, 2026
2d9ab3e
fix
yn1323 Apr 5, 2026
0829151
feat: CI/CDパイプラインの環境分離とConvexデプロイ追加
yn1323 Apr 5, 2026
5138351
skill
yn1323 Apr 5, 2026
c99963a
Merge branch 'develop' into feat/0323
yn1323 Apr 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
284 changes: 284 additions & 0 deletions .agents/skills/convex-create-component/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
---
name: convex-create-component
description: Designs and builds Convex components with isolated tables, clear boundaries, and app-facing wrappers. Use this skill when creating a new Convex component, extracting reusable backend logic into a component, building a third-party integration that owns its own tables, packaging Convex functionality for reuse, or when the user mentions defineComponent, app.use, ComponentApi, ctx.runQuery/runMutation across component boundaries, or wants to separate concerns into isolated Convex modules.
---

# Convex Create Component

Create reusable Convex components with clear boundaries and a small app-facing API.

## When to Use

- Creating a new Convex component in an existing app
- Extracting reusable backend logic into a component
- Building a third-party integration that should own its own tables and workflows
- Packaging Convex functionality for reuse across multiple apps

## When Not to Use

- One-off business logic that belongs in the main app
- Thin utilities that do not need Convex tables or functions
- App-level orchestration that should stay in `convex/`
- Cases where a normal TypeScript library is enough

## Workflow

1. Ask the user what they are building and what the end goal is. If the repo already makes the answer obvious, say so and confirm before proceeding.
2. Choose the shape using the decision tree below and read the matching reference file.
3. Decide whether a component is justified. Prefer normal app code or a regular library if the feature does not need isolated tables, backend functions, or reusable persistent state.
4. Make a short plan for:
- what tables the component owns
- what public functions it exposes
- what data must be passed in from the app (auth, env vars, parent IDs)
- what stays in the app as wrappers or HTTP mounts
5. Create the component structure with `convex.config.ts`, `schema.ts`, and function files.
6. Implement functions using the component's own `./_generated/server` imports, not the app's generated files.
7. Wire the component into the app with `app.use(...)`. If the app does not already have `convex/convex.config.ts`, create it.
8. Call the component from the app through `components.<name>` using `ctx.runQuery`, `ctx.runMutation`, or `ctx.runAction`.
9. If React clients, HTTP callers, or public APIs need access, create wrapper functions in the app instead of exposing component functions directly.
10. Run `npx convex dev` and fix codegen, type, or boundary issues before finishing.

## Choose the Shape

Ask the user, then pick one path:

| Goal | Shape | Reference |
|------|-------|-----------|
| Component for this app only | Local | `references/local-components.md` |
| Publish or share across apps | Packaged | `references/packaged-components.md` |
| User explicitly needs local + shared library code | Hybrid | `references/hybrid-components.md` |
| Not sure | Default to local | `references/local-components.md` |

Read exactly one reference file before proceeding.

## Default Approach

Unless the user explicitly wants an npm package, default to a local component:

- Put it under `convex/components/<componentName>/`
- Define it with `defineComponent(...)` in its own `convex.config.ts`
- Install it from the app's `convex/convex.config.ts` with `app.use(...)`
- Let `npx convex dev` generate the component's own `_generated/` files

## Component Skeleton

A minimal local component with a table and two functions, plus the app wiring.

```ts
// convex/components/notifications/convex.config.ts
import { defineComponent } from "convex/server";

export default defineComponent("notifications");
```

```ts
// convex/components/notifications/schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

export default defineSchema({
notifications: defineTable({
userId: v.string(),
message: v.string(),
read: v.boolean(),
}).index("by_user", ["userId"]),
});
```

```ts
// convex/components/notifications/lib.ts
import { v } from "convex/values";
import { mutation, query } from "./_generated/server.js";

export const send = mutation({
args: { userId: v.string(), message: v.string() },
returns: v.id("notifications"),
handler: async (ctx, args) => {
return await ctx.db.insert("notifications", {
userId: args.userId,
message: args.message,
read: false,
});
},
});

export const listUnread = query({
args: { userId: v.string() },
returns: v.array(
v.object({
_id: v.id("notifications"),
_creationTime: v.number(),
userId: v.string(),
message: v.string(),
read: v.boolean(),
})
),
handler: async (ctx, args) => {
return await ctx.db
.query("notifications")
.withIndex("by_user", (q) => q.eq("userId", args.userId))
.filter((q) => q.eq(q.field("read"), false))
.collect();
},
});
```

```ts
// convex/convex.config.ts
import { defineApp } from "convex/server";
import notifications from "./components/notifications/convex.config.js";

const app = defineApp();
app.use(notifications);

export default app;
```

```ts
// convex/notifications.ts (app-side wrapper)
import { v } from "convex/values";
import { mutation, query } from "./_generated/server";
import { components } from "./_generated/api";
import { getAuthUserId } from "@convex-dev/auth/server";

export const sendNotification = mutation({
args: { message: v.string() },
returns: v.null(),
handler: async (ctx, args) => {
const userId = await getAuthUserId(ctx);
if (!userId) throw new Error("Not authenticated");

await ctx.runMutation(components.notifications.lib.send, {
userId,
message: args.message,
});
return null;
},
});

export const myUnread = query({
args: {},
handler: async (ctx) => {
const userId = await getAuthUserId(ctx);
if (!userId) throw new Error("Not authenticated");

return await ctx.runQuery(components.notifications.lib.listUnread, {
userId,
});
},
});
```

Note the reference path shape: a function in `convex/components/notifications/lib.ts` is called as `components.notifications.lib.send` from the app.

## Critical Rules

- Keep authentication in the app, because `ctx.auth` is not available inside components.
- Keep environment access in the app, because component functions cannot read `process.env`.
- Pass parent app IDs across the boundary as strings, because `Id` types become plain strings in the app-facing `ComponentApi`.
- Do not use `v.id("parentTable")` for app-owned tables inside component args or schema, because the component has no access to the app's table namespace.
- Import `query`, `mutation`, and `action` from the component's own `./_generated/server`, not the app's generated files.
- Do not expose component functions directly to clients. Create app wrappers when client access is needed, because components are internal and need auth/env wiring the app provides.
- If the component defines HTTP handlers, mount the routes in the app's `convex/http.ts`, because components cannot register their own HTTP routes.
- If the component needs pagination, use `paginator` from `convex-helpers` instead of built-in `.paginate()`, because `.paginate()` does not work across the component boundary.
- Add `args` and `returns` validators to all public component functions, because the component boundary requires explicit type contracts.

## Patterns

### Authentication and environment access

```ts
// Bad: component code cannot rely on app auth or env
const identity = await ctx.auth.getUserIdentity();
const apiKey = process.env.OPENAI_API_KEY;
```

```ts
// Good: the app resolves auth and env, then passes explicit values
const userId = await getAuthUserId(ctx);
if (!userId) throw new Error("Not authenticated");

await ctx.runAction(components.translator.translate, {
userId,
apiKey: process.env.OPENAI_API_KEY,
text: args.text,
});
```

### Client-facing API

```ts
// Bad: assuming a component function is directly callable by clients
export const send = components.notifications.send;
```

```ts
// Good: re-export through an app mutation or query
export const sendNotification = mutation({
args: { message: v.string() },
returns: v.null(),
handler: async (ctx, args) => {
const userId = await getAuthUserId(ctx);
if (!userId) throw new Error("Not authenticated");

await ctx.runMutation(components.notifications.lib.send, {
userId,
message: args.message,
});
return null;
},
});
```

### IDs across the boundary

```ts
// Bad: parent app table IDs are not valid component validators
args: { userId: v.id("users") }
```

```ts
// Good: treat parent-owned IDs as strings at the boundary
args: { userId: v.string() }
```

### Advanced Patterns

For additional patterns including function handles for callbacks, deriving validators from schema, static configuration with a globals table, and class-based client wrappers, see `references/advanced-patterns.md`.

## Validation

Try validation in this order:

1. `npx convex codegen --component-dir convex/components/<name>`
2. `npx convex codegen`
3. `npx convex dev`

Important:

- Fresh repos may fail these commands until `CONVEX_DEPLOYMENT` is configured.
- Until codegen runs, component-local `./_generated/*` imports and app-side `components.<name>...` references will not typecheck.
- If validation blocks on Convex login or deployment setup, stop and ask the user for that exact step instead of guessing.

## Reference Files

Read exactly one of these after the user confirms the goal:

- `references/local-components.md`
- `references/packaged-components.md`
- `references/hybrid-components.md`

Official docs: [Authoring Components](https://docs.convex.dev/components/authoring)

## Checklist

- [ ] Asked the user what they want to build and confirmed the shape
- [ ] Read the matching reference file
- [ ] Confirmed a component is the right abstraction
- [ ] Planned tables, public API, boundaries, and app wrappers
- [ ] Component lives under `convex/components/<name>/` (or package layout if publishing)
- [ ] Component imports from its own `./_generated/server`
- [ ] Auth, env access, and HTTP routes stay in the app
- [ ] Parent app IDs cross the boundary as `v.string()`
- [ ] Public functions have `args` and `returns` validators
- [ ] Ran `npx convex dev` and fixed codegen or type issues
10 changes: 10 additions & 0 deletions .agents/skills/convex-create-component/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
interface:
display_name: "Convex Create Component"
short_description: "Design and build reusable Convex components with clear boundaries."
icon_small: "./assets/icon.svg"
icon_large: "./assets/icon.svg"
brand_color: "#14B8A6"
default_prompt: "Help me create a Convex component for this feature. First check that a component is actually justified, then design the tables, API surface, and app-facing wrappers before implementing it."

policy:
allow_implicit_invocation: true
3 changes: 3 additions & 0 deletions .agents/skills/convex-create-component/assets/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading