insforge 1.2.10 → 1.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. package/.claude-plugin/marketplace.json +20 -20
  2. package/.dockerignore +60 -60
  3. package/.env.example +83 -77
  4. package/.github/ISSUE_TEMPLATE/bug_report.yml +36 -36
  5. package/.github/ISSUE_TEMPLATE/config.yml +11 -11
  6. package/.github/ISSUE_TEMPLATE/feature_request.yml +26 -26
  7. package/.github/PULL_REQUEST_TEMPLATE.md +7 -7
  8. package/.github/copilot-instructions.md +146 -146
  9. package/.github/workflows/build-image.yml +65 -65
  10. package/.github/workflows/ci-premerge-check.yml +23 -23
  11. package/.github/workflows/e2e.yml +63 -63
  12. package/.github/workflows/lint-and-format.yml +32 -32
  13. package/.prettierignore +64 -64
  14. package/CHANGELOG.md +46 -44
  15. package/CLAUDE_PLUGIN.md +104 -104
  16. package/CODE_OF_CONDUCT.md +128 -128
  17. package/CONTRIBUTING.md +125 -125
  18. package/Dockerfile +30 -30
  19. package/GITHUB_OAUTH_SETUP.md +49 -49
  20. package/GOOGLE_OAUTH_SETUP.md +148 -148
  21. package/LICENSE +201 -201
  22. package/README.md +182 -182
  23. package/assets/Dark.svg +23 -23
  24. package/auth/package.json +30 -28
  25. package/auth/src/lib/broadcastService.ts +4 -4
  26. package/auth/src/lib/insforge.ts +8 -0
  27. package/auth/src/main.tsx +2 -4
  28. package/auth/src/pages/SignInPage.tsx +5 -2
  29. package/auth/src/pages/SignUpPage.tsx +5 -2
  30. package/auth/src/pages/VerifyEmailPage.tsx +18 -0
  31. package/auth/tsconfig.json +33 -32
  32. package/auth/tsconfig.node.json +11 -11
  33. package/backend/package.json +82 -75
  34. package/backend/src/api/middlewares/rate-limiters.ts +127 -127
  35. package/backend/src/api/routes/ai/index.routes.ts +475 -468
  36. package/backend/src/api/routes/auth/index.routes.ts +720 -570
  37. package/backend/src/api/routes/auth/oauth.routes.ts +478 -448
  38. package/backend/src/api/routes/database/advance.routes.ts +37 -16
  39. package/backend/src/api/routes/database/index.routes.ts +80 -1
  40. package/backend/src/api/routes/database/records.routes.ts +48 -184
  41. package/backend/src/api/routes/database/rpc.routes.ts +69 -0
  42. package/backend/src/api/routes/database/tables.routes.ts +0 -14
  43. package/backend/src/api/routes/deployments/index.routes.ts +192 -0
  44. package/backend/src/api/routes/docs/index.routes.ts +76 -76
  45. package/backend/src/api/routes/email/index.routes.ts +35 -0
  46. package/backend/src/api/routes/functions/index.routes.ts +21 -15
  47. package/backend/src/api/routes/metadata/index.routes.ts +38 -0
  48. package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
  49. package/backend/src/api/routes/realtime/index.routes.ts +12 -0
  50. package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
  51. package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
  52. package/backend/src/api/routes/storage/index.routes.ts +18 -12
  53. package/backend/src/api/routes/usage/index.routes.ts +6 -4
  54. package/backend/src/api/routes/webhooks/index.routes.ts +109 -0
  55. package/backend/src/infra/database/database.manager.ts +14 -11
  56. package/backend/src/infra/database/migrations/000_create-base-tables.sql +141 -141
  57. package/backend/src/infra/database/migrations/001_create-helper-functions.sql +40 -40
  58. package/backend/src/infra/database/migrations/002_rename-auth-tables.sql +29 -29
  59. package/backend/src/infra/database/migrations/003_create-users-table.sql +55 -55
  60. package/backend/src/infra/database/migrations/004_add-reload-postgrest-func.sql +23 -23
  61. package/backend/src/infra/database/migrations/005_enable-project-admin-modify-users.sql +29 -29
  62. package/backend/src/infra/database/migrations/006_modify-ai-usage-table.sql +24 -24
  63. package/backend/src/infra/database/migrations/007_drop-metadata-table.sql +1 -1
  64. package/backend/src/infra/database/migrations/008_add-system-tables.sql +76 -76
  65. package/backend/src/infra/database/migrations/009_add-function-secrets.sql +23 -23
  66. package/backend/src/infra/database/migrations/010_modify-ai-config-modalities.sql +93 -93
  67. package/backend/src/infra/database/migrations/011_refactor-secrets-table.sql +15 -15
  68. package/backend/src/infra/database/migrations/012_add-storage-uploaded-by.sql +7 -7
  69. package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -44
  70. package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +7 -7
  71. package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +59 -59
  72. package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -24
  73. package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
  74. package/backend/src/infra/database/migrations/018_schema-rework.sql +441 -0
  75. package/backend/src/infra/database/migrations/019_create-deployments-table.sql +36 -0
  76. package/backend/src/infra/database/migrations/020_add-audio-modality.sql +11 -0
  77. package/backend/src/infra/database/migrations/bootstrap/bootstrap-migrations.js +103 -0
  78. package/backend/src/infra/realtime/realtime.manager.ts +246 -0
  79. package/backend/src/infra/realtime/webhook-sender.ts +82 -0
  80. package/backend/src/infra/security/token.manager.ts +216 -125
  81. package/backend/src/infra/socket/socket.manager.ts +198 -64
  82. package/backend/src/providers/ai/openrouter.provider.ts +24 -12
  83. package/backend/src/providers/database/base.provider.ts +39 -0
  84. package/backend/src/providers/database/cloud.provider.ts +159 -0
  85. package/backend/src/providers/deployments/vercel.provider.ts +516 -0
  86. package/backend/src/providers/email/base.provider.ts +4 -7
  87. package/backend/src/providers/email/cloud.provider.ts +84 -0
  88. package/backend/src/providers/oauth/apple.provider.ts +266 -0
  89. package/backend/src/providers/oauth/index.ts +1 -0
  90. package/backend/src/server.ts +329 -284
  91. package/backend/src/services/ai/ai-config.service.ts +6 -6
  92. package/backend/src/services/ai/ai-model.service.ts +60 -60
  93. package/backend/src/services/ai/ai-usage.service.ts +7 -7
  94. package/backend/src/services/ai/chat-completion.service.ts +415 -220
  95. package/backend/src/services/ai/helpers.ts +64 -64
  96. package/backend/src/services/ai/image-generation.service.ts +3 -3
  97. package/backend/src/services/ai/index.ts +13 -13
  98. package/backend/src/services/auth/auth-config.service.ts +4 -4
  99. package/backend/src/services/auth/auth-otp.service.ts +6 -6
  100. package/backend/src/services/auth/auth.service.ts +148 -74
  101. package/backend/src/services/auth/index.ts +4 -4
  102. package/backend/src/services/auth/oauth-config.service.ts +12 -12
  103. package/backend/src/services/database/database-advance.service.ts +19 -55
  104. package/backend/src/services/database/database-table.service.ts +38 -94
  105. package/backend/src/services/database/database.service.ts +127 -0
  106. package/backend/src/services/database/postgrest-proxy.service.ts +165 -0
  107. package/backend/src/services/deployments/deployment.service.ts +693 -0
  108. package/backend/src/services/email/email.service.ts +5 -7
  109. package/backend/src/services/functions/function.service.ts +61 -41
  110. package/backend/src/services/logs/audit.service.ts +10 -10
  111. package/backend/src/services/realtime/index.ts +3 -0
  112. package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
  113. package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
  114. package/backend/src/services/realtime/realtime-message.service.ts +260 -0
  115. package/backend/src/services/secrets/secret.service.ts +101 -27
  116. package/backend/src/services/storage/storage.service.ts +30 -30
  117. package/backend/src/services/usage/usage.service.ts +6 -6
  118. package/backend/src/types/ai.ts +8 -0
  119. package/backend/src/types/auth.ts +16 -1
  120. package/backend/src/types/database.ts +2 -0
  121. package/backend/src/types/deployments.ts +33 -0
  122. package/backend/src/types/realtime.ts +18 -0
  123. package/backend/src/types/socket.ts +7 -31
  124. package/backend/src/types/storage.ts +1 -1
  125. package/backend/src/types/webhooks.ts +45 -0
  126. package/backend/src/utils/cookies.ts +34 -0
  127. package/backend/src/utils/environment.ts +0 -14
  128. package/backend/src/utils/s3-config-loader.ts +64 -0
  129. package/backend/src/utils/seed.ts +79 -43
  130. package/backend/src/utils/sql-parser.ts +216 -0
  131. package/backend/src/utils/utils.ts +114 -114
  132. package/backend/src/utils/validations.ts +10 -10
  133. package/backend/tests/README.md +133 -133
  134. package/backend/tests/cleanup-all-test-data.sh +230 -230
  135. package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
  136. package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
  137. package/backend/tests/local/test-ai-config.sh +129 -129
  138. package/backend/tests/local/test-ai-usage.sh +80 -80
  139. package/backend/tests/local/test-auth-router.sh +143 -143
  140. package/backend/tests/local/test-database-router.sh +222 -222
  141. package/backend/tests/local/test-e2e.sh +240 -240
  142. package/backend/tests/local/test-fk-errors.sh +96 -96
  143. package/backend/tests/local/test-functions.sh +123 -123
  144. package/backend/tests/local/test-id-field.sh +200 -200
  145. package/backend/tests/local/test-logs.sh +132 -132
  146. package/backend/tests/local/test-public-bucket.sh +264 -264
  147. package/backend/tests/local/test-rpc.sh +141 -0
  148. package/backend/tests/local/test-secrets.sh +249 -249
  149. package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
  150. package/backend/tests/local/test-traditional-rest.sh +208 -208
  151. package/backend/tests/manual/README.md +50 -50
  152. package/backend/tests/manual/create-large-table-simple.sql +10 -10
  153. package/backend/tests/manual/seed-large-table.sql +100 -100
  154. package/backend/tests/manual/setup-large-table-extras.sql +33 -33
  155. package/backend/tests/manual/test-ai-model-plugins.sh +258 -0
  156. package/backend/tests/manual/test-bulk-upsert.sh +409 -409
  157. package/backend/tests/manual/test-database-advance.sh +296 -296
  158. package/backend/tests/manual/test-postgrest-stability.sh +191 -191
  159. package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
  160. package/backend/tests/manual/test-rawsql-modes.sh +244 -244
  161. package/backend/tests/manual/test-universal-storage.sh +263 -263
  162. package/backend/tests/manual/test-users.sql +17 -17
  163. package/backend/tests/run-all-tests.sh +139 -139
  164. package/backend/tests/setup.ts +0 -0
  165. package/backend/tests/test-config.sh +338 -338
  166. package/backend/tests/unit/analyze-query.test.ts +697 -0
  167. package/backend/tests/unit/database-advance.test.ts +326 -0
  168. package/backend/tests/unit/helpers.test.ts +2 -2
  169. package/backend/tsconfig.json +22 -22
  170. package/claude-plugin/.claude-plugin/plugin.json +24 -24
  171. package/claude-plugin/README.md +133 -133
  172. package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +273 -270
  173. package/docker-compose.prod.yml +204 -200
  174. package/docker-compose.yml +232 -228
  175. package/docker-init/db/db-init.sql +97 -97
  176. package/docker-init/db/jwt.sql +5 -5
  177. package/docker-init/db/postgresql.conf +16 -16
  178. package/docker-init/logs/vector.yml +236 -236
  179. package/docs/README.md +44 -44
  180. package/docs/agent-docs/deployment.md +79 -0
  181. package/docs/agent-docs/real-time.md +269 -0
  182. package/docs/changelog.mdx +212 -67
  183. package/docs/core-concepts/ai/architecture.mdx +350 -372
  184. package/docs/core-concepts/ai/sdk.mdx +238 -213
  185. package/docs/core-concepts/authentication/architecture.mdx +276 -278
  186. package/docs/core-concepts/authentication/sdk.mdx +710 -414
  187. package/docs/core-concepts/authentication/ui-components/customization.mdx +733 -529
  188. package/docs/core-concepts/authentication/ui-components/nextjs.mdx +247 -221
  189. package/docs/core-concepts/authentication/ui-components/react-router.mdx +183 -184
  190. package/docs/core-concepts/authentication/ui-components/react.mdx +136 -129
  191. package/docs/core-concepts/database/architecture.mdx +292 -255
  192. package/docs/core-concepts/database/pgvector.mdx +138 -0
  193. package/docs/core-concepts/database/sdk.mdx +382 -382
  194. package/docs/core-concepts/deployments/architecture.mdx +152 -0
  195. package/docs/core-concepts/email/architecture.mdx +103 -0
  196. package/docs/core-concepts/email/sdk.mdx +53 -0
  197. package/docs/core-concepts/functions/architecture.mdx +105 -105
  198. package/docs/core-concepts/functions/sdk.mdx +183 -184
  199. package/docs/core-concepts/realtime/architecture.mdx +446 -0
  200. package/docs/core-concepts/realtime/sdk.mdx +409 -0
  201. package/docs/core-concepts/storage/architecture.mdx +243 -243
  202. package/docs/core-concepts/storage/sdk.mdx +253 -253
  203. package/docs/deployment/README.md +94 -94
  204. package/docs/deployment/deploy-to-aws-ec2.md +564 -564
  205. package/docs/deployment/deploy-to-azure-virtual-machines.md +312 -312
  206. package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -613
  207. package/docs/deployment/deploy-to-render.md +441 -441
  208. package/docs/deprecated/insforge-auth-api.md +214 -214
  209. package/docs/deprecated/insforge-auth-sdk.md +99 -99
  210. package/docs/deprecated/insforge-db-api.md +358 -358
  211. package/docs/deprecated/insforge-db-sdk.md +139 -139
  212. package/docs/deprecated/insforge-debug-sdk.md +156 -156
  213. package/docs/deprecated/insforge-debug.md +64 -64
  214. package/docs/deprecated/insforge-instructions.md +123 -123
  215. package/docs/deprecated/insforge-project.md +117 -117
  216. package/docs/deprecated/insforge-storage-api.md +278 -278
  217. package/docs/deprecated/insforge-storage-sdk.md +158 -158
  218. package/docs/docs.json +240 -210
  219. package/docs/examples/framework-guides/nextjs.mdx +131 -131
  220. package/docs/examples/framework-guides/nuxt.mdx +165 -165
  221. package/docs/examples/framework-guides/react.mdx +165 -165
  222. package/docs/examples/framework-guides/svelte.mdx +153 -153
  223. package/docs/examples/framework-guides/vue.mdx +159 -159
  224. package/docs/examples/overview.mdx +67 -67
  225. package/docs/favicon.png +0 -0
  226. package/docs/favicon.svg +4 -19
  227. package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
  228. package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
  229. package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
  230. package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
  231. package/docs/images/changelog/dec-2025/apple-oauth.mp4 +0 -0
  232. package/docs/images/changelog/dec-2025/mcp-installer.png +0 -0
  233. package/docs/images/changelog/dec-2025/moreModels.png +0 -0
  234. package/docs/images/changelog/dec-2025/multi-region.webp +0 -0
  235. package/docs/images/changelog/dec-2025/postgres-connection.webp +0 -0
  236. package/docs/images/changelog/dec-2025/realtime-module.jpg +0 -0
  237. package/docs/images/changelog/dec-2025/realtime2.png +0 -0
  238. package/docs/images/icons/ai.svg +4 -4
  239. package/docs/images/logos/nextjs.svg +4 -4
  240. package/docs/images/logos/nuxt.svg +4 -4
  241. package/docs/images/logos/react.svg +5 -5
  242. package/docs/images/logos/svelte.svg +4 -4
  243. package/docs/images/logos/vue.svg +5 -5
  244. package/docs/images/mcp-setup/CC-MCP-1.mp4 +0 -0
  245. package/docs/images/mcp-setup/CC-MCP-2.mp4 +0 -0
  246. package/docs/images/mcp-setup/Cursor-MCP-1.mp4 +0 -0
  247. package/docs/images/mcp-setup/Cursor-MCP-2.mp4 +0 -0
  248. package/docs/images/mcp-setup/Cursor-MCP-3.mp4 +0 -0
  249. package/docs/images/mcp-setup/claude-code-connect.png +0 -0
  250. package/docs/images/mcp-setup/cline-1.png +0 -0
  251. package/docs/images/mcp-setup/cline-2.png +0 -0
  252. package/docs/images/mcp-setup/cline-3.png +0 -0
  253. package/docs/images/mcp-setup/connect-project.png +0 -0
  254. package/docs/images/mcp-setup/copilot-1.png +0 -0
  255. package/docs/images/mcp-setup/copilot-2.png +0 -0
  256. package/docs/images/mcp-setup/copilot-3.png +0 -0
  257. package/docs/images/mcp-setup/mcp-json-1.png +0 -0
  258. package/docs/images/mcp-setup/mcp-json-2.png +0 -0
  259. package/docs/images/mcp-setup/qoder-1.png +0 -0
  260. package/docs/images/mcp-setup/qoder-2.png +0 -0
  261. package/docs/images/mcp-setup/roocode-1.png +0 -0
  262. package/docs/images/mcp-setup/roocode-2.png +0 -0
  263. package/docs/images/mcp-setup/trae-1.png +0 -0
  264. package/docs/images/mcp-setup/trae-2.png +0 -0
  265. package/docs/images/mcp-setup/trae-3.png +0 -0
  266. package/docs/images/mcp-setup/trae-4.png +0 -0
  267. package/docs/images/mcp-setup/trae-5.png +0 -0
  268. package/docs/images/mcp-setup/windsurf-1.png +0 -0
  269. package/docs/images/mcp-setup/windsurf-2.png +0 -0
  270. package/docs/insforge-instructions-sdk.md +93 -88
  271. package/docs/introduction.mdx +46 -45
  272. package/docs/logo/dark.svg +22 -22
  273. package/docs/logo/light.svg +20 -20
  274. package/docs/mcp-setup.mdx +332 -0
  275. package/docs/oauth-server.mdx +563 -0
  276. package/docs/partnership.mdx +720 -646
  277. package/docs/quickstart.mdx +82 -82
  278. package/docs/showcase.mdx +52 -52
  279. package/docs/snippets/sdk-installation.mdx +21 -21
  280. package/docs/snippets/service-icons.mdx +27 -27
  281. package/docs/vscode-extension.mdx +74 -0
  282. package/eslint.config.js +1 -0
  283. package/examples/oauth/frontend-oauth-example.html +250 -250
  284. package/examples/response-examples.md +443 -443
  285. package/frontend/components.json +17 -17
  286. package/frontend/package.json +69 -69
  287. package/frontend/src/App.tsx +8 -3
  288. package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
  289. package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
  290. package/frontend/src/assets/icons/checked.svg +3 -3
  291. package/frontend/src/assets/icons/connected.svg +3 -3
  292. package/frontend/src/assets/icons/error.svg +3 -3
  293. package/frontend/src/assets/icons/loader.svg +9 -9
  294. package/frontend/src/assets/icons/pencil.svg +4 -4
  295. package/frontend/src/assets/icons/refresh.svg +4 -4
  296. package/frontend/src/assets/icons/step_active.svg +3 -3
  297. package/frontend/src/assets/icons/step_inactive.svg +11 -11
  298. package/frontend/src/assets/icons/warning.svg +3 -3
  299. package/frontend/src/assets/logos/antigravity.svg +1 -0
  300. package/frontend/src/assets/logos/apple.svg +3 -3
  301. package/frontend/src/assets/logos/claude_code.svg +3 -3
  302. package/frontend/src/assets/logos/cline.svg +6 -6
  303. package/frontend/src/assets/logos/copilot.svg +10 -0
  304. package/frontend/src/assets/logos/cursor.svg +20 -20
  305. package/frontend/src/assets/logos/deepseek.svg +139 -0
  306. package/frontend/src/assets/logos/discord.svg +8 -8
  307. package/frontend/src/assets/logos/facebook.svg +3 -3
  308. package/frontend/src/assets/logos/gemini.svg +19 -19
  309. package/frontend/src/assets/logos/github.svg +5 -5
  310. package/frontend/src/assets/logos/google.svg +13 -13
  311. package/frontend/src/assets/logos/grok.svg +10 -10
  312. package/frontend/src/assets/logos/insforge_dark.svg +15 -15
  313. package/frontend/src/assets/logos/insforge_light.svg +15 -15
  314. package/frontend/src/assets/logos/instagram.svg +1 -1
  315. package/frontend/src/assets/logos/kiro.svg +9 -0
  316. package/frontend/src/assets/logos/linkedin.svg +3 -3
  317. package/frontend/src/assets/logos/openai.svg +10 -10
  318. package/frontend/src/assets/logos/qoder.svg +4 -0
  319. package/frontend/src/assets/logos/qwen.svg +15 -0
  320. package/frontend/src/assets/logos/roo_code.svg +9 -9
  321. package/frontend/src/assets/logos/spotify.svg +16 -16
  322. package/frontend/src/assets/logos/tiktok.svg +5 -5
  323. package/frontend/src/assets/logos/trae.svg +3 -3
  324. package/frontend/src/assets/logos/windsurf.svg +10 -10
  325. package/frontend/src/assets/logos/x.svg +3 -3
  326. package/frontend/src/components/CodeBlock.tsx +2 -2
  327. package/frontend/src/components/ConnectCTA.tsx +3 -2
  328. package/frontend/src/components/datagrid/DataGrid.tsx +90 -62
  329. package/frontend/src/components/datagrid/datagridTypes.tsx +2 -1
  330. package/frontend/src/components/datagrid/index.ts +1 -1
  331. package/frontend/src/components/index.ts +0 -1
  332. package/frontend/src/components/layout/AppHeader.tsx +13 -37
  333. package/frontend/src/components/layout/AppSidebar.tsx +85 -100
  334. package/frontend/src/components/layout/Layout.tsx +34 -32
  335. package/frontend/src/components/layout/PrimaryMenu.tsx +12 -4
  336. package/frontend/src/components/radix/Select.tsx +151 -151
  337. package/frontend/src/features/ai/components/AIConfigCard.tsx +200 -200
  338. package/frontend/src/features/ai/components/AIEmptyState.tsx +23 -23
  339. package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +102 -101
  340. package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -135
  341. package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -51
  342. package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -118
  343. package/frontend/src/features/ai/components/index.ts +6 -6
  344. package/frontend/src/features/ai/helpers.ts +147 -141
  345. package/frontend/src/features/ai/{page → pages}/AIPage.tsx +166 -166
  346. package/frontend/src/features/auth/components/AuthPreview.tsx +96 -96
  347. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +1 -0
  348. package/frontend/src/features/auth/components/UsersDataGrid.tsx +61 -31
  349. package/frontend/src/features/auth/components/index.ts +5 -5
  350. package/frontend/src/features/auth/helpers.tsx +8 -0
  351. package/frontend/src/features/auth/{page → pages}/AuthMethodsPage.tsx +275 -275
  352. package/frontend/src/features/auth/{page → pages}/UsersPage.tsx +0 -28
  353. package/frontend/src/features/dashboard/{page → pages}/DashboardPage.tsx +1 -1
  354. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +0 -2
  355. package/frontend/src/features/database/components/ForeignKeyCell.tsx +38 -11
  356. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +18 -8
  357. package/frontend/src/features/database/components/LinkRecordModal.tsx +61 -13
  358. package/frontend/src/features/database/components/RecordFormField.tsx +1 -1
  359. package/frontend/src/features/database/components/SQLModal.tsx +75 -0
  360. package/frontend/src/features/database/components/TableForm.tsx +0 -4
  361. package/frontend/src/features/database/components/TableSidebar.tsx +0 -3
  362. package/frontend/src/features/database/components/TablesEmptyState.tsx +1 -1
  363. package/frontend/src/features/database/components/TemplatePreview.tsx +1 -2
  364. package/frontend/src/features/database/constants.ts +16 -28
  365. package/frontend/src/features/database/hooks/useCSVImport.ts +3 -2
  366. package/frontend/src/features/database/hooks/useDatabase.ts +66 -0
  367. package/frontend/src/features/database/hooks/useRawSQL.ts +3 -2
  368. package/frontend/src/features/database/hooks/useTables.ts +30 -28
  369. package/frontend/src/features/database/index.ts +1 -0
  370. package/frontend/src/features/database/{page → pages}/FunctionsPage.tsx +29 -42
  371. package/frontend/src/features/database/{page → pages}/IndexesPage.tsx +34 -51
  372. package/frontend/src/features/database/{page → pages}/PoliciesPage.tsx +42 -58
  373. package/frontend/src/features/database/{page → pages}/SQLEditorPage.tsx +2 -2
  374. package/frontend/src/features/database/{page → pages}/TablesPage.tsx +0 -42
  375. package/frontend/src/features/database/{page → pages}/TriggersPage.tsx +34 -51
  376. package/frontend/src/features/database/services/advance.service.ts +1 -41
  377. package/frontend/src/features/database/services/database.service.ts +55 -0
  378. package/frontend/src/features/database/services/record.service.ts +4 -20
  379. package/frontend/src/features/database/services/table.service.ts +1 -10
  380. package/frontend/src/features/database/templates/ai-chatbot.ts +6 -6
  381. package/frontend/src/features/database/templates/ecommerce-platform.ts +2 -2
  382. package/frontend/src/features/database/templates/instagram-clone.ts +10 -10
  383. package/frontend/src/features/database/templates/notion-clone.ts +8 -8
  384. package/frontend/src/features/database/templates/reddit-clone.ts +10 -10
  385. package/frontend/src/features/deployments/components/DeploymentRow.tsx +93 -0
  386. package/frontend/src/features/deployments/components/DeploymentsEmptyState.tsx +15 -0
  387. package/frontend/src/features/deployments/hooks/useDeployments.ts +157 -0
  388. package/frontend/src/features/deployments/pages/DeploymentsPage.tsx +318 -0
  389. package/frontend/src/features/deployments/services/deployments.service.ts +63 -0
  390. package/frontend/src/features/functions/components/FunctionRow.tsx +72 -72
  391. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +56 -56
  392. package/frontend/src/features/functions/components/SecretRow.tsx +3 -3
  393. package/frontend/src/features/functions/components/index.ts +5 -5
  394. package/frontend/src/features/functions/hooks/useFunctions.ts +5 -4
  395. package/frontend/src/features/functions/hooks/useSecrets.ts +6 -9
  396. package/frontend/src/features/functions/{page → pages}/FunctionsPage.tsx +21 -44
  397. package/frontend/src/features/functions/{page → pages}/SecretsPage.tsx +118 -116
  398. package/frontend/src/features/functions/services/function.service.ts +8 -25
  399. package/frontend/src/features/functions/services/secret.service.ts +23 -41
  400. package/frontend/src/features/login/{page → pages}/CloudLoginPage.tsx +125 -118
  401. package/frontend/src/features/logs/components/LogDetailPanel.tsx +41 -0
  402. package/frontend/src/features/logs/components/LogsDataGrid.tsx +32 -1
  403. package/frontend/src/features/logs/components/index.ts +1 -0
  404. package/frontend/src/features/logs/hooks/useMcpUsage.ts +13 -66
  405. package/frontend/src/features/logs/{page → pages}/LogsPage.tsx +36 -6
  406. package/frontend/src/features/onboard/components/ApiCredentialsSection.tsx +59 -0
  407. package/frontend/src/features/onboard/components/ConnectionStringSection.tsx +180 -0
  408. package/frontend/src/features/onboard/components/McpConnectionSection.tsx +159 -0
  409. package/frontend/src/features/onboard/components/OnboardingController.tsx +68 -0
  410. package/frontend/src/features/onboard/components/OnboardingModal.tsx +121 -267
  411. package/frontend/src/features/onboard/components/ShowPasswordButton.tsx +21 -0
  412. package/frontend/src/features/onboard/components/index.ts +9 -4
  413. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +1 -1
  414. package/frontend/src/features/onboard/components/mcp/QoderDeeplinkGenerator.tsx +36 -0
  415. package/frontend/src/features/onboard/components/mcp/helpers.tsx +123 -98
  416. package/frontend/src/features/onboard/components/mcp/index.ts +4 -3
  417. package/frontend/src/features/onboard/index.ts +17 -13
  418. package/frontend/src/features/realtime/components/ChannelRow.tsx +83 -0
  419. package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
  420. package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
  421. package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
  422. package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
  423. package/frontend/src/features/realtime/index.ts +11 -0
  424. package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
  425. package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
  426. package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
  427. package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
  428. package/frontend/src/features/settings/pages/SettingsPage.tsx +349 -0
  429. package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +1 -29
  430. package/frontend/src/features/visualizer/components/AuthNode.tsx +4 -4
  431. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +24 -11
  432. package/frontend/src/features/visualizer/{page → pages}/VisualizerPage.tsx +11 -36
  433. package/frontend/src/index.css +249 -249
  434. package/frontend/src/lib/contexts/ModalContext.tsx +35 -0
  435. package/frontend/src/lib/contexts/SocketContext.tsx +119 -75
  436. package/frontend/src/lib/hooks/useMetadata.ts +45 -1
  437. package/frontend/src/lib/hooks/useModal.tsx +2 -0
  438. package/frontend/src/lib/routing/AppRoutes.tsx +103 -84
  439. package/frontend/src/lib/services/metadata.service.ts +20 -3
  440. package/frontend/src/lib/utils/cloudMessaging.ts +1 -1
  441. package/frontend/src/lib/utils/menuItems.ts +223 -183
  442. package/frontend/src/lib/utils/utils.ts +196 -183
  443. package/frontend/tsconfig.json +25 -25
  444. package/frontend/tsconfig.node.json +9 -9
  445. package/functions/deno.json +24 -24
  446. package/functions/server.ts +6 -6
  447. package/functions/worker-template.js +1 -1
  448. package/i18n/README.ar.md +130 -130
  449. package/i18n/README.de.md +130 -130
  450. package/i18n/README.es.md +154 -154
  451. package/i18n/README.fr.md +134 -134
  452. package/i18n/README.hi.md +129 -129
  453. package/i18n/README.ja.md +174 -174
  454. package/i18n/README.ko.md +136 -136
  455. package/i18n/README.pt-BR.md +131 -131
  456. package/i18n/README.ru.md +129 -129
  457. package/i18n/README.zh-CN.md +133 -133
  458. package/openapi/ai.yaml +825 -715
  459. package/openapi/auth.yaml +1324 -1244
  460. package/openapi/email.yaml +158 -0
  461. package/openapi/functions.yaml +475 -475
  462. package/openapi/health.yaml +29 -29
  463. package/openapi/logs.yaml +221 -223
  464. package/openapi/metadata.yaml +175 -177
  465. package/openapi/realtime.yaml +699 -0
  466. package/openapi/records.yaml +381 -381
  467. package/openapi/secrets.yaml +370 -370
  468. package/openapi/storage.yaml +875 -875
  469. package/openapi/tables.yaml +462 -463
  470. package/package.json +97 -97
  471. package/shared-schemas/package.json +31 -31
  472. package/shared-schemas/src/ai-api.schema.ts +251 -143
  473. package/shared-schemas/src/ai.schema.ts +8 -4
  474. package/shared-schemas/src/auth-api.schema.ts +380 -339
  475. package/shared-schemas/src/auth.schema.ts +18 -11
  476. package/shared-schemas/src/cloud-events.schema.ts +26 -0
  477. package/shared-schemas/src/database-api.schema.ts +32 -1
  478. package/shared-schemas/src/database.schema.ts +39 -0
  479. package/shared-schemas/src/deployments-api.schema.ts +55 -0
  480. package/shared-schemas/src/deployments.schema.ts +30 -0
  481. package/shared-schemas/src/docs.schema.ts +32 -0
  482. package/shared-schemas/src/email-api.schema.ts +30 -0
  483. package/shared-schemas/src/functions-api.schema.ts +13 -4
  484. package/shared-schemas/src/functions.schema.ts +1 -1
  485. package/shared-schemas/src/index.ts +22 -14
  486. package/shared-schemas/src/metadata.schema.ts +39 -4
  487. package/shared-schemas/src/realtime-api.schema.ts +111 -0
  488. package/shared-schemas/src/realtime.schema.ts +143 -0
  489. package/shared-schemas/src/secrets-api.schema.ts +44 -0
  490. package/shared-schemas/src/secrets.schema.ts +15 -0
  491. package/shared-schemas/tsconfig.json +21 -21
  492. package/tsconfig.json +7 -7
  493. package/zeabur/README.md +26 -13
  494. package/zeabur/template.yml +1001 -1032
  495. package/.cursor/rules/cursor-rules.mdc +0 -94
  496. package/backend/src/types/profile.ts +0 -55
  497. package/frontend/src/components/ProjectInfoModal.tsx +0 -128
  498. package/frontend/src/features/database/hooks/useFullMetadata.ts +0 -18
  499. package/test-gemini.sh +0 -35
  500. package/test-usage-admin.sh +0 -57
  501. package/test-usage.sh +0 -50
  502. /package/frontend/src/features/auth/{page → pages}/ConfigurationPage.tsx +0 -0
  503. /package/frontend/src/features/database/{page → pages}/TemplatesPage.tsx +0 -0
  504. /package/frontend/src/features/login/{page → pages}/LoginPage.tsx +0 -0
  505. /package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +0 -0
  506. /package/frontend/src/features/logs/{page → pages}/MCPLogsPage.tsx +0 -0
@@ -1,270 +1,273 @@
1
- ---
2
- name: insforge-schema-patterns
3
- description: Database schema patterns for InsForge including social graphs, e-commerce, content publishing, and multi-tenancy with RLS policies. Use when designing data models with relationships, foreign keys, or Row Level Security.
4
- ---
5
-
6
- # InsForge Schema Patterns
7
-
8
- Expert patterns for designing PostgreSQL schemas optimized for InsForge's PostgREST backend.
9
-
10
- ## Pattern 1: Social Graph (Follows)
11
-
12
- **Use when:** Building social features like Twitter, Instagram, LinkedIn connections
13
-
14
- **Schema:**
15
- ```sql
16
- CREATE TABLE follows (
17
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
18
- follower_id UUID REFERENCES users(id) ON DELETE CASCADE,
19
- following_id UUID REFERENCES users(id) ON DELETE CASCADE,
20
- created_at TIMESTAMPTZ DEFAULT NOW(),
21
- UNIQUE(follower_id, following_id)
22
- );
23
-
24
- -- Index for fast lookups
25
- CREATE INDEX idx_follows_follower ON follows(follower_id);
26
- CREATE INDEX idx_follows_following ON follows(following_id);
27
-
28
- -- RLS: Users can read all follows but only create their own
29
- ALTER TABLE follows ENABLE ROW LEVEL SECURITY;
30
-
31
- CREATE POLICY "Anyone can read follows" ON follows
32
- FOR SELECT USING (true);
33
-
34
- CREATE POLICY "Users can follow others" ON follows
35
- FOR INSERT
36
- TO authenticated
37
- WITH CHECK (uid() = follower_id);
38
-
39
- CREATE POLICY "Users can unfollow" ON follows
40
- FOR DELETE
41
- TO authenticated
42
- USING (uid() = follower_id);
43
- ```
44
-
45
- **Query with InsForge SDK:**
46
- ```javascript
47
- // Get users I follow with their profiles
48
- const { data: following } = await client.database
49
- .from('follows')
50
- .select('*, following:following_id(id, nickname, avatar_url, bio)')
51
- .eq('follower_id', currentUserId);
52
-
53
- // Get my followers
54
- const { data: followers } = await client.database
55
- .from('follows')
56
- .select('*, follower:follower_id(id, nickname, avatar_url, bio)')
57
- .eq('following_id', currentUserId);
58
-
59
- // Check if user1 follows user2
60
- const { data: isFollowing } = await client.database
61
- .from('follows')
62
- .select()
63
- .eq('follower_id', user1Id)
64
- .eq('following_id', user2Id)
65
- .single();
66
-
67
- // Follow a user
68
- await client.database
69
- .from('follows')
70
- .insert([{ follower_id: currentUserId, following_id: targetUserId }]);
71
- ```
72
-
73
- ---
74
-
75
- ## Pattern 2: Likes (Many-to-Many Junction Table)
76
-
77
- **Use when:** Users can like posts, comments, or other content
78
-
79
- **Schema:**
80
- ```sql
81
- CREATE TABLE likes (
82
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
83
- user_id UUID REFERENCES users(id) ON DELETE CASCADE,
84
- post_id UUID REFERENCES posts(id) ON DELETE CASCADE,
85
- created_at TIMESTAMPTZ DEFAULT NOW(),
86
- UNIQUE(user_id, post_id) -- Prevent duplicate likes
87
- );
88
-
89
- CREATE INDEX idx_likes_post ON likes(post_id);
90
- CREATE INDEX idx_likes_user ON likes(user_id);
91
-
92
- ALTER TABLE likes ENABLE ROW LEVEL SECURITY;
93
-
94
- CREATE POLICY "Anyone can read likes" ON likes
95
- FOR SELECT USING (true);
96
-
97
- CREATE POLICY "Users can like posts" ON likes
98
- FOR INSERT
99
- TO authenticated
100
- WITH CHECK (uid() = user_id);
101
-
102
- CREATE POLICY "Users can unlike their likes" ON likes
103
- FOR DELETE
104
- TO authenticated
105
- USING (uid() = user_id);
106
- ```
107
-
108
- **Query with InsForge SDK:**
109
- ```javascript
110
- // Get post with like count and whether current user liked it
111
- const { data: post } = await client.database
112
- .from('posts')
113
- .select(`
114
- *,
115
- likes(count),
116
- user_like:likes!inner(id, user_id)
117
- `)
118
- .eq('id', postId)
119
- .eq('user_like.user_id', currentUserId)
120
- .single();
121
-
122
- // Like a post
123
- await client.database
124
- .from('likes')
125
- .insert([{ user_id: currentUserId, post_id: postId }]);
126
-
127
- // Unlike a post
128
- await client.database
129
- .from('likes')
130
- .delete()
131
- .eq('user_id', currentUserId)
132
- .eq('post_id', postId);
133
- ```
134
-
135
- ---
136
-
137
- ## Pattern 3: Nested Comments (Self-Referential)
138
-
139
- **Use when:** Building comment threads, nested replies
140
-
141
- **Schema:**
142
- ```sql
143
- CREATE TABLE comments (
144
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
145
- post_id UUID REFERENCES posts(id) ON DELETE CASCADE,
146
- user_id UUID REFERENCES users(id) ON DELETE CASCADE,
147
- parent_comment_id UUID REFERENCES comments(id) ON DELETE CASCADE,
148
- content TEXT NOT NULL,
149
- created_at TIMESTAMPTZ DEFAULT NOW(),
150
- updated_at TIMESTAMPTZ DEFAULT NOW()
151
- );
152
-
153
- CREATE INDEX idx_comments_post ON comments(post_id);
154
- CREATE INDEX idx_comments_parent ON comments(parent_comment_id);
155
-
156
- ALTER TABLE comments ENABLE ROW LEVEL SECURITY;
157
-
158
- CREATE POLICY "Anyone can read comments" ON comments
159
- FOR SELECT USING (true);
160
-
161
- CREATE POLICY "Authenticated users can comment" ON comments
162
- FOR INSERT
163
- TO authenticated
164
- WITH CHECK (uid() = user_id);
165
-
166
- CREATE POLICY "Users can edit their comments" ON comments
167
- FOR UPDATE
168
- TO authenticated
169
- USING (uid() = user_id)
170
- WITH CHECK (uid() = user_id);
171
-
172
- CREATE POLICY "Users can delete their comments" ON comments
173
- FOR DELETE
174
- TO authenticated
175
- USING (uid() = user_id);
176
- ```
177
-
178
- **Query with InsForge SDK:**
179
- ```javascript
180
- // Get top-level comments with author info
181
- const { data: comments } = await client.database
182
- .from('comments')
183
- .select('*, author:user_id(nickname, avatar_url)')
184
- .eq('post_id', postId)
185
- .is('parent_comment_id', null)
186
- .order('created_at', { ascending: false });
187
-
188
- // Get replies to a comment
189
- const { data: replies } = await client.database
190
- .from('comments')
191
- .select('*, author:user_id(nickname, avatar_url)')
192
- .eq('parent_comment_id', commentId)
193
- .order('created_at', { ascending: true });
194
- ```
195
-
196
- ---
197
-
198
- ## Pattern 4: Multi-Tenant (Organization Scoped)
199
-
200
- **Use when:** Building SaaS apps where data is scoped to organizations/workspaces
201
-
202
- **Schema:**
203
- ```sql
204
- CREATE TABLE organizations (
205
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
206
- name TEXT NOT NULL,
207
- created_at TIMESTAMPTZ DEFAULT NOW()
208
- );
209
-
210
- CREATE TABLE organization_members (
211
- organization_id UUID REFERENCES organizations(id) ON DELETE CASCADE,
212
- user_id UUID REFERENCES users(id) ON DELETE CASCADE,
213
- role TEXT NOT NULL CHECK (role IN ('owner', 'admin', 'member')),
214
- joined_at TIMESTAMPTZ DEFAULT NOW(),
215
- PRIMARY KEY (organization_id, user_id)
216
- );
217
-
218
- CREATE TABLE projects (
219
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
220
- organization_id UUID REFERENCES organizations(id) ON DELETE CASCADE,
221
- name TEXT NOT NULL,
222
- created_at TIMESTAMPTZ DEFAULT NOW()
223
- );
224
-
225
- -- RLS: Users can only see projects in their organizations
226
- ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
227
-
228
- CREATE POLICY "Users see org projects" ON projects
229
- FOR SELECT
230
- TO authenticated
231
- USING (
232
- organization_id IN (
233
- SELECT organization_id
234
- FROM organization_members
235
- WHERE user_id = uid()
236
- )
237
- );
238
-
239
- CREATE POLICY "Admins can create projects" ON projects
240
- FOR INSERT
241
- TO authenticated
242
- WITH CHECK (
243
- organization_id IN (
244
- SELECT organization_id
245
- FROM organization_members
246
- WHERE user_id = uid()
247
- AND role IN ('owner', 'admin')
248
- )
249
- );
250
- ```
251
-
252
- ---
253
-
254
- ## Best Practices
255
-
256
- 1. **Always add indexes** on foreign key columns for performance
257
- 2. **Use UNIQUE constraints** on junction tables to prevent duplicates
258
- 3. **Enable RLS** on all user-facing tables
259
- 4. **Use ON DELETE CASCADE** for automatic cleanup
260
- 5. **Foreign key expansion** in SDK uses the syntax: `table:column(fields)`
261
- 6. **Count aggregations** use: `table(count)`
262
- 7. **Filter nested tables** with: `nested_table!inner()` for inner join behavior
263
-
264
- ## Common Mistakes to Avoid
265
-
266
- - ❌ Forgetting indexes on foreign keys → Slow queries
267
- - Not using UNIQUE on junction tables → Duplicate likes/follows
268
- - ❌ Missing RLS policies → Data leaks
269
- - ❌ Using `.single()` on queries that might return multiple rows → Errors
270
- - ❌ Not wrapping INSERT data in arraysPostgREST error
1
+ ---
2
+ name: insforge-schema-patterns
3
+ description: Database schema patterns for InsForge including social graphs, e-commerce, content publishing, and multi-tenancy with RLS policies. Use when designing data models with relationships, foreign keys, or Row Level Security.
4
+ ---
5
+
6
+ # InsForge Schema Patterns
7
+
8
+ Expert patterns for designing PostgreSQL schemas optimized for InsForge's PostgREST backend.
9
+
10
+ ## Pattern 1: Social Graph (Follows)
11
+
12
+ **Use when:** Building social features like Twitter, Instagram, LinkedIn connections
13
+
14
+ **Schema:**
15
+ ```sql
16
+ CREATE TABLE follows (
17
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
18
+ follower_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
19
+ following_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
20
+ created_at TIMESTAMPTZ DEFAULT NOW(),
21
+ UNIQUE(follower_id, following_id)
22
+ );
23
+
24
+ -- Index for fast lookups
25
+ CREATE INDEX idx_follows_follower ON follows(follower_id);
26
+ CREATE INDEX idx_follows_following ON follows(following_id);
27
+
28
+ -- RLS: Users can read all follows but only create their own
29
+ ALTER TABLE follows ENABLE ROW LEVEL SECURITY;
30
+
31
+ CREATE POLICY "Anyone can read follows" ON follows
32
+ FOR SELECT USING (true);
33
+
34
+ CREATE POLICY "Users can follow others" ON follows
35
+ FOR INSERT
36
+ TO authenticated
37
+ WITH CHECK (uid() = follower_id);
38
+
39
+ CREATE POLICY "Users can unfollow" ON follows
40
+ FOR DELETE
41
+ TO authenticated
42
+ USING (uid() = follower_id);
43
+ ```
44
+
45
+ **Query with InsForge SDK:**
46
+ ```javascript
47
+ // Get users I follow
48
+ const { data: following } = await client.database
49
+ .from('follows')
50
+ .select()
51
+ .eq('follower_id', currentUserId);
52
+
53
+ // Get my followers
54
+ const { data: followers } = await client.database
55
+ .from('follows')
56
+ .select()
57
+ .eq('following_id', currentUserId);
58
+
59
+ // Check if user1 follows user2
60
+ const { data: isFollowing } = await client.database
61
+ .from('follows')
62
+ .select()
63
+ .eq('follower_id', user1Id)
64
+ .eq('following_id', user2Id)
65
+ .single();
66
+
67
+ // Follow a user
68
+ await client.database
69
+ .from('follows')
70
+ .insert([{ follower_id: currentUserId, following_id: targetUserId }]);
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Pattern 2: Likes (Many-to-Many Junction Table)
76
+
77
+ **Use when:** Users can like posts, comments, or other content
78
+
79
+ **Schema:**
80
+ ```sql
81
+ CREATE TABLE likes (
82
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
83
+ user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
84
+ post_id UUID REFERENCES posts(id) ON DELETE CASCADE,
85
+ created_at TIMESTAMPTZ DEFAULT NOW(),
86
+ UNIQUE(user_id, post_id) -- Prevent duplicate likes
87
+ );
88
+
89
+ CREATE INDEX idx_likes_post ON likes(post_id);
90
+ CREATE INDEX idx_likes_user ON likes(user_id);
91
+
92
+ ALTER TABLE likes ENABLE ROW LEVEL SECURITY;
93
+
94
+ CREATE POLICY "Anyone can read likes" ON likes
95
+ FOR SELECT USING (true);
96
+
97
+ CREATE POLICY "Users can like posts" ON likes
98
+ FOR INSERT
99
+ TO authenticated
100
+ WITH CHECK (uid() = user_id);
101
+
102
+ CREATE POLICY "Users can unlike their likes" ON likes
103
+ FOR DELETE
104
+ TO authenticated
105
+ USING (uid() = user_id);
106
+ ```
107
+
108
+ **Query with InsForge SDK:**
109
+ ```javascript
110
+ // Get post with like count and whether current user liked it
111
+ const { data: post } = await client.database
112
+ .from('posts')
113
+ .select(`
114
+ *,
115
+ likes(count),
116
+ user_like:likes!inner(id, user_id)
117
+ `)
118
+ .eq('id', postId)
119
+ .eq('user_like.user_id', currentUserId)
120
+ .single();
121
+
122
+ // Like a post
123
+ await client.database
124
+ .from('likes')
125
+ .insert([{ user_id: currentUserId, post_id: postId }]);
126
+
127
+ // Unlike a post
128
+ await client.database
129
+ .from('likes')
130
+ .delete()
131
+ .eq('user_id', currentUserId)
132
+ .eq('post_id', postId);
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Pattern 3: Nested Comments (Self-Referential)
138
+
139
+ **Use when:** Building comment threads, nested replies
140
+
141
+ **Schema:**
142
+ ```sql
143
+ CREATE TABLE comments (
144
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
145
+ post_id UUID REFERENCES posts(id) ON DELETE CASCADE,
146
+ user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
147
+ parent_comment_id UUID REFERENCES comments(id) ON DELETE CASCADE,
148
+ content TEXT NOT NULL,
149
+ created_at TIMESTAMPTZ DEFAULT NOW(),
150
+ updated_at TIMESTAMPTZ DEFAULT NOW()
151
+ );
152
+
153
+ CREATE INDEX idx_comments_post ON comments(post_id);
154
+ CREATE INDEX idx_comments_parent ON comments(parent_comment_id);
155
+
156
+ ALTER TABLE comments ENABLE ROW LEVEL SECURITY;
157
+
158
+ CREATE POLICY "Anyone can read comments" ON comments
159
+ FOR SELECT USING (true);
160
+
161
+ CREATE POLICY "Authenticated users can comment" ON comments
162
+ FOR INSERT
163
+ TO authenticated
164
+ WITH CHECK (uid() = user_id);
165
+
166
+ CREATE POLICY "Users can edit their comments" ON comments
167
+ FOR UPDATE
168
+ TO authenticated
169
+ USING (uid() = user_id)
170
+ WITH CHECK (uid() = user_id);
171
+
172
+ CREATE POLICY "Users can delete their comments" ON comments
173
+ FOR DELETE
174
+ TO authenticated
175
+ USING (uid() = user_id);
176
+ ```
177
+
178
+ **Query with InsForge SDK:**
179
+ ```javascript
180
+ // Get top-level comments with author info
181
+ // Note: profile is a JSONB column containing { name, avatar_url, bio, birthday }
182
+ const { data: comments } = await client.database
183
+ .from('comments')
184
+ .select('*, author:user_id(id, profile)')
185
+ .eq('post_id', postId)
186
+ .is('parent_comment_id', null)
187
+ .order('created_at', { ascending: false });
188
+
189
+ // Access author info: comment.author.profile.name, comment.author.profile.avatar_url
190
+
191
+ // Get replies to a comment
192
+ const { data: replies } = await client.database
193
+ .from('comments')
194
+ .select('*, author:user_id(id, profile)')
195
+ .eq('parent_comment_id', commentId)
196
+ .order('created_at', { ascending: true });
197
+ ```
198
+
199
+ ---
200
+
201
+ ## Pattern 4: Multi-Tenant (Organization Scoped)
202
+
203
+ **Use when:** Building SaaS apps where data is scoped to organizations/workspaces
204
+
205
+ **Schema:**
206
+ ```sql
207
+ CREATE TABLE organizations (
208
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
209
+ name TEXT NOT NULL,
210
+ created_at TIMESTAMPTZ DEFAULT NOW()
211
+ );
212
+
213
+ CREATE TABLE organization_members (
214
+ organization_id UUID REFERENCES organizations(id) ON DELETE CASCADE,
215
+ user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
216
+ role TEXT NOT NULL CHECK (role IN ('owner', 'admin', 'member')),
217
+ joined_at TIMESTAMPTZ DEFAULT NOW(),
218
+ PRIMARY KEY (organization_id, user_id)
219
+ );
220
+
221
+ CREATE TABLE projects (
222
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
223
+ organization_id UUID REFERENCES organizations(id) ON DELETE CASCADE,
224
+ name TEXT NOT NULL,
225
+ created_at TIMESTAMPTZ DEFAULT NOW()
226
+ );
227
+
228
+ -- RLS: Users can only see projects in their organizations
229
+ ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
230
+
231
+ CREATE POLICY "Users see org projects" ON projects
232
+ FOR SELECT
233
+ TO authenticated
234
+ USING (
235
+ organization_id IN (
236
+ SELECT organization_id
237
+ FROM organization_members
238
+ WHERE user_id = uid()
239
+ )
240
+ );
241
+
242
+ CREATE POLICY "Admins can create projects" ON projects
243
+ FOR INSERT
244
+ TO authenticated
245
+ WITH CHECK (
246
+ organization_id IN (
247
+ SELECT organization_id
248
+ FROM organization_members
249
+ WHERE user_id = uid()
250
+ AND role IN ('owner', 'admin')
251
+ )
252
+ );
253
+ ```
254
+
255
+ ---
256
+
257
+ ## Best Practices
258
+
259
+ 1. **Always add indexes** on foreign key columns for performance
260
+ 2. **Use UNIQUE constraints** on junction tables to prevent duplicates
261
+ 3. **Enable RLS** on all user-facing tables
262
+ 4. **Use ON DELETE CASCADE** for automatic cleanup
263
+ 5. **Foreign key expansion** in SDK uses the syntax: `table:column(fields)`
264
+ 6. **Count aggregations** use: `table(count)`
265
+ 7. **Filter nested tables** with: `nested_table!inner()` for inner join behavior
266
+
267
+ ## Common Mistakes to Avoid
268
+
269
+ - ❌ Forgetting indexes on foreign keys Slow queries
270
+ - ❌ Not using UNIQUE on junction tablesDuplicate likes/follows
271
+ - ❌ Missing RLS policies → Data leaks
272
+ - ❌ Using `.single()` on queries that might return multiple rows → Errors
273
+ - ❌ Not wrapping INSERT data in arrays → PostgREST error