@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,419 @@
1
+ # Storage Quick Setup Guide
2
+
3
+ LibreDB Studio supports three storage modes. Pick the one that fits your use case and follow the steps below.
4
+
5
+ > For a deep dive into the architecture, see [STORAGE_ARCHITECTURE.md](./STORAGE_ARCHITECTURE.md).
6
+
7
+ ---
8
+
9
+ ## Which Mode Should I Use?
10
+
11
+ | Mode | Best For | Persistence | Multi-User | Setup |
12
+ |------|----------|-------------|------------|-------|
13
+ | **Local** (default) | Solo dev, quick start | Browser only | No | Zero config |
14
+ | **SQLite** | Small teams, single server | Server file | Yes | 1 env var |
15
+ | **PostgreSQL** | Enterprise, multi-node | External DB | Yes | 2 env vars |
16
+
17
+ ---
18
+
19
+ ## 1. Local Mode (Default)
20
+
21
+ No configuration needed. All data stays in the browser's `localStorage`.
22
+
23
+ ```bash
24
+ # Just start the app — that's it
25
+ bun dev
26
+ ```
27
+
28
+ **What you get:**
29
+ - Instant start, no database required
30
+ - Data persists across page reloads
31
+ - Data is lost if browser storage is cleared or you switch browsers/devices
32
+
33
+ **When to move on:** When you need data to survive across devices, browsers, or team members.
34
+
35
+ ---
36
+
37
+ ## 2. SQLite Mode
38
+
39
+ A single file on the server. Great for self-hosted single-node deployments.
40
+
41
+ ### Minimal Setup (Just One Env Var)
42
+
43
+ ```bash
44
+ # .env.local
45
+ STORAGE_PROVIDER=sqlite
46
+ ```
47
+
48
+ ```bash
49
+ bun dev
50
+ ```
51
+
52
+ That's it. When `STORAGE_SQLITE_PATH` is not provided, the default path is `./data/libredb-storage.db`.
53
+
54
+ ### What Happens Automatically
55
+
56
+ On the first API request, the SQLite provider:
57
+
58
+ 1. **Creates the directory** — `./data/` (or whatever parent directory the path points to) is created recursively if it doesn't exist
59
+ 2. **Creates the database file** — `libredb-storage.db` is created by `better-sqlite3`
60
+ 3. **Enables WAL mode** — Write-Ahead Logging for better concurrent read performance
61
+ 4. **Creates the table** — `user_storage` table with the schema below
62
+
63
+ No manual setup, no migrations, no SQL scripts needed.
64
+
65
+ ### Custom Path
66
+
67
+ If you want the database file in a different location:
68
+
69
+ ```bash
70
+ # .env.local
71
+ STORAGE_PROVIDER=sqlite
72
+ STORAGE_SQLITE_PATH=/var/lib/libredb/storage.db
73
+ ```
74
+
75
+ The directory must be writable by the app process. The directory and file are created automatically.
76
+
77
+ ### Docker
78
+
79
+ ```yaml
80
+ # docker-compose.yml
81
+ services:
82
+ app:
83
+ image: ghcr.io/libredb/libredb-studio:latest
84
+ ports:
85
+ - "3000:3000"
86
+ environment:
87
+ - STORAGE_PROVIDER=sqlite
88
+ - STORAGE_SQLITE_PATH=/app/data/libredb-storage.db
89
+ volumes:
90
+ - storage-data:/app/data
91
+
92
+ volumes:
93
+ storage-data:
94
+ ```
95
+
96
+ ```bash
97
+ docker-compose up -d
98
+ ```
99
+
100
+ > **Volume is essential.** Without it, data is lost when the container restarts.
101
+
102
+ ### Verify
103
+
104
+ ```bash
105
+ curl http://localhost:3000/api/storage/config
106
+ # → {"provider":"sqlite","serverMode":true}
107
+ ```
108
+
109
+ ### Manual Table Creation (Optional)
110
+
111
+ The table is auto-created, but if you prefer to create it yourself (e.g., for auditing or version control):
112
+
113
+ ```sql
114
+ CREATE TABLE IF NOT EXISTS user_storage (
115
+ user_id TEXT NOT NULL,
116
+ collection TEXT NOT NULL,
117
+ data TEXT NOT NULL,
118
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
119
+ PRIMARY KEY (user_id, collection)
120
+ );
121
+
122
+ -- Recommended: enable WAL mode for concurrent read performance
123
+ PRAGMA journal_mode = WAL;
124
+ ```
125
+
126
+ ---
127
+
128
+ ## 3. PostgreSQL Mode
129
+
130
+ Recommended for production, teams, and high-availability deployments.
131
+
132
+ > **Important:** Unlike SQLite, `STORAGE_POSTGRES_URL` is **required**. There is no default value. If you set `STORAGE_PROVIDER=postgres` without providing a connection string, the app will throw an error on the first storage request:
133
+ > ```
134
+ > Error: STORAGE_POSTGRES_URL is required when STORAGE_PROVIDER=postgres
135
+ > ```
136
+
137
+ ### Local Development
138
+
139
+ ```bash
140
+ # Start a PostgreSQL instance (if you don't have one)
141
+ docker run -d --name libredb-pg \
142
+ -e POSTGRES_DB=libredb \
143
+ -e POSTGRES_USER=libredb \
144
+ -e POSTGRES_PASSWORD=secret \
145
+ -p 5432:5432 \
146
+ postgres:16-alpine
147
+ ```
148
+
149
+ ```bash
150
+ # .env.local
151
+ STORAGE_PROVIDER=postgres
152
+ STORAGE_POSTGRES_URL=postgresql://libredb:secret@localhost:5432/libredb?sslmode=disable
153
+ ```
154
+
155
+ ```bash
156
+ bun dev
157
+ ```
158
+
159
+ ### What Happens Automatically
160
+
161
+ On the first API request, the PostgreSQL provider:
162
+
163
+ 1. **Creates a connection pool** — max 5 connections, 30s idle timeout
164
+ 2. **Creates the table** — `user_storage` table with the schema below via `CREATE TABLE IF NOT EXISTS`
165
+
166
+ The database itself must already exist. The **table** is auto-created, but the **database** is not.
167
+
168
+ ### Required Privileges
169
+
170
+ The PostgreSQL user specified in `STORAGE_POSTGRES_URL` needs:
171
+
172
+ | Privilege | Why |
173
+ |-----------|-----|
174
+ | `CREATE TABLE` | Auto-create `user_storage` on first request (only needed once) |
175
+ | `INSERT` | Save user data |
176
+ | `UPDATE` | Update existing data |
177
+ | `SELECT` | Read user data |
178
+
179
+ If your DBA restricts `CREATE TABLE`, you can create the table manually (see below) and the user only needs `INSERT`/`UPDATE`/`SELECT`.
180
+
181
+ ### Docker Compose (App + PostgreSQL)
182
+
183
+ ```yaml
184
+ # docker-compose.yml
185
+ services:
186
+ app:
187
+ image: ghcr.io/libredb/libredb-studio:latest
188
+ ports:
189
+ - "3000:3000"
190
+ environment:
191
+ - STORAGE_PROVIDER=postgres
192
+ - STORAGE_POSTGRES_URL=postgresql://libredb:secret@db:5432/libredb?sslmode=disable
193
+ depends_on:
194
+ db:
195
+ condition: service_healthy
196
+
197
+ db:
198
+ image: postgres:16-alpine
199
+ environment:
200
+ - POSTGRES_DB=libredb
201
+ - POSTGRES_USER=libredb
202
+ - POSTGRES_PASSWORD=secret
203
+ volumes:
204
+ - pgdata:/var/lib/postgresql/data
205
+ healthcheck:
206
+ test: ["CMD-SHELL", "pg_isready -U libredb"]
207
+ interval: 5s
208
+ timeout: 3s
209
+ retries: 5
210
+
211
+ volumes:
212
+ pgdata:
213
+ ```
214
+
215
+ ```bash
216
+ docker-compose up -d
217
+ ```
218
+
219
+ ### Using an Existing PostgreSQL
220
+
221
+ Just set the connection string — the table is auto-created:
222
+
223
+ ```bash
224
+ STORAGE_PROVIDER=postgres
225
+ STORAGE_POSTGRES_URL=postgresql://user:pass@your-pg-host:5432/your_db
226
+ ```
227
+
228
+ Use `sslmode=disable` for local/non-SSL PostgreSQL and `sslmode=require` for managed cloud PostgreSQL:
229
+
230
+ ```bash
231
+ # Local PostgreSQL
232
+ STORAGE_POSTGRES_URL=postgresql://user:pass@localhost:5432/your_db?sslmode=disable
233
+
234
+ # Cloud PostgreSQL
235
+ STORAGE_POSTGRES_URL=postgresql://user:pass@your-pg-host:5432/your_db?sslmode=require
236
+ ```
237
+
238
+ ### Verify
239
+
240
+ ```bash
241
+ curl http://localhost:3000/api/storage/config
242
+ # → {"provider":"postgres","serverMode":true}
243
+ ```
244
+
245
+ ### Manual Table Creation (Optional)
246
+
247
+ The table is auto-created on first request. However, if you prefer to create it yourself — for example, in environments where the app user doesn't have `CREATE TABLE` privileges, or you want to track schema changes in version control:
248
+
249
+ ```sql
250
+ -- PostgreSQL
251
+ CREATE TABLE IF NOT EXISTS user_storage (
252
+ user_id TEXT NOT NULL,
253
+ collection TEXT NOT NULL,
254
+ data TEXT NOT NULL,
255
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
256
+ PRIMARY KEY (user_id, collection)
257
+ );
258
+
259
+ -- Optional: index for faster lookups by user
260
+ CREATE INDEX IF NOT EXISTS idx_user_storage_user_id ON user_storage (user_id);
261
+ ```
262
+
263
+ #### Minimal Privileges (When Table Already Exists)
264
+
265
+ If a DBA creates the table, the app user only needs:
266
+
267
+ ```sql
268
+ -- Grant only data access (no DDL needed)
269
+ GRANT SELECT, INSERT, UPDATE ON user_storage TO libredb_app;
270
+ ```
271
+
272
+ ---
273
+
274
+ ## Migration: Local to Server
275
+
276
+ When you switch from local mode to SQLite or PostgreSQL, **existing browser data is automatically migrated** on first login:
277
+
278
+ 1. User opens the app in server mode
279
+ 2. The sync hook detects it's the first time (no `libredb_server_migrated` flag)
280
+ 3. All localStorage data is sent to the server via `POST /api/storage/migrate`
281
+ 4. Server merges the data (ID-based deduplication — no duplicates)
282
+ 5. A flag is set in localStorage to prevent re-migration
283
+ 6. From this point on, the server is the source of truth
284
+
285
+ **No manual steps required.** Just change the env var and restart.
286
+
287
+ > If multiple users were sharing a browser in local mode, only the data from the user who migrates first will be sent. Each user's server storage is isolated by their login email.
288
+
289
+ ---
290
+
291
+ ## Environment Variables Reference
292
+
293
+ | Variable | Required | Default | Description |
294
+ |----------|----------|---------|-------------|
295
+ | `STORAGE_PROVIDER` | No | `local` | `local`, `sqlite`, or `postgres` |
296
+ | `STORAGE_SQLITE_PATH` | No | `./data/libredb-storage.db` | Path to SQLite file. Directory and file are auto-created. |
297
+ | `STORAGE_POSTGRES_URL` | **Yes** (postgres mode) | — | PostgreSQL connection string. **No default — app will error without it.** |
298
+
299
+ > These are **server-side only** variables (no `NEXT_PUBLIC_` prefix). The client discovers the mode at runtime via `GET /api/storage/config`. This means one Docker image works for all modes.
300
+
301
+ ### Default Behavior Summary
302
+
303
+ | Mode | Config needed | What's auto-created |
304
+ |------|--------------|---------------------|
305
+ | `local` | Nothing | N/A (browser localStorage) |
306
+ | `sqlite` | Just `STORAGE_PROVIDER=sqlite` | Directory + DB file + WAL mode + table |
307
+ | `postgres` | `STORAGE_PROVIDER=postgres` + `STORAGE_POSTGRES_URL` | Table only (database must exist) |
308
+
309
+ ---
310
+
311
+ ## Health Check
312
+
313
+ Check if the storage backend is reachable:
314
+
315
+ ```bash
316
+ # Storage mode info (always works, no auth needed)
317
+ curl http://localhost:3000/api/storage/config
318
+
319
+ # Full data fetch (requires auth cookie)
320
+ curl -b cookies.txt http://localhost:3000/api/storage
321
+ ```
322
+
323
+ ---
324
+
325
+ ## Troubleshooting
326
+
327
+ ### "Data not syncing to server"
328
+
329
+ 1. Check storage mode: `curl http://localhost:3000/api/storage/config`
330
+ 2. Make sure the response shows `"serverMode": true`
331
+ 3. Check browser console for sync errors (look for `[StorageSync]` prefixed logs)
332
+
333
+ ### SQLite: "SQLITE_CANTOPEN"
334
+
335
+ - The directory in `STORAGE_SQLITE_PATH` must be writable by the app process
336
+ - In Docker, make sure the volume is mounted correctly
337
+
338
+ ### PostgreSQL: "STORAGE_POSTGRES_URL is required"
339
+
340
+ - You set `STORAGE_PROVIDER=postgres` but didn't provide `STORAGE_POSTGRES_URL`
341
+ - Unlike SQLite, PostgreSQL has **no default** — a connection string is always required
342
+ - Fix: add `STORAGE_POSTGRES_URL=postgresql://user:pass@host:5432/dbname` to your env
343
+
344
+ ### PostgreSQL: "Connection refused"
345
+
346
+ - Verify `STORAGE_POSTGRES_URL` is correct and the database is reachable
347
+ - In Docker Compose, use the service name (`db`) as the host, not `localhost`
348
+ - Check that the PostgreSQL container is healthy: `docker-compose ps`
349
+
350
+ ### PostgreSQL: "server does not support SSL connections"
351
+
352
+ - Your PostgreSQL server does not accept SSL, but SSL is enabled in the connection URL
353
+ - Fix local setups by adding `?sslmode=disable` to `STORAGE_POSTGRES_URL`
354
+ - For managed cloud PostgreSQL, use `?sslmode=require`
355
+
356
+ ### "Data disappeared after switching modes"
357
+
358
+ - Switching from server mode **back** to local mode doesn't pull data from the server
359
+ - Local mode only reads from localStorage
360
+ - To recover: switch back to server mode, the data is still in the database
361
+
362
+ ### "Duplicate data after migration"
363
+
364
+ - Migration uses ID-based deduplication — this shouldn't happen
365
+ - If it does, check if the same user logged in from multiple browsers before migration completed
366
+
367
+ ---
368
+
369
+ ## Database Schema Reference
370
+
371
+ Both SQLite and PostgreSQL use the same single-table design. The table is auto-created on first request, but the full DDL is provided here for reference.
372
+
373
+ ### SQLite
374
+
375
+ ```sql
376
+ CREATE TABLE IF NOT EXISTS user_storage (
377
+ user_id TEXT NOT NULL,
378
+ collection TEXT NOT NULL,
379
+ data TEXT NOT NULL,
380
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
381
+ PRIMARY KEY (user_id, collection)
382
+ );
383
+
384
+ PRAGMA journal_mode = WAL;
385
+ ```
386
+
387
+ ### PostgreSQL
388
+
389
+ ```sql
390
+ CREATE TABLE IF NOT EXISTS user_storage (
391
+ user_id TEXT NOT NULL,
392
+ collection TEXT NOT NULL,
393
+ data TEXT NOT NULL,
394
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
395
+ PRIMARY KEY (user_id, collection)
396
+ );
397
+
398
+ -- Optional: index for faster lookups by user
399
+ CREATE INDEX IF NOT EXISTS idx_user_storage_user_id ON user_storage (user_id);
400
+ ```
401
+
402
+ ### Schema Explanation
403
+
404
+ | Column | Type | Description |
405
+ |--------|------|-------------|
406
+ | `user_id` | TEXT | User's email from JWT token (e.g., `admin@libredb.org`) |
407
+ | `collection` | TEXT | Data category: `connections`, `history`, `saved_queries`, `schema_snapshots`, `saved_charts`, `active_connection_id`, `audit_log`, `masking_config`, `threshold_config` |
408
+ | `data` | TEXT | JSON-serialized collection data |
409
+ | `updated_at` | TEXT / TIMESTAMPTZ | Last modification timestamp |
410
+
411
+ Each row stores **one user's one collection** as a JSON blob. Adding a new collection type requires no schema changes — just a new row.
412
+
413
+ ---
414
+
415
+ ## What's Next?
416
+
417
+ - [STORAGE_ARCHITECTURE.md](./STORAGE_ARCHITECTURE.md) — Deep dive into the write-through cache, sync hook, and provider internals
418
+ - [ARCHITECTURE.md](./ARCHITECTURE.md) — Overall system architecture
419
+ - [OIDC_SETUP.md](./OIDC_SETUP.md) — SSO configuration (pairs well with server storage for team deployments)
@@ -0,0 +1,36 @@
1
+ # LibreDB Studio: Expert Web/Mobile Database Management System
2
+
3
+ ## Vision
4
+ To provide a zero-install, professional-grade database management experience that rivals desktop tools (DataGrip, DBeaver) while being optimized for both high-end desktop workflows and rapid mobile database administration.
5
+
6
+ ## Top 10 High-Impact Features
7
+
8
+ 1. **Monaco SQL IntelliSense (IDE Experience)**: Integration of the Monaco Editor (VS Code core) with schema-aware autocomplete. It suggests table names, columns, and keywords based on the active connection.
9
+ 2. **Universal Pro Data Grid**: A virtualized, high-performance table component supporting millions of rows with inline editing, multi-select, and Excel-like copy-paste.
10
+ 3. **Visual Schema Graph (Mini-ERD)**: An interactive visualization of table relationships to help users understand complex schemas at a glance.
11
+ 4. **Multi-Tab Query Workspace**: Support for multiple query buffers with persistent results, allowing parallel work across different tables or databases.
12
+ 5. **Execution Plan Visualizer (EXPLAIN)**: A professional tool to analyze query performance visually, helping experts optimize their SQL.
13
+ 6. **AI SQL Copilot**: Natural language to SQL conversion using OpenAI/Anthropic models to speed up complex query writing.
14
+ 7. **Smart Mobile SQL Toolbar**: A custom, swipeable keyboard extension for mobile devices providing quick access to common SQL operators and keywords.
15
+ 8. **Query History & Cloud Snippets**: Searchable history of all executed queries and a "Favorites" system to sync common snippets across devices.
16
+ 9. **Advanced Data Exporter**: One-click export to CSV, JSON, SQL inserts, Markdown, and Excel with preview capabilities.
17
+ 10. **Live DB Health Monitoring**: Real-time dashboard showing active connections, long-running queries, and basic resource metrics (CPU/Memory if API permitted).
18
+
19
+ ## Development Roadmap
20
+
21
+ ### Phase 1: The Expert Core (Now)
22
+ - [ ] Replace basic textareas with **Monaco Editor**.
23
+ - [ ] Implement **Schema-Aware Autocomplete** (fetching table/column metadata).
24
+ - [ ] Introduce **Multi-Tab** support for the editor.
25
+
26
+ ### Phase 2: Professional Data Handling
27
+ - [ ] Transition to a **Virtualized Pro Grid** (TanStack Table + Windowing).
28
+ - [ ] Add **Inline Editing** and **Batch Save** functionality.
29
+
30
+ ### Phase 3: Mobile & UX Excellence
31
+ - [ ] Build the **Mobile SQL Toolbar**.
32
+ - [ ] Implement **Query History & Snippets** sidebar.
33
+
34
+ ### Phase 4: Expert Analysis Tools
35
+ - [ ] Visual **EXPLAIN** integration.
36
+ - [ ] **ER Diagram** viewer for the explorer.