Skill instructions
insforge19.6 KB
View saved version →
---
name: insforge
description: >-
Use this skill when writing app code with InsForge or @insforge/sdk: database CRUD, auth, storage uploads/storage RLS, functions, OpenRouter AI, realtime, emails, Stripe or Razorpay payments, or pointing S3-compatible tooling (aws CLI, AWS SDKs, rclone, Terraform, boto3) at InsForge Storage. Trigger on requests like add auth, fetch data, upload files, make a bucket public, add checkout, sell subscriptions, or send email. For infrastructure, SQL migrations, CLI commands, or payment provider setup, use insforge-cli instead.
license: Apache-2.0
---
# InsForge App Integration Skill
This skill covers **client-side SDK integration** using `@insforge/sdk`. For backend infrastructure operations (creating tables, inspecting schema, deploying functions, secrets, managing storage buckets, configuring payment provider keys/catalog, website deployments, cron job and schedules, logs, etc.), use the **insforge-cli** skill.
## Quick Setup
### 1. Install the SDK
```bash
npm install @insforge/sdk@latest
```
### 2. Set up environment variables
Before using the SDK, create a `.env` file (or `.env.local` for Next.js) in your project root with your InsForge URL and anon key.
#### How to get your URL and anon key
1. **Ensure the project is linked.** Check for `.insforge/project.json` in the project root.
- Generate it with `npx @insforge/cli link` for an existing project or `npx @insforge/cli create` for a new project.
2. **Get the anon key** via the CLI:
```bash
npx @insforge/cli secrets get ANON_KEY
```
3. **Get the URL** from the `oss_host` field in `.insforge/project.json` (e.g., `https://myapp.us-east.insforge.app`).
4. **Write both values** to the `.env` file using the correct framework prefix (see table below).
> **Important:** Use the anon key for user-scoped SDK clients, including SSR. For privileged server-only app code that needs admin/service access, use `createAdminClient({ apiKey })`; the API key is a full-access admin key, equivalent to a service role key on other platforms.
Use the correct environment variable prefix and access pattern for your framework:
| Framework | `.env` file | Variables | Access Pattern |
| ----------------------------- | ------------ | ----------------------------------------------------------- | ------------------------------------------- |
| **Next.js** | `.env.local` | `NEXT_PUBLIC_INSFORGE_URL`, `NEXT_PUBLIC_INSFORGE_ANON_KEY` | `process.env.NEXT_PUBLIC_*` |
| **Vite** (React, Vue, Svelte) | `.env` | `VITE_INSFORGE_URL`, `VITE_INSFORGE_ANON_KEY` | `import.meta.env.VITE_*` |
| **Astro** | `.env` | `PUBLIC_INSFORGE_URL`, `PUBLIC_INSFORGE_ANON_KEY` | `import.meta.env.PUBLIC_*` |
| **SvelteKit** | `.env` | `PUBLIC_INSFORGE_URL`, `PUBLIC_INSFORGE_ANON_KEY` | `import { env } from '$env/dynamic/public'` |
| **Create React App** | `.env` | `REACT_APP_INSFORGE_URL`, `REACT_APP_INSFORGE_ANON_KEY` | `process.env.REACT_APP_*` |
| **Node.js / Server** | `.env` | `INSFORGE_URL`, `INSFORGE_ANON_KEY` | `process.env.*` |
Example `.env.local` for Next.js:
```bash
NEXT_PUBLIC_INSFORGE_URL=https://your-appkey.us-east.insforge.app
NEXT_PUBLIC_INSFORGE_ANON_KEY=eyJhbGciOiJIUzI1NiIs...
```
> **Important:** Keep `.env` files local. Add `.env`, `.env.local`, and `.env*.local` to your `.gitignore` and keep `.env.example` for documenting required variables.
### 3. Initialize the client
Next.js:
```javascript
import { createClient } from '@insforge/sdk'
const insforge = createClient({
baseUrl: process.env.NEXT_PUBLIC_INSFORGE_URL,
anonKey: process.env.NEXT_PUBLIC_INSFORGE_ANON_KEY
})
```
Vite:
```javascript
import { createClient } from '@insforge/sdk'
const insforge = createClient({
baseUrl: import.meta.env.VITE_INSFORGE_URL,
anonKey: import.meta.env.VITE_INSFORGE_ANON_KEY
})
```
Astro:
```javascript
import { createClient } from '@insforge/sdk'
const insforge = createClient({
baseUrl: import.meta.env.PUBLIC_INSFORGE_URL,
anonKey: import.meta.env.PUBLIC_INSFORGE_ANON_KEY
})
```
For trusted server-only code that needs project-admin access:
```javascript
import { createAdminClient } from "@insforge/sdk";
const admin = createAdminClient({
baseUrl: process.env.INSFORGE_URL,
apiKey: process.env.INSFORGE_API_KEY,
});
```
## Module Reference
| Module | Integration Guide |
| ------------- | ------------------------------------------------------------ |
| **Database** | [database/sdk-integration.md](database/sdk-integration.md) |
| **Auth** | [auth/sdk-integration.md](auth/sdk-integration.md) |
| **Storage** | [storage/sdk-integration.md](storage/sdk-integration.md) |
| **Functions** | [functions/sdk-integration.md](functions/sdk-integration.md) |
| **AI** | [ai/overview.md](ai/overview.md) |
| **Real-time** | [realtime/sdk-integration.md](realtime/sdk-integration.md) |
| **Email** | [email/sdk-integration.md](email/sdk-integration.md) |
| **Payments: Stripe** | [payments/stripe.md](payments/stripe.md) |
| **Payments: Razorpay** | [payments/razorpay.md](payments/razorpay.md) |
### What Each Module Covers
| Module | Content |
| ------------- | ------------------------------------------------------------------------------------------------------------- |
| **Database** | CRUD operations, filters, pagination, RPC calls |
| **Auth** | Sign up/in, OAuth, sessions, profiles, password reset |
| **Storage** | Upload, download, delete files; S3-compatible gateway for CI / backup tooling; write RLS policies for buckets |
| **Functions** | Invoke edge functions |
| **AI** | OpenRouter AI calls for chat, images, video, audio, embeddings, and model discovery |
| **Email** | Send custom transactional HTML emails (welcome, newsletter, notifications) |
| **Payments: Stripe** | Stripe Checkout Sessions, subscriptions, and Billing Portal redirects |
| **Payments: Razorpay** | Razorpay Orders, Subscriptions, Checkout.js, and subscription management |
| **Real-time** | Connect, subscribe, publish events, and track presence snapshots plus join/leave deltas |
### Guides
| Guide | When to Use |
| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [../insforge-cli/references/database/access-control.md](../insforge-cli/references/database/access-control.md) | Backend setup for application-table access control — covers RLS, infinite recursion prevention, `SECURITY DEFINER` patterns, performance tips, and common InsForge patterns |
| [storage/s3-gateway.md](storage/s3-gateway.md) | Fallback path when the consumer is existing S3 tooling (aws CLI, AWS SDKs, rclone, Terraform, boto3) and adopting `@insforge/sdk` is impractical — covers endpoint/region setup, access-key management, path-style addressing, and supported vs. not-supported S3 operations. **Requires InsForge 2.0.9+.** **Prefer the SDK** ([storage/sdk-integration.md](storage/sdk-integration.md)) for app code |
| [storage/postgres-rls.md](storage/postgres-rls.md) | Writing RLS policies for `storage.objects` — owner-only, public-read, path-scoped, team-shared, and the `NULL uploaded_by` caveat for mixed REST + S3 buckets |
| [../insforge-cli/references/database/vector.md](../insforge-cli/references/database/vector.md) | Backend setup for semantic search, recommendations, or RAG — covers the `vector` extension, schema/dimensions, distance operators, HNSW/IVFFlat indexes, and RPC similarity search |
| [ai/chat-completions.md](ai/chat-completions.md) | Text generation, structured answers, and streaming chat through OpenRouter |
| [ai/image-generation.md](ai/image-generation.md) | Image generation/editing through OpenRouter, then durable storage in InsForge Storage |
| [ai/video-generation.md](ai/video-generation.md) | Async OpenRouter video jobs, status polling, and storing generated media |
| [ai/audio.md](ai/audio.md) | Speech-to-text, text-to-speech, and storing audio assets/transcripts with InsForge |
| [ai/embeddings-and-rag.md](ai/embeddings-and-rag.md) | Generating embeddings through OpenRouter, storing them in pgvector, and wiring up a basic RAG pipeline |
| [ai/models-list.md](ai/models-list.md) | Discovering OpenRouter model IDs, modalities, parameters, pricing, and embedding dimensions |
| [payments](../insforge-cli/references/payments/overview.md) | Configuring Stripe/Razorpay keys, syncing provider catalog, setting up webhooks, and writing payment RLS before app integration |
### Building Payments for a New App
First choose the provider. There is no generic app payments guide:
- For Stripe Checkout, subscriptions, and Billing Portal, load [payments/stripe.md](payments/stripe.md).
- For Razorpay Orders, Subscriptions, Checkout.js, and cancel/pause/resume flows, load [payments/razorpay.md](payments/razorpay.md).
Before writing app code, check provider setup with the **insforge-cli** payments references:
```bash
npx @insforge/cli payments stripe status
npx @insforge/cli payments razorpay status
```
If the chosen provider is unconfigured, ask the developer/admin to configure that provider first.
### Real-time Backend Setup
The real-time SDK is for frontend event handling and messaging. Configure channel patterns, database triggers, and channel/message RLS with the **insforge-cli** skill; see [realtime](../insforge-cli/references/realtime.md).
### Backend Configuration
Supported project config knobs are managed via the CLI — use
`npx @insforge/cli config export/plan/apply` for auth redirect URLs,
verification flags, password policy, auth SMTP settings, storage upload size,
realtime/schedule retention, and cloud deployment subdomain. OAuth providers,
external app setup, storage buckets, functions, secrets, and deployment env vars
still use their dedicated dashboard or CLI flows. See the **insforge-cli**
skill's Configuration section.
### Risky backend changes? Use a branch first
When a code change in this skill depends on a **schema migration**, **new RLS policy**, **OAuth provider config change**, or any other backend change that affects prod behavior, create a backend branch first. Branches share `JWT_SECRET` (existing user JWTs keep working) but get a fresh database + EC2 + `API_KEY` / `ANON_KEY`, so you can test the SDK + backend change end-to-end in isolation.
The full branching workflow lives in the **insforge-cli** skill — see [branch](../insforge-cli/references/branch/overview.md) for the decision guide and lifecycle commands. Typical loop:
```bash
npx @insforge/cli branch create feat-x --mode schema-only
# ... apply migrations / change auth config / update RLS on the branch ...
# ... test the SDK against the branch backend ...
npx @insforge/cli branch merge feat-x --dry-run # review SQL
npx @insforge/cli branch merge feat-x # apply to parent
```
> ⚠ **After `branch create` or `branch switch`**, update the app's InsForge URL and anon-key env values, then **restart your dev server** (or re-source `.env`) so the SDK talks to the selected branch backend.
## SDK Quick Reference
All SDK methods return `{ data, error }`.
| Module | Methods |
| -------------------- | ---------------------------------------------------------------------------------------------------- |
| `insforge.database` | `.from().select()`, `.insert()`, `.update()`, `.delete()`, `.rpc()` |
| `insforge.auth` | `.signUp()`, `.signInWithPassword()`, `.signInWithOAuth()`, `.signOut()`, `.getCurrentUser()` |
| `insforge.storage` | `.from().upload()`, `.uploadAuto()`, `.download()`, `.remove()` |
| `insforge.functions` | `.invoke()` |
| `insforge.ai` | Deprecated fallback only: `.chat.completions.create()`, `.images.generate()`, `.embeddings.create()` |
| `insforge.realtime` | `.connect()`, `.subscribe()`, `.publish()`, `.on()`, `.disconnect()` |
| `insforge.emails` | `.send({ to, subject, html, cc?, bcc?, from?, replyTo? })` |
| `insforge.payments.stripe` | `.createCheckoutSession()`, `.createCustomerPortalSession()` |
| `insforge.payments.razorpay` | `.createOrder()`, `.verifyOrder()`, `.createSubscription()`, `.verifySubscription()`, `.cancelSubscription()`, `.pauseSubscription()`, `.resumeSubscription()` |
## Important Notes
- **Database inserts require array format**: `insert([{...}])`
- **Next.js / SSR auth**: Use `@insforge/sdk/ssr` helpers (`createBrowserClient`, `createServerClient`, `createAuthActions`, `createRefreshAuthRouter`) and import `updateSession` from `@insforge/sdk/ssr/middleware` in Proxy/Middleware. Keep the refresh token httpOnly, run auth mutations through `createAuthActions()` on the server, return only safe app data from Server Actions, and let the browser read the short-lived access token for Storage/Realtime. See [auth/ssr-integration.md](auth/ssr-integration.md)
- **Storage**: Save both `url` AND `key` to database for download/delete operations
- **Functions invoke URL**: `/functions/{slug}`
- **Email delivery**: Auth emails (signup verification, password reset, magic links, invites) ship on **every plan**. Custom email via `insforge.emails.send()` ships on **every paid plan**. Use the platform-managed delivery path; custom sender domain is dashboard config. See [email/sdk-integration.md](email/sdk-integration.md).
- **Payments**: Configure provider keys/catalog with `npx @insforge/cli payments <provider> ...` first; frontend code uses provider-scoped SDK modules.
- **Payment RLS**: Before payment UI, add app-specific RLS on provider runtime tables. Stripe uses `payments.stripe_checkout_sessions` and `payments.stripe_customer_portal_sessions`; Razorpay uses `payments.razorpay_orders` and `payments.razorpay_subscriptions`. Durable fulfillment triggers go on `payments.webhook_events`, not success URLs, Checkout callbacks, or `payments.transactions`.
- **Use Tailwind CSS v3.4**
- **Always local build before deploy**: Prevents wasted build resources and faster debugging
- **SDK package**: Use `@insforge/sdk` directly for all features including authentication.
- **Deployment**: Include a `vercel.json` in the project root for SPA routing (React, React Router apps). The `download-template` tool includes this automatically.
- **Branching for risky backend changes**: If your SDK code depends on a new schema, RLS policy, or auth config change, create a branch via `npx @insforge/cli branch create` first — see the **insforge-cli** skill's [branch](../insforge-cli/references/branch/overview.md) reference. After `branch create` / `branch switch`, update the app's InsForge URL and anon-key env values, then **restart the dev server**.
Referenced files: 19
insforge-cli31.1 KB
View saved version →
---
name: insforge-cli
description: >-
Use this skill whenever someone needs a backend, or a task touches InsForge backend or cloud infrastructure through the InsForge CLI: projects, SQL, migrations, RLS policies, functions, storage, deployments, compute, secrets, config, schedules, logs, diagnostics, import/export, AI/OpenRouter setup, Stripe/Razorpay payments, Apify web scraping / data sources, PostHog product analytics, backend branches, agent memory (remember/recall project facts and decisions), or CLI docs. For app code with InsForge or @insforge/sdk, use the insforge app-integration skill instead.
license: Apache-2.0
---
# InsForge CLI
Use this skill whenever someone needs a backend, or when managing InsForge backend and cloud infrastructure with the InsForge CLI. For application code that calls InsForge from a frontend, backend, or edge function, use the `insforge` app-integration skill instead.
## Core Rules
- Always run the CLI through `npx @insforge/cli <command>`. Do not install or call a global `insforge` binary.
- If the project is already linked, use the current linked project. Run login, project creation, link, project discovery, organization listing, or cloud project commands only when connection setup is actually needed.
- Treat InsForge API keys as full-access admin keys. Keep them server-only and out of frontend/public env vars.
- Prefer CLI commands and documented project config over raw backend HTTP calls. If `config apply` reports unsupported/skipped fields, surface that result instead of bypassing the CLI with direct API calls.
- Use `--json` when structured output or non-interactive value collection is needed. Use `--yes` for confirmation prompts when the user has approved the action.
- At the start of a non-trivial task on a linked project, run `npx @insforge/cli memory list` (cheap, no AI call) and recall any title relevant to the task before designing or debugging. Record decisions and gotchas with `memory remember` at the moment they happen. See `references/memory.md`.
## Global Options
| Flag | Use |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--json` | Structured JSON output and skip value-collection prompts such as text/select prompts. Errors if any required value is missing. Combine with `-y` for destructive commands that also ask for Y/N confirmation. |
| `-y`, `--yes` | Auto-accept Y/N confirmation prompts such as delete or overwrite prompts. Does not skip value-collection prompts; use `--json` for that. |
## Exit Codes
| Code | Meaning |
| ---- | ------------------------------------------------------- |
| 0 | Success |
| 1 | General error, including HTTP 400+ from function invoke |
| 2 | Not authenticated |
| 3 | Project not linked |
| 4 | Resource not found |
| 5 | Permission denied |
## Environment Variables
| Variable | Use |
| ----------------------- | ---------------------------------- |
| `INSFORGE_ACCESS_TOKEN` | Override stored access token |
| `INSFORGE_PROJECT_ID` | Override linked project ID |
| `INSFORGE_EMAIL` | Email for non-interactive login |
| `INSFORGE_PASSWORD` | Password for non-interactive login |
## Connection Setup
If a task needs project access and the connection state is unknown, start with `npx @insforge/cli current`. Use `npx @insforge/cli whoami` when the authenticated identity matters or when `current` reports that the CLI is not authenticated.
If not authenticated, run `npx @insforge/cli login` (opens a browser). For headless / agent / CI contexts with no browser, authenticate non-interactively with a user API key: `npx @insforge/cli login --user-api-key "$INSFORGE_USER_API_KEY"` (the user creates the key in the dashboard under Profile → API Keys). If no project is linked, use `npx @insforge/cli link` for an existing project or `npx @insforge/cli create` when the user asked for a new backend. In workflows that are already prelinked or preconfigured, such as CI, local test projects, automation, or explicit user-provided project context, use that project context directly.
## Command Routing
| Need | CLI area | Reference |
| -------------------------------------------------------------------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------- |
| Login, logout, current user | `login`, `logout`, `whoami` | `references/login.md` |
| Create/link/list/current project | `create`, `link`, `list`, `current`, `metadata` | `references/create.md` |
| Project lifecycle: status, rename, delete, restore, version update, instance resize, transfer | `projects` | this file |
| Subscription/plan, credits, usage, payment history, billing cycles, plan upgrade, billing portal | `billing`, `usage` | this file |
| Organizations and members (create, update, invite, roles) | `orgs` | this file |
| Project backups (list, latest, create, rename, delete, restore) | `backups` | this file |
| Schema, SQL, RLS, triggers, indexes, imports, exports | `db` | `references/database/*` |
| Auth redirects, password policy, SMTP, storage size, realtime/schedule retention, subdomain config | `config` | `references/config.md` |
| Storage buckets and objects | `storage` | this file |
| Realtime backend setup | `db` migrations | `references/realtime.md` |
| Edge functions | `functions` | `references/functions-deploy.md` |
| AI/OpenRouter key setup | `ai setup` | this file |
| Agent memory: project facts, decisions, gotchas across sessions | `memory` | `references/memory.md` |
| Stripe/Razorpay keys, catalog sync, webhooks | `payments` | `references/payments/overview.md` |
| Frontend deployments | `deployments` | `references/deployments/deploy.md` |
| Custom domains, Cloudflare Registrar, DNS sync, SSL verification | `domains` | `references/deployments/domains.md` |
| Backend containers/services | `compute` | `references/compute-deploy.md` |
| Secrets/env vars | `secrets`, deployment/compute env commands | this file |
| Scheduled jobs | `schedules` | `references/schedules.md` |
| Backend branches | `branch` | `references/branch/overview.md`, `references/branch/merge.md`, `references/branch/reset.md` |
| Logs and health checks | `logs`, `diagnose` | `references/diagnostics.md` |
| Built-in documentation lookup | `docs` | this file |
| PostHog setup | `posthog setup` | `references/posthog.md` |
| Apify web scraper (connect, auth bridge, scrape, land, schedule) | `webscraper apify` | `references/webscraper/apify.md` |
## Database Workflow
Use database references before writing migrations when the task involves non-trivial database work:
- `references/database/migrations.md` - migration file creation and apply workflow.
- `references/database/query.md` - raw SQL execution and targeted inspection.
- `references/database/access-control.md` - RLS, grants, recursion-safe helper functions, ACLs, protected fields, and public projections.
- `references/database/integrity.md` - constraints, triggers, derived state, lifecycle guards, append-only history, and server-maintained fields.
- `references/database/vector.md` - pgvector extension, vector schema, distance operators, indexes, and vector search SQL/RPC patterns.
- `references/database/export.md` / `references/database/import.md` - schema or data import/export tasks.
Default pattern:
- Prefer `npx @insforge/cli db migrations new <name>` plus a migration SQL file for schema, grants, indexes, triggers, functions, and RLS policy changes.
- Apply migrations with `npx @insforge/cli db migrations up --all`.
- For new schema work, group related DDL into one migration when practical.
- Use targeted inspection when existing state is unknown or a command fails.
- Use `npx @insforge/cli db query <sql>` for targeted inspection and small corrective row/data SQL only when a migration is not appropriate.
- Use `npx @insforge/cli db rpc <fn> [--data <json>]` to call database functions through the backend.
Public schema scope:
- For generic application database work, create and modify app-owned objects in the `public` schema.
- Create, alter, drop, grant, revoke, index, trigger, function, view, and policy changes on `public` application objects.
- Do not create custom schemas or write to InsForge-managed/system schemas such as `auth`, `storage`, `realtime`, `payments`, `graphql`, `extensions`, `pg_catalog`, `information_schema`, or `system`, unless you are working on that specific feature module and its docs explicitly allow the operation.
- It is allowed to reference built-in objects such as `auth.users(id)` and `auth.uid()` from public tables or public RLS policies; do not modify those built-in objects.
- Do not create users, seed business rows, or run application CRUD workflows unless the user request explicitly asks for data migration, repair, or test setup.
RLS and access control:
- Use `auth.uid()` or an equivalent authenticated identity expression for user ownership checks.
- Add both SQL privileges and RLS policies. Policies do not replace `GRANT`.
- Runtime roles have broad default DML privileges on `public` tables so RLS can decide row access. If a table needs narrower operation or column access, explicitly `REVOKE` the broad privilege before granting the exact allowed operations or columns.
- Include `WITH CHECK` for INSERT and UPDATE policies so writes cannot create rows the user should not own.
- Prefer helper functions for cross-table RLS checks when direct policy joins can recurse through other RLS policies.
- Helper functions called from RLS policies that query RLS-enabled tables should be `SECURITY DEFINER`.
- Put RLS helper functions in `public` and schema-qualify references such as `public.team_members` and `auth.uid()`.
- For ACLs, protected owner/tenant/role fields, field-level update masks, sanitized public views, or recursion-sensitive policies, read `references/database/access-control.md` before writing migrations.
Integrity:
- For counters, balances, latest pointers, append-only history, state transitions, lifecycle guards, protected deletes, quota guards, leases, or trigger-maintained columns, read `references/database/integrity.md` before writing migrations.
Vector:
- For pgvector, vector search functions, score semantics, ANN indexes, hybrid ranking, RAG chunk retrieval, multi-vector search, or embedding version selection, read `references/database/vector.md` before writing migrations.
## Project and Configuration
Project commands:
- `npx @insforge/cli create` - create a new project. Use `--json` with required flags for non-interactive agent runs. See `references/create.md`.
- `npx @insforge/cli link` - link the current directory to an existing project.
- `npx @insforge/cli current` - show current linked project.
- `npx @insforge/cli metadata --json` - inspect backend metadata when discovery is needed.
Project lifecycle (operates on the linked project unless `--project <id>` is given):
- `npx @insforge/cli projects get [--project <id>]` - show a project's current status, in-flight `operation_status`, region, instance type, and version. Use this to poll after an async operation (restore, version update, instance resize) until `operation_status` clears.
- `npx @insforge/cli projects update [--name <name>] [--domain <domain>] [--storage-size <gib>] [--project <id>]` - rename or change project settings.
- `npx @insforge/cli projects restore [--project <id>]` - bring a paused project back online. Only paused projects can be restored.
- `npx @insforge/cli projects update-version [--wait] [--project <id>]` - update the backend to the latest InsForge version (resolved automatically; no-op if already current). Causes a brief restart. Add `--wait` to block until it finishes instead of returning while queued.
- `npx @insforge/cli projects upgrade-instance <type> [--project <id>]` - change the instance class. Valid: `nano`, `micro`, `small`, `medium`, `large`, `xl` (`xl` is the ceiling). Restarts the project and changes the bill.
- `npx @insforge/cli projects delete --project <id>` - permanently delete a project and all of its resources. `--project` is required (it will not default to the linked project). Irreversible — confirm the exact project id with the user first; this is a guarded, human-in-the-loop operation, so do not auto-bypass the confirmation.
- `npx @insforge/cli projects transfer <targetOrgId> --project <id>` - move a project to another organization (billing and access move with it). `--project` is required (it will not default to the linked project). Guarded, human-in-the-loop — confirm the source project and target org first.
Configuration:
- Use `npx @insforge/cli config export`, `config plan`, and `config apply` for supported `insforge.toml` knobs.
- TOML is for config values only. SQL belongs in `db migrations`; function code belongs in `functions deploy`; frontend code belongs in `deployments deploy`; compute code/images belong in `compute deploy`.
- If `config apply` returns `skipped[]`, report the skipped items and required backend upgrade. Do not retry with raw HTTP.
## Organizations and Members
Org-scoped commands resolve the organization in this order: `--org-id` flag, `INSFORGE_ORG_ID`, the linked project's org, the configured default org, then a prompt (or single-org auto-select). Pass `--org-id <id>` to act on a specific org.
- `npx @insforge/cli orgs list` - list organizations you belong to.
- `npx @insforge/cli orgs create <name> [--type personal|team|company]` - create an organization (default type `team`).
- `npx @insforge/cli orgs update [--name <name>] [--type <type>] [--org-id <id>]` - rename or change an organization's type.
- `npx @insforge/cli orgs members list [--org-id <id>]` - list members and pending invitations.
- `npx @insforge/cli orgs members invite <email> [--role administrator|developer] [--org-id <id>]` - invite a member (default role `developer`).
- `npx @insforge/cli orgs members role <memberId> <role> [--org-id <id>]` - change a member's role (`administrator` or `developer`).
- `npx @insforge/cli orgs members remove <memberId> [--org-id <id>]` - remove a member. Confirm intent first.
## Billing and Usage
Inspect the organization's plan/consumption and manage its subscription. Org resolution matches the Organizations section.
- `npx @insforge/cli billing status [--org-id <id>]` - show the current subscription/plan and period.
- `npx @insforge/cli billing credits [--org-id <id>]` - show the credit balance and recent credit transactions.
- `npx @insforge/cli billing history [--org-id <id>]` - list past payments / invoices.
- `npx @insforge/cli billing cycles [--org-id <id>]` - show the current and previous billing-cycle windows.
- `npx @insforge/cli usage [--org-id <id>]` - show consumption for the current billing period (summary plus per-project breakdown: database, storage, egress, etc.).
- `npx @insforge/cli billing upgrade <plan> [--org-id <id>]` - start a Stripe checkout to change the plan (`free | starter | pro | team | enterprise`). Opens the hosted checkout URL in the browser and also prints it. With `--json` it prints a JSON object (`{ checkoutUrl, sessionId }`) and does not open a browser — use this in headless/CI. No charge happens until the user completes checkout; the backend validates the plan and admin permission.
- `npx @insforge/cli billing manage [--org-id <id>]` - open the Stripe customer portal to manage the subscription, payment method, or cancellation. Opens the portal URL in the browser and also prints it. With `--json` it prints a JSON object (`{ portalUrl }`) and does not open a browser — use this in headless/CI.
## Backups
Operates on the linked project unless `--project <id>` is given.
- `npx @insforge/cli backups list [--project <id>]` - list backups.
- `npx @insforge/cli backups latest [--project <id>]` - show the most recent backup.
- `npx @insforge/cli backups create [--name <name>] [--wait] [--project <id>]` - create a backup. `--name` is optional; when provided it must be 1–64 chars. `--wait` blocks until it finishes instead of returning while queued.
- `npx @insforge/cli backups rename <backupId> <name> [--project <id>]` - rename a backup (pass `""` to clear the name).
- `npx @insforge/cli backups delete <backupId> [--project <id>]` - delete a backup. Confirm intent first.
- `npx @insforge/cli backups restore <backupId> [--project <id>]` - restore the project from a backup. This OVERWRITES the project's current database and storage; data written since that backup is lost. Confirm intent first.
## Storage
- `npx @insforge/cli storage buckets` - list buckets.
- `npx @insforge/cli storage create-bucket <name> [--private]` - create a bucket.
- `npx @insforge/cli storage delete-bucket <name>` - delete a bucket and all objects. Confirm destructive intent first.
- `npx @insforge/cli storage list-objects <bucket> [--prefix] [--search] [--limit] [--sort]` - inspect objects.
- `npx @insforge/cli storage upload <file> --bucket <name> [--key <objectKey>]` - upload an object.
- `npx @insforge/cli storage download <objectKey> --bucket <name> [--output <path>]` - download an object.
- `npx @insforge/cli storage s3-keys list` - list S3-compatible access keys (secret values are never shown).
- `npx @insforge/cli storage s3-keys create [--description <text>]` - create an S3 access key. The secret access key is shown ONCE on creation — capture it immediately.
- `npx @insforge/cli storage s3-keys delete <id>` - delete an S3 access key. Tools using it stop working. Confirm intent first.
For storage access-control behavior implemented through Postgres policies, use the storage-specific product docs or feature guidance. Do not treat storage internals as generic public-schema database tables unless the referenced storage docs explicitly say to.
## Realtime
Create channel patterns, app-table publish triggers, and channel/message RLS through migrations. See `references/realtime.md`.
## Edge Functions
- `npx @insforge/cli functions list` - list deployed functions.
- `npx @insforge/cli functions code <slug>` - view function source.
- `npx @insforge/cli functions deploy <slug> --file <path>` - deploy or update. See `references/functions-deploy.md`.
- `npx @insforge/cli functions invoke <slug> [--data <json>] [--method GET|POST]` - invoke a function.
- `npx @insforge/cli functions delete <slug>` - delete a function. Confirm destructive intent first.
## AI Gateway
- `npx @insforge/cli ai setup` fetches the linked project's active OpenRouter key and writes `OPENROUTER_API_KEY` to a local server-side env file.
- Keep `OPENROUTER_API_KEY` server-only. Never expose it as `NEXT_PUBLIC_*`, `VITE_*`, `PUBLIC_*`, or `REACT_APP_*`.
## Memory
Every project has built-in agent memory: durable facts, decisions, and gotchas that survive across sessions. Use it as a reflex, not an afterthought.
- `npx @insforge/cli memory list` - cheap title index (no AI call). Run at the start of a non-trivial task; recall any title relevant to the task.
- `npx @insforge/cli memory recall "<query>" [--scope] [--limit] [--threshold]` - semantic + keyword recall.
- `npx @insforge/cli memory remember "<content>" [--kind] [--title] [--scope] [--source]` - store one atomic memory. Record decisions and gotchas at the moment they happen, not at session end.
- `npx @insforge/cli memory remember --file <path>` - extract durable memories from a transcript or notes file.
Storing is idempotent: re-remembering a known fact is a no-op, and a contradicting fact updates the existing memory instead of duplicating it - when the truth changes, just `remember` the new truth. See `references/memory.md` for what to store, kinds, and examples.
## Payments
Use `payments` for Stripe/Razorpay backend setup and catalog sync. See `references/payments/overview.md`.
- Payments are provider-specific: use `payments stripe ...` or `payments razorpay ...` explicitly.
- Configure provider keys with `payments <provider> config set`; setting keys automatically syncs provider state when the key or account changes.
- Check key/account/sync/webhook health with `payments <provider> status`.
- Run `payments <provider> sync` to manually refresh or retry mirrored provider data.
- Stripe uses Products/Prices and supports managed webhook registration; Razorpay uses Items/Plans/Orders and requires manual webhook setup in the Razorpay Dashboard.
- Prefer test mode while building. Use live mode only after explicit user approval.
- If the backend reports payments unavailable, ask the user/admin to enable or upgrade payments. Do not work around it by storing provider keys as generic secrets or embedding payment secret keys in app code.
- Load `references/payments/stripe.md` or `references/payments/razorpay.md` before provider-specific setup.
Runtime checkout, subscriptions, customer portal flows, and app code belong in the `insforge` app-integration skill.
## Deployments
Frontend deployments:
- Build locally first when the app has a build step.
- Ensure frontend runtime env vars are configured with the correct framework prefix before deployment.
- Use `npx @insforge/cli deployments deploy <dir>` for frontend source directories. Do not deploy generated output directories unless the deployment reference explicitly calls for it.
- See `references/deployments/deploy.md`.
Custom domains:
- Use `npx @insforge/cli domains ...` for custom domains, Cloudflare Registrar, DNS sync, and SSL verification.
- See `references/deployments/domains.md`.
Backend compute services:
- Use `npx @insforge/cli compute ...`; do not manage InsForge compute services directly with the user's own `flyctl` account.
- Use source mode for a directory with a Dockerfile, or image mode with `--image <url>` for a pre-built image.
- Use `--env-file` or repeatable env-set/update commands for secrets instead of large inline JSON.
- See `references/compute-deploy.md`.
## Secrets
- `npx @insforge/cli secrets list [--all]` - list secret keys without values.
- `npx @insforge/cli secrets get <key>` - retrieve a secret value only when necessary.
- `npx @insforge/cli secrets add <key> <value> [--reserved] [--expires <ISO date>]` - create a secret.
- `npx @insforge/cli secrets update <key> [--value] [--active] [--reserved] [--expires]` - update a secret.
- `npx @insforge/cli secrets delete <key>` - soft-delete a secret. Confirm intent first.
- `npx @insforge/cli secrets rotate <api-key|anon-key> [--grace-hours <n>]` - rotate the project API key or anon key. The new key is printed ONCE — capture it. The old key keeps working during the grace period (server default if `--grace-hours` is omitted); update all consumers before it expires.
## Schedules
- `npx @insforge/cli schedules list/get/create/update/delete/logs`.
- Use standard 5-field cron for wall-clock schedules.
- Use pg_cron interval syntax such as `30 seconds` for sub-minute cadence. Six-field cron with seconds is not supported.
- Headers can reference InsForge secrets with `${{secrets.KEY_NAME}}`.
- See `references/schedules.md` for cron formats, secret header references, examples, common mistakes, and the recommended setup workflow.
## Branching
Use backend branches to test risky schema, RLS, auth, or function changes before applying them to production. See `references/branch/overview.md`.
Common commands:
- `npx @insforge/cli branch create <name> [--mode full|schema-only] [--no-switch]`
- `npx @insforge/cli branch list`
- `npx @insforge/cli branch switch <name>` or `--parent`
- `npx @insforge/cli branch merge <name> [--dry-run] [--save-sql <path>]`
- `npx @insforge/cli branch reset <name>`
- `npx @insforge/cli branch delete <name>`
Branching requires a backend version that supports it. If unavailable, report the backend version limitation instead of inventing a workaround.
## Diagnostics and Logs
- `npx @insforge/cli diagnose` - full health report.
- `npx @insforge/cli diagnose --ai "<issue description>"` - ask the InsForge debug agent to diagnose a concrete backend issue.
- `npx @insforge/cli diagnose metrics [--range 1h|6h|24h|7d]` - EC2 metrics.
- `npx @insforge/cli diagnose advisor [--severity critical|warning|info] [--category security|performance|health]` - advisor issues.
- `npx @insforge/cli diagnose db [--check <checks>]` - database health checks.
- `npx @insforge/cli diagnose logs [--source <name>] [--limit <n>]` - aggregate error logs.
- `npx @insforge/cli logs <source> [--limit <n>]` - source-specific backend logs.
Typical log sources include `function.logs`, `function-deploy.logs`, `postgres.logs`, `postgrest.logs`, and `insforge.logs`. See `references/diagnostics.md` for common debugging scenarios and source selection.
## Documentation
- `npx @insforge/cli docs` - list documentation topics.
- `npx @insforge/cli docs instructions` - setup guide.
- `npx @insforge/cli docs <feature> <language>` - feature docs for `db`, `storage`, `functions`, `auth`, `ai`, or `realtime` in `typescript`, `swift`, `kotlin`, or `rest-api`.
For application code with InsForge or `@insforge/sdk`, use the `insforge` app-integration skill and use `docs` only as official feature reference.
## PostHog
- `npx @insforge/cli posthog setup` ensures the dashboard has a PostHog connection, then prints the official PostHog wizard command plus the connected project's public `phc_` API key and host.
- ⚠️ `posthog setup` alone does NOT instrument the app: no env vars, no SDK, no events until the wizard step happens. The wizard is interactive and may open a browser; ask the user to run it in their real terminal, or instrument manually using the printed `phc_` key/host (PostHog's public client key, safe in frontend env vars).
- Cloud only: self-hosted backends don't expose the integration. Do not substitute a `phc_` key from a separate PostHog account into app env vars — the Analytics page reads from the server-side connection that only `posthog setup` populates; use the key it prints.
## Apify web scraper
- `npx @insforge/cli webscraper apify connect` — one-time OAuth connect; stores a refreshable token in InsForge.
- `npx @insforge/cli webscraper apify login` — auth bridge: fetches the InsForge-managed token, runs `apify login --token`, and installs Apify's official agent skills. Never run plain `apify login` (browser OAuth). On any Apify `401` / "not logged in", re-run `login`.
- See `references/webscraper/apify.md` for the full scrape → land → schedule workflow and size-based landing strategy.
## Non-Interactive CI/CD
Use env vars and JSON mode for automated contexts:
```bash
INSFORGE_EMAIL=$EMAIL INSFORGE_PASSWORD=$PASSWORD npx @insforge/cli login --email -y
npx @insforge/cli link --project-id $PROJECT_ID --org-id $ORG_ID -y
npx @insforge/cli db query "SELECT 1 AS ok" --json
```
## Project Configuration File
After `create` or `link`, `.insforge/project.json` contains the linked project ID, app key, region, API key, and backend URL.
- Never commit `.insforge/project.json` or share it publicly.
- Do not edit it manually. Use `npx @insforge/cli link` or branch commands to switch projects.
Referenced files: 28
insforge-debug10.3 KB
View saved version →
---
name: insforge-debug
description: >-
Use when diagnosing problems in an InsForge project — reactive failures (SDK
error object, HTTP 4xx/5xx, gateway timeout 502/503/504, edge function failure
or timeout, login/OAuth/auth errors, RLS denial, realtime channel issues,
slow query on one endpoint, edge function or Vercel deploy failure), proactive
audits (security/RLS review, performance/index review, system health check,
pre-launch readiness), or when the user has an error but doesn't know where
to start.
license: Apache-2.0
---
# InsForge Debug
Diagnose problems in InsForge projects by combining the backend's observability primitives — logs, metrics, db-health, advisor, policies, metadata, error objects, deploy state, and AI assist. This skill provides:
1. A reference per **debug primitive** (one observability surface each — under `references/`)
2. **Symptom Recipes** (below) that name the primitive sequence for known reactive symptoms and proactive audits
**Always use `npx @insforge/cli`** — never install the CLI globally.
## Fastest Path: AI-Assisted Triage
When the user gives a concrete description (error message, failing URL, HTTP status), hand it to the InsForge debug agent. Unlike the other primitives, this one returns suggestions, not just observations — verify the diagnosis against the primitives it cites before acting on it.
```bash
npx @insforge/cli diagnose --ai "<issue description>"
```
See [references/ai-assisted.md](references/ai-assisted.md) for when to use this first vs when to skip, and how to verify the output.
## Debug Primitives
Each primitive is one independently-queryable observability surface backed by a distinct underlying data source. Real diagnoses are compositions of primitives.
All commands run via `npx @insforge/cli ...`. The `(command)` shown next to each primitive is the actual CLI command — primitive names are concept labels, **not** CLI subcommand names (e.g., "DB health" is `diagnose db`, not `diagnose db-health`; "Policies" is `db policies`, not `diagnose policies`).
| Primitive (command) | What you see | Reference |
|---------------------|-------------|-----------|
| **Logs** (`logs <source>`; `diagnose logs` for cross-source aggregate) | Time-stream of events from 5 backend sources (`insforge.logs` / `postgREST.logs` / `postgres.logs` / `function.logs` / `function-deploy.logs`) | [references/logs.md](references/logs.md) |
| **Metrics** (`diagnose metrics`) | EC2 instance time-series (CPU / memory / disk / network) over `1h` / `6h` / `24h` / `7d` | [references/metrics.md](references/metrics.md) |
| **DB health** (`diagnose db`) | Current Postgres state via 7 named checks (`connections` / `slow-queries` / `bloat` / `size` / `index-usage` / `locks` / `cache-hit`) | [references/db-health.md](references/db-health.md) |
| **Advisor** (`diagnose advisor --json`) | Static-scan issues across 3 categories (`security` / `performance` / `health`) with `ruleId` / `affectedObject` / `recommendation` | [references/advisor.md](references/advisor.md) |
| **Policies** (`db policies`) | Active RLS rules from `pg_policies` (USING / WITH CHECK per cmd per role) — returns all policies as a dump | [references/policies.md](references/policies.md) |
| **Metadata** (`metadata --json`) | Declarative backend state dump (auth config / tables / buckets / functions / AI models / realtime channels) | [references/metadata.md](references/metadata.md) |
| **Error objects** (no command — read SDK / HTTP response) | SDK error envelope + HTTP status — the routing table from a client-visible error to the right log source | [references/error-objects.md](references/error-objects.md) |
| **Deploy state** (`deployments list` + `deployments status <id> --json` + `logs function-deploy.logs`) | Frontend (Vercel) deployment history + per-deploy metadata, plus edge function deploy logs | [references/deploy-state.md](references/deploy-state.md) |
| **AI assist** (`diagnose --ai "<description>"`) | LLM agent that combines the other primitives — returns a diagnosis with suggestions | [references/ai-assisted.md](references/ai-assisted.md) |
## Symptom Recipes
Each recipe is a primitive call sequence with one-line "look for X" at each step. Command syntax, flags, and deep interpretation are in the per-primitive references above.
### Recipe: SDK returned `{ data: null, error: { code, message } }`
1. **error-objects** — read code/message/details. If code starts with `PGRST*`, route by prefix using the table in the reference.
2. **logs** (matching source per error-objects routing) — find the error timestamp, get the full backend-side context.
3. **db-health** (`connections`, `locks`, `slow-queries`) — only if the error suggests DB issue (PostgREST timeout, lock conflict).
### Recipe: HTTP 4xx/5xx response on a specific request
1. **error-objects** — use the HTTP status routing table to pick the log source (each status has a distinct path; 429 is special).
2. **logs** (right source for that status) — find the failing request line and error.
3. **metrics** — only for 5xx patterns spanning multiple endpoints, to confirm system-wide load issue.
### Recipe: RLS access issue (403 on write, or empty result on read)
> Same bug, two surfacings. Writes (INSERT / UPDATE / DELETE) fail loudly with **403**. Reads (SELECT) fail silently with an **empty array** — PostgREST filters denied rows out instead of returning 403, so the request looks successful with zero rows. Diagnosis path is the same except step 1 only applies to the 403 variant.
1. **logs** (`postgREST.logs`) — *403 variant only*: find the policy violation event with table and role context. *Empty-result variant*: skip — no error is logged for silently-filtered rows.
2. **policies** — list policies for that table; walk USING / WITH CHECK against the actual request and the JWT claim used.
3. **metadata** — verify auth config (which claim feeds `auth.uid()` / `requesting_user_id()`; for third-party auth like Clerk/Auth0, is the provider registered as a JWT issuer?).
4. **db query** (`db query "<sql>"`) — *empty-result variant only*: confirm rows that *should* be visible actually exist by querying as service role (not as the user): `npx @insforge/cli db query "SELECT id, user_id FROM <table>"`. Distinguishes "RLS filtered everything" from "no matching data exists".
### Recipe: Login fails / OAuth callback errors / token expired
1. **logs** (`insforge.logs`) — find auth errors with timestamp and provider context.
2. **metadata** — verify the provider is enabled, redirect URLs match the callback URL exactly (protocol + host + path).
### Recipe: Edge function runtime error / timeout
1. **logs** (`function.logs`) — get the error stack and execution context.
2. **metadata** — confirm the function exists and `status: "active"`.
3. (If needed) `npx @insforge/cli functions code <slug>` — inspect the source for obvious issues.
### Recipe: `functions deploy` failed
1. **deploy-state** (`function-deploy.logs`) — find the build/push error.
2. **metadata** — confirm whether the function ended up in the active list (partial-deploy detection).
### Recipe: `deployments deploy` failed (Vercel)
1. **deploy-state** (`deployments list` + `status <id> --json`) — read `status`, `metadata.webhookEventType`, and `envVarKeys`.
2. **Local** `npm run build` — reproduce the same error locally for faster iteration.
### Recipe: Single slow query / one endpoint slow
1. **logs** (`postgres.logs`) — find the query text and timestamp.
2. **db-health** (`slow-queries`, `index-usage`) — confirm it's in `pg_stat_statements`; check for missing index.
3. **policies** — if it's an RLS-gated table, verify the policy isn't adding hidden joins.
### Recipe: All responses slow / high CPU/memory (active incident)
1. **metrics** (`--range 1h`) — confirm system-wide pressure (CPU / memory / disk).
2. **db-health** — DB is the most common bottleneck; check `connections`, `locks`, `slow-queries`.
3. **logs** (`diagnose logs` aggregate) — error patterns across sources at the spike timestamp.
4. **advisor** (`--severity critical`) — pre-existing known issues that may explain the degradation.
### Recipe: Realtime channel won't connect / messages missing
1. **logs** (`insforge.logs`) — WebSocket errors and subscription failures.
2. **metadata** — verify the channel pattern matches what the client subscribes to, `enabled: true`.
3. **policies** — RLS on the underlying table (realtime delivers row changes; RLS gates which rows the subscriber sees).
### Recipe: 429 rate limit
1. **error-objects** — confirm 429 status. **No logs are recorded for 429s; no `Retry-After` header is returned.** Don't waste time grepping logs.
2. **metrics** (`--range 1h`) — overall backend load context.
3. **Fix is always client-side**: debounce, batch, exponential backoff, eliminate retry loops.
### Recipe: Gateway timeout (502 / 503 / 504) on a specific URL
Route by URL subsystem before drilling:
| URL pattern | Drill into |
|-------------|-----------|
| `/api/database/records/...` | **logs** (`postgREST.logs` → `postgres.logs`) + **db-health** (`locks`, `slow-queries`) |
| `/functions/<slug>` | **logs** (`function.logs`) — function may be crash-looping |
| `/api/auth/...` | **logs** (`insforge.logs`) |
| Any path during system-wide spike | **metrics** (`--range 1h`) |
### Recipe: Pre-launch / proactive audit
> Requires Platform login (`npx @insforge/cli login`). **Not available when the project is linked via `--api-key`** — fall back to `db-health` + `policies` + `metadata` for a manual audit in that case.
1. **advisor** — full scan, then `--severity critical` first, then warnings.
2. **advisor** (`--category security`) — focus on security issues; cross-verify with **policies** (RLS coverage) and **metadata** (auth config, public buckets, secret presence).
3. **advisor** (`--category performance`) — cross-verify with **db-health** (`slow-queries`, `index-usage`, `bloat`).
4. **advisor** (`--category health`) — cross-verify with **metrics** (resource trends over `7d`).
5. After fixes, re-run **advisor** and confirm `isResolved: true` for each addressed `ruleId`.
### Recipe: Don't know where to start
1. **ai-assisted** (`diagnose --ai "<error or URL>"`) — get a starting hypothesis.
2. **Verify** by re-checking the primitives the diagnosis names. Trust the primitive observations over the suggestion.
Referenced files: 10
insforge-integrations5.81 KB
View saved version →
---
name: insforge-integrations
description: >-
Use when wiring an external auth provider (Clerk, Auth0, WorkOS, Kinde,
Stytch, Better Auth) into InsForge for JWT-based RLS, or when adding the
OKX x402 payment facilitator for onchain pay-per-use billing.
license: Apache-2.0
---
# InsForge Integrations
This skill covers integrating **third-party providers** with InsForge. Currently two categories are supported: **auth providers** (RLS via JWT claims) and **payment facilitators** (x402 HTTP payment protocol). Each provider has its own guide under this directory.
## Auth Providers
| Provider | Guide | When to use |
|----------|-------|-------------|
| [Clerk](references/clerk.md) | Clerk JWT Templates + InsForge RLS | Clerk signs tokens directly via JWT Template — no server-side signing needed |
| [Auth0](references/auth0.md) | Auth0 Actions + InsForge RLS | Auth0 uses a post-login Action to embed claims into the access token |
| [WorkOS](references/workos.md) | WorkOS AuthKit + InsForge RLS | WorkOS AuthKit middleware + server-side JWT signing with `jsonwebtoken` |
| [Kinde](references/kinde.md) | Kinde + InsForge RLS | Kinde token customization for InsForge integration |
| [Stytch](references/stytch.md) | Stytch + InsForge RLS | Stytch session tokens for InsForge integration |
| [Better Auth](references/better-auth.md) | Better Auth + InsForge RLS | Self-hosted auth running in your InsForge Postgres — no third-party SaaS, no per-MAU cost |
## Payment Facilitators
| Provider | Guide | When to use |
|----------|-------|-------------|
| [OKX x402](references/okx-x402.md) | OKX as x402 facilitator (USDG on X Layer) | Pay-per-use HTTP endpoints settled onchain with zero gas for the payer |
## Common Patterns
### Auth providers
1. **Provider signs or issues a JWT** containing the user's ID
2. **JWT is passed to InsForge** via `accessToken` in `createClient()` (deprecated alias: `edgeFunctionToken`)
3. **InsForge exposes claims** through `auth.jwt()` in SQL
4. **RLS policies** use a `requesting_user_id()` function to enforce row-level security
### Payment facilitators (x402)
1. **Server returns `402 Payment Required`** with a JSON challenge base64-encoded in `PAYMENT-REQUIRED` header
2. **Client signs an EIP-3009 authorization** using the stablecoin's EIP-712 domain
3. **Server forwards the signed payload** to the facilitator's `/verify` + `/settle` endpoints
4. **Server records the settled payment** in an InsForge table with a realtime trigger for live dashboards
## Choosing a Provider
**Auth**
- **Clerk** — Simplest setup; JWT Template handles signing, no server code needed
- **Auth0** — Flexible; uses post-login Actions for claim injection
- **WorkOS** — Enterprise-focused; AuthKit middleware + server-side JWT signing
- **Kinde** — Developer-friendly; built-in token customization
- **Stytch** — API-first; session-based token flow
- **Better Auth** — Self-hosted in your Postgres; no SaaS vendor; you own the user table. Pairs cleanly with InsForge's Postgres via a connection string + a small bridge route. Requires a one-time `REVOKE` after migrate to seal PostgREST exposure.
**Payment facilitators**
- **OKX x402** — Onchain pay-per-use via USDG on X Layer; zero gas for the payer
## Setup
1. Identify which provider the project uses
2. Read the corresponding reference guide from the tables above
3. Follow the provider-specific setup steps
## Usage Examples
Each provider guide includes full code examples for:
- Provider dashboard configuration (API keys, application settings, etc.)
- Server and client code (JWT utilities for auth; facilitator client + signing utilities for payments)
- Database setup (RLS for auth; payment table + realtime trigger for payments)
- Environment variable setup
Refer to the specific `references/<provider>.md` file for complete examples.
## Best Practices
**Auth**
- All auth provider user IDs are strings (not UUIDs) — always use `TEXT` columns for `user_id`
- Use `requesting_user_id()` instead of `auth.uid()` for RLS policies
- Pass the JWT via `accessToken` — a static string, not a function; for short-lived tokens (Clerk) sync refreshes with `client.setAccessToken(token, AuthChangeEvent.TOKEN_REFRESHED)` after the initial same-user sign-in
- Always get the JWT secret via `npx @insforge/cli secrets get JWT_SECRET`
**Payment facilitators (x402)**
- Always check the result of the database `insert(...)` after settlement — settlement takes money onchain before the insert runs; a silent DB failure loses the record
- Add `UNIQUE` to the `tx_hash` column to prevent duplicate records from retries
- Verify EIP-712 domain (`name`, `version`) against the token contract's on-chain `DOMAIN_SEPARATOR` — wrong values produce `Invalid Authority` errors
- Use a `MOCK_OKX_FACILITATOR` env flag for local dev so the full flow can be exercised without real funds
## Common Mistakes
**Auth**
| Mistake | Solution |
|---------|----------|
| Using `auth.uid()` for RLS | Use `requesting_user_id()` — third-party IDs are strings, not UUIDs |
| Using UUID columns for `user_id` | Use `TEXT` — all supported providers use string-format IDs |
| Hardcoding the JWT secret | Always retrieve via `npx @insforge/cli secrets get JWT_SECRET` |
| Missing `requesting_user_id()` function | Must be created before RLS policies will work |
**Payments (x402)**
| Mistake | Solution |
|---------|----------|
| Using an OKX exchange trading API key | Create a separate Web3 API key at `web3.okx.com/onchainos/dev-portal` |
| Wrong EIP-712 domain values | Read the token contract's `DOMAIN_SEPARATOR` — for USDG on X Layer use `name: "Global Dollar"`, `version: "1"` |
| Ignoring DB insert error after settlement | Always destructure `{ error }` and log/handle it — money has already moved |
| `MOCK_OKX_FACILITATOR=true` in production | Mock mode is demo-only; it returns fake tx hashes and bypasses verification |
Referenced files: 8