InsForge SDK 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, website deployments, cron job and schedules, logs, etc.), use the insforge-cli skill.
Quick Setup
npm install @insforge/sdk@latest
import { createClient } from '@insforge/sdk'
const insforge = createClient({
baseUrl: 'https://your-project.region.insforge.app',
anonKey: 'your-anon-key'
})
Module Reference
| Module |
SDK Integration |
| Database |
database/sdk-integration.md |
| Auth |
auth/sdk-integration.md |
| Storage |
storage/sdk-integration.md |
| Functions |
functions/sdk-integration.md |
| AI |
ai/sdk-integration.md |
| Real-time |
realtime/sdk-integration.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 |
| Functions |
Invoke edge functions |
| AI |
Chat completions, image generation, embeddings |
| Real-time |
Connect, subscribe, publish events |
Guides
| Guide |
When to Use |
| database/postgres-rls.md |
Writing or reviewing RLS policies — covers infinite recursion prevention, SECURITY DEFINER patterns, performance tips, and common InsForge RLS patterns |
Real-time Configuration
For real-time channels and database triggers, use insforge db query with SQL to create triggers that publish to channels. The real-time SDK is for frontend event handling and messaging, not backend configuration.
Create Database Triggers
Automatically publish events when database records change.
-- Create trigger function
CREATE OR REPLACE FUNCTION notify_order_changes()
RETURNS TRIGGER AS $$
BEGIN
PERFORM realtime.publish(
'order:' || NEW.id::text, -- channel
TG_OP || '_order', -- event: INSERT_order, UPDATE_order
jsonb_build_object(
'id', NEW.id,
'status', NEW.status,
'total', NEW.total
)
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Attach to table
CREATE TRIGGER order_realtime
AFTER INSERT OR UPDATE ON orders
FOR EACH ROW
EXECUTE FUNCTION notify_order_changes();
Conditional Trigger (Status Changes Only)
CREATE OR REPLACE FUNCTION notify_order_status()
RETURNS TRIGGER AS $$
BEGIN
PERFORM realtime.publish(
'order:' || NEW.id::text,
'status_changed',
jsonb_build_object('id', NEW.id, 'status', NEW.status)
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
CREATE TRIGGER order_status_trigger
AFTER UPDATE ON orders
FOR EACH ROW
WHEN (OLD.status IS DISTINCT FROM NEW.status)
EXECUTE FUNCTION notify_order_status();
Access Control (RLS)
RLS is disabled by default. To restrict channel access:
ALTER TABLE realtime.channels ENABLE ROW LEVEL SECURITY;
ALTER TABLE realtime.messages ENABLE ROW LEVEL SECURITY;
- Restrict Subscribe (SELECT on channels)
CREATE POLICY "users_subscribe_own_orders"
ON realtime.channels FOR SELECT
TO authenticated
USING (
pattern = 'order:%'
AND EXISTS (
SELECT 1 FROM orders
WHERE id = NULLIF(split_part(realtime.channel_name(), ':', 2), '')::uuid
AND user_id = auth.uid()
)
);
- Restrict Publish (INSERT on messages)
CREATE POLICY "members_publish_chat"
ON realtime.messages FOR INSERT
TO authenticated
WITH CHECK (
channel_name LIKE 'chat:%'
AND EXISTS (
SELECT 1 FROM chat_members
WHERE room_id = NULLIF(split_part(channel_name, ':', 2), '')::uuid
AND user_id = auth.uid()
)
);
| Task |
SQL |
| Create channel |
INSERT INTO realtime.channels (pattern, description, enabled) VALUES (...) |
| Create trigger |
CREATE TRIGGER ... EXECUTE FUNCTION ... |
| Publish from SQL |
PERFORM realtime.publish(channel, event, payload) |
| Enable RLS |
ALTER TABLE realtime.channels ENABLE ROW LEVEL SECURITY |
Best Practices
Create channel patterns first before subscribing from frontend
- Insert channel patterns into
realtime.channels table
- Ensure
enabled is set to true
Use specific channel patterns
- Use wildcard
% patterns for dynamic channels (e.g., order:% for order:123)
- Use exact patterns for global channels (e.g.,
notifications)
Common Mistakes
| Mistake |
Solution |
| Subscribing to undefined channel pattern |
Create channel pattern in realtime.channels first |
| Channel not receiving messages |
Ensure channel enabled is true |
| Publishing without trigger |
Create database trigger to auto-publish on changes |
Recommended Workflow
1. Create channel patterns → INSERT INTO realtime.channels
2. Ensure enabled = true → Set enabled to true
3. Create triggers if needed → Auto-publish on database changes
4. Proceed with SDK subscribe → Use channel name matching pattern
Backend Configuration (Not Yet in CLI)
These modules still require HTTP API calls because the CLI does not yet support them:
| Module |
Backend Configuration |
| Auth |
auth/backend-configuration.md |
| AI |
ai/backend-configuration.md |
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(), .getCurrentSession() |
insforge.storage |
.from().upload(), .uploadAuto(), .download(), .remove() |
insforge.functions |
.invoke() |
insforge.ai |
.chat.completions.create(), .images.generate(), .embeddings.create() |
insforge.realtime |
.connect(), .subscribe(), .publish(), .on(), .disconnect() |
Important Notes
- Database inserts require array format:
insert([{...}]) not insert({...})
- Storage: Save both
url AND key to database for download/delete operations
- Functions invoke URL:
/functions/{slug} (without /api prefix)
- Use Tailwind CSS v3.4 (do not upgrade to v4)
- Always local build before deploy: Prevents wasted build resources and faster debugging
1---2name: insforge3description: Use this skill whenever writing frontend code that talks to a backend for database queries, authentication, file uploads, AI features, real-time messaging, or edge function calls — especially if the project uses InsForge or @insforge/sdk. Trigger on any of these contexts: querying/inserting/updating/deleting database rows from frontend code, adding login/signup/OAuth/password-reset flows, uploading or downloading files to storage, invoking serverless functions, calling AI chat completions or image generation, subscribing to real-time WebSocket channels, or writing RLS policies. If the user asks for these features generically (e.g., "add auth to my React app", "fetch data from my database", "upload files") and you're unsure whether they use InsForge, consult this skill and ask. For backend infrastructure (creating tables via SQL, deploying functions, CLI commands), use insforge-cli instead.4---56# InsForge SDK Skill78This skill covers **client-side SDK integration** using `@insforge/sdk`. For backend infrastructure operations (creating tables, inspecting schema, deploying functions, secrets, managing storage buckets, website deployments, cron job and schedules, logs, etc.), use the **insforge-cli** skill.910## Quick Setup1112```bash13npm install @insforge/sdk@latest14```1516```javascript17import { createClient } from '@insforge/sdk'1819const insforge = createClient({20 baseUrl: 'https://your-project.region.insforge.app',21 anonKey: 'your-anon-key'22})23```2425## Module Reference2627| Module | SDK Integration |28|--------|-----------------|29| **Database** | [database/sdk-integration.md](database/sdk-integration.md) |30| **Auth** | [auth/sdk-integration.md](auth/sdk-integration.md) |31| **Storage** | [storage/sdk-integration.md](storage/sdk-integration.md) |32| **Functions** | [functions/sdk-integration.md](functions/sdk-integration.md) |33| **AI** | [ai/sdk-integration.md](ai/sdk-integration.md) |34| **Real-time** | [realtime/sdk-integration.md](realtime/sdk-integration.md) |3536### What Each Module Covers3738| Module | Content |39|--------|---------|40| **Database** | CRUD operations, filters, pagination, RPC calls |41| **Auth** | Sign up/in, OAuth, sessions, profiles, password reset |42| **Storage** | Upload, download, delete files |43| **Functions** | Invoke edge functions |44| **AI** | Chat completions, image generation, embeddings |45| **Real-time** | Connect, subscribe, publish events |4647### Guides4849| Guide | When to Use |50|-------|-------------|51| [database/postgres-rls.md](database/postgres-rls.md) | Writing or reviewing RLS policies — covers infinite recursion prevention, `SECURITY DEFINER` patterns, performance tips, and common InsForge RLS patterns |5253### Real-time Configuration5455For real-time channels and database triggers, use `insforge db query` with SQL to create triggers that publish to channels. The real-time SDK is for frontend event handling and messaging, not backend configuration.5657#### Create Database Triggers5859Automatically publish events when database records change.6061```sql62-- Create trigger function63CREATE OR REPLACE FUNCTION notify_order_changes()64RETURNS TRIGGER AS $$65BEGIN66 PERFORM realtime.publish(67 'order:' || NEW.id::text, -- channel68 TG_OP || '_order', -- event: INSERT_order, UPDATE_order69 jsonb_build_object(70 'id', NEW.id,71 'status', NEW.status,72 'total', NEW.total73 )74 );75 RETURN NEW;76END;77$$ LANGUAGE plpgsql SECURITY DEFINER;7879-- Attach to table80CREATE TRIGGER order_realtime81 AFTER INSERT OR UPDATE ON orders82 FOR EACH ROW83 EXECUTE FUNCTION notify_order_changes();84```8586#### Conditional Trigger (Status Changes Only)8788```sql89CREATE OR REPLACE FUNCTION notify_order_status()90RETURNS TRIGGER AS $$91BEGIN92 PERFORM realtime.publish(93 'order:' || NEW.id::text,94 'status_changed',95 jsonb_build_object('id', NEW.id, 'status', NEW.status)96 );97 RETURN NEW;98END;99$$ LANGUAGE plpgsql SECURITY DEFINER;100101CREATE TRIGGER order_status_trigger102 AFTER UPDATE ON orders103 FOR EACH ROW104 WHEN (OLD.status IS DISTINCT FROM NEW.status)105 EXECUTE FUNCTION notify_order_status();106```107108#### Access Control (RLS)109110RLS is disabled by default. To restrict channel access:111112- **Enable RLS**113114```sql115ALTER TABLE realtime.channels ENABLE ROW LEVEL SECURITY;116ALTER TABLE realtime.messages ENABLE ROW LEVEL SECURITY;117```118119- **Restrict Subscribe (SELECT on channels)**120121```sql122CREATE POLICY "users_subscribe_own_orders"123ON realtime.channels FOR SELECT124TO authenticated125USING (126 pattern = 'order:%'127 AND EXISTS (128 SELECT 1 FROM orders129 WHERE id = NULLIF(split_part(realtime.channel_name(), ':', 2), '')::uuid130 AND user_id = auth.uid()131 )132);133```134135- **Restrict Publish (INSERT on messages)**136137```sql138CREATE POLICY "members_publish_chat"139ON realtime.messages FOR INSERT140TO authenticated141WITH CHECK (142 channel_name LIKE 'chat:%'143 AND EXISTS (144 SELECT 1 FROM chat_members145 WHERE room_id = NULLIF(split_part(channel_name, ':', 2), '')::uuid146 AND user_id = auth.uid()147 )148);149```150151- **Quick Reference**152153| Task | SQL |154|------|-----|155| Create channel | `INSERT INTO realtime.channels (pattern, description, enabled) VALUES (...)` |156| Create trigger | `CREATE TRIGGER ... EXECUTE FUNCTION ...` |157| Publish from SQL | `PERFORM realtime.publish(channel, event, payload)` |158| Enable RLS | `ALTER TABLE realtime.channels ENABLE ROW LEVEL SECURITY` |159160161#### Best Practices1621631. **Create channel patterns first** before subscribing from frontend164 - Insert channel patterns into `realtime.channels` table165 - Ensure `enabled` is set to `true`1661672. **Use specific channel patterns**168 - Use wildcard `%` patterns for dynamic channels (e.g., `order:%` for `order:123`)169 - Use exact patterns for global channels (e.g., `notifications`)170171#### Common Mistakes172173| Mistake | Solution |174|---------|----------|175| Subscribing to undefined channel pattern | Create channel pattern in `realtime.channels` first |176| Channel not receiving messages | Ensure channel `enabled` is `true` |177| Publishing without trigger | Create database trigger to auto-publish on changes |178179#### Recommended Workflow180181```text1821. Create channel patterns → INSERT INTO realtime.channels1832. Ensure enabled = true → Set enabled to true1843. Create triggers if needed → Auto-publish on database changes1854. Proceed with SDK subscribe → Use channel name matching pattern186```187188### Backend Configuration (Not Yet in CLI)189190These modules still require HTTP API calls because the CLI does not yet support them:191192| Module | Backend Configuration |193|--------|----------------------|194| **Auth** | [auth/backend-configuration.md](auth/backend-configuration.md) |195| **AI** | [ai/backend-configuration.md](ai/backend-configuration.md) |196197## SDK Quick Reference198199All SDK methods return `{ data, error }`.200201| Module | Methods |202|--------|---------|203| `insforge.database` | `.from().select()`, `.insert()`, `.update()`, `.delete()`, `.rpc()` |204| `insforge.auth` | `.signUp()`, `.signInWithPassword()`, `.signInWithOAuth()`, `.signOut()`, `.getCurrentSession()` |205| `insforge.storage` | `.from().upload()`, `.uploadAuto()`, `.download()`, `.remove()` |206| `insforge.functions` | `.invoke()` |207| `insforge.ai` | `.chat.completions.create()`, `.images.generate()`, `.embeddings.create()` |208| `insforge.realtime` | `.connect()`, `.subscribe()`, `.publish()`, `.on()`, `.disconnect()` |209210## Important Notes211212- **Database inserts require array format**: `insert([{...}])` not `insert({...})`213- **Storage**: Save both `url` AND `key` to database for download/delete operations214- **Functions invoke URL**: `/functions/{slug}` (without `/api` prefix)215- **Use Tailwind CSS v3.4** (do not upgrade to v4)216- **Always local build before deploy**: Prevents wasted build resources and faster debugging