@libredb/studio 0.9.7

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 (572) hide show
  1. package/.claude/settings.local.json +127 -0
  2. package/.cursorrules +426 -0
  3. package/.devin/wiki.json +143 -0
  4. package/.dockerignore +80 -0
  5. package/.env.example +159 -0
  6. package/.github/ISSUE_TEMPLATE/bug_report.md +49 -0
  7. package/.github/ISSUE_TEMPLATE/feature_request.md +29 -0
  8. package/.github/PULL_REQUEST_TEMPLATE.md +57 -0
  9. package/.github/workflows/ci.yml +185 -0
  10. package/.github/workflows/codeql.yml +57 -0
  11. package/.github/workflows/docker-build-push.yml +118 -0
  12. package/.github/workflows/helm-release.yml +113 -0
  13. package/CLAUDE.md +265 -0
  14. package/CODE_OF_CONDUCT.md +124 -0
  15. package/CONTRIBUTING.md +154 -0
  16. package/Dockerfile +73 -0
  17. package/LICENSE +21 -0
  18. package/README.md +614 -0
  19. package/SECURITY.md +107 -0
  20. package/artifacthub-repo.yml +4 -0
  21. package/bun.lock +1714 -0
  22. package/bunfig.toml +3 -0
  23. package/charts/libredb-studio/.helmignore +11 -0
  24. package/charts/libredb-studio/Chart.lock +6 -0
  25. package/charts/libredb-studio/Chart.yaml +50 -0
  26. package/charts/libredb-studio/README.md +206 -0
  27. package/charts/libredb-studio/templates/NOTES.txt +59 -0
  28. package/charts/libredb-studio/templates/_helpers.tpl +135 -0
  29. package/charts/libredb-studio/templates/configmap.yaml +37 -0
  30. package/charts/libredb-studio/templates/deployment.yaml +184 -0
  31. package/charts/libredb-studio/templates/hpa.yaml +32 -0
  32. package/charts/libredb-studio/templates/ingress.yaml +41 -0
  33. package/charts/libredb-studio/templates/networkpolicy.yaml +50 -0
  34. package/charts/libredb-studio/templates/pdb.yaml +18 -0
  35. package/charts/libredb-studio/templates/pvc.yaml +23 -0
  36. package/charts/libredb-studio/templates/secret.yaml +30 -0
  37. package/charts/libredb-studio/templates/seed-configmap.yaml +11 -0
  38. package/charts/libredb-studio/templates/service.yaml +22 -0
  39. package/charts/libredb-studio/templates/serviceaccount.yaml +13 -0
  40. package/charts/libredb-studio/values.schema.json +246 -0
  41. package/charts/libredb-studio/values.yaml +286 -0
  42. package/components.json +22 -0
  43. package/conductor/code_styleguides/typescript.md +43 -0
  44. package/conductor/product-guidelines.md +43 -0
  45. package/conductor/product.md +3 -0
  46. package/conductor/setup_state.json +1 -0
  47. package/conductor/tech-stack.md +39 -0
  48. package/conductor/tracks/enhance_postgres_monitoring_20251227/metadata.json +8 -0
  49. package/conductor/tracks/enhance_postgres_monitoring_20251227/plan.md +44 -0
  50. package/conductor/tracks/enhance_postgres_monitoring_20251227/spec.md +31 -0
  51. package/conductor/tracks.md +8 -0
  52. package/conductor/workflow.md +333 -0
  53. package/database-compose.yml +55 -0
  54. package/docker/postgres-init/01-extensions.sql +10 -0
  55. package/docker/postgres-init/02-sample-data.sql +585 -0
  56. package/docker/postgres.yml +68 -0
  57. package/docker-compose.yml +38 -0
  58. package/docs/AI_PLAN.md +74 -0
  59. package/docs/API_DOCS.md +875 -0
  60. package/docs/ARCHITECTURE.md +218 -0
  61. package/docs/DATABASE_PROVIDERS.md +358 -0
  62. package/docs/FEATURES.md +116 -0
  63. package/docs/HELM_CHART.md +252 -0
  64. package/docs/LOGIN_PAGE.md +178 -0
  65. package/docs/MONACO_EDITOR_PERFORMANCE.md +315 -0
  66. package/docs/OIDC_ARCH.md +681 -0
  67. package/docs/OIDC_SETUP.md +322 -0
  68. package/docs/POSTGRES_METRICS.md +516 -0
  69. package/docs/QUERY_OPTIMIZATION.md +370 -0
  70. package/docs/SEED_CONNECTIONS.md +468 -0
  71. package/docs/SQL_ALIAS_COMPLETION.md +190 -0
  72. package/docs/STORAGE_ARCHITECTURE.md +565 -0
  73. package/docs/STORAGE_QUICK_SETUP.md +419 -0
  74. package/docs/TECHNICAL_PLAN.md +36 -0
  75. package/docs/THEMING.md +345 -0
  76. package/docs/adding-a-new-database-provider.md +642 -0
  77. package/docs/backlogs/000-PLATFORM_DATA_SYNC_DATABASE.md +360 -0
  78. package/docs/backlogs/001-INLINE_DATA_EDITING.md +118 -0
  79. package/docs/backlogs/002-DATA_IMPORT.md +215 -0
  80. package/docs/backlogs/003-QUERY_TIME_MACHINE.md +183 -0
  81. package/docs/backlogs/004-AI_DATA_STORYTELLER.md +292 -0
  82. package/docs/backlogs/005-QUERY_PLAYGROUND.md +352 -0
  83. package/docs/backlogs/006-DATA_MASKING.md +418 -0
  84. package/docs/enterprise-features.md +718 -0
  85. package/docs/kubernetes-helm-chart-artifacthub-plan.md +803 -0
  86. package/docs/medium-koyeb-article-en.md +215 -0
  87. package/docs/plans/test-plans.md +445 -0
  88. package/docs/releases/RELEASE.V0.3.0.md +22 -0
  89. package/docs/releases/RELEASE.V0.4.0.md +154 -0
  90. package/docs/releases/RELEASE.V0.5.0.md +252 -0
  91. package/docs/releases/RELEASE_v0.5.6.md +145 -0
  92. package/docs/releases/RELEASE_v0.6.1.md +303 -0
  93. package/docs/releases/RELEASE_v0.6.7.md +292 -0
  94. package/docs/releases/RELEASE_v0.7.0.md +332 -0
  95. package/docs/releases/RELEASE_v0.8.0.md +521 -0
  96. package/docs/sampledb/titanic.sql +1379 -0
  97. package/docs/superpowers/plans/2026-03-25-seed-connections.md +1362 -0
  98. package/docs/superpowers/specs/2026-03-25-seed-connections-design.md +590 -0
  99. package/e2e/admin-dashboard.spec.ts +64 -0
  100. package/e2e/connection-management.spec.ts +58 -0
  101. package/e2e/export.spec.ts +34 -0
  102. package/e2e/login.spec.ts +85 -0
  103. package/e2e/query-execution.spec.ts +35 -0
  104. package/e2e/tab-management.spec.ts +64 -0
  105. package/eslint.config.mjs +28 -0
  106. package/fly.toml +43 -0
  107. package/next.config.ts +32 -0
  108. package/package.json +130 -0
  109. package/playwright.config.ts +34 -0
  110. package/postcss.config.mjs +7 -0
  111. package/public/favicon-32x32.png +0 -0
  112. package/public/favicon.ico +0 -0
  113. package/public/file.svg +1 -0
  114. package/public/globe.svg +1 -0
  115. package/public/logo.svg +32 -0
  116. package/public/next.svg +1 -0
  117. package/public/screenshots/code-generator.png +0 -0
  118. package/public/screenshots/connection-modal.png +0 -0
  119. package/public/screenshots/data-profiler.png +0 -0
  120. package/public/screenshots/erd-diagram.png +0 -0
  121. package/public/screenshots/hero-editor.png +0 -0
  122. package/public/screenshots/nl2sql.png +0 -0
  123. package/public/vercel.svg +1 -0
  124. package/public/window.svg +1 -0
  125. package/render.yaml +58 -0
  126. package/scripts/merge-lcov.mjs +239 -0
  127. package/sonar-project.properties +16 -0
  128. package/src/app/admin/error.tsx +46 -0
  129. package/src/app/admin/page.tsx +10 -0
  130. package/src/app/api/admin/audit/route.ts +52 -0
  131. package/src/app/api/admin/fleet-health/route.ts +81 -0
  132. package/src/app/api/ai/autopilot/route.ts +105 -0
  133. package/src/app/api/ai/chat/route.ts +132 -0
  134. package/src/app/api/ai/describe-schema/route.ts +52 -0
  135. package/src/app/api/ai/explain/route.ts +86 -0
  136. package/src/app/api/ai/impact/route.ts +97 -0
  137. package/src/app/api/ai/index-advisor/route.ts +98 -0
  138. package/src/app/api/ai/nl2sql/route.ts +87 -0
  139. package/src/app/api/ai/query-safety/route.ts +87 -0
  140. package/src/app/api/auth/login/route.ts +62 -0
  141. package/src/app/api/auth/logout/route.ts +25 -0
  142. package/src/app/api/auth/me/route.ts +10 -0
  143. package/src/app/api/auth/oidc/callback/route.ts +82 -0
  144. package/src/app/api/auth/oidc/login/route.ts +43 -0
  145. package/src/app/api/connections/managed/route.ts +35 -0
  146. package/src/app/api/db/cancel/route.ts +42 -0
  147. package/src/app/api/db/disconnect/route.ts +28 -0
  148. package/src/app/api/db/health/route.ts +49 -0
  149. package/src/app/api/db/maintenance/route.ts +72 -0
  150. package/src/app/api/db/monitoring/route.ts +62 -0
  151. package/src/app/api/db/multi-query/route.ts +116 -0
  152. package/src/app/api/db/pool-stats/route.ts +37 -0
  153. package/src/app/api/db/profile/route.ts +144 -0
  154. package/src/app/api/db/provider-meta/route.ts +49 -0
  155. package/src/app/api/db/query/route.ts +50 -0
  156. package/src/app/api/db/schema/route.ts +47 -0
  157. package/src/app/api/db/schema-snapshot/route.ts +42 -0
  158. package/src/app/api/db/test-connection/route.ts +55 -0
  159. package/src/app/api/db/transaction/route.ts +111 -0
  160. package/src/app/api/storage/[collection]/route.ts +67 -0
  161. package/src/app/api/storage/config/route.ts +17 -0
  162. package/src/app/api/storage/migrate/route.ts +45 -0
  163. package/src/app/api/storage/route.ts +32 -0
  164. package/src/app/error.tsx +49 -0
  165. package/src/app/global-error.tsx +55 -0
  166. package/src/app/globals.css +146 -0
  167. package/src/app/icon.svg +42 -0
  168. package/src/app/layout.tsx +34 -0
  169. package/src/app/login/login-form.tsx +301 -0
  170. package/src/app/login/page.tsx +11 -0
  171. package/src/app/monitoring/page.tsx +8 -0
  172. package/src/app/not-found.tsx +29 -0
  173. package/src/app/page.tsx +5 -0
  174. package/src/components/AIAutopilotPanel.tsx +238 -0
  175. package/src/components/CodeGenerator.tsx +271 -0
  176. package/src/components/CommandPalette.tsx +227 -0
  177. package/src/components/ConnectionModal.tsx +759 -0
  178. package/src/components/CreateTableModal.tsx +281 -0
  179. package/src/components/DataCharts.tsx +962 -0
  180. package/src/components/DataImportModal.tsx +582 -0
  181. package/src/components/DataProfiler.tsx +335 -0
  182. package/src/components/DatabaseDocs.tsx +251 -0
  183. package/src/components/MaskingSettings.tsx +414 -0
  184. package/src/components/MobileNav.tsx +50 -0
  185. package/src/components/NL2SQLPanel.tsx +281 -0
  186. package/src/components/PivotTable.tsx +257 -0
  187. package/src/components/QueryEditor.tsx +760 -0
  188. package/src/components/QueryHistory.tsx +344 -0
  189. package/src/components/QuerySafetyDialog.tsx +290 -0
  190. package/src/components/ResultsGrid.tsx +644 -0
  191. package/src/components/SaveQueryModal.tsx +104 -0
  192. package/src/components/SavedQueries.tsx +128 -0
  193. package/src/components/SchemaDiagram.tsx +473 -0
  194. package/src/components/SchemaDiff.tsx +473 -0
  195. package/src/components/SnapshotTimeline.tsx +116 -0
  196. package/src/components/Studio.tsx +639 -0
  197. package/src/components/TestDataGenerator.tsx +261 -0
  198. package/src/components/VisualExplain.tsx +820 -0
  199. package/src/components/admin/AdminDashboard.tsx +163 -0
  200. package/src/components/admin/tabs/AuditTab.tsx +531 -0
  201. package/src/components/admin/tabs/MonitoringEmbed.tsx +11 -0
  202. package/src/components/admin/tabs/OperationsTab.tsx +646 -0
  203. package/src/components/admin/tabs/OverviewTab.tsx +1328 -0
  204. package/src/components/admin/tabs/SecurityTab.tsx +284 -0
  205. package/src/components/community-section.tsx +92 -0
  206. package/src/components/icons/db-icons.tsx +84 -0
  207. package/src/components/libredb-logo.tsx +61 -0
  208. package/src/components/monitoring/MonitoringDashboard.tsx +345 -0
  209. package/src/components/monitoring/tabs/MetricChart.tsx +82 -0
  210. package/src/components/monitoring/tabs/OverviewTab.tsx +263 -0
  211. package/src/components/monitoring/tabs/PerformanceTab.tsx +254 -0
  212. package/src/components/monitoring/tabs/PoolTab.tsx +174 -0
  213. package/src/components/monitoring/tabs/QueriesTab.tsx +287 -0
  214. package/src/components/monitoring/tabs/SessionsTab.tsx +316 -0
  215. package/src/components/monitoring/tabs/StorageTab.tsx +335 -0
  216. package/src/components/monitoring/tabs/TablesTab.tsx +300 -0
  217. package/src/components/results-grid/ResultCard.tsx +111 -0
  218. package/src/components/results-grid/RowDetailSheet.tsx +178 -0
  219. package/src/components/results-grid/StatsBar.tsx +201 -0
  220. package/src/components/results-grid/index.ts +1 -0
  221. package/src/components/results-grid/utils.ts +23 -0
  222. package/src/components/schema-explorer/ColumnList.tsx +53 -0
  223. package/src/components/schema-explorer/SchemaExplorer.tsx +182 -0
  224. package/src/components/schema-explorer/TableItem.tsx +210 -0
  225. package/src/components/schema-explorer/index.ts +1 -0
  226. package/src/components/sidebar/ConnectionItem.tsx +105 -0
  227. package/src/components/sidebar/ConnectionsList.tsx +62 -0
  228. package/src/components/sidebar/Sidebar.tsx +130 -0
  229. package/src/components/sidebar/index.ts +2 -0
  230. package/src/components/studio/BottomPanel.tsx +286 -0
  231. package/src/components/studio/QueryToolbar.tsx +180 -0
  232. package/src/components/studio/StudioDesktopHeader.tsx +114 -0
  233. package/src/components/studio/StudioMobileHeader.tsx +340 -0
  234. package/src/components/studio/StudioTabBar.tsx +82 -0
  235. package/src/components/studio/index.ts +5 -0
  236. package/src/components/ui/accordion.tsx +66 -0
  237. package/src/components/ui/alert-dialog.tsx +157 -0
  238. package/src/components/ui/alert.tsx +66 -0
  239. package/src/components/ui/aspect-ratio.tsx +11 -0
  240. package/src/components/ui/avatar.tsx +53 -0
  241. package/src/components/ui/badge.tsx +46 -0
  242. package/src/components/ui/breadcrumb.tsx +109 -0
  243. package/src/components/ui/button-group.tsx +83 -0
  244. package/src/components/ui/button.tsx +60 -0
  245. package/src/components/ui/calendar.tsx +216 -0
  246. package/src/components/ui/card.tsx +92 -0
  247. package/src/components/ui/carousel.tsx +241 -0
  248. package/src/components/ui/chart.tsx +357 -0
  249. package/src/components/ui/checkbox.tsx +32 -0
  250. package/src/components/ui/collapsible.tsx +33 -0
  251. package/src/components/ui/command.tsx +184 -0
  252. package/src/components/ui/context-menu.tsx +252 -0
  253. package/src/components/ui/dialog.tsx +143 -0
  254. package/src/components/ui/drawer.tsx +135 -0
  255. package/src/components/ui/dropdown-menu.tsx +257 -0
  256. package/src/components/ui/empty.tsx +104 -0
  257. package/src/components/ui/field.tsx +248 -0
  258. package/src/components/ui/form.tsx +167 -0
  259. package/src/components/ui/hover-card.tsx +44 -0
  260. package/src/components/ui/input-group.tsx +170 -0
  261. package/src/components/ui/input-otp.tsx +77 -0
  262. package/src/components/ui/input.tsx +21 -0
  263. package/src/components/ui/item.tsx +193 -0
  264. package/src/components/ui/kbd.tsx +28 -0
  265. package/src/components/ui/label.tsx +24 -0
  266. package/src/components/ui/menubar.tsx +276 -0
  267. package/src/components/ui/navigation-menu.tsx +168 -0
  268. package/src/components/ui/pagination.tsx +127 -0
  269. package/src/components/ui/popover.tsx +48 -0
  270. package/src/components/ui/progress.tsx +31 -0
  271. package/src/components/ui/radio-group.tsx +45 -0
  272. package/src/components/ui/resizable.tsx +56 -0
  273. package/src/components/ui/scroll-area.tsx +58 -0
  274. package/src/components/ui/select.tsx +187 -0
  275. package/src/components/ui/separator.tsx +28 -0
  276. package/src/components/ui/sheet.tsx +139 -0
  277. package/src/components/ui/sidebar.tsx +726 -0
  278. package/src/components/ui/skeleton.tsx +13 -0
  279. package/src/components/ui/slider.tsx +63 -0
  280. package/src/components/ui/sonner.tsx +40 -0
  281. package/src/components/ui/spinner.tsx +16 -0
  282. package/src/components/ui/switch.tsx +31 -0
  283. package/src/components/ui/table.tsx +116 -0
  284. package/src/components/ui/tabs.tsx +66 -0
  285. package/src/components/ui/textarea.tsx +18 -0
  286. package/src/components/ui/toggle-group.tsx +83 -0
  287. package/src/components/ui/toggle.tsx +47 -0
  288. package/src/components/ui/tooltip.tsx +61 -0
  289. package/src/exports/components.ts +15 -0
  290. package/src/exports/index.ts +4 -0
  291. package/src/exports/providers.ts +4 -0
  292. package/src/exports/types.ts +26 -0
  293. package/src/hooks/use-ai-chat.ts +182 -0
  294. package/src/hooks/use-all-connections.ts +66 -0
  295. package/src/hooks/use-api-call.ts +71 -0
  296. package/src/hooks/use-auth.ts +51 -0
  297. package/src/hooks/use-connection-form.ts +349 -0
  298. package/src/hooks/use-connection-manager.ts +169 -0
  299. package/src/hooks/use-connection-payload.ts +15 -0
  300. package/src/hooks/use-inline-editing.ts +109 -0
  301. package/src/hooks/use-mobile.ts +20 -0
  302. package/src/hooks/use-monitoring-data.ts +270 -0
  303. package/src/hooks/use-provider-metadata.ts +62 -0
  304. package/src/hooks/use-query-execution.ts +478 -0
  305. package/src/hooks/use-storage-sync.ts +259 -0
  306. package/src/hooks/use-tab-manager.ts +231 -0
  307. package/src/hooks/use-toast.ts +20 -0
  308. package/src/hooks/use-transaction-control.ts +64 -0
  309. package/src/lib/api/error-codes.ts +30 -0
  310. package/src/lib/api/errors.ts +236 -0
  311. package/src/lib/api/with-error-handler.ts +41 -0
  312. package/src/lib/audit.ts +105 -0
  313. package/src/lib/auth.ts +87 -0
  314. package/src/lib/connection-string-parser.ts +172 -0
  315. package/src/lib/data-masking.ts +385 -0
  316. package/src/lib/db/base-provider.ts +325 -0
  317. package/src/lib/db/errors.ts +317 -0
  318. package/src/lib/db/factory.ts +324 -0
  319. package/src/lib/db/index.ts +123 -0
  320. package/src/lib/db/providers/document/index.ts +6 -0
  321. package/src/lib/db/providers/document/mongodb.ts +992 -0
  322. package/src/lib/db/providers/keyvalue/redis.ts +554 -0
  323. package/src/lib/db/providers/sql/index.ts +11 -0
  324. package/src/lib/db/providers/sql/mssql.ts +1065 -0
  325. package/src/lib/db/providers/sql/mysql.ts +978 -0
  326. package/src/lib/db/providers/sql/oracle.ts +1044 -0
  327. package/src/lib/db/providers/sql/postgres.ts +1179 -0
  328. package/src/lib/db/providers/sql/sql-base.ts +174 -0
  329. package/src/lib/db/providers/sql/sqlite.ts +721 -0
  330. package/src/lib/db/types.ts +437 -0
  331. package/src/lib/db/utils/pool-manager.ts +287 -0
  332. package/src/lib/db/utils/query-limiter.ts +239 -0
  333. package/src/lib/db-ui-config.ts +86 -0
  334. package/src/lib/editor/mongodb-completions.ts +172 -0
  335. package/src/lib/editor/sql-completions.ts +280 -0
  336. package/src/lib/llm/base-provider.ts +117 -0
  337. package/src/lib/llm/factory.ts +102 -0
  338. package/src/lib/llm/index.ts +90 -0
  339. package/src/lib/llm/providers/custom.ts +181 -0
  340. package/src/lib/llm/providers/gemini.ts +126 -0
  341. package/src/lib/llm/providers/ollama.ts +154 -0
  342. package/src/lib/llm/providers/openai.ts +146 -0
  343. package/src/lib/llm/types.ts +173 -0
  344. package/src/lib/llm/utils/config.ts +187 -0
  345. package/src/lib/llm/utils/retry.ts +119 -0
  346. package/src/lib/llm/utils/streaming.ts +202 -0
  347. package/src/lib/logger.ts +127 -0
  348. package/src/lib/monitoring-thresholds.ts +44 -0
  349. package/src/lib/oidc.ts +262 -0
  350. package/src/lib/query-generators.ts +61 -0
  351. package/src/lib/schema-diff/diff-engine.ts +273 -0
  352. package/src/lib/schema-diff/migration-generator.ts +208 -0
  353. package/src/lib/schema-diff/types.ts +55 -0
  354. package/src/lib/seed/config-loader.ts +79 -0
  355. package/src/lib/seed/connection-filter.ts +49 -0
  356. package/src/lib/seed/credential-resolver.ts +62 -0
  357. package/src/lib/seed/index.ts +40 -0
  358. package/src/lib/seed/resolve-connection.ts +57 -0
  359. package/src/lib/seed/types.ts +69 -0
  360. package/src/lib/sql/alias-extractor.ts +267 -0
  361. package/src/lib/sql/index.ts +8 -0
  362. package/src/lib/sql/statement-splitter.ts +167 -0
  363. package/src/lib/sql/types.ts +40 -0
  364. package/src/lib/ssh/tunnel.ts +142 -0
  365. package/src/lib/storage/factory.ts +84 -0
  366. package/src/lib/storage/index.ts +14 -0
  367. package/src/lib/storage/local-storage.ts +99 -0
  368. package/src/lib/storage/providers/postgres.ts +225 -0
  369. package/src/lib/storage/providers/sqlite.ts +153 -0
  370. package/src/lib/storage/storage-facade.ts +272 -0
  371. package/src/lib/storage/types.ts +75 -0
  372. package/src/lib/time-series-buffer.ts +58 -0
  373. package/src/lib/types.ts +173 -0
  374. package/src/lib/utils.ts +6 -0
  375. package/src/proxy.ts +104 -0
  376. package/src/types/db-drivers.d.ts +23 -0
  377. package/src/types/html2canvas.d.ts +9 -0
  378. package/tests/api/admin/audit.test.ts +178 -0
  379. package/tests/api/admin/fleet-health.test.ts +183 -0
  380. package/tests/api/ai/autopilot.test.ts +174 -0
  381. package/tests/api/ai/chat.test.ts +250 -0
  382. package/tests/api/ai/describe-schema.test.ts +266 -0
  383. package/tests/api/ai/explain.test.ts +199 -0
  384. package/tests/api/ai/impact.test.ts +168 -0
  385. package/tests/api/ai/index-advisor.test.ts +171 -0
  386. package/tests/api/ai/nl2sql.test.ts +202 -0
  387. package/tests/api/ai/query-safety.test.ts +196 -0
  388. package/tests/api/auth/login.test.ts +170 -0
  389. package/tests/api/auth/logout.test.ts +140 -0
  390. package/tests/api/auth/me.test.ts +73 -0
  391. package/tests/api/auth/oidc-callback.test.ts +215 -0
  392. package/tests/api/auth/oidc-login.test.ts +127 -0
  393. package/tests/api/db/cancel.test.ts +198 -0
  394. package/tests/api/db/disconnect.test.ts +124 -0
  395. package/tests/api/db/health.test.ts +222 -0
  396. package/tests/api/db/maintenance.test.ts +263 -0
  397. package/tests/api/db/monitoring.test.ts +221 -0
  398. package/tests/api/db/multi-query.test.ts +316 -0
  399. package/tests/api/db/pool-stats.test.ts +135 -0
  400. package/tests/api/db/profile.test.ts +330 -0
  401. package/tests/api/db/provider-meta.test.ts +193 -0
  402. package/tests/api/db/query.test.ts +314 -0
  403. package/tests/api/db/schema-snapshot.test.ts +170 -0
  404. package/tests/api/db/schema.test.ts +191 -0
  405. package/tests/api/db/test-connection.test.ts +185 -0
  406. package/tests/api/db/transaction.test.ts +314 -0
  407. package/tests/api/proxy.test.ts +191 -0
  408. package/tests/api/seed/managed-route.test.ts +113 -0
  409. package/tests/api/storage/config.test.ts +42 -0
  410. package/tests/api/storage/storage-routes.test.ts +309 -0
  411. package/tests/components/AIAutopilotPanel.test.tsx +756 -0
  412. package/tests/components/AdminPage.test.tsx +33 -0
  413. package/tests/components/CodeGenerator.test.tsx +182 -0
  414. package/tests/components/CommandPalette.test.tsx +428 -0
  415. package/tests/components/CommunitySection.test.tsx +91 -0
  416. package/tests/components/ConnectionModal.mobile.test.tsx +284 -0
  417. package/tests/components/ConnectionModal.test.tsx +570 -0
  418. package/tests/components/CreateTableModal.test.tsx +383 -0
  419. package/tests/components/DataCharts.test.tsx +739 -0
  420. package/tests/components/DataImportModal.test.tsx +751 -0
  421. package/tests/components/DataProfiler.test.tsx +589 -0
  422. package/tests/components/DatabaseDocs.test.tsx +353 -0
  423. package/tests/components/LoginPage.test.tsx +163 -0
  424. package/tests/components/LoginPageOIDC.test.tsx +92 -0
  425. package/tests/components/MaskingSettings.test.tsx +498 -0
  426. package/tests/components/MobileNav.test.tsx +30 -0
  427. package/tests/components/MonitoringPage.test.tsx +32 -0
  428. package/tests/components/NL2SQLPanel.test.tsx +621 -0
  429. package/tests/components/Page.test.tsx +33 -0
  430. package/tests/components/PivotTable.test.tsx +350 -0
  431. package/tests/components/QueryEditor.test.tsx +1730 -0
  432. package/tests/components/QueryHistory.test.tsx +572 -0
  433. package/tests/components/QuerySafetyDialog.test.tsx +586 -0
  434. package/tests/components/ResultsGrid.test.tsx +804 -0
  435. package/tests/components/RootLayout.test.tsx +83 -0
  436. package/tests/components/SaveQueryModal.test.tsx +25 -0
  437. package/tests/components/SavedQueries.test.tsx +43 -0
  438. package/tests/components/SchemaDiagram.test.tsx +1034 -0
  439. package/tests/components/SchemaDiff.test.tsx +906 -0
  440. package/tests/components/SnapshotTimeline.test.tsx +174 -0
  441. package/tests/components/Studio.test.tsx +1030 -0
  442. package/tests/components/TestDataGenerator.test.tsx +291 -0
  443. package/tests/components/VisualExplain.test.tsx +704 -0
  444. package/tests/components/admin/AdminDashboard.test.tsx +205 -0
  445. package/tests/components/admin/AuditTab.test.tsx +220 -0
  446. package/tests/components/admin/MonitoringEmbed.test.tsx +58 -0
  447. package/tests/components/admin/OperationsTab.test.tsx +975 -0
  448. package/tests/components/admin/OverviewTab.test.tsx +254 -0
  449. package/tests/components/admin/SecurityTab.test.tsx +467 -0
  450. package/tests/components/monitoring/MetricChart.test.tsx +111 -0
  451. package/tests/components/monitoring/MonitoringDashboard.test.tsx +259 -0
  452. package/tests/components/monitoring/OverviewTab.test.tsx +78 -0
  453. package/tests/components/monitoring/PerformanceTab.test.tsx +87 -0
  454. package/tests/components/monitoring/PoolTab.test.tsx +42 -0
  455. package/tests/components/monitoring/QueriesTab.test.tsx +80 -0
  456. package/tests/components/monitoring/SessionsTab.test.tsx +154 -0
  457. package/tests/components/monitoring/StorageTab.test.tsx +127 -0
  458. package/tests/components/monitoring/TablesTab.test.tsx +153 -0
  459. package/tests/components/results-grid/ResultCard.test.tsx +105 -0
  460. package/tests/components/results-grid/RowDetailSheet.test.tsx +308 -0
  461. package/tests/components/results-grid/StatsBar.test.tsx +162 -0
  462. package/tests/components/schema-explorer/ColumnList.test.tsx +151 -0
  463. package/tests/components/schema-explorer/SchemaExplorer.test.tsx +461 -0
  464. package/tests/components/schema-explorer/TableItem.test.tsx +415 -0
  465. package/tests/components/sidebar/ConnectionItem.test.tsx +201 -0
  466. package/tests/components/sidebar/ConnectionsList.test.tsx +176 -0
  467. package/tests/components/sidebar/Sidebar.test.tsx +187 -0
  468. package/tests/components/studio/BottomPanel.test.tsx +383 -0
  469. package/tests/components/studio/QueryToolbar.test.tsx +321 -0
  470. package/tests/components/studio/StudioDesktopHeader.test.tsx +377 -0
  471. package/tests/components/studio/StudioMobileHeader.test.tsx +198 -0
  472. package/tests/components/studio/StudioTabBar.test.tsx +331 -0
  473. package/tests/fixtures/connections.ts +96 -0
  474. package/tests/fixtures/masking-configs.ts +86 -0
  475. package/tests/fixtures/query-results.ts +71 -0
  476. package/tests/fixtures/schemas.ts +64 -0
  477. package/tests/fixtures/seed-connections/invalid-config.yaml +7 -0
  478. package/tests/fixtures/seed-connections/minimal-config.yaml +8 -0
  479. package/tests/fixtures/seed-connections/mixed-credentials.yaml +23 -0
  480. package/tests/fixtures/seed-connections/multi-role-config.yaml +30 -0
  481. package/tests/fixtures/seed-connections/valid-config.json +15 -0
  482. package/tests/fixtures/seed-connections/valid-config.yaml +51 -0
  483. package/tests/helpers/mock-fetch.ts +59 -0
  484. package/tests/helpers/mock-monaco.ts +112 -0
  485. package/tests/helpers/mock-navigation.ts +28 -0
  486. package/tests/helpers/mock-next.ts +80 -0
  487. package/tests/helpers/mock-provider.ts +133 -0
  488. package/tests/helpers/mock-sonner.ts +29 -0
  489. package/tests/helpers/render-with-providers.tsx +19 -0
  490. package/tests/hooks/use-ai-chat.test.ts +600 -0
  491. package/tests/hooks/use-auth.test.ts +371 -0
  492. package/tests/hooks/use-connection-form.test.ts +743 -0
  493. package/tests/hooks/use-connection-manager.test.ts +466 -0
  494. package/tests/hooks/use-inline-editing.test.ts +321 -0
  495. package/tests/hooks/use-mobile.test.ts +177 -0
  496. package/tests/hooks/use-monitoring-data.test.ts +819 -0
  497. package/tests/hooks/use-provider-metadata.test.ts +228 -0
  498. package/tests/hooks/use-query-execution.test.ts +1212 -0
  499. package/tests/hooks/use-tab-manager.test.ts +756 -0
  500. package/tests/hooks/use-toast.test.ts +74 -0
  501. package/tests/hooks/use-transaction-control.test.ts +211 -0
  502. package/tests/integration/db/mongodb-provider.test.ts +698 -0
  503. package/tests/integration/db/mssql-provider.test.ts +840 -0
  504. package/tests/integration/db/mysql-provider.test.ts +872 -0
  505. package/tests/integration/db/oracle-provider.test.ts +843 -0
  506. package/tests/integration/db/postgres-provider.test.ts +1382 -0
  507. package/tests/integration/db/redis-provider.test.ts +526 -0
  508. package/tests/integration/db/sqlite-provider.test.ts +480 -0
  509. package/tests/integration/seed/seed-pipeline.test.ts +102 -0
  510. package/tests/isolated/factory-singleton.test.ts +150 -0
  511. package/tests/isolated/use-storage-sync.test.ts +389 -0
  512. package/tests/run-components.sh +196 -0
  513. package/tests/setup-dom.ts +58 -0
  514. package/tests/setup.ts +40 -0
  515. package/tests/unit/api-errors.test.ts +210 -0
  516. package/tests/unit/code-generator-functions.test.ts +271 -0
  517. package/tests/unit/components/column-list.test.tsx +190 -0
  518. package/tests/unit/components/data-import-modal.test.tsx +441 -0
  519. package/tests/unit/components/studio-mobile-header.test.tsx +327 -0
  520. package/tests/unit/data-charts-functions.test.ts +496 -0
  521. package/tests/unit/data-import-functions.test.ts +320 -0
  522. package/tests/unit/data-import-utils.test.ts +125 -0
  523. package/tests/unit/db/base-provider.test.ts +517 -0
  524. package/tests/unit/db/errors.test.ts +403 -0
  525. package/tests/unit/db/factory.test.ts +436 -0
  526. package/tests/unit/db/pool-manager.test.ts +440 -0
  527. package/tests/unit/db/query-limiter.test.ts +387 -0
  528. package/tests/unit/db/sql-base.test.ts +438 -0
  529. package/tests/unit/lib/api/error-codes.test.ts +39 -0
  530. package/tests/unit/lib/audit.test.ts +326 -0
  531. package/tests/unit/lib/auth.test.ts +146 -0
  532. package/tests/unit/lib/connection-string-parser.test.ts +424 -0
  533. package/tests/unit/lib/data-masking.test.ts +583 -0
  534. package/tests/unit/lib/db-icons.test.tsx +41 -0
  535. package/tests/unit/lib/monitoring-thresholds.test.ts +133 -0
  536. package/tests/unit/lib/oidc.test.ts +509 -0
  537. package/tests/unit/lib/query-generators.test.ts +127 -0
  538. package/tests/unit/lib/storage/factory.test.ts +71 -0
  539. package/tests/unit/lib/storage/local-storage.test.ts +114 -0
  540. package/tests/unit/lib/storage/providers/postgres.test.ts +312 -0
  541. package/tests/unit/lib/storage/providers/sqlite.test.ts +232 -0
  542. package/tests/unit/lib/storage/storage-facade-extended.test.ts +331 -0
  543. package/tests/unit/lib/storage/storage-facade.test.ts +184 -0
  544. package/tests/unit/lib/storage.test.ts +317 -0
  545. package/tests/unit/lib/time-series-buffer.test.ts +212 -0
  546. package/tests/unit/lib/utils.test.ts +24 -0
  547. package/tests/unit/llm/base-provider.test.ts +238 -0
  548. package/tests/unit/llm/config.test.ts +262 -0
  549. package/tests/unit/llm/custom-provider.test.ts +281 -0
  550. package/tests/unit/llm/gemini-provider.test.ts +248 -0
  551. package/tests/unit/llm/llm-factory.test.ts +155 -0
  552. package/tests/unit/llm/ollama-provider.test.ts +288 -0
  553. package/tests/unit/llm/openai-provider.test.ts +324 -0
  554. package/tests/unit/llm/retry.test.ts +180 -0
  555. package/tests/unit/llm/streaming.test.ts +355 -0
  556. package/tests/unit/logger.test.ts +198 -0
  557. package/tests/unit/mongodb-completions.test.ts +516 -0
  558. package/tests/unit/pivot-table-functions.test.ts +76 -0
  559. package/tests/unit/query-cancelled-error.test.ts +81 -0
  560. package/tests/unit/schema-diff/diff-engine.test.ts +367 -0
  561. package/tests/unit/schema-diff/migration-generator.test.ts +513 -0
  562. package/tests/unit/seed/config-loader.test.ts +73 -0
  563. package/tests/unit/seed/connection-filter.test.ts +91 -0
  564. package/tests/unit/seed/credential-resolver.test.ts +85 -0
  565. package/tests/unit/seed/index.test.ts +72 -0
  566. package/tests/unit/seed/resolve-connection.test.ts +74 -0
  567. package/tests/unit/seed/types.test.ts +129 -0
  568. package/tests/unit/sql/alias-extractor.test.ts +444 -0
  569. package/tests/unit/sql/statement-splitter.test.ts +348 -0
  570. package/tests/unit/sql-completions.test.ts +463 -0
  571. package/tests/unit/ssh-tunnel.test.ts +465 -0
  572. package/tsconfig.json +42 -0
@@ -0,0 +1,468 @@
1
+ # Seed Connections — Pre-Configured Database Connections
2
+
3
+ Seed Connections let administrators pre-configure database connections via a YAML or JSON file. Users see these connections immediately after login — no manual setup required.
4
+
5
+ **Use cases:**
6
+ - Platform/SaaS: provision databases for all users on signup
7
+ - Enterprise: give teams access to staging/production databases
8
+ - On-prem: DevOps pre-loads connections via Helm values or Docker volumes
9
+
10
+ ## Quick Start
11
+
12
+ **1.** Create `seed-connections.yaml`:
13
+
14
+ ```yaml
15
+ version: "1"
16
+
17
+ connections:
18
+ - id: "prod-db"
19
+ name: "Production Database"
20
+ type: postgres
21
+ host: "${DB_HOST}"
22
+ port: 5432
23
+ database: "${DB_NAME}"
24
+ user: "${DB_USER}"
25
+ password: "${DB_PASSWORD}"
26
+ roles: ["*"]
27
+ ```
28
+
29
+ **2.** Mount and set env vars:
30
+
31
+ ```bash
32
+ docker run \
33
+ -v ./seed-connections.yaml:/app/config/seed-connections.yaml:ro \
34
+ -e SEED_CONFIG_PATH=/app/config/seed-connections.yaml \
35
+ -e DB_HOST=mydb.internal -e DB_NAME=mydb \
36
+ -e DB_USER=reader -e DB_PASSWORD=secret \
37
+ ghcr.io/libredb/libredb-studio:latest
38
+ ```
39
+
40
+ **3.** Login — the connection appears in the sidebar with a lock icon.
41
+
42
+ ---
43
+
44
+ ## Config File Format
45
+
46
+ The config file is YAML (`.yaml`, `.yml`) or JSON (`.json`). Format is auto-detected by file extension.
47
+
48
+ ```yaml
49
+ version: "1"
50
+
51
+ defaults: # Optional — merged into every connection
52
+ managed: true
53
+ environment: production
54
+ ssl:
55
+ mode: require
56
+ rejectUnauthorized: true
57
+
58
+ connections:
59
+ - id: "analytics-pg" # Required, unique, lowercase slug [a-z0-9-]
60
+ name: "Analytics DB" # Required, display name in UI
61
+ type: postgres # Required: postgres|mysql|sqlite|mongodb|redis|oracle|mssql
62
+ host: "${PG_HOST}"
63
+ port: 5432
64
+ database: analytics
65
+ user: "${PG_USER}"
66
+ password: "${PG_PASSWORD}"
67
+ environment: production # production|staging|development|local|other
68
+ group: "Data Team" # Group label in sidebar
69
+ color: "#10B981" # Hex color for environment badge
70
+ roles: ["admin"] # Who can see this connection
71
+ managed: true # Read-only in UI (default from `defaults`)
72
+ ssl:
73
+ mode: require
74
+ rejectUnauthorized: true
75
+ # serviceName: "ORCL" # Oracle only
76
+ # instanceName: "MSSQL$" # SQL Server only
77
+
78
+ - id: "dev-mysql"
79
+ name: "Dev MySQL"
80
+ type: mysql
81
+ host: "${MYSQL_HOST}"
82
+ port: 3306
83
+ database: devdb
84
+ user: "${MYSQL_USER}"
85
+ password: "${MYSQL_PASSWORD}"
86
+ roles: ["*"] # Everyone can see this
87
+ managed: false # User gets an editable copy
88
+ environment: development
89
+ ```
90
+
91
+ ### Field Reference
92
+
93
+ | Field | Required | Default | Description |
94
+ |-------|----------|---------|-------------|
95
+ | `version` | Yes | — | Must be `"1"` |
96
+ | `defaults` | No | — | Merged into all connections (connection values override) |
97
+ | `defaults.managed` | No | `true` | Default managed state |
98
+ | `defaults.environment` | No | — | Default environment label |
99
+ | `defaults.ssl` | No | — | Default SSL config |
100
+ | `connections` | Yes | — | Array of connection definitions (min 1) |
101
+ | `connections[].id` | Yes | — | Unique slug: `[a-z0-9-]+`, max 64 chars |
102
+ | `connections[].name` | Yes | — | Display name, max 128 chars |
103
+ | `connections[].type` | Yes | — | Database type (see supported list above) |
104
+ | `connections[].host` | No | — | Hostname or IP |
105
+ | `connections[].port` | No | — | Port number (1-65535) |
106
+ | `connections[].database` | No | — | Database name |
107
+ | `connections[].user` | No | — | Username |
108
+ | `connections[].password` | No | — | Password (use `${ENV_VAR}` syntax) |
109
+ | `connections[].connectionString` | No | — | Full connection string (use `${ENV_VAR}`) |
110
+ | `connections[].roles` | Yes | — | Access control: `["*"]`, `["admin"]`, `["user"]`, `["admin", "user"]` |
111
+ | `connections[].managed` | No | from defaults | `true` = read-only, `false` = editable copy |
112
+ | `connections[].environment` | No | from defaults | Environment badge |
113
+ | `connections[].group` | No | — | Group label |
114
+ | `connections[].color` | No | — | Hex color for badge (e.g., `#10B981`) |
115
+ | `connections[].ssl` | No | from defaults | SSL configuration |
116
+ | `connections[].serviceName` | No | — | Oracle service name |
117
+ | `connections[].instanceName` | No | — | SQL Server instance name |
118
+
119
+ ---
120
+
121
+ ## Credential Management
122
+
123
+ Credentials are never stored in the config file directly. Use `${ENV_VAR}` syntax to reference environment variables:
124
+
125
+ ```yaml
126
+ connections:
127
+ - id: "prod-db"
128
+ password: "${PROD_DB_PASSWORD}" # Resolved from process.env at runtime
129
+ connectionString: "${MONGO_URI}" # Also works for connection strings
130
+ user: "${DB_USER}" # Any field can use ${} syntax
131
+ ```
132
+
133
+ **How it works:**
134
+ 1. Config file is read from disk (YAML/JSON)
135
+ 2. `${VARIABLE_NAME}` patterns are resolved from `process.env`
136
+ 3. If an env var is undefined, that connection is **skipped** (others continue working)
137
+ 4. Plaintext passwords trigger a warning log (but still work)
138
+
139
+ **Resolvable fields:** `password`, `connectionString`, `user`, `host`, `database`
140
+
141
+ ### Credential Sources by Deployment
142
+
143
+ | Deployment | How to provide credentials |
144
+ |------------|---------------------------|
145
+ | **Docker** | `-e DB_PASSWORD=secret` |
146
+ | **Docker Compose** | `environment:` block or `.env` file |
147
+ | **Kubernetes** | `Secret` → `extraEnvFrom` in Helm values |
148
+ | **Vault/SSM** | External Secrets Operator → K8s Secret → `extraEnvFrom` |
149
+
150
+ ### Kubernetes Example
151
+
152
+ ```yaml
153
+ # Create a K8s Secret with credentials
154
+ apiVersion: v1
155
+ kind: Secret
156
+ metadata:
157
+ name: seed-db-credentials
158
+ type: Opaque
159
+ stringData:
160
+ PG_PASSWORD: "my-secret-password"
161
+ MYSQL_PASSWORD: "another-secret"
162
+
163
+ ---
164
+ # Reference in Helm values
165
+ extraEnvFrom:
166
+ - secretRef:
167
+ name: seed-db-credentials
168
+ ```
169
+
170
+ ---
171
+
172
+ ## Role-Based Access Control
173
+
174
+ Each connection has a `roles` field that controls which users can see it:
175
+
176
+ | Config | Who sees it |
177
+ |--------|-------------|
178
+ | `roles: ["*"]` | All authenticated users |
179
+ | `roles: ["admin"]` | Admin users only |
180
+ | `roles: ["user"]` | Regular users only |
181
+ | `roles: ["admin", "user"]` | Both (same as `["*"]`) |
182
+
183
+ Roles are matched against the JWT session's `role` field. The role is extracted server-side from the JWT token — never from client input.
184
+
185
+ **Current limitation:** The system supports `admin` and `user` roles only (matching the JWT `role` claim). Custom roles (e.g., `data-team`, `backend`) are planned for a future release with expanded OIDC role claim support.
186
+
187
+ ### How Role Filtering Works
188
+
189
+ ```
190
+ User logs in → JWT contains { role: "user" }
191
+
192
+ GET /api/connections/managed
193
+
194
+ Server reads config → filters by role
195
+
196
+ User sees only connections where roles includes "user" or "*"
197
+ ```
198
+
199
+ ---
200
+
201
+ ## Managed vs. Unmanaged Connections
202
+
203
+ ### `managed: true` (default)
204
+
205
+ - Connection appears with a **lock icon** in the sidebar
206
+ - Users **cannot edit or delete** it
207
+ - Credentials are **never sent to the client** — server resolves them at query time
208
+ - If admin updates the config (e.g., password rotation), all users get the new credentials automatically
209
+ - Best for: production databases, shared resources
210
+
211
+ ### `managed: false`
212
+
213
+ - On first load, the connection is **copied to the user's local storage** with credentials
214
+ - User **can edit or delete** their copy
215
+ - Once copied, the connection belongs to the user — admin changes to the seed config won't affect existing copies
216
+ - If the user deletes their copy, it will be re-imported on next login
217
+ - Best for: development databases, sandbox environments
218
+
219
+ ### Comparison
220
+
221
+ | Behavior | `managed: true` | `managed: false` |
222
+ |----------|-----------------|-------------------|
223
+ | UI edit/delete | Locked | Allowed |
224
+ | Credentials on client | Never | Copied once |
225
+ | Password rotation | Automatic | User must re-import |
226
+ | Admin removes from config | Disappears for all | User copy remains |
227
+ | Server-side credential resolution | Yes | No (user has local copy) |
228
+
229
+ ---
230
+
231
+ ## Hot Reload
232
+
233
+ The config file is **cached in memory** with a TTL (default 60 seconds). When the file changes:
234
+
235
+ 1. Next API request after TTL expires triggers a re-read
236
+ 2. New connections appear, removed connections disappear
237
+ 3. Updated credentials take effect immediately (for `managed: true`)
238
+ 4. **No restart required**
239
+
240
+ ### Tuning the Cache TTL
241
+
242
+ ```bash
243
+ # Default: 60 seconds
244
+ SEED_CACHE_TTL_MS=60000
245
+
246
+ # Faster refresh (5 seconds) — useful during development
247
+ SEED_CACHE_TTL_MS=5000
248
+
249
+ # Slower refresh (5 minutes) — production with infrequent changes
250
+ SEED_CACHE_TTL_MS=300000
251
+ ```
252
+
253
+ In Kubernetes, ConfigMap updates propagate in ~60-120s (kubelet sync period). Combined with the cache TTL, expect ~2-3 minutes for changes to take effect.
254
+
255
+ ---
256
+
257
+ ## Deployment Examples
258
+
259
+ ### Docker
260
+
261
+ ```bash
262
+ docker run -d \
263
+ -v ./seed-connections.yaml:/app/config/seed-connections.yaml:ro \
264
+ -e SEED_CONFIG_PATH=/app/config/seed-connections.yaml \
265
+ -e PG_PASSWORD=secret \
266
+ -e JWT_SECRET=your-32-char-jwt-secret-here!! \
267
+ -e ADMIN_PASSWORD=MyAdmin123 \
268
+ -e USER_PASSWORD=MyUser123 \
269
+ -p 3000:3000 \
270
+ ghcr.io/libredb/libredb-studio:latest
271
+ ```
272
+
273
+ ### Docker Compose
274
+
275
+ ```yaml
276
+ services:
277
+ libredb:
278
+ image: ghcr.io/libredb/libredb-studio:latest
279
+ ports:
280
+ - "3000:3000"
281
+ volumes:
282
+ - ./seed-connections.yaml:/app/config/seed-connections.yaml:ro
283
+ environment:
284
+ SEED_CONFIG_PATH: /app/config/seed-connections.yaml
285
+ JWT_SECRET: your-32-char-jwt-secret-here!!
286
+ ADMIN_PASSWORD: MyAdmin123
287
+ USER_PASSWORD: MyUser123
288
+ PG_PASSWORD: ${PG_PASSWORD}
289
+ MYSQL_PASSWORD: ${MYSQL_PASSWORD}
290
+ env_file:
291
+ - .env # Store credentials here
292
+ ```
293
+
294
+ ### Kubernetes (Helm)
295
+
296
+ **Option A — Inline config in values.yaml:**
297
+
298
+ ```yaml
299
+ seedConnections:
300
+ enabled: true
301
+ config:
302
+ version: "1"
303
+ defaults:
304
+ managed: true
305
+ environment: production
306
+ connections:
307
+ - id: "prod-analytics"
308
+ name: "Production Analytics"
309
+ type: postgres
310
+ host: analytics-db.internal
311
+ port: 5432
312
+ database: analytics
313
+ user: readonly
314
+ password: "${ANALYTICS_DB_PASSWORD}"
315
+ roles: ["admin"]
316
+ color: "#10B981"
317
+ - id: "staging-api"
318
+ name: "Staging API DB"
319
+ type: mysql
320
+ host: staging-mysql.internal
321
+ password: "${STAGING_DB_PASSWORD}"
322
+ roles: ["*"]
323
+ managed: false
324
+ environment: staging
325
+
326
+ extraEnvFrom:
327
+ - secretRef:
328
+ name: seed-db-credentials
329
+ ```
330
+
331
+ **Option B — External ConfigMap:**
332
+
333
+ ```yaml
334
+ seedConnections:
335
+ enabled: true
336
+ existingConfigMap: "my-seed-connections" # Pre-created ConfigMap
337
+ configMapKey: "connections.yaml" # Key within the ConfigMap
338
+
339
+ extraEnvFrom:
340
+ - secretRef:
341
+ name: seed-db-credentials
342
+ ```
343
+
344
+ ---
345
+
346
+ ## Error Handling
347
+
348
+ | Scenario | Behavior |
349
+ |----------|----------|
350
+ | Config file not found | App runs normally, no seed connections. Warning logged. |
351
+ | Invalid YAML/JSON | Endpoint returns 500. Error logged with details. |
352
+ | Invalid config (Zod validation fails) | Endpoint returns 500 with validation errors. |
353
+ | Unrecognized `version` | Endpoint returns 500. Future versions require code update. |
354
+ | `${ENV_VAR}` not defined | That connection is **skipped**. Others work normally. Error logged. |
355
+ | User role doesn't match any connection | Empty list returned. Normal behavior. |
356
+ | Seed connection not found at query time | 404 response. |
357
+ | User doesn't have access to seed connection | 403 response. |
358
+
359
+ **Design principle:** One broken connection never breaks the others. Each connection is resolved independently.
360
+
361
+ ---
362
+
363
+ ## Security Model
364
+
365
+ ### Credential Protection
366
+
367
+ - `managed: true` connections: passwords **never reach the client**. The API strips `password` and `connectionString` from responses. Server resolves credentials at query execution time.
368
+ - Config file should be mounted **read-only** (`:ro` in Docker, `readOnly: true` in Kubernetes).
369
+ - Use `${ENV_VAR}` for all secrets. Plaintext passwords trigger a warning log.
370
+
371
+ ### Role Enforcement
372
+
373
+ - User role is extracted from the JWT session **server-side** — never from client headers or request params.
374
+ - Every database operation (query, schema, health check, etc.) goes through `resolveConnection()` which verifies role access before returning credentials.
375
+ - Role check failures return 403 with no credential information.
376
+
377
+ ### Audit Trail
378
+
379
+ Every operation on a managed connection is logged:
380
+
381
+ ```json
382
+ {
383
+ "event": "managed_connection_query",
384
+ "connectionId": "prod-analytics",
385
+ "user": "admin@company.com",
386
+ "role": "admin",
387
+ "route": "/api/db/query",
388
+ "timestamp": "2026-03-25T10:30:00Z"
389
+ }
390
+ ```
391
+
392
+ ---
393
+
394
+ ## Environment Variables
395
+
396
+ | Variable | Default | Description |
397
+ |----------|---------|-------------|
398
+ | `SEED_CONFIG_PATH` | `/app/config/seed-connections.yaml` | Path to config file |
399
+ | `SEED_CACHE_TTL_MS` | `60000` | Cache TTL in milliseconds |
400
+
401
+ ---
402
+
403
+ ## Troubleshooting
404
+
405
+ ### Connections don't appear after login
406
+
407
+ 1. Check if the config file exists at `SEED_CONFIG_PATH`
408
+ 2. Check server logs for `Seed config file not found` warning
409
+ 3. Verify the YAML is valid: `cat seed-connections.yaml | python3 -c "import yaml,sys; yaml.safe_load(sys.stdin)"`
410
+ 4. Check if `${ENV_VAR}` values are set: connections with unresolvable vars are silently skipped
411
+
412
+ ### "Access denied" error when querying
413
+
414
+ The user's role doesn't match the connection's `roles` array. Check:
415
+ - User JWT role: login as admin vs user
416
+ - Connection `roles` field in config
417
+
418
+ ### Credentials not updating after config change
419
+
420
+ - `managed: true`: Wait for TTL to expire (default 60s), or restart the app
421
+ - `managed: false`: The user has a local copy. They need to delete it from the sidebar and re-login to get the updated version
422
+
423
+ ### Two identical connections in sidebar
424
+
425
+ Clear browser localStorage (`libredb_connections` key) and refresh. This can happen if a connection was persisted before being marked as managed.
426
+
427
+ ---
428
+
429
+ ## Architecture
430
+
431
+ ```
432
+ seed-connections.yaml (volume mount)
433
+
434
+ ┌─────▼──────────┐
435
+ │ ConfigLoader │ Read + YAML/JSON parse + Zod validate + TTL cache
436
+ └─────┬──────────┘
437
+
438
+ ┌─────▼──────────────┐
439
+ │ CredentialResolver │ ${ENV_VAR} → process.env + plaintext warning
440
+ └─────┬──────────────┘
441
+
442
+ ┌─────▼──────────────┐
443
+ │ ConnectionFilter │ Role filter + defaults merge → ManagedConnection[]
444
+ └─────┬──────────────┘
445
+
446
+ ┌─────▼───────────────────────┐
447
+ │ GET /api/connections/managed │ Auth + strip credentials for managed:true
448
+ └─────┬───────────────────────┘
449
+
450
+ ┌─────▼────────────────────┐
451
+ │ useConnectionManager │ Merge managed + user connections
452
+ └─────┬────────────────────┘
453
+
454
+ ┌─────▼────────────────────────────┐
455
+ │ resolveConnection() (all routes) │ seed: prefix → server-side credential resolution
456
+ └──────────────────────────────────┘
457
+ ```
458
+
459
+ **Module:** `src/lib/seed/` — 6 files, ~350 lines total
460
+
461
+ | File | Responsibility |
462
+ |------|---------------|
463
+ | `types.ts` | Zod schemas + TypeScript types |
464
+ | `config-loader.ts` | File read + parse + validate + cache |
465
+ | `credential-resolver.ts` | `${ENV_VAR}` resolution |
466
+ | `connection-filter.ts` | Role filter + defaults merge |
467
+ | `resolve-connection.ts` | Shared utility for all API routes |
468
+ | `index.ts` | Public API: `getManagedConnections()` |
@@ -0,0 +1,190 @@
1
+ # SQL Alias-Based Code Completion
2
+
3
+ This document describes the intelligent SQL code completion feature that provides context-aware autocompletion with alias support in the Monaco Editor.
4
+
5
+ ## Features
6
+
7
+ ### 1. Alias-Based Column Completion
8
+
9
+ When you define a table alias in your SQL query, typing the alias followed by a dot (`.`) will suggest columns from the referenced table.
10
+
11
+ **Supported Patterns:**
12
+
13
+ | Pattern | Example | Result |
14
+ |---------|---------|--------|
15
+ | `FROM table AS alias` | `FROM employee AS e WHERE e.` | employee columns |
16
+ | `FROM table alias` | `FROM employee e WHERE e.` | employee columns |
17
+ | `JOIN table AS alias` | `JOIN department AS d ON d.` | department columns |
18
+ | `JOIN table alias` | `LEFT JOIN salary s ON s.` | salary columns |
19
+ | `schema.table alias` | `FROM employees.employee e WHERE e.` | employee columns |
20
+ | Multiple aliases | `FROM a AS x JOIN b AS y` | Both `x.` and `y.` work |
21
+ | CTE references | `WITH cte AS (...) SELECT cte.` | CTE columns |
22
+ | Direct table | `employee.` | employee columns |
23
+
24
+ ### 2. Context-Aware Completions
25
+
26
+ The completion system intelligently shows suggestions based on SQL context:
27
+
28
+ **Columns are shown only after:**
29
+ - `SELECT` keyword
30
+ - `WHERE` clause
31
+ - `AND`, `OR` operators
32
+ - `ON` (in JOIN conditions)
33
+ - `SET` (in UPDATE statements)
34
+ - `HAVING` clause
35
+ - `ORDER BY`, `GROUP BY` clauses
36
+ - Comma (`,`) in column lists
37
+
38
+ **Columns are NOT shown when:**
39
+ - Typing keywords like `FROM`, `JOIN`, `WHERE`
40
+ - After `SELECT *` (expecting keyword, not column)
41
+
42
+ ### 3. Prioritized Suggestions
43
+
44
+ Suggestions are sorted by relevance:
45
+
46
+ | Priority | Type | Description |
47
+ |----------|------|-------------|
48
+ | 1st | Keywords | SQL keywords (SELECT, FROM, WHERE, etc.) |
49
+ | 2nd | Functions | SQL functions (COUNT, SUM, AVG, etc.) |
50
+ | 3rd | Tables | Database tables |
51
+ | 4th | Snippets | Query templates |
52
+ | 5th | Columns | Table columns (context-dependent) |
53
+
54
+ ## Architecture
55
+
56
+ ### Module Structure
57
+
58
+ ```
59
+ src/lib/sql/
60
+ ├── alias-extractor.ts # Core alias extraction logic
61
+ ├── types.ts # TypeScript interfaces
62
+ └── index.ts # Module exports
63
+ ```
64
+
65
+ ### Key Components
66
+
67
+ #### 1. Alias Extractor (`src/lib/sql/alias-extractor.ts`)
68
+
69
+ Lightweight regex-based SQL parser that extracts table aliases without external dependencies.
70
+
71
+ **Functions:**
72
+ - `extractAliases(sql: string)` - Extract all table aliases from a SQL query
73
+ - `resolveAlias(identifier: string, aliases: Map)` - Resolve an alias to its table name
74
+
75
+ **How it works:**
76
+ 1. Preprocesses SQL to remove comments and string literals
77
+ 2. Extracts FROM clause aliases
78
+ 3. Extracts JOIN clause aliases
79
+ 4. Extracts CTE (WITH clause) aliases
80
+ 5. Returns a Map of alias → table name
81
+
82
+ #### 2. Completion Provider (`src/components/QueryEditor.tsx`)
83
+
84
+ Monaco Editor completion provider that integrates with the alias extractor.
85
+
86
+ **Dot-triggered completion flow:**
87
+ ```
88
+ User types: "e."
89
+
90
+ 1. Try direct table lookup: columnMap.get("e")
91
+ ↓ (not found)
92
+ 2. Extract aliases from query text
93
+
94
+ 3. Resolve "e" → "employee"
95
+
96
+ 4. Find columns: columnMap.get("employee")
97
+
98
+ 5. Return column suggestions
99
+ ```
100
+
101
+ ### Edge Cases Handled
102
+
103
+ 1. **SQL Keywords as Aliases**: Filters out `ON`, `WHERE`, `AND`, etc.
104
+ 2. **Comments**: Removes `--` and `/* */` before parsing
105
+ 3. **String Literals**: Replaces with placeholder to avoid false matches
106
+ 4. **Case Insensitivity**: Alias lookup is case-insensitive
107
+ 5. **Schema Prefixes**: Handles `schema.table` format (e.g., `employees.employee`)
108
+
109
+ ## Performance Considerations
110
+
111
+ - **No external SQL parser**: Keeps bundle size small
112
+ - **Regex-based parsing**: Fast execution (<10ms for typical queries)
113
+ - **Lazy evaluation**: Alias extraction only runs on dot-trigger
114
+ - **Cursor-limited parsing**: Only parses text from start to cursor position
115
+ - **Early exit**: Skips parsing if no FROM/JOIN/WITH keywords found
116
+
117
+ ## Examples
118
+
119
+ ### Basic Alias Usage
120
+ ```sql
121
+ SELECT e.first_name, e.last_name
122
+ FROM employee e
123
+ WHERE e.hire_date > '2020-01-01'
124
+ ```
125
+ Typing `e.` after defining `FROM employee e` will suggest all employee columns.
126
+
127
+ ### Multiple Table Aliases
128
+ ```sql
129
+ SELECT
130
+ e.first_name,
131
+ d.dept_name,
132
+ s.amount
133
+ FROM employee e
134
+ JOIN department_employee de ON de.employee_id = e.id
135
+ JOIN department d ON d.id = de.department_id
136
+ JOIN salary s ON s.employee_id = e.id
137
+ ```
138
+ Each alias (`e`, `de`, `d`, `s`) resolves to its respective table.
139
+
140
+ ### CTE Support
141
+ ```sql
142
+ WITH active_employees AS (
143
+ SELECT * FROM employee WHERE status = 'active'
144
+ )
145
+ SELECT ae.first_name
146
+ FROM active_employees ae
147
+ WHERE ae.department_id = 1
148
+ ```
149
+ The `ae` alias resolves to the CTE `active_employees`.
150
+
151
+ ## Integration
152
+
153
+ The alias completion is automatically available in the SQL editor. No configuration required.
154
+
155
+ ### API
156
+
157
+ ```typescript
158
+ import { extractAliases, resolveAlias } from '@/lib/sql';
159
+
160
+ // Extract aliases from a query
161
+ const { aliases } = extractAliases('SELECT * FROM employee e WHERE e.id = 1');
162
+
163
+ // Resolve an alias
164
+ const tableName = resolveAlias('e', aliases); // Returns 'employee'
165
+ ```
166
+
167
+ ## Type Definitions
168
+
169
+ ```typescript
170
+ interface TableAlias {
171
+ alias: string; // e.g., 'e'
172
+ tableName: string; // e.g., 'employee'
173
+ schema?: string; // e.g., 'employees'
174
+ source: 'from' | 'join' | 'cte';
175
+ }
176
+
177
+ interface AliasExtractionResult {
178
+ aliases: Map<string, TableAlias>;
179
+ hasTableReferences: boolean;
180
+ }
181
+ ```
182
+
183
+ ## Related Files
184
+
185
+ | File | Description |
186
+ |------|-------------|
187
+ | `src/lib/sql/types.ts` | Type definitions |
188
+ | `src/lib/sql/alias-extractor.ts` | Core parsing logic |
189
+ | `src/lib/sql/index.ts` | Module exports |
190
+ | `src/components/QueryEditor.tsx` | Monaco Editor integration |