Agent Skills by ALSEL
OpenAIソフトウェア開発⭐ リポ 18品質スコア 77/100

instantdb

InstantDBをバックエンドとして、完全に機能するアプリケーションを構築できます。React、バニラJS、またはExpoアプリケーションを作成する際に使用します。アプリ構築のリクエストで自動的に起動します。

description の原文を見る

Build complete, functional apps with InstantDB as the backend. Use when creating React/vanilla JS or expo applications. Triggers on requests for building apps.

SKILL.md 本文

InstantDBに深い専門知識を持つワールドクラスのシニアフロントエンドエンジニアとして行動してください。バックエンドとしてInstantDBを使用し、優れたビジュアルエステティクスを備えた完全で機能的なアプリを生成することが主な目標です。

InstantDB(別名Instant)について

Instantは、クライアント側のデータベース(モダンFirebase)で、ビルトインクエリ、トランザクション、認証、権限、ストレージ、リアルタイム、およびオフラインサポートを備えています。

Instant SDK

Instantはクライアント側のJavaScript SDKと管理SDKを提供します:

  • @instantdb/core --- バニラJS
  • @instantdb/react --- React
  • @instantdb/react-native --- React Native / Expo
  • @instantdb/admin --- バックエンドスクリプト / サーバー

インストール時は、常にプロジェクトが使用しているパッケージマネージャー(npm、pnpm、bun)を確認してから、Instant SDKの最新バージョンをインストールしてください。Reactで作業する場合は、特に指定されていない限りNextとTailwindを使用してください。

Instantアプリの管理

前提条件

instant.schema.tsinstant.perms.ts を探してください。これらはスキーマと権限を定義します。 .env または別の環境ファイルでアプリIDと管理トークンを探してください。

スキーマ/権限ファイルは存在するがアプリID/管理トークンが見つからない場合は、ユーザーにそれらをどこで見つけるか、または新しいアプリを作成するかを尋ねてください。

新しいアプリを作成するには:

npx instant-cli init-without-files --title <APP_NAME>

これでアプリIDと管理トークンが出力されます。これらを環境ファイルに保存してください。

ログインしていないことに関連するエラーが発生した場合は、ユーザーに以下を実行するよう指示してください:

  • https://instantdb.com で無料登録またはログイン
  • 次に npx instant-cli login を実行してCLIを認証
  • その後、初期化コマンドを再実行

アプリID/管理トークンはあるがスキーマ/権限ファイルがない場合は、それらを取得します:

npx instant-cli pull --yes

スキーマの変更

instant.schema.ts を編集してからプッシュします:

npx instant-cli push schema --yes

新しいフィールド = 追加; 見つからないフィールド = 削除。

フィールドの名前を変更するには:

npx instant-cli push schema --rename 'posts.author:posts.creator stores.owner:stores.manager' --yes

権限の変更

instant.perms.ts を編集してからプッシュします:

npx instant-cli push perms --yes

重要なクエリガイドライン

重要:Reactを使用する場合は、フックのルールに従うようにしてください。フックは条件付きで表示することはできません。

重要:スキーマで、フィルター処理またはソート処理する任意のフィールドにインデックスを付ける必要があります。そうしないと、フィルター処理またはソート処理を試みるときにエラーが発生します。

以下がソートの仕組みです:

ソート:          order: { field: 'asc' | 'desc' }

例:             $: { order: { dueDate: 'asc' } }

注:             - フィールドはスキーマでインデックス付き + 型指定される必要があります
                 - ネストされた属性でソートできません(例:'owner.name')

重要:以下は、InstantDBクエリで使用できるすべてのフィルタリングオプションを定義する where オペレーターマップの簡潔なサマリーです。フィールド値、比較、配列、テキストパターン、および論理条件に基づいて結果を絞り込みます。

等価性:          { field: value }

不等号:          { field: { $ne: value } }

Nullチェック:     { field: { $isNull: true | false } }

比較:            $gt, $lt, $gte, $lte   (インデックス付き + 型指定フィールドのみ)

セット:          { field: { $in: [v1, v2] } }

部分文字列:      { field: { $like: 'Get%' } }      // 大文字小文字を区別
                  { field: { $ilike: '%get%' } }   // 大文字小文字を区別しない

論理:            and: [ {...}, {...} ]
                  or:  [ {...}, {...} ]

ネストされたフィールド: 'relation.field': value

重要:上記のオペレーターマップは、現在Instantがサポートしている where フィルターの完全なセットです。$exists$nin、または $regex はありません。また $like$ilikestartsWith / endsWith / includes に使用するものです。

重要:ページネーションキー(limitoffsetfirstafterlastbefore)は、トップレベルのネームスペースでのみ機能します。ネストされたリレーション上で使用しないでください。そうするとエラーが発生します。

重要:InstantDBでのある機能の動作方法が不確かな場合は、詳細を学ぶために、ドキュメント内の関連URLを取得してください。

重要な権限ガイドライン

InstantDBで権限を書く際の重要なガイドラインを以下に示します。

data.ref

  • リンク属性に data.ref("<path.to.attr>") を使用してください。
  • 常にリストを返します。
  • 属性で終わる必要があります。

正しい例

auth.id in data.ref('post.author.id') // auth.idが著者idのリスト内にある
data.ref('owner.id') == [] // オーナーがいない

エラー例

auth.id in data.post.author.id
auth.id in data.ref('author')
data.ref('admins.id') == auth.id
auth.id == data.ref('owner.id')
data.ref('owner.id') == null
data.ref('owner.id').length > 0

auth.ref

  • data.ref と同じですが、パスは $user で始まる必要があります。
  • リストを返します。

正しい例

'admin' in auth.ref('$user.role.type')
auth.ref('$user.role.type')[0] == 'admin'

エラー例

auth.ref('role.type')
auth.ref('$user.role.type') == 'admin'

非対応

newData.ref('x')
data.ref(someVar + '.members.id')

$users の権限

  • デフォルトの view 権限は auth.id == data.id
  • デフォルトの createupdatedelete 権限はfalse
  • viewupdate をオーバーライドできます
  • createdelete をオーバーライドできません

$files の権限

  • デフォルト権限はすべてfalse。必要に応じてオーバーライドしてアクセスを許可してください。
  • data.ref$files 権限では機能しません。
  • data.path.startsWith(...) または data.path.endsWith(...) を使用して、 パスベースのルールを書いてください。

フィールドレベルの権限

エンティティが公開されている間、特定のフィールドへのアクセスを制限します:

{
  "$users": {
    "allow": {
      "view": "true"
    },
    "fields": {
      "email": "auth.id == data.id"
    }
  }
}

注:

  • フィールドルールは、そのフィールドに対するエンティティレベルの view をオーバーライドします
  • 公開エンティティの機密データ(メール、電話番号)を非表示にするのに役立ちます

ベストプラクティス

Instantの初期化時に schema を渡す

クエリとトランザクションのタイプセーフティを確保するために、Instantの初期化時に常に schema を渡してください

import schema from '@/instant.schema`

// クライアント側
import { init } from '@instantdb/react'; // または関連するInstant SDK
const clientDb = init({ appId, schema });

// バックエンド側
import { init } from '@instantdb/admin';
const adminDb = init({ appId, adminToken, schema });

id() を使用してIDを生成する

新しいエンティティのIDを生成するために常に id() を使用してください

import { id } from '@instantdb/react'; // または関連するInstant SDK
import { clientDb } from '@/lib/clientDb'
clientDb.transact(clientDb.tx.todos[id()].create({ title: 'New Todo' }));

データモデルにInstantユーティリティ型を使用する

常にInstantユーティリティ型を使用してデータモデルに型を付けてください

import { AppSchema } from '@/instant.schema';

type Todo = InstaQLEntity<AppSchema, 'todos'>; // clientDb.useQuery({ todos: {} }) からのtodo
type PostsWithProfile = InstaQLEntity<
  AppSchema,
  'posts',
  { author: { avatar: {} } }
>; // clientDb.useQuery({ posts: { author: { avatar: {} } } }) からのpost

認証状態に db.useAuth または db.subscribeAuth を使用する

import { clientDb } from '@/lib/clientDb';

// React/React Nativeアプリの場合は db.useAuth を使用
function App() {
  const { isLoading, user, error } = clientDb.useAuth();
  if (isLoading) { return null; }
  if (error) { return <Error message={error.message /}></div>; }
  if (user) { return <Main />; }
  return <Login />;
}

// バニラJSアプリの場合は db.subscribeAuth を使用
function App() {
  renderLoading();
  db.subscribeAuth((auth) => {
    if (auth.error) { renderAuthError(auth.error.message); }
    else if (auth.user) { renderLoggedInPage(auth.user); }
    else { renderSignInPage(); }
  });
}

CLIからのアドホッククエリ

npx instant-cli query '{ posts: {} }' --admin を実行してアプリをクエリします。コンテキストフラグが必須です:--admin--as-email <email>、または --as-guest。また --app <id> もサポートしています。

Admin SDKを使用したアドホックスクリプト

バックエンド上でアドホックスクリプトを実行するには @instantdb/admin を使用してください。 以下はチャットアプリのスキーマの例であり、シードおよびリセットスクリプトが含まれています。

// instant.schema.ts
const _schema = i.schema({
  entities: {
    $users: i.entity({
      email: i.string().unique().indexed().optional(),
    }),
    profiles: i.entity({
      displayName: i.string(),
    }),
    channels: i.entity({
      name: i.string().indexed(),
    }),
    messages: i.entity({
      content: i.string(),
      timestamp: i.number().indexed(),
    }),
  },
  links: {
    userProfile: {
      forward: { on: "profiles", has: "one", label: "user", onDelete: "cascade" }, // 重要:`cascade` はhas-oneリンクでのみ使用できます
      reverse: { on: "$users", has: "one", label: "profile" },
    },
    authorMessages: {
      forward: { on: "messages", has: "one", label: "author", onDelete: "cascade" },
      reverse: { on: "profiles", has: "many", label: "messages", },
    },
    channelMessages: {
      forward: { on: "messages", has: "one", label: "channel", onDelete: "cascade" },
      reverse: { on: "channels", has: "many", label: "messages" },
    },
  },
});

// scripts/seed.ts
import { id } from "@instantdb/admin";
import { adminDb } from "@/lib/adminDb";

const users: Record<string, User> = { ... }
const channels: Record<string, Channel> = { ... }
const mockMessages: Message[] = [ ... ]

function seed() {
  console.log("Seeding db...");
  const userTxs = Object.values(users).map(u => adminDb.tx.$users[u.id].create({}));
  const profileTxs = Object.values(users).map(u => adminDb.tx.profiles[u.id].create({ displayName: u.displayName }).link({ user: u.id }));
  const channelTxs = Object.values(channels).map(c => adminDb.tx.channels[c.id].create({ name: c.name }))
  const messageTxs = mockMessages.map(m => {
    const messageId = id();
    return adminDb.tx.messages[messageId].create({
      content: m.content,
      timestamp: m.timestamp,
    })
      .link({ author: users[m.author].id })
      .link({ channel: channels[m.channel].id });
  })

  adminDb.transact([...userTxs, ...profileTxs, ...channelTxs, ...messageTxs]);
}

seed();

// scripts/reset.ts
import { adminDb } from "@/lib/adminDb";

async function reset() {
  console.log("Resetting database...");
  const { $users, channels } = await adminDb.query({ $users: {}, channels: {} });

  // すべてのユーザーを削除するとプロファイルとメッセージがカスケード削除されます
  const userTxs = $users.map(user => adminDb.tx.$users[user.id].delete());

  const channelTxs = channels.map(channel => adminDb.tx.channels[channel.id].delete());
  adminDb.transact([...userTxs, ...channelTxs]);
}

reset();

Instantドキュメント

以下の箇条書きはInstantドキュメントへのリンクです。InstantDBのさまざまな機能を使用する方法に関する詳細な情報を提供します。各行は以下のパターンに従います

トピックの詳細を学ぶために、URLを取得してください。

最後に

答える前に考えてください。コードが tsc --noEmit でタイプチェックを通過し、期待通りに動作することを確認してください。 忘れないでください!エステティクスは非常に重要です。すべてのアプリは素晴らしく見える必要があり、優れた機能性を持つ必要があります!

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
fivestones
リポジトリ
fivestones/family-organizer
ライセンス
MIT
最終更新
2026/4/6

Source: https://github.com/fivestones/family-organizer / ライセンス: MIT

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: fivestones · fivestones/family-organizer · ライセンス: MIT