taruvi-refine-providers について
Refine を使った Taruvi のフロントエンド開発向けスキルです。プロバイダー、フック、認証、アクセス制御、本番向け UI の指針を扱い、ブラウザー側のデータやユーザーフローを実装する開発者を対象とします。
主な機能
- 01Refine プロバイダーとフックの指針
- 02CRUD、ストレージ、アプリデータの処理
- 03認証とアクセス制御
- 04本番向け UI の指針
- 05非推奨 API の移行案内
活用シーン
- 01ページネーション付きデータテーブルの構築
- 02アップロードとファイル管理の追加
- 03ログインとロール別 UI の実装
- 04Taruvi 関数と分析クエリの実行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ taruvi-ai/ taruvi-skills --skill taruvi-refine-providersインストール後、Claude Code で/taruvi-refine-providersを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
eval_queries.jsonreferences/access-control-provider.mdapp-provider.mdauth-provider.mddatabase-provider.mdoverview.mdstorage-provider.mdtypes-and-utilities.mduser-provider.md詳細
Taruvi Refine プロバイダー(フロントエンド)
Taruvi 向けのフロントエンドスキルです。ブラウザーで実行されるすべてを網羅します。@taruvi/refine-providers の接続、Taruvi に対する Refine フックの使用、本番環境対応のリスト/ダッシュボード/ドロップダウン/アップロードの UX、認証フロー、アクセス制御が対象です。
リソースのプロビジョニングや Python 関数本体の作成を行う場合は、taruvi-app-developer に切り替えてください。
プロバイダーマップ
| プロバイダー | Refine キー | 用途 |
|---|---|---|
dataProvider(client) | default | データテーブルの CRUD、フィルター、ページネーション、集計、グラフ |
storageDataProvider(client) | storage | ファイル/オブジェクトのアップロード、一覧表示、ダウンロード、削除 |
appDataProvider(client) | app | 関数/分析の実行、ロール、設定、シークレット(useCustom/useList/useOne 経由) |
userDataProvider(client) | user | ユーザーの CRUD |
authProvider(client) | authProvider prop | ログイン、ログアウト、トークンの更新、ID、権限 |
accessControlProvider(client) | accessControlProvider prop | useCan/CanAccess 向けの Cerbos 一括チェック |
フックのサポート対応表と meta オプションについては、overview.md を参照してください。
非推奨 — 使用しないでください: functionsDataProvider、analyticsDataProvider。代わりに、meta.kind: "function" または meta.kind: "analytics" を指定した appDataProvider + useCustom を使用してください。
ワークフロー
overview.mdを一度読みます。インストール、クライアントのセットアップ、プロバイダー/フックの全体マップが記載されています。- タスクに該当するリファレンスを開きます(下表を参照)。
- インストール済みパッケージで現在使える非推奨ではない API を確認します。古い例があるという理由だけで、非推奨の API を使った新しいコードをリリースしないでください。
- 本番環境対応のデフォルト設定を適用します(次のセクションを参照)。
- 完了を報告する前に、各ロールで UI を確認し、リストのアクション、作成ボタン、メニュー項目が適切に表示/非表示になることを確かめます。
リファレンス一覧
| タスク | 参照先 |
|---|---|
| データベースの CRUD、フィルター、集計、グラフ | database-provider.md |
| ファイルのアップロード、一括削除、メタデータ、フィルター | storage-provider.md |
| 関数の実行、分析、ロール、設定、シークレット | app-provider.md |
| ユーザーの CRUD | user-provider.md |
| ログイン、ログアウト、トークンフロー、ID | auth-provider.md |
useCan、CanAccess、プレフィックス付き ACL リソース | access-control-provider.md |
| TypeScript の型、非推奨機能からの移行 | types-and-utilities.md |
本番環境対応のデフォルト設定
ユーザーが明示的に対象範囲を絞らない限り、すべてのフロントエンド成果物で以下を満たす必要があります。これらは推奨事項ではありません。
リスト/テーブル
- デフォルトではバックエンドページネーションを使用します。デフォルトの
pageSizeは10とし、10/20/50/100を選択できるようにします。 - サーバーサイドで検索、フィルター、ソートを行います。プロバイダーの
filters/sortersに渡し、取得済みの行に対して React 側で再適用してはいけません。 - 検索入力欄と関連するフィルターコントロール(ステータス、部門、日付範囲)を表示します。検索には 300~500ms のデバウンスを設定します。
- ページごとに主要な検索コントロールを 1 つだけ設けます。同じフィールドに対して、
DataGridのクイックフィルターと別のページ検索を重複させないでください。 - MUI の
DataGridにはuseDataGridを使用します。useListとコンポーネント状態を手動で組み合わせる方法は、文書化された例外であり、デフォルトではありません。
ダッシュボード/KPI/グラフ
- デフォルト:
useListで datatable のaggregateとgroupByを使用し、meta.aggregate: ["count"]を指定します(配列である点に注意してください。aggregate: "count"はエラーなしで失敗します)。複数テーブルにまたがる処理が必要な場合は、データプロバイダーがpopulateと集計を同時にサポートしているため、まずそちらを試してください。populate した FK フィールドの集計で通常は対応できます。 - 分析クエリは例外であり、デフォルトではありません。
appDataProviderとuseCustom({ meta: { kind: "analytics" } })を使うのは、(a)データソースが外部データベースである場合、または(b)SQL をデータプロバイダーでは本当に表現できない場合に限ります。たとえば、グループ化された集計を伴う複数テーブルの結合、ウィンドウ関数、再帰的 CTE などです。クエリの登録にはバックエンドへの別途のラウンドトリップ(taruvi-app-developer)が必要です。meta.aggregateとmeta.populateを指定した単一のuseListでできる処理には使用しないでください。 - サマリー指標を算出するために、すべての行を React に取得してはいけません。
- グラフクエリでは
depthを明示的に設定してください。 havingが機能するのは、groupByの後だけです。集計前のフィルタリングにはfiltersを使用してください。
ネットワーク経由のドロップダウン
- 静的な
Selectではなく、Autocomplete(または同等の入力補完機能)を使用してください。 - ページネーション付きのバックエンドクエリ(デフォルトの
pageSizeは10)を使用し、検索はデバウンスしてプロバイダーのフィルターに渡してください。1 回だけ読み込んだデータをクライアント側でフィルタリングしてはいけません。
ファイルのアップロード/添付ファイル
- デフォルトでは複数ファイルに対応した UX にしてください。全体を一括で成功または失敗として扱わず、ファイルごとの成功/失敗を報告してください。
- バッチアップロードは 10 ファイル以下/100MB 以下に分割し、バッチ削除は 100 パス以下に分割してください。
- クォータは目安として扱い、アップロードをブロックせず警告として表示してください。
- 上書き時には警告してください。アップロードすると既存のパスは通知なく置き換えられます。
visibilityはバケットレベルで設定してください。バケットのデフォルトより、オブジェクトごとの設定が優先されます。
一括操作
- 単一リソースにはバックエンドの一括操作(
updateMany、deleteMany)を使用し、複数リソースにまたがるカスケード処理にはサーバーレス関数を使用してください。 - 選択範囲(選択した行とフィルター済みの集合のどちらか)を明確に表示し、一部失敗の詳細を示して、影響を受けるクエリを無効化してください。
通知
連携済みの Refine notificationProvider(useNotification)を使用してください。別のトースト/スナックバーシステムを追加しないでください。
コントラクトのルール(必須)
関数の実行
useCustom({
url: "<function-slug>",
method: "post",
dataProviderName: "app",
payload: { /* inputs */ },
meta: { kind: "function" },
});
payload に入力を渡します。values や config.payload ではありません。
分析の実行
同じ形式で meta: { kind: "analytics" } を指定します。
アクセス制御
useCan/CanAccessのリソースには、datatable:employees、function:employee-terminate、query:hrms-dashboard-summaryのようなプレフィックス付き ACL 文字列を使用してください。params.entityTypeや、プレフィックスのないリソース名は使用しないでください。- 確認前に UI アクションを正規の Cerbos アクションに対応付けてください。
list/show→read、edit→update、create→create、delete→delete、関数/クエリのexecute。 - ランタイムのペイロードを確認してください。
/check/resourcesのresource.kindは、要求されたresource文字列と完全に一致する必要があります。 useCanを手動でデバウンスまたはスロットリングしないでください。accessControlProviderはすでに DataLoader 経由でバッチ処理を行います。
クライアントの設定
const client = new Client({
apiKey: import.meta.env.VITE_TARUVI_API_KEY,
appSlug: import.meta.env.VITE_TARUVI_APP_SLUG,
apiUrl: import.meta.env.VITE_TARUVI_API_URL,
});
<Refine
dataProvider={{
default: dataProvider(client),
storage: storageDataProvider(client),
app: appDataProvider(client),
user: userDataProvider(client),
}}
notificationProvider={useNotificationProvider}
authProvider={authProvider(client)}
accessControlProvider={accessControlProvider(client)}
/>
環境変数には、フレームワークがブラウザーに公開するプレフィックス(VITE_*、REACT_APP_*、NEXT_PUBLIC_*)を使用してください。ハードコードしてはいけません。
ここで取り上げておきたい注意点
見落としやすいポイントです。ドメインごとの落とし穴はリファレンスを参照してください。
- 401 と 403 — 401 はセッションの有効期限切れ(再ログイン)です。403 はアクセス拒否(拒否されたことを表示)です。403 を 401 として扱うと、再ログインが無限に繰り返されます。
- ロール変更後の
_cachedUser— ID 情報はモジュール内でキャッシュされ、logout()を呼び出したときにのみクリアされます。管理者ロールの変更後は、強制的に再ログインするか、["identity"]および["access-control"]のクエリーキーを無効化してください。 - 非同期関数に対する
useCustom— 非同期関数は結果ではなくtask_idを返します。関数を同期処理(30 秒未満)にするか、別のステータス確認関数を使ったポーリングパターンを組み込んでください。 dataProviderNameの指定漏れ — 適切なdataProviderNameを指定せずにuseCustom/useCreateを使うと、defaultにルーティングされ、わかりにくい「リソースが見つかりません」というエラーが返されます。関数や分析では常に"app"を、バケットでは"storage"を指定してください。- 事前入力されたフォームフィールド — デフォルト値のある TextField には
InputLabelProps: { shrink: true }を設定し、ラベルが重ならないようにしてください。 aggregateは配列でなければなりません —aggregate: "count"はエラーなしで失敗します。aggregate: ["count"]を使ってください。- バックエンドデータに対するクライアント側でのフィルタリング — 行のページを取得して React でフィルタリングするのは、正確性とスケーラビリティの両方に関わるバグです。常に状態をプロバイダークエリーに渡してください。