@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,252 @@
1
+ # Helm Chart Architecture
2
+
3
+ ## Overview
4
+
5
+ LibreDB Studio's Helm chart provides a production-grade Kubernetes deployment with security hardening, pluggable storage, autoscaling, and dual distribution (GitHub Pages + OCI).
6
+
7
+ ## Distribution Channels
8
+
9
+ | Channel | URL | Command |
10
+ |---------|-----|---------|
11
+ | **ArtifactHub** | [artifacthub.io/packages/helm/libredb-studio/libredb-studio](https://artifacthub.io/packages/helm/libredb-studio/libredb-studio) | Browse & discover |
12
+ | **Helm Repo** | `https://libredb.org/libredb-studio/` | `helm repo add libredb https://libredb.org/libredb-studio/` |
13
+ | **OCI Registry** | `oci://ghcr.io/libredb/charts/libredb-studio` | `helm install libredb oci://ghcr.io/libredb/charts/libredb-studio` |
14
+
15
+ ## Chart Structure
16
+
17
+ ```
18
+ charts/libredb-studio/
19
+ β”œβ”€β”€ Chart.yaml # Metadata, appVersion, Bitnami PostgreSQL dependency
20
+ β”œβ”€β”€ values.yaml # All configurable defaults
21
+ β”œβ”€β”€ values.schema.json # JSON Schema validation (helm lint --strict)
22
+ β”œβ”€β”€ .helmignore # Package exclusion patterns
23
+ β”œβ”€β”€ README.md # Chart-level documentation
24
+ └── templates/
25
+ β”œβ”€β”€ _helpers.tpl # Named templates (labels, names, image, storage logic)
26
+ β”œβ”€β”€ deployment.yaml # App Deployment (checksum restart, emptyDir, probes)
27
+ β”œβ”€β”€ service.yaml # ClusterIP / NodePort / LoadBalancer
28
+ β”œβ”€β”€ ingress.yaml # Optional Ingress (nginx/traefik)
29
+ β”œβ”€β”€ configmap.yaml # Non-sensitive env vars (PORT, storage, LLM, OIDC)
30
+ β”œβ”€β”€ secret.yaml # Sensitive env vars (JWT, passwords, API keys)
31
+ β”œβ”€β”€ serviceaccount.yaml # SA with IRSA/Workload Identity annotations
32
+ β”œβ”€β”€ hpa.yaml # HorizontalPodAutoscaler (CPU + memory)
33
+ β”œβ”€β”€ pdb.yaml # PodDisruptionBudget
34
+ β”œβ”€β”€ pvc.yaml # PersistentVolumeClaim (SQLite mode)
35
+ β”œβ”€β”€ networkpolicy.yaml # Ingress/egress rules (DB ports, DNS, HTTPS)
36
+ └── NOTES.txt # Post-install usage instructions
37
+ ```
38
+
39
+ ## Architecture Decisions
40
+
41
+ ### 1. Security Hardening
42
+
43
+ The chart enforces a restrictive security posture by default:
44
+
45
+ ```yaml
46
+ podSecurityContext:
47
+ runAsNonRoot: true
48
+ runAsUser: 1001 # Matches Dockerfile (adduser --uid 1001 nextjs)
49
+ runAsGroup: 1001
50
+ fsGroup: 1001
51
+ seccompProfile:
52
+ type: RuntimeDefault
53
+
54
+ securityContext:
55
+ allowPrivilegeEscalation: false
56
+ readOnlyRootFilesystem: true
57
+ capabilities:
58
+ drop: [ALL]
59
+ ```
60
+
61
+ **readOnlyRootFilesystem + emptyDir**: Next.js writes to `.next/cache` at runtime. Two `emptyDir` volumes solve this without relaxing security:
62
+ - `/app/.next/cache` β€” Next.js ISR/build cache (ephemeral, per-pod)
63
+ - `/tmp` β€” Temporary files
64
+
65
+ ### 2. Dockerfile Alignment
66
+
67
+ The chart is tightly coupled to the Dockerfile:
68
+
69
+ | Dockerfile | Chart |
70
+ |-----------|-------|
71
+ | `EXPOSE 3000/tcp` | `service.targetPort: 3000` |
72
+ | `adduser --uid 1001 nextjs` | `podSecurityContext.runAsUser: 1001` |
73
+ | `WORKDIR /app` | Volume mounts under `/app/` |
74
+ | `mkdir -p data` | PVC mounts at `/app/data` (SQLite mode) |
75
+ | `GET /api/db/health` | Startup/readiness/liveness probes |
76
+
77
+ ### 3. Storage Modes
78
+
79
+ ```
80
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
81
+ β”‚ values.yaml β”‚
82
+ β”‚ storageProvider β”‚
83
+ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
84
+ β”‚
85
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
86
+ β–Ό β–Ό β–Ό
87
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
88
+ β”‚ local β”‚ β”‚ sqlite β”‚ β”‚ postgres β”‚
89
+ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
90
+ β”‚ No PVCβ”‚ β”‚ Auto β”‚ β”‚ External β”‚
91
+ β”‚ No DB β”‚ β”‚ PVC β”‚ β”‚ URL or β”‚
92
+ β”‚ β”‚ β”‚ create β”‚ β”‚ Subchart β”‚
93
+ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
94
+ ```
95
+
96
+ - **local** (default): Browser localStorage only. No server-side persistence.
97
+ - **sqlite**: Auto-creates PVC. Single-writer β€” do not use with multiple replicas.
98
+ - **postgres**: Two options:
99
+ - `postgresql.enabled=true` β†’ Deploys Bitnami subchart, auto-wires `STORAGE_POSTGRES_URL`
100
+ - `secrets.storagePostgresUrl` β†’ External PostgreSQL connection
101
+
102
+ **Auto-wiring logic** (`_helpers.tpl`):
103
+ ```
104
+ if postgresql.enabled AND storageProvider == "local":
105
+ effective storageProvider = "postgres" # auto-switch
106
+ ```
107
+
108
+ ### 4. PostgreSQL Subchart Integration
109
+
110
+ When `postgresql.enabled=true`:
111
+
112
+ ```
113
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
114
+ β”‚ LibreDB Studio Pod β”‚ β”‚ PostgreSQL Pod β”‚
115
+ β”‚ β”‚ β”‚ (Bitnami subchart) β”‚
116
+ β”‚ STORAGE_POSTGRES_URLβ”œβ”€β”€β”€β”€β”€β–Ίβ”‚ :5432 β”‚
117
+ β”‚ = postgresql:// β”‚ β”‚ β”‚
118
+ β”‚ libredb:$PASS@ β”‚ β”‚ Secret: β”‚
119
+ β”‚ <release>-pg:5432 β”‚ β”‚ <release>-postgresql β”‚
120
+ β”‚ /libredb_storage β”‚ β”‚ β”‚
121
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
122
+ ```
123
+
124
+ Subchart secret name follows Bitnami convention: `<release-name>-postgresql` (not `<release>-<chart>-postgresql`).
125
+
126
+ ### 5. Secret Management
127
+
128
+ ```
129
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
130
+ β”‚ secrets.existingSecret β”‚
131
+ β”‚ β”‚
132
+ β”‚ Set? ──Yes──► Use external secret β”‚
133
+ β”‚ β”‚ (Vault/Sealed Secrets/ESO) β”‚
134
+ β”‚ No Skip secret.yaml rendering β”‚
135
+ β”‚ β”‚ β”‚
136
+ β”‚ β–Ό β”‚
137
+ β”‚ secret.yaml rendered with: β”‚
138
+ β”‚ - required: jwtSecret, adminPassword, β”‚
139
+ β”‚ userPassword β”‚
140
+ β”‚ - optional: llmApiKey, oidcClientId/Secret, β”‚
141
+ β”‚ storagePostgresUrl β”‚
142
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
143
+ ```
144
+
145
+ `existingSecretKeys` allows custom key name mapping for external secrets.
146
+
147
+ ### 6. ConfigMap / Environment Variables
148
+
149
+ All non-sensitive configuration flows through a ConfigMap:
150
+
151
+ | Variable | Source | Conditional |
152
+ |----------|--------|-------------|
153
+ | `NODE_ENV` | Fixed `production` | Always |
154
+ | `PORT` | `service.targetPort` | Always |
155
+ | `HOSTNAME` | Fixed `0.0.0.0` | Always |
156
+ | `NEXT_TELEMETRY_DISABLED` | Fixed `1` | Always |
157
+ | `NEXT_PUBLIC_AUTH_PROVIDER` | `authProvider` | Always |
158
+ | `STORAGE_PROVIDER` | Auto-wired (see above) | Always |
159
+ | `STORAGE_SQLITE_PATH` | `config.storageSqlitePath` | When sqlite |
160
+ | `LLM_PROVIDER/MODEL/API_URL` | `config.llm*` | When set |
161
+ | `OIDC_*` | `config.oidc*` | When `authProvider=oidc` |
162
+
163
+ ### 7. Pod Restart on Config Change
164
+
165
+ Deployment annotations include checksums of ConfigMap and Secret:
166
+
167
+ ```yaml
168
+ annotations:
169
+ checksum/config: {{ sha256sum configmap.yaml }}
170
+ checksum/secret: {{ sha256sum secret.yaml }}
171
+ ```
172
+
173
+ Any change to configuration values triggers a rolling restart automatically.
174
+
175
+ ## Release Pipeline
176
+
177
+ ```
178
+ Push to main (charts/** changed)
179
+ β”‚
180
+ β–Ό
181
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
182
+ β”‚ helm-release.yml β”‚
183
+ β”‚ β”‚
184
+ β”‚ Job 1: lint-test β”‚
185
+ β”‚ β”œβ”€β”€ ct lint (chart-testing) β”‚
186
+ β”‚ β”œβ”€β”€ Kind cluster create β”‚
187
+ β”‚ └── ct install (real cluster test) β”‚
188
+ β”‚ β”‚
189
+ β”‚ Job 2: release-github-pages β”‚
190
+ β”‚ β”œβ”€β”€ helm dependency build β”‚
191
+ β”‚ └── chart-releaser-action β”‚
192
+ β”‚ β”œβ”€β”€ GitHub Release (tag + .tgz) β”‚
193
+ β”‚ └── gh-pages index.yaml update β”‚
194
+ β”‚ β”‚
195
+ β”‚ Job 3: release-oci β”‚
196
+ β”‚ β”œβ”€β”€ helm dependency build β”‚
197
+ β”‚ β”œβ”€β”€ helm package β”‚
198
+ β”‚ └── helm push β†’ ghcr.io/libredb/chartsβ”‚
199
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
200
+ β”‚
201
+ β–Ό
202
+ ArtifactHub auto-scan (~30 min)
203
+ ```
204
+
205
+ ### Version Management
206
+
207
+ - `Chart.yaml version` (e.g., `0.1.0`): Chart version, bumped for chart-only changes
208
+ - `Chart.yaml appVersion` (e.g., `0.8.10`): Must match `package.json` version
209
+ - CI enforces `appVersion == package.json.version` via the `helm-lint` job
210
+
211
+ ## Deployment Examples
212
+
213
+ ### Minimal (port-forward)
214
+ ```bash
215
+ helm repo add libredb https://libredb.org/libredb-studio/
216
+ helm install libredb libredb/libredb-studio \
217
+ --set secrets.jwtSecret=$(openssl rand -base64 32) \
218
+ --set secrets.adminPassword=MyAdmin123 \
219
+ --set secrets.userPassword=MyUser123
220
+ kubectl port-forward svc/libredb-libredb-studio 3000:80
221
+ ```
222
+
223
+ ### Production (Ingress + PostgreSQL + HPA)
224
+ ```bash
225
+ helm install libredb libredb/libredb-studio \
226
+ --set secrets.jwtSecret=$(openssl rand -base64 32) \
227
+ --set secrets.adminPassword=StrongPass123 \
228
+ --set secrets.userPassword=StrongPass456 \
229
+ --set postgresql.enabled=true \
230
+ --set postgresql.auth.password=pg-secret \
231
+ --set ingress.enabled=true \
232
+ --set ingress.className=nginx \
233
+ --set "ingress.hosts[0].host=libredb.example.com" \
234
+ --set "ingress.hosts[0].paths[0].path=/" \
235
+ --set "ingress.hosts[0].paths[0].pathType=Prefix" \
236
+ --set "ingress.tls[0].secretName=libredb-tls" \
237
+ --set "ingress.tls[0].hosts[0]=libredb.example.com" \
238
+ --set autoscaling.enabled=true \
239
+ --set podDisruptionBudget.enabled=true
240
+ ```
241
+
242
+ ### External Secrets (Vault / ESO)
243
+ ```bash
244
+ helm install libredb libredb/libredb-studio \
245
+ --set secrets.existingSecret=my-vault-secret
246
+ ```
247
+
248
+ ## Known Limitations
249
+
250
+ 1. **SQLite + Multi-Replica**: SQLite is single-writer. `storageProvider=sqlite` with `replicaCount > 1` will cause write conflicts. Use `postgres` for multi-replica.
251
+ 2. **ISR Cache**: Next.js ISR cache is per-pod (emptyDir). Session-based app, so no impact.
252
+ 3. **Chart appVersion**: Must be manually synced with `package.json` (CI validates but doesn't auto-bump).
@@ -0,0 +1,178 @@
1
+ # Login Page
2
+
3
+ The login page uses a responsive split-panel layout that adapts between OIDC (SSO) and local (email/password) authentication modes.
4
+
5
+ ---
6
+
7
+ ## Architecture
8
+
9
+ ```
10
+ src/app/login/
11
+ β”œβ”€β”€ page.tsx # Server component β€” reads NEXT_PUBLIC_AUTH_PROVIDER env var
12
+ └── login-form.tsx # Client component β€” all UI and auth logic
13
+ ```
14
+
15
+ **`page.tsx`** is a server component with `export const dynamic = 'force-dynamic'` to ensure the auth provider env var is read at runtime (critical for Docker deployments where the env var is not available during build).
16
+
17
+ **`login-form.tsx`** receives `authProvider` as a prop and renders the appropriate form based on whether the value is `"oidc"` or `"local"` (default).
18
+
19
+ ---
20
+
21
+ ## Layout
22
+
23
+ ### Desktop (lg and above)
24
+
25
+ ```
26
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
27
+ β”‚ β”‚ β”‚
28
+ β”‚ Left Panel (55%) β”‚ Right Panel (45%) β”‚
29
+ β”‚ β”‚ β”‚
30
+ β”‚ β”Œβ”€ Logo ─────────────┐ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
31
+ β”‚ β”‚ πŸ”² LibreDB Studio β”‚ β”‚ β”‚ Welcome back β”‚ β”‚
32
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚
33
+ β”‚ β”‚ β”‚ [Form] β”‚ β”‚
34
+ β”‚ Hero text β”‚ β”‚ β”‚ β”‚
35
+ β”‚ "The open-source SQL β”‚ β”‚ OIDC: SSO β”‚ β”‚
36
+ β”‚ IDE for cloud-native β”‚ β”‚ button β”‚ β”‚
37
+ β”‚ teams" β”‚ β”‚ β”‚ β”‚
38
+ β”‚ β”‚ β”‚ Local: β”‚ β”‚
39
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ email/pass β”‚ β”‚
40
+ β”‚ β”‚Feature 1β”‚ β”‚Feature 2β”‚ β”‚ β”‚ + test btns β”‚ β”‚
41
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚
42
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
43
+ β”‚ β”‚Feature 3β”‚ β”‚Feature 4β”‚ β”‚ β”‚
44
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
45
+ β”‚ β”‚ β”‚
46
+ β”‚ Supported Databases β”‚ β”‚
47
+ β”‚ [PG] [MySQL] [MongoDB].. β”‚ β”‚
48
+ β”‚ β”‚ β”‚
49
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
50
+ ```
51
+
52
+ ### Mobile (below lg)
53
+
54
+ ```
55
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
56
+ β”‚ πŸ”² LibreDB Studio β”‚ ← Compact branding
57
+ β”‚ Open-source SQL IDE β”‚
58
+ β”‚ β”‚
59
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
60
+ β”‚ β”‚ Sign in β”‚ β”‚
61
+ β”‚ β”‚ β”‚ β”‚
62
+ β”‚ β”‚ [Form] β”‚ β”‚
63
+ β”‚ β”‚ β”‚ β”‚
64
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
65
+ β”‚ β”‚
66
+ β”‚ [PG] [MySQL] ... β”‚ ← DB badges
67
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
68
+ ```
69
+
70
+ - Left branding panel is hidden (`hidden lg:flex`)
71
+ - Mobile branding appears above the card (`lg:hidden`)
72
+ - Card title: "Welcome back" (desktop) / "Sign in" (mobile)
73
+ - Card description adapts per viewport
74
+ - Accessibility: mobile branding uses `<h2>` to avoid duplicate `<h1>` tags
75
+
76
+ ---
77
+
78
+ ## Authentication Modes
79
+
80
+ ### OIDC Mode (`NEXT_PUBLIC_AUTH_PROVIDER=oidc`)
81
+
82
+ When OIDC is active, the right panel shows:
83
+
84
+ 1. **ShieldCheck icon** with "Single Sign-On" label
85
+ 2. **"Login with SSO" button** β€” triggers a full-page redirect to `/api/auth/oidc/login`
86
+ 3. **Security badges** β€” "Encrypted" and "OIDC Protected"
87
+
88
+ The SSO flow uses standard browser redirect (not popup). The OIDC login route handles PKCE, and the callback route creates a local JWT session before redirecting to `/` or `/admin` based on the mapped role.
89
+
90
+ ### Local Mode (`NEXT_PUBLIC_AUTH_PROVIDER=local`, default)
91
+
92
+ When local auth is active, the right panel shows:
93
+
94
+ 1. **Email/password form** with icon-prefixed inputs
95
+ 2. **"Sign In" button** β€” calls `POST /api/auth/login` with JSON body
96
+ 3. **Quick Access section** β€” two test buttons (Admin / User) that auto-fill credentials and submit
97
+
98
+ On successful login, the user is redirected based on their role:
99
+ - `admin` β†’ `/admin`
100
+ - `user` β†’ `/`
101
+
102
+ ---
103
+
104
+ ## Design System
105
+
106
+ The login page follows the app's premium dark aesthetic:
107
+
108
+ | Element | Value | Notes |
109
+ |---------|-------|-------|
110
+ | Left panel background | `bg-zinc-950` | Matches app background (`--background: #09090b`) |
111
+ | Gradient overlay | `from-blue-950/20 to-cyan-950/10` | Subtle blue tint for depth |
112
+ | Accent color | `text-blue-400` | App's primary accent |
113
+ | Feature cards | `bg-white/[0.03] border-white/[0.05]` | Glassmorphism, matching admin dashboard |
114
+ | Feature icon bg | `bg-blue-500/10 border-blue-500/10` | Blue-tinted icon containers |
115
+ | Ambient orbs | `bg-blue-500/[0.07]`, `bg-cyan-500/[0.05]` | Soft glow, same pattern as admin dashboard |
116
+ | Dot grid | `opacity-[0.04]`, 32px spacing | Decorative texture |
117
+ | Panel separator | `bg-white/[0.06]` | 1px right edge line |
118
+ | Text hierarchy | `text-white` β†’ `text-zinc-200` β†’ `text-zinc-400` β†’ `text-zinc-500` β†’ `text-zinc-600` | 5-level opacity scale |
119
+ | Mobile icon | `bg-zinc-900 border-white/[0.08]` | Dark container with blue glow shadow |
120
+ | Form card | `border-muted-foreground/10 shadow-2xl` | Shadcn Card with elevated shadow |
121
+
122
+ ---
123
+
124
+ ## Files
125
+
126
+ | File | Purpose |
127
+ |------|---------|
128
+ | `src/app/login/page.tsx` | Server component, reads auth provider env var, forces dynamic rendering |
129
+ | `src/app/login/login-form.tsx` | Client component, split-panel layout, OIDC/local form rendering |
130
+ | `tests/components/LoginPage.test.tsx` | Component tests β€” rendering, form submission, OIDC mode |
131
+
132
+ ---
133
+
134
+ ## Environment Variables
135
+
136
+ | Variable | Default | Effect on Login |
137
+ |----------|---------|-----------------|
138
+ | `NEXT_PUBLIC_AUTH_PROVIDER` | `local` | `"oidc"` β†’ SSO button, `"local"` β†’ email/password form |
139
+ | `NEXT_PUBLIC_APP_VERSION` | β€” | Displayed in footer as `v{version}` |
140
+
141
+ ---
142
+
143
+ ## Customization
144
+
145
+ ### Changing branding text
146
+
147
+ Edit the `features` array and hero text in `login-form.tsx`:
148
+
149
+ ```tsx
150
+ const features = [
151
+ { icon: Globe, title: '7+ Database Engines', desc: 'PostgreSQL, MySQL, ...' },
152
+ { icon: Zap, title: 'AI-Native Queries', desc: 'Natural language to SQL...' },
153
+ // ...
154
+ ];
155
+ ```
156
+
157
+ Hero text is in the `<h1>` element. The gradient word uses `from-blue-400 to-cyan-400`.
158
+
159
+ ### Changing database badges
160
+
161
+ Both desktop and mobile lists are separate arrays. Keep them in sync:
162
+
163
+ ```tsx
164
+ // Desktop (left panel, line ~131)
165
+ {['PostgreSQL', 'MySQL', 'MongoDB', 'Oracle', 'SQL Server'].map(...)}
166
+
167
+ // Mobile (bottom pills, line ~316)
168
+ {['PostgreSQL', 'MySQL', 'MongoDB', 'Oracle', 'SQL Server'].map(...)}
169
+ ```
170
+
171
+ ### Changing colors
172
+
173
+ To align with a different brand, update these Tailwind classes:
174
+
175
+ - **Accent**: Replace `blue-400`, `blue-500`, `blue-950` with your color
176
+ - **Gradient text**: `from-blue-400 to-cyan-400` on the hero heading
177
+ - **Feature icons**: `bg-blue-500/10 border-blue-500/10` and `text-blue-400`
178
+ - **Mobile icon**: `bg-blue-500/20` glow and `text-blue-400` icon