@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.
- package/.claude/settings.local.json +127 -0
- package/.cursorrules +426 -0
- package/.devin/wiki.json +143 -0
- package/.dockerignore +80 -0
- package/.env.example +159 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +49 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +29 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +57 -0
- package/.github/workflows/ci.yml +185 -0
- package/.github/workflows/codeql.yml +57 -0
- package/.github/workflows/docker-build-push.yml +118 -0
- package/.github/workflows/helm-release.yml +113 -0
- package/CLAUDE.md +265 -0
- package/CODE_OF_CONDUCT.md +124 -0
- package/CONTRIBUTING.md +154 -0
- package/Dockerfile +73 -0
- package/LICENSE +21 -0
- package/README.md +614 -0
- package/SECURITY.md +107 -0
- package/artifacthub-repo.yml +4 -0
- package/bun.lock +1714 -0
- package/bunfig.toml +3 -0
- package/charts/libredb-studio/.helmignore +11 -0
- package/charts/libredb-studio/Chart.lock +6 -0
- package/charts/libredb-studio/Chart.yaml +50 -0
- package/charts/libredb-studio/README.md +206 -0
- package/charts/libredb-studio/templates/NOTES.txt +59 -0
- package/charts/libredb-studio/templates/_helpers.tpl +135 -0
- package/charts/libredb-studio/templates/configmap.yaml +37 -0
- package/charts/libredb-studio/templates/deployment.yaml +184 -0
- package/charts/libredb-studio/templates/hpa.yaml +32 -0
- package/charts/libredb-studio/templates/ingress.yaml +41 -0
- package/charts/libredb-studio/templates/networkpolicy.yaml +50 -0
- package/charts/libredb-studio/templates/pdb.yaml +18 -0
- package/charts/libredb-studio/templates/pvc.yaml +23 -0
- package/charts/libredb-studio/templates/secret.yaml +30 -0
- package/charts/libredb-studio/templates/seed-configmap.yaml +11 -0
- package/charts/libredb-studio/templates/service.yaml +22 -0
- package/charts/libredb-studio/templates/serviceaccount.yaml +13 -0
- package/charts/libredb-studio/values.schema.json +246 -0
- package/charts/libredb-studio/values.yaml +286 -0
- package/components.json +22 -0
- package/conductor/code_styleguides/typescript.md +43 -0
- package/conductor/product-guidelines.md +43 -0
- package/conductor/product.md +3 -0
- package/conductor/setup_state.json +1 -0
- package/conductor/tech-stack.md +39 -0
- package/conductor/tracks/enhance_postgres_monitoring_20251227/metadata.json +8 -0
- package/conductor/tracks/enhance_postgres_monitoring_20251227/plan.md +44 -0
- package/conductor/tracks/enhance_postgres_monitoring_20251227/spec.md +31 -0
- package/conductor/tracks.md +8 -0
- package/conductor/workflow.md +333 -0
- package/database-compose.yml +55 -0
- package/docker/postgres-init/01-extensions.sql +10 -0
- package/docker/postgres-init/02-sample-data.sql +585 -0
- package/docker/postgres.yml +68 -0
- package/docker-compose.yml +38 -0
- package/docs/AI_PLAN.md +74 -0
- package/docs/API_DOCS.md +875 -0
- package/docs/ARCHITECTURE.md +218 -0
- package/docs/DATABASE_PROVIDERS.md +358 -0
- package/docs/FEATURES.md +116 -0
- package/docs/HELM_CHART.md +252 -0
- package/docs/LOGIN_PAGE.md +178 -0
- package/docs/MONACO_EDITOR_PERFORMANCE.md +315 -0
- package/docs/OIDC_ARCH.md +681 -0
- package/docs/OIDC_SETUP.md +322 -0
- package/docs/POSTGRES_METRICS.md +516 -0
- package/docs/QUERY_OPTIMIZATION.md +370 -0
- package/docs/SEED_CONNECTIONS.md +468 -0
- package/docs/SQL_ALIAS_COMPLETION.md +190 -0
- package/docs/STORAGE_ARCHITECTURE.md +565 -0
- package/docs/STORAGE_QUICK_SETUP.md +419 -0
- package/docs/TECHNICAL_PLAN.md +36 -0
- package/docs/THEMING.md +345 -0
- package/docs/adding-a-new-database-provider.md +642 -0
- package/docs/backlogs/000-PLATFORM_DATA_SYNC_DATABASE.md +360 -0
- package/docs/backlogs/001-INLINE_DATA_EDITING.md +118 -0
- package/docs/backlogs/002-DATA_IMPORT.md +215 -0
- package/docs/backlogs/003-QUERY_TIME_MACHINE.md +183 -0
- package/docs/backlogs/004-AI_DATA_STORYTELLER.md +292 -0
- package/docs/backlogs/005-QUERY_PLAYGROUND.md +352 -0
- package/docs/backlogs/006-DATA_MASKING.md +418 -0
- package/docs/enterprise-features.md +718 -0
- package/docs/kubernetes-helm-chart-artifacthub-plan.md +803 -0
- package/docs/medium-koyeb-article-en.md +215 -0
- package/docs/plans/test-plans.md +445 -0
- package/docs/releases/RELEASE.V0.3.0.md +22 -0
- package/docs/releases/RELEASE.V0.4.0.md +154 -0
- package/docs/releases/RELEASE.V0.5.0.md +252 -0
- package/docs/releases/RELEASE_v0.5.6.md +145 -0
- package/docs/releases/RELEASE_v0.6.1.md +303 -0
- package/docs/releases/RELEASE_v0.6.7.md +292 -0
- package/docs/releases/RELEASE_v0.7.0.md +332 -0
- package/docs/releases/RELEASE_v0.8.0.md +521 -0
- package/docs/sampledb/titanic.sql +1379 -0
- package/docs/superpowers/plans/2026-03-25-seed-connections.md +1362 -0
- package/docs/superpowers/specs/2026-03-25-seed-connections-design.md +590 -0
- package/e2e/admin-dashboard.spec.ts +64 -0
- package/e2e/connection-management.spec.ts +58 -0
- package/e2e/export.spec.ts +34 -0
- package/e2e/login.spec.ts +85 -0
- package/e2e/query-execution.spec.ts +35 -0
- package/e2e/tab-management.spec.ts +64 -0
- package/eslint.config.mjs +28 -0
- package/fly.toml +43 -0
- package/next.config.ts +32 -0
- package/package.json +130 -0
- package/playwright.config.ts +34 -0
- package/postcss.config.mjs +7 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/logo.svg +32 -0
- package/public/next.svg +1 -0
- package/public/screenshots/code-generator.png +0 -0
- package/public/screenshots/connection-modal.png +0 -0
- package/public/screenshots/data-profiler.png +0 -0
- package/public/screenshots/erd-diagram.png +0 -0
- package/public/screenshots/hero-editor.png +0 -0
- package/public/screenshots/nl2sql.png +0 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/render.yaml +58 -0
- package/scripts/merge-lcov.mjs +239 -0
- package/sonar-project.properties +16 -0
- package/src/app/admin/error.tsx +46 -0
- package/src/app/admin/page.tsx +10 -0
- package/src/app/api/admin/audit/route.ts +52 -0
- package/src/app/api/admin/fleet-health/route.ts +81 -0
- package/src/app/api/ai/autopilot/route.ts +105 -0
- package/src/app/api/ai/chat/route.ts +132 -0
- package/src/app/api/ai/describe-schema/route.ts +52 -0
- package/src/app/api/ai/explain/route.ts +86 -0
- package/src/app/api/ai/impact/route.ts +97 -0
- package/src/app/api/ai/index-advisor/route.ts +98 -0
- package/src/app/api/ai/nl2sql/route.ts +87 -0
- package/src/app/api/ai/query-safety/route.ts +87 -0
- package/src/app/api/auth/login/route.ts +62 -0
- package/src/app/api/auth/logout/route.ts +25 -0
- package/src/app/api/auth/me/route.ts +10 -0
- package/src/app/api/auth/oidc/callback/route.ts +82 -0
- package/src/app/api/auth/oidc/login/route.ts +43 -0
- package/src/app/api/connections/managed/route.ts +35 -0
- package/src/app/api/db/cancel/route.ts +42 -0
- package/src/app/api/db/disconnect/route.ts +28 -0
- package/src/app/api/db/health/route.ts +49 -0
- package/src/app/api/db/maintenance/route.ts +72 -0
- package/src/app/api/db/monitoring/route.ts +62 -0
- package/src/app/api/db/multi-query/route.ts +116 -0
- package/src/app/api/db/pool-stats/route.ts +37 -0
- package/src/app/api/db/profile/route.ts +144 -0
- package/src/app/api/db/provider-meta/route.ts +49 -0
- package/src/app/api/db/query/route.ts +50 -0
- package/src/app/api/db/schema/route.ts +47 -0
- package/src/app/api/db/schema-snapshot/route.ts +42 -0
- package/src/app/api/db/test-connection/route.ts +55 -0
- package/src/app/api/db/transaction/route.ts +111 -0
- package/src/app/api/storage/[collection]/route.ts +67 -0
- package/src/app/api/storage/config/route.ts +17 -0
- package/src/app/api/storage/migrate/route.ts +45 -0
- package/src/app/api/storage/route.ts +32 -0
- package/src/app/error.tsx +49 -0
- package/src/app/global-error.tsx +55 -0
- package/src/app/globals.css +146 -0
- package/src/app/icon.svg +42 -0
- package/src/app/layout.tsx +34 -0
- package/src/app/login/login-form.tsx +301 -0
- package/src/app/login/page.tsx +11 -0
- package/src/app/monitoring/page.tsx +8 -0
- package/src/app/not-found.tsx +29 -0
- package/src/app/page.tsx +5 -0
- package/src/components/AIAutopilotPanel.tsx +238 -0
- package/src/components/CodeGenerator.tsx +271 -0
- package/src/components/CommandPalette.tsx +227 -0
- package/src/components/ConnectionModal.tsx +759 -0
- package/src/components/CreateTableModal.tsx +281 -0
- package/src/components/DataCharts.tsx +962 -0
- package/src/components/DataImportModal.tsx +582 -0
- package/src/components/DataProfiler.tsx +335 -0
- package/src/components/DatabaseDocs.tsx +251 -0
- package/src/components/MaskingSettings.tsx +414 -0
- package/src/components/MobileNav.tsx +50 -0
- package/src/components/NL2SQLPanel.tsx +281 -0
- package/src/components/PivotTable.tsx +257 -0
- package/src/components/QueryEditor.tsx +760 -0
- package/src/components/QueryHistory.tsx +344 -0
- package/src/components/QuerySafetyDialog.tsx +290 -0
- package/src/components/ResultsGrid.tsx +644 -0
- package/src/components/SaveQueryModal.tsx +104 -0
- package/src/components/SavedQueries.tsx +128 -0
- package/src/components/SchemaDiagram.tsx +473 -0
- package/src/components/SchemaDiff.tsx +473 -0
- package/src/components/SnapshotTimeline.tsx +116 -0
- package/src/components/Studio.tsx +639 -0
- package/src/components/TestDataGenerator.tsx +261 -0
- package/src/components/VisualExplain.tsx +820 -0
- package/src/components/admin/AdminDashboard.tsx +163 -0
- package/src/components/admin/tabs/AuditTab.tsx +531 -0
- package/src/components/admin/tabs/MonitoringEmbed.tsx +11 -0
- package/src/components/admin/tabs/OperationsTab.tsx +646 -0
- package/src/components/admin/tabs/OverviewTab.tsx +1328 -0
- package/src/components/admin/tabs/SecurityTab.tsx +284 -0
- package/src/components/community-section.tsx +92 -0
- package/src/components/icons/db-icons.tsx +84 -0
- package/src/components/libredb-logo.tsx +61 -0
- package/src/components/monitoring/MonitoringDashboard.tsx +345 -0
- package/src/components/monitoring/tabs/MetricChart.tsx +82 -0
- package/src/components/monitoring/tabs/OverviewTab.tsx +263 -0
- package/src/components/monitoring/tabs/PerformanceTab.tsx +254 -0
- package/src/components/monitoring/tabs/PoolTab.tsx +174 -0
- package/src/components/monitoring/tabs/QueriesTab.tsx +287 -0
- package/src/components/monitoring/tabs/SessionsTab.tsx +316 -0
- package/src/components/monitoring/tabs/StorageTab.tsx +335 -0
- package/src/components/monitoring/tabs/TablesTab.tsx +300 -0
- package/src/components/results-grid/ResultCard.tsx +111 -0
- package/src/components/results-grid/RowDetailSheet.tsx +178 -0
- package/src/components/results-grid/StatsBar.tsx +201 -0
- package/src/components/results-grid/index.ts +1 -0
- package/src/components/results-grid/utils.ts +23 -0
- package/src/components/schema-explorer/ColumnList.tsx +53 -0
- package/src/components/schema-explorer/SchemaExplorer.tsx +182 -0
- package/src/components/schema-explorer/TableItem.tsx +210 -0
- package/src/components/schema-explorer/index.ts +1 -0
- package/src/components/sidebar/ConnectionItem.tsx +105 -0
- package/src/components/sidebar/ConnectionsList.tsx +62 -0
- package/src/components/sidebar/Sidebar.tsx +130 -0
- package/src/components/sidebar/index.ts +2 -0
- package/src/components/studio/BottomPanel.tsx +286 -0
- package/src/components/studio/QueryToolbar.tsx +180 -0
- package/src/components/studio/StudioDesktopHeader.tsx +114 -0
- package/src/components/studio/StudioMobileHeader.tsx +340 -0
- package/src/components/studio/StudioTabBar.tsx +82 -0
- package/src/components/studio/index.ts +5 -0
- package/src/components/ui/accordion.tsx +66 -0
- package/src/components/ui/alert-dialog.tsx +157 -0
- package/src/components/ui/alert.tsx +66 -0
- package/src/components/ui/aspect-ratio.tsx +11 -0
- package/src/components/ui/avatar.tsx +53 -0
- package/src/components/ui/badge.tsx +46 -0
- package/src/components/ui/breadcrumb.tsx +109 -0
- package/src/components/ui/button-group.tsx +83 -0
- package/src/components/ui/button.tsx +60 -0
- package/src/components/ui/calendar.tsx +216 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/carousel.tsx +241 -0
- package/src/components/ui/chart.tsx +357 -0
- package/src/components/ui/checkbox.tsx +32 -0
- package/src/components/ui/collapsible.tsx +33 -0
- package/src/components/ui/command.tsx +184 -0
- package/src/components/ui/context-menu.tsx +252 -0
- package/src/components/ui/dialog.tsx +143 -0
- package/src/components/ui/drawer.tsx +135 -0
- package/src/components/ui/dropdown-menu.tsx +257 -0
- package/src/components/ui/empty.tsx +104 -0
- package/src/components/ui/field.tsx +248 -0
- package/src/components/ui/form.tsx +167 -0
- package/src/components/ui/hover-card.tsx +44 -0
- package/src/components/ui/input-group.tsx +170 -0
- package/src/components/ui/input-otp.tsx +77 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/item.tsx +193 -0
- package/src/components/ui/kbd.tsx +28 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/menubar.tsx +276 -0
- package/src/components/ui/navigation-menu.tsx +168 -0
- package/src/components/ui/pagination.tsx +127 -0
- package/src/components/ui/popover.tsx +48 -0
- package/src/components/ui/progress.tsx +31 -0
- package/src/components/ui/radio-group.tsx +45 -0
- package/src/components/ui/resizable.tsx +56 -0
- package/src/components/ui/scroll-area.tsx +58 -0
- package/src/components/ui/select.tsx +187 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +139 -0
- package/src/components/ui/sidebar.tsx +726 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/slider.tsx +63 -0
- package/src/components/ui/sonner.tsx +40 -0
- package/src/components/ui/spinner.tsx +16 -0
- package/src/components/ui/switch.tsx +31 -0
- package/src/components/ui/table.tsx +116 -0
- package/src/components/ui/tabs.tsx +66 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/toggle-group.tsx +83 -0
- package/src/components/ui/toggle.tsx +47 -0
- package/src/components/ui/tooltip.tsx +61 -0
- package/src/exports/components.ts +15 -0
- package/src/exports/index.ts +4 -0
- package/src/exports/providers.ts +4 -0
- package/src/exports/types.ts +26 -0
- package/src/hooks/use-ai-chat.ts +182 -0
- package/src/hooks/use-all-connections.ts +66 -0
- package/src/hooks/use-api-call.ts +71 -0
- package/src/hooks/use-auth.ts +51 -0
- package/src/hooks/use-connection-form.ts +349 -0
- package/src/hooks/use-connection-manager.ts +169 -0
- package/src/hooks/use-connection-payload.ts +15 -0
- package/src/hooks/use-inline-editing.ts +109 -0
- package/src/hooks/use-mobile.ts +20 -0
- package/src/hooks/use-monitoring-data.ts +270 -0
- package/src/hooks/use-provider-metadata.ts +62 -0
- package/src/hooks/use-query-execution.ts +478 -0
- package/src/hooks/use-storage-sync.ts +259 -0
- package/src/hooks/use-tab-manager.ts +231 -0
- package/src/hooks/use-toast.ts +20 -0
- package/src/hooks/use-transaction-control.ts +64 -0
- package/src/lib/api/error-codes.ts +30 -0
- package/src/lib/api/errors.ts +236 -0
- package/src/lib/api/with-error-handler.ts +41 -0
- package/src/lib/audit.ts +105 -0
- package/src/lib/auth.ts +87 -0
- package/src/lib/connection-string-parser.ts +172 -0
- package/src/lib/data-masking.ts +385 -0
- package/src/lib/db/base-provider.ts +325 -0
- package/src/lib/db/errors.ts +317 -0
- package/src/lib/db/factory.ts +324 -0
- package/src/lib/db/index.ts +123 -0
- package/src/lib/db/providers/document/index.ts +6 -0
- package/src/lib/db/providers/document/mongodb.ts +992 -0
- package/src/lib/db/providers/keyvalue/redis.ts +554 -0
- package/src/lib/db/providers/sql/index.ts +11 -0
- package/src/lib/db/providers/sql/mssql.ts +1065 -0
- package/src/lib/db/providers/sql/mysql.ts +978 -0
- package/src/lib/db/providers/sql/oracle.ts +1044 -0
- package/src/lib/db/providers/sql/postgres.ts +1179 -0
- package/src/lib/db/providers/sql/sql-base.ts +174 -0
- package/src/lib/db/providers/sql/sqlite.ts +721 -0
- package/src/lib/db/types.ts +437 -0
- package/src/lib/db/utils/pool-manager.ts +287 -0
- package/src/lib/db/utils/query-limiter.ts +239 -0
- package/src/lib/db-ui-config.ts +86 -0
- package/src/lib/editor/mongodb-completions.ts +172 -0
- package/src/lib/editor/sql-completions.ts +280 -0
- package/src/lib/llm/base-provider.ts +117 -0
- package/src/lib/llm/factory.ts +102 -0
- package/src/lib/llm/index.ts +90 -0
- package/src/lib/llm/providers/custom.ts +181 -0
- package/src/lib/llm/providers/gemini.ts +126 -0
- package/src/lib/llm/providers/ollama.ts +154 -0
- package/src/lib/llm/providers/openai.ts +146 -0
- package/src/lib/llm/types.ts +173 -0
- package/src/lib/llm/utils/config.ts +187 -0
- package/src/lib/llm/utils/retry.ts +119 -0
- package/src/lib/llm/utils/streaming.ts +202 -0
- package/src/lib/logger.ts +127 -0
- package/src/lib/monitoring-thresholds.ts +44 -0
- package/src/lib/oidc.ts +262 -0
- package/src/lib/query-generators.ts +61 -0
- package/src/lib/schema-diff/diff-engine.ts +273 -0
- package/src/lib/schema-diff/migration-generator.ts +208 -0
- package/src/lib/schema-diff/types.ts +55 -0
- package/src/lib/seed/config-loader.ts +79 -0
- package/src/lib/seed/connection-filter.ts +49 -0
- package/src/lib/seed/credential-resolver.ts +62 -0
- package/src/lib/seed/index.ts +40 -0
- package/src/lib/seed/resolve-connection.ts +57 -0
- package/src/lib/seed/types.ts +69 -0
- package/src/lib/sql/alias-extractor.ts +267 -0
- package/src/lib/sql/index.ts +8 -0
- package/src/lib/sql/statement-splitter.ts +167 -0
- package/src/lib/sql/types.ts +40 -0
- package/src/lib/ssh/tunnel.ts +142 -0
- package/src/lib/storage/factory.ts +84 -0
- package/src/lib/storage/index.ts +14 -0
- package/src/lib/storage/local-storage.ts +99 -0
- package/src/lib/storage/providers/postgres.ts +225 -0
- package/src/lib/storage/providers/sqlite.ts +153 -0
- package/src/lib/storage/storage-facade.ts +272 -0
- package/src/lib/storage/types.ts +75 -0
- package/src/lib/time-series-buffer.ts +58 -0
- package/src/lib/types.ts +173 -0
- package/src/lib/utils.ts +6 -0
- package/src/proxy.ts +104 -0
- package/src/types/db-drivers.d.ts +23 -0
- package/src/types/html2canvas.d.ts +9 -0
- package/tests/api/admin/audit.test.ts +178 -0
- package/tests/api/admin/fleet-health.test.ts +183 -0
- package/tests/api/ai/autopilot.test.ts +174 -0
- package/tests/api/ai/chat.test.ts +250 -0
- package/tests/api/ai/describe-schema.test.ts +266 -0
- package/tests/api/ai/explain.test.ts +199 -0
- package/tests/api/ai/impact.test.ts +168 -0
- package/tests/api/ai/index-advisor.test.ts +171 -0
- package/tests/api/ai/nl2sql.test.ts +202 -0
- package/tests/api/ai/query-safety.test.ts +196 -0
- package/tests/api/auth/login.test.ts +170 -0
- package/tests/api/auth/logout.test.ts +140 -0
- package/tests/api/auth/me.test.ts +73 -0
- package/tests/api/auth/oidc-callback.test.ts +215 -0
- package/tests/api/auth/oidc-login.test.ts +127 -0
- package/tests/api/db/cancel.test.ts +198 -0
- package/tests/api/db/disconnect.test.ts +124 -0
- package/tests/api/db/health.test.ts +222 -0
- package/tests/api/db/maintenance.test.ts +263 -0
- package/tests/api/db/monitoring.test.ts +221 -0
- package/tests/api/db/multi-query.test.ts +316 -0
- package/tests/api/db/pool-stats.test.ts +135 -0
- package/tests/api/db/profile.test.ts +330 -0
- package/tests/api/db/provider-meta.test.ts +193 -0
- package/tests/api/db/query.test.ts +314 -0
- package/tests/api/db/schema-snapshot.test.ts +170 -0
- package/tests/api/db/schema.test.ts +191 -0
- package/tests/api/db/test-connection.test.ts +185 -0
- package/tests/api/db/transaction.test.ts +314 -0
- package/tests/api/proxy.test.ts +191 -0
- package/tests/api/seed/managed-route.test.ts +113 -0
- package/tests/api/storage/config.test.ts +42 -0
- package/tests/api/storage/storage-routes.test.ts +309 -0
- package/tests/components/AIAutopilotPanel.test.tsx +756 -0
- package/tests/components/AdminPage.test.tsx +33 -0
- package/tests/components/CodeGenerator.test.tsx +182 -0
- package/tests/components/CommandPalette.test.tsx +428 -0
- package/tests/components/CommunitySection.test.tsx +91 -0
- package/tests/components/ConnectionModal.mobile.test.tsx +284 -0
- package/tests/components/ConnectionModal.test.tsx +570 -0
- package/tests/components/CreateTableModal.test.tsx +383 -0
- package/tests/components/DataCharts.test.tsx +739 -0
- package/tests/components/DataImportModal.test.tsx +751 -0
- package/tests/components/DataProfiler.test.tsx +589 -0
- package/tests/components/DatabaseDocs.test.tsx +353 -0
- package/tests/components/LoginPage.test.tsx +163 -0
- package/tests/components/LoginPageOIDC.test.tsx +92 -0
- package/tests/components/MaskingSettings.test.tsx +498 -0
- package/tests/components/MobileNav.test.tsx +30 -0
- package/tests/components/MonitoringPage.test.tsx +32 -0
- package/tests/components/NL2SQLPanel.test.tsx +621 -0
- package/tests/components/Page.test.tsx +33 -0
- package/tests/components/PivotTable.test.tsx +350 -0
- package/tests/components/QueryEditor.test.tsx +1730 -0
- package/tests/components/QueryHistory.test.tsx +572 -0
- package/tests/components/QuerySafetyDialog.test.tsx +586 -0
- package/tests/components/ResultsGrid.test.tsx +804 -0
- package/tests/components/RootLayout.test.tsx +83 -0
- package/tests/components/SaveQueryModal.test.tsx +25 -0
- package/tests/components/SavedQueries.test.tsx +43 -0
- package/tests/components/SchemaDiagram.test.tsx +1034 -0
- package/tests/components/SchemaDiff.test.tsx +906 -0
- package/tests/components/SnapshotTimeline.test.tsx +174 -0
- package/tests/components/Studio.test.tsx +1030 -0
- package/tests/components/TestDataGenerator.test.tsx +291 -0
- package/tests/components/VisualExplain.test.tsx +704 -0
- package/tests/components/admin/AdminDashboard.test.tsx +205 -0
- package/tests/components/admin/AuditTab.test.tsx +220 -0
- package/tests/components/admin/MonitoringEmbed.test.tsx +58 -0
- package/tests/components/admin/OperationsTab.test.tsx +975 -0
- package/tests/components/admin/OverviewTab.test.tsx +254 -0
- package/tests/components/admin/SecurityTab.test.tsx +467 -0
- package/tests/components/monitoring/MetricChart.test.tsx +111 -0
- package/tests/components/monitoring/MonitoringDashboard.test.tsx +259 -0
- package/tests/components/monitoring/OverviewTab.test.tsx +78 -0
- package/tests/components/monitoring/PerformanceTab.test.tsx +87 -0
- package/tests/components/monitoring/PoolTab.test.tsx +42 -0
- package/tests/components/monitoring/QueriesTab.test.tsx +80 -0
- package/tests/components/monitoring/SessionsTab.test.tsx +154 -0
- package/tests/components/monitoring/StorageTab.test.tsx +127 -0
- package/tests/components/monitoring/TablesTab.test.tsx +153 -0
- package/tests/components/results-grid/ResultCard.test.tsx +105 -0
- package/tests/components/results-grid/RowDetailSheet.test.tsx +308 -0
- package/tests/components/results-grid/StatsBar.test.tsx +162 -0
- package/tests/components/schema-explorer/ColumnList.test.tsx +151 -0
- package/tests/components/schema-explorer/SchemaExplorer.test.tsx +461 -0
- package/tests/components/schema-explorer/TableItem.test.tsx +415 -0
- package/tests/components/sidebar/ConnectionItem.test.tsx +201 -0
- package/tests/components/sidebar/ConnectionsList.test.tsx +176 -0
- package/tests/components/sidebar/Sidebar.test.tsx +187 -0
- package/tests/components/studio/BottomPanel.test.tsx +383 -0
- package/tests/components/studio/QueryToolbar.test.tsx +321 -0
- package/tests/components/studio/StudioDesktopHeader.test.tsx +377 -0
- package/tests/components/studio/StudioMobileHeader.test.tsx +198 -0
- package/tests/components/studio/StudioTabBar.test.tsx +331 -0
- package/tests/fixtures/connections.ts +96 -0
- package/tests/fixtures/masking-configs.ts +86 -0
- package/tests/fixtures/query-results.ts +71 -0
- package/tests/fixtures/schemas.ts +64 -0
- package/tests/fixtures/seed-connections/invalid-config.yaml +7 -0
- package/tests/fixtures/seed-connections/minimal-config.yaml +8 -0
- package/tests/fixtures/seed-connections/mixed-credentials.yaml +23 -0
- package/tests/fixtures/seed-connections/multi-role-config.yaml +30 -0
- package/tests/fixtures/seed-connections/valid-config.json +15 -0
- package/tests/fixtures/seed-connections/valid-config.yaml +51 -0
- package/tests/helpers/mock-fetch.ts +59 -0
- package/tests/helpers/mock-monaco.ts +112 -0
- package/tests/helpers/mock-navigation.ts +28 -0
- package/tests/helpers/mock-next.ts +80 -0
- package/tests/helpers/mock-provider.ts +133 -0
- package/tests/helpers/mock-sonner.ts +29 -0
- package/tests/helpers/render-with-providers.tsx +19 -0
- package/tests/hooks/use-ai-chat.test.ts +600 -0
- package/tests/hooks/use-auth.test.ts +371 -0
- package/tests/hooks/use-connection-form.test.ts +743 -0
- package/tests/hooks/use-connection-manager.test.ts +466 -0
- package/tests/hooks/use-inline-editing.test.ts +321 -0
- package/tests/hooks/use-mobile.test.ts +177 -0
- package/tests/hooks/use-monitoring-data.test.ts +819 -0
- package/tests/hooks/use-provider-metadata.test.ts +228 -0
- package/tests/hooks/use-query-execution.test.ts +1212 -0
- package/tests/hooks/use-tab-manager.test.ts +756 -0
- package/tests/hooks/use-toast.test.ts +74 -0
- package/tests/hooks/use-transaction-control.test.ts +211 -0
- package/tests/integration/db/mongodb-provider.test.ts +698 -0
- package/tests/integration/db/mssql-provider.test.ts +840 -0
- package/tests/integration/db/mysql-provider.test.ts +872 -0
- package/tests/integration/db/oracle-provider.test.ts +843 -0
- package/tests/integration/db/postgres-provider.test.ts +1382 -0
- package/tests/integration/db/redis-provider.test.ts +526 -0
- package/tests/integration/db/sqlite-provider.test.ts +480 -0
- package/tests/integration/seed/seed-pipeline.test.ts +102 -0
- package/tests/isolated/factory-singleton.test.ts +150 -0
- package/tests/isolated/use-storage-sync.test.ts +389 -0
- package/tests/run-components.sh +196 -0
- package/tests/setup-dom.ts +58 -0
- package/tests/setup.ts +40 -0
- package/tests/unit/api-errors.test.ts +210 -0
- package/tests/unit/code-generator-functions.test.ts +271 -0
- package/tests/unit/components/column-list.test.tsx +190 -0
- package/tests/unit/components/data-import-modal.test.tsx +441 -0
- package/tests/unit/components/studio-mobile-header.test.tsx +327 -0
- package/tests/unit/data-charts-functions.test.ts +496 -0
- package/tests/unit/data-import-functions.test.ts +320 -0
- package/tests/unit/data-import-utils.test.ts +125 -0
- package/tests/unit/db/base-provider.test.ts +517 -0
- package/tests/unit/db/errors.test.ts +403 -0
- package/tests/unit/db/factory.test.ts +436 -0
- package/tests/unit/db/pool-manager.test.ts +440 -0
- package/tests/unit/db/query-limiter.test.ts +387 -0
- package/tests/unit/db/sql-base.test.ts +438 -0
- package/tests/unit/lib/api/error-codes.test.ts +39 -0
- package/tests/unit/lib/audit.test.ts +326 -0
- package/tests/unit/lib/auth.test.ts +146 -0
- package/tests/unit/lib/connection-string-parser.test.ts +424 -0
- package/tests/unit/lib/data-masking.test.ts +583 -0
- package/tests/unit/lib/db-icons.test.tsx +41 -0
- package/tests/unit/lib/monitoring-thresholds.test.ts +133 -0
- package/tests/unit/lib/oidc.test.ts +509 -0
- package/tests/unit/lib/query-generators.test.ts +127 -0
- package/tests/unit/lib/storage/factory.test.ts +71 -0
- package/tests/unit/lib/storage/local-storage.test.ts +114 -0
- package/tests/unit/lib/storage/providers/postgres.test.ts +312 -0
- package/tests/unit/lib/storage/providers/sqlite.test.ts +232 -0
- package/tests/unit/lib/storage/storage-facade-extended.test.ts +331 -0
- package/tests/unit/lib/storage/storage-facade.test.ts +184 -0
- package/tests/unit/lib/storage.test.ts +317 -0
- package/tests/unit/lib/time-series-buffer.test.ts +212 -0
- package/tests/unit/lib/utils.test.ts +24 -0
- package/tests/unit/llm/base-provider.test.ts +238 -0
- package/tests/unit/llm/config.test.ts +262 -0
- package/tests/unit/llm/custom-provider.test.ts +281 -0
- package/tests/unit/llm/gemini-provider.test.ts +248 -0
- package/tests/unit/llm/llm-factory.test.ts +155 -0
- package/tests/unit/llm/ollama-provider.test.ts +288 -0
- package/tests/unit/llm/openai-provider.test.ts +324 -0
- package/tests/unit/llm/retry.test.ts +180 -0
- package/tests/unit/llm/streaming.test.ts +355 -0
- package/tests/unit/logger.test.ts +198 -0
- package/tests/unit/mongodb-completions.test.ts +516 -0
- package/tests/unit/pivot-table-functions.test.ts +76 -0
- package/tests/unit/query-cancelled-error.test.ts +81 -0
- package/tests/unit/schema-diff/diff-engine.test.ts +367 -0
- package/tests/unit/schema-diff/migration-generator.test.ts +513 -0
- package/tests/unit/seed/config-loader.test.ts +73 -0
- package/tests/unit/seed/connection-filter.test.ts +91 -0
- package/tests/unit/seed/credential-resolver.test.ts +85 -0
- package/tests/unit/seed/index.test.ts +72 -0
- package/tests/unit/seed/resolve-connection.test.ts +74 -0
- package/tests/unit/seed/types.test.ts +129 -0
- package/tests/unit/sql/alias-extractor.test.ts +444 -0
- package/tests/unit/sql/statement-splitter.test.ts +348 -0
- package/tests/unit/sql-completions.test.ts +463 -0
- package/tests/unit/ssh-tunnel.test.ts +465 -0
- package/tsconfig.json +42 -0
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
-- Sample data for LibreDB Studio testing
|
|
2
|
+
-- This runs on libredb_dev database
|
|
3
|
+
|
|
4
|
+
\c libredb_dev
|
|
5
|
+
|
|
6
|
+
-- ============================================
|
|
7
|
+
-- SCHEMA SETUP
|
|
8
|
+
-- ============================================
|
|
9
|
+
CREATE SCHEMA IF NOT EXISTS app;
|
|
10
|
+
SET search_path TO app, public;
|
|
11
|
+
|
|
12
|
+
-- ============================================
|
|
13
|
+
-- TABLES
|
|
14
|
+
-- ============================================
|
|
15
|
+
|
|
16
|
+
-- Categories table
|
|
17
|
+
CREATE TABLE IF NOT EXISTS app.categories (
|
|
18
|
+
id SERIAL PRIMARY KEY,
|
|
19
|
+
name VARCHAR(100) NOT NULL,
|
|
20
|
+
slug VARCHAR(100) UNIQUE NOT NULL,
|
|
21
|
+
description TEXT,
|
|
22
|
+
parent_id INTEGER REFERENCES app.categories(id),
|
|
23
|
+
is_active BOOLEAN DEFAULT true,
|
|
24
|
+
sort_order INTEGER DEFAULT 0,
|
|
25
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE INDEX idx_categories_parent ON app.categories(parent_id);
|
|
29
|
+
CREATE INDEX idx_categories_slug ON app.categories(slug);
|
|
30
|
+
|
|
31
|
+
-- Customers table
|
|
32
|
+
CREATE TABLE IF NOT EXISTS app.customers (
|
|
33
|
+
id SERIAL PRIMARY KEY,
|
|
34
|
+
email VARCHAR(255) UNIQUE NOT NULL,
|
|
35
|
+
first_name VARCHAR(100) NOT NULL,
|
|
36
|
+
last_name VARCHAR(100) NOT NULL,
|
|
37
|
+
phone VARCHAR(20),
|
|
38
|
+
date_of_birth DATE,
|
|
39
|
+
gender VARCHAR(10),
|
|
40
|
+
avatar_url VARCHAR(500),
|
|
41
|
+
loyalty_points INTEGER DEFAULT 0,
|
|
42
|
+
tier VARCHAR(20) DEFAULT 'bronze',
|
|
43
|
+
is_verified BOOLEAN DEFAULT false,
|
|
44
|
+
notes TEXT,
|
|
45
|
+
metadata JSONB DEFAULT '{}',
|
|
46
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
47
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
CREATE INDEX idx_customers_email ON app.customers(email);
|
|
51
|
+
CREATE INDEX idx_customers_tier ON app.customers(tier);
|
|
52
|
+
CREATE INDEX idx_customers_created_at ON app.customers(created_at);
|
|
53
|
+
|
|
54
|
+
-- Customer addresses
|
|
55
|
+
CREATE TABLE IF NOT EXISTS app.customer_addresses (
|
|
56
|
+
id SERIAL PRIMARY KEY,
|
|
57
|
+
customer_id INTEGER REFERENCES app.customers(id) ON DELETE CASCADE,
|
|
58
|
+
type VARCHAR(20) DEFAULT 'shipping',
|
|
59
|
+
is_default BOOLEAN DEFAULT false,
|
|
60
|
+
full_name VARCHAR(200),
|
|
61
|
+
street_address VARCHAR(500) NOT NULL,
|
|
62
|
+
apartment VARCHAR(100),
|
|
63
|
+
city VARCHAR(100) NOT NULL,
|
|
64
|
+
state VARCHAR(100),
|
|
65
|
+
postal_code VARCHAR(20) NOT NULL,
|
|
66
|
+
country VARCHAR(100) DEFAULT 'Turkey',
|
|
67
|
+
phone VARCHAR(20),
|
|
68
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
CREATE INDEX idx_customer_addresses_customer ON app.customer_addresses(customer_id);
|
|
72
|
+
|
|
73
|
+
-- Products table
|
|
74
|
+
CREATE TABLE IF NOT EXISTS app.products (
|
|
75
|
+
id SERIAL PRIMARY KEY,
|
|
76
|
+
sku VARCHAR(50) UNIQUE NOT NULL,
|
|
77
|
+
name VARCHAR(255) NOT NULL,
|
|
78
|
+
slug VARCHAR(255) UNIQUE NOT NULL,
|
|
79
|
+
description TEXT,
|
|
80
|
+
short_description VARCHAR(500),
|
|
81
|
+
price DECIMAL(10, 2) NOT NULL,
|
|
82
|
+
compare_at_price DECIMAL(10, 2),
|
|
83
|
+
cost_price DECIMAL(10, 2),
|
|
84
|
+
stock_quantity INTEGER DEFAULT 0,
|
|
85
|
+
low_stock_threshold INTEGER DEFAULT 10,
|
|
86
|
+
category_id INTEGER REFERENCES app.categories(id),
|
|
87
|
+
brand VARCHAR(100),
|
|
88
|
+
weight_kg DECIMAL(5, 2),
|
|
89
|
+
dimensions JSONB,
|
|
90
|
+
images JSONB DEFAULT '[]',
|
|
91
|
+
tags TEXT[],
|
|
92
|
+
is_active BOOLEAN DEFAULT true,
|
|
93
|
+
is_featured BOOLEAN DEFAULT false,
|
|
94
|
+
rating_avg DECIMAL(2, 1) DEFAULT 0,
|
|
95
|
+
rating_count INTEGER DEFAULT 0,
|
|
96
|
+
view_count INTEGER DEFAULT 0,
|
|
97
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
98
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
CREATE INDEX idx_products_sku ON app.products(sku);
|
|
102
|
+
CREATE INDEX idx_products_slug ON app.products(slug);
|
|
103
|
+
CREATE INDEX idx_products_category ON app.products(category_id);
|
|
104
|
+
CREATE INDEX idx_products_price ON app.products(price);
|
|
105
|
+
CREATE INDEX idx_products_brand ON app.products(brand);
|
|
106
|
+
CREATE INDEX idx_products_tags ON app.products USING GIN(tags);
|
|
107
|
+
CREATE INDEX idx_products_is_active ON app.products(is_active) WHERE is_active = true;
|
|
108
|
+
|
|
109
|
+
-- Orders table
|
|
110
|
+
CREATE TABLE IF NOT EXISTS app.orders (
|
|
111
|
+
id SERIAL PRIMARY KEY,
|
|
112
|
+
order_number VARCHAR(50) UNIQUE NOT NULL,
|
|
113
|
+
customer_id INTEGER REFERENCES app.customers(id),
|
|
114
|
+
status VARCHAR(30) DEFAULT 'pending',
|
|
115
|
+
payment_status VARCHAR(30) DEFAULT 'pending',
|
|
116
|
+
payment_method VARCHAR(50),
|
|
117
|
+
subtotal DECIMAL(12, 2) NOT NULL,
|
|
118
|
+
tax_amount DECIMAL(12, 2) DEFAULT 0,
|
|
119
|
+
shipping_amount DECIMAL(12, 2) DEFAULT 0,
|
|
120
|
+
discount_amount DECIMAL(12, 2) DEFAULT 0,
|
|
121
|
+
total_amount DECIMAL(12, 2) NOT NULL,
|
|
122
|
+
currency VARCHAR(3) DEFAULT 'TRY',
|
|
123
|
+
shipping_address JSONB,
|
|
124
|
+
billing_address JSONB,
|
|
125
|
+
notes TEXT,
|
|
126
|
+
internal_notes TEXT,
|
|
127
|
+
ip_address INET,
|
|
128
|
+
user_agent TEXT,
|
|
129
|
+
shipped_at TIMESTAMP WITH TIME ZONE,
|
|
130
|
+
delivered_at TIMESTAMP WITH TIME ZONE,
|
|
131
|
+
cancelled_at TIMESTAMP WITH TIME ZONE,
|
|
132
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
133
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
CREATE INDEX idx_orders_customer ON app.orders(customer_id);
|
|
137
|
+
CREATE INDEX idx_orders_status ON app.orders(status);
|
|
138
|
+
CREATE INDEX idx_orders_payment_status ON app.orders(payment_status);
|
|
139
|
+
CREATE INDEX idx_orders_created_at ON app.orders(created_at);
|
|
140
|
+
CREATE INDEX idx_orders_order_number ON app.orders(order_number);
|
|
141
|
+
|
|
142
|
+
-- Order items table
|
|
143
|
+
CREATE TABLE IF NOT EXISTS app.order_items (
|
|
144
|
+
id SERIAL PRIMARY KEY,
|
|
145
|
+
order_id INTEGER REFERENCES app.orders(id) ON DELETE CASCADE,
|
|
146
|
+
product_id INTEGER REFERENCES app.products(id),
|
|
147
|
+
product_name VARCHAR(255) NOT NULL,
|
|
148
|
+
product_sku VARCHAR(50) NOT NULL,
|
|
149
|
+
quantity INTEGER NOT NULL,
|
|
150
|
+
unit_price DECIMAL(10, 2) NOT NULL,
|
|
151
|
+
discount_percent DECIMAL(5, 2) DEFAULT 0,
|
|
152
|
+
total_price DECIMAL(12, 2) NOT NULL,
|
|
153
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
CREATE INDEX idx_order_items_order ON app.order_items(order_id);
|
|
157
|
+
CREATE INDEX idx_order_items_product ON app.order_items(product_id);
|
|
158
|
+
|
|
159
|
+
-- Product reviews
|
|
160
|
+
CREATE TABLE IF NOT EXISTS app.product_reviews (
|
|
161
|
+
id SERIAL PRIMARY KEY,
|
|
162
|
+
product_id INTEGER REFERENCES app.products(id) ON DELETE CASCADE,
|
|
163
|
+
customer_id INTEGER REFERENCES app.customers(id),
|
|
164
|
+
rating INTEGER CHECK (rating >= 1 AND rating <= 5),
|
|
165
|
+
title VARCHAR(200),
|
|
166
|
+
content TEXT,
|
|
167
|
+
is_verified_purchase BOOLEAN DEFAULT false,
|
|
168
|
+
is_approved BOOLEAN DEFAULT false,
|
|
169
|
+
helpful_count INTEGER DEFAULT 0,
|
|
170
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
CREATE INDEX idx_reviews_product ON app.product_reviews(product_id);
|
|
174
|
+
CREATE INDEX idx_reviews_customer ON app.product_reviews(customer_id);
|
|
175
|
+
CREATE INDEX idx_reviews_rating ON app.product_reviews(rating);
|
|
176
|
+
|
|
177
|
+
-- Inventory movements
|
|
178
|
+
CREATE TABLE IF NOT EXISTS app.inventory_movements (
|
|
179
|
+
id BIGSERIAL PRIMARY KEY,
|
|
180
|
+
product_id INTEGER REFERENCES app.products(id),
|
|
181
|
+
movement_type VARCHAR(30) NOT NULL,
|
|
182
|
+
quantity INTEGER NOT NULL,
|
|
183
|
+
quantity_before INTEGER NOT NULL,
|
|
184
|
+
quantity_after INTEGER NOT NULL,
|
|
185
|
+
reference_type VARCHAR(50),
|
|
186
|
+
reference_id INTEGER,
|
|
187
|
+
notes TEXT,
|
|
188
|
+
created_by VARCHAR(100),
|
|
189
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
CREATE INDEX idx_inventory_product ON app.inventory_movements(product_id);
|
|
193
|
+
CREATE INDEX idx_inventory_type ON app.inventory_movements(movement_type);
|
|
194
|
+
CREATE INDEX idx_inventory_created_at ON app.inventory_movements(created_at);
|
|
195
|
+
|
|
196
|
+
-- Coupons
|
|
197
|
+
CREATE TABLE IF NOT EXISTS app.coupons (
|
|
198
|
+
id SERIAL PRIMARY KEY,
|
|
199
|
+
code VARCHAR(50) UNIQUE NOT NULL,
|
|
200
|
+
description TEXT,
|
|
201
|
+
discount_type VARCHAR(20) NOT NULL,
|
|
202
|
+
discount_value DECIMAL(10, 2) NOT NULL,
|
|
203
|
+
min_order_amount DECIMAL(10, 2),
|
|
204
|
+
max_discount_amount DECIMAL(10, 2),
|
|
205
|
+
usage_limit INTEGER,
|
|
206
|
+
usage_count INTEGER DEFAULT 0,
|
|
207
|
+
starts_at TIMESTAMP WITH TIME ZONE,
|
|
208
|
+
expires_at TIMESTAMP WITH TIME ZONE,
|
|
209
|
+
is_active BOOLEAN DEFAULT true,
|
|
210
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
CREATE INDEX idx_coupons_code ON app.coupons(code);
|
|
214
|
+
CREATE INDEX idx_coupons_active ON app.coupons(is_active, starts_at, expires_at);
|
|
215
|
+
|
|
216
|
+
-- Audit log
|
|
217
|
+
CREATE TABLE IF NOT EXISTS app.audit_log (
|
|
218
|
+
id BIGSERIAL PRIMARY KEY,
|
|
219
|
+
table_name VARCHAR(100) NOT NULL,
|
|
220
|
+
record_id INTEGER,
|
|
221
|
+
action VARCHAR(20) NOT NULL,
|
|
222
|
+
old_values JSONB,
|
|
223
|
+
new_values JSONB,
|
|
224
|
+
changed_by VARCHAR(100),
|
|
225
|
+
ip_address INET,
|
|
226
|
+
user_agent TEXT,
|
|
227
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
CREATE INDEX idx_audit_table ON app.audit_log(table_name);
|
|
231
|
+
CREATE INDEX idx_audit_record ON app.audit_log(table_name, record_id);
|
|
232
|
+
CREATE INDEX idx_audit_created_at ON app.audit_log(created_at);
|
|
233
|
+
|
|
234
|
+
-- ============================================
|
|
235
|
+
-- SEED DATA
|
|
236
|
+
-- ============================================
|
|
237
|
+
|
|
238
|
+
-- Categories
|
|
239
|
+
INSERT INTO app.categories (name, slug, description, parent_id, sort_order) VALUES
|
|
240
|
+
('Electronics', 'electronics', 'Electronic devices and gadgets', NULL, 1),
|
|
241
|
+
('Computers', 'computers', 'Laptops, desktops and accessories', 1, 1),
|
|
242
|
+
('Smartphones', 'smartphones', 'Mobile phones and tablets', 1, 2),
|
|
243
|
+
('Audio', 'audio', 'Headphones, speakers and audio equipment', 1, 3),
|
|
244
|
+
('Fashion', 'fashion', 'Clothing and accessories', NULL, 2),
|
|
245
|
+
('Men', 'men', 'Mens clothing', 5, 1),
|
|
246
|
+
('Women', 'women', 'Womens clothing', 5, 2),
|
|
247
|
+
('Home & Garden', 'home-garden', 'Home decor and garden supplies', NULL, 3),
|
|
248
|
+
('Kitchen', 'kitchen', 'Kitchen appliances and utensils', 8, 1),
|
|
249
|
+
('Furniture', 'furniture', 'Indoor and outdoor furniture', 8, 2),
|
|
250
|
+
('Sports', 'sports', 'Sports equipment and outdoor gear', NULL, 4),
|
|
251
|
+
('Books', 'books', 'Books, e-books and audiobooks', NULL, 5)
|
|
252
|
+
ON CONFLICT (slug) DO NOTHING;
|
|
253
|
+
|
|
254
|
+
-- Customers (50 customers)
|
|
255
|
+
INSERT INTO app.customers (email, first_name, last_name, phone, date_of_birth, gender, loyalty_points, tier, is_verified) VALUES
|
|
256
|
+
('ahmet.yilmaz@email.com', 'Ahmet', 'Yilmaz', '+905551234501', '1985-03-15', 'male', 2500, 'gold', true),
|
|
257
|
+
('ayse.demir@email.com', 'Ayse', 'Demir', '+905551234502', '1990-07-22', 'female', 1500, 'silver', true),
|
|
258
|
+
('mehmet.kaya@email.com', 'Mehmet', 'Kaya', '+905551234503', '1988-11-08', 'male', 3500, 'platinum', true),
|
|
259
|
+
('fatma.celik@email.com', 'Fatma', 'Celik', '+905551234504', '1995-01-30', 'female', 800, 'bronze', true),
|
|
260
|
+
('ali.ozturk@email.com', 'Ali', 'Ozturk', '+905551234505', '1982-09-12', 'male', 1200, 'silver', true),
|
|
261
|
+
('zeynep.arslan@email.com', 'Zeynep', 'Arslan', '+905551234506', '1993-04-25', 'female', 4200, 'platinum', true),
|
|
262
|
+
('mustafa.sahin@email.com', 'Mustafa', 'Sahin', '+905551234507', '1978-12-03', 'male', 600, 'bronze', false),
|
|
263
|
+
('elif.yildiz@email.com', 'Elif', 'Yildiz', '+905551234508', '1991-06-18', 'female', 2100, 'gold', true),
|
|
264
|
+
('emre.kurt@email.com', 'Emre', 'Kurt', '+905551234509', '1987-02-28', 'male', 950, 'bronze', true),
|
|
265
|
+
('selin.dogan@email.com', 'Selin', 'Dogan', '+905551234510', '1994-08-14', 'female', 1800, 'silver', true),
|
|
266
|
+
('burak.aydin@email.com', 'Burak', 'Aydin', '+905551234511', '1986-05-09', 'male', 2800, 'gold', true),
|
|
267
|
+
('deniz.kilic@email.com', 'Deniz', 'Kilic', '+905551234512', '1992-10-21', 'female', 550, 'bronze', false),
|
|
268
|
+
('can.erdogan@email.com', 'Can', 'Erdogan', '+905551234513', '1989-01-17', 'male', 3100, 'platinum', true),
|
|
269
|
+
('ece.polat@email.com', 'Ece', 'Polat', '+905551234514', '1996-07-04', 'female', 420, 'bronze', true),
|
|
270
|
+
('kerem.ozdemir@email.com', 'Kerem', 'Ozdemir', '+905551234515', '1984-03-29', 'male', 1650, 'silver', true),
|
|
271
|
+
('ipek.korkmaz@email.com', 'Ipek', 'Korkmaz', '+905551234516', '1997-11-11', 'female', 2300, 'gold', true),
|
|
272
|
+
('tolga.aksoy@email.com', 'Tolga', 'Aksoy', '+905551234517', '1981-08-06', 'male', 750, 'bronze', true),
|
|
273
|
+
('melis.cetin@email.com', 'Melis', 'Cetin', '+905551234518', '1993-02-14', 'female', 1950, 'silver', true),
|
|
274
|
+
('oguz.karaca@email.com', 'Oguz', 'Karaca', '+905551234519', '1990-12-25', 'male', 5100, 'platinum', true),
|
|
275
|
+
('pinar.guler@email.com', 'Pinar', 'Guler', '+905551234520', '1988-04-02', 'female', 1100, 'silver', true),
|
|
276
|
+
('serkan.yalcin@email.com', 'Serkan', 'Yalcin', '+905551234521', '1983-09-19', 'male', 2650, 'gold', true),
|
|
277
|
+
('ceren.koc@email.com', 'Ceren', 'Koc', '+905551234522', '1995-06-08', 'female', 380, 'bronze', false),
|
|
278
|
+
('baran.tekin@email.com', 'Baran', 'Tekin', '+905551234523', '1979-01-23', 'male', 4500, 'platinum', true),
|
|
279
|
+
('gamze.sen@email.com', 'Gamze', 'Sen', '+905551234524', '1992-07-31', 'female', 1400, 'silver', true),
|
|
280
|
+
('arda.cinar@email.com', 'Arda', 'Cinar', '+905551234525', '1986-11-15', 'male', 2200, 'gold', true)
|
|
281
|
+
ON CONFLICT (email) DO NOTHING;
|
|
282
|
+
|
|
283
|
+
-- Customer addresses
|
|
284
|
+
INSERT INTO app.customer_addresses (customer_id, type, is_default, full_name, street_address, apartment, city, state, postal_code, country, phone)
|
|
285
|
+
SELECT
|
|
286
|
+
c.id, 'shipping', true, c.first_name || ' ' || c.last_name,
|
|
287
|
+
'Ataturk Caddesi No: ' || (c.id * 10),
|
|
288
|
+
'Daire ' || (c.id % 10 + 1),
|
|
289
|
+
CASE (c.id % 5)
|
|
290
|
+
WHEN 0 THEN 'Istanbul'
|
|
291
|
+
WHEN 1 THEN 'Ankara'
|
|
292
|
+
WHEN 2 THEN 'Izmir'
|
|
293
|
+
WHEN 3 THEN 'Bursa'
|
|
294
|
+
ELSE 'Antalya'
|
|
295
|
+
END,
|
|
296
|
+
CASE (c.id % 5)
|
|
297
|
+
WHEN 0 THEN 'Kadikoy'
|
|
298
|
+
WHEN 1 THEN 'Cankaya'
|
|
299
|
+
WHEN 2 THEN 'Konak'
|
|
300
|
+
WHEN 3 THEN 'Nilufer'
|
|
301
|
+
ELSE 'Muratpasa'
|
|
302
|
+
END,
|
|
303
|
+
LPAD((34000 + c.id * 100)::text, 5, '0'),
|
|
304
|
+
'Turkey',
|
|
305
|
+
c.phone
|
|
306
|
+
FROM app.customers c;
|
|
307
|
+
|
|
308
|
+
-- Products (30 products)
|
|
309
|
+
INSERT INTO app.products (sku, name, slug, description, short_description, price, compare_at_price, cost_price, stock_quantity, category_id, brand, weight_kg, is_active, is_featured, rating_avg, rating_count, view_count) VALUES
|
|
310
|
+
('LAPTOP-001', 'MacBook Pro 14" M3', 'macbook-pro-14-m3', 'Apple MacBook Pro with M3 chip, 16GB RAM, 512GB SSD. Perfect for professionals.', 'Powerful laptop for professionals', 89999.99, 94999.99, 75000.00, 45, 2, 'Apple', 1.55, true, true, 4.8, 124, 5420),
|
|
311
|
+
('LAPTOP-002', 'Dell XPS 15', 'dell-xps-15', 'Dell XPS 15 with Intel i9, 32GB RAM, 1TB SSD, OLED display.', '15-inch premium ultrabook', 74999.99, NULL, 62000.00, 32, 2, 'Dell', 1.86, true, true, 4.6, 89, 3210),
|
|
312
|
+
('LAPTOP-003', 'ThinkPad X1 Carbon', 'thinkpad-x1-carbon', 'Lenovo ThinkPad X1 Carbon Gen 11, business-class ultrabook.', 'Business ultrabook', 64999.99, 69999.99, 52000.00, 28, 2, 'Lenovo', 1.12, true, false, 4.7, 67, 2890),
|
|
313
|
+
('PHONE-001', 'iPhone 15 Pro Max', 'iphone-15-pro-max', 'Apple iPhone 15 Pro Max 256GB with A17 Pro chip and titanium design.', 'Latest flagship iPhone', 74999.99, NULL, 65000.00, 120, 3, 'Apple', 0.22, true, true, 4.9, 256, 12500),
|
|
314
|
+
('PHONE-002', 'Samsung Galaxy S24 Ultra', 'samsung-galaxy-s24-ultra', 'Samsung Galaxy S24 Ultra with S Pen, 200MP camera, AI features.', 'Premium Android flagship', 69999.99, 74999.99, 58000.00, 85, 3, 'Samsung', 0.23, true, true, 4.7, 198, 9800),
|
|
315
|
+
('PHONE-003', 'Google Pixel 8 Pro', 'google-pixel-8-pro', 'Google Pixel 8 Pro with Tensor G3, best-in-class camera.', 'Pure Android experience', 44999.99, NULL, 38000.00, 65, 3, 'Google', 0.21, true, false, 4.5, 87, 4560),
|
|
316
|
+
('AUDIO-001', 'AirPods Pro 2', 'airpods-pro-2', 'Apple AirPods Pro 2nd Gen with USB-C, active noise cancellation.', 'Premium wireless earbuds', 9999.99, 10999.99, 8000.00, 200, 4, 'Apple', 0.05, true, true, 4.8, 445, 15600),
|
|
317
|
+
('AUDIO-002', 'Sony WH-1000XM5', 'sony-wh-1000xm5', 'Sony WH-1000XM5 wireless noise canceling headphones.', 'Industry-leading NC headphones', 12999.99, NULL, 10500.00, 75, 4, 'Sony', 0.25, true, true, 4.9, 312, 8900),
|
|
318
|
+
('AUDIO-003', 'Bose QuietComfort Ultra', 'bose-quietcomfort-ultra', 'Bose QuietComfort Ultra headphones with spatial audio.', 'Premium comfort headphones', 14999.99, 15999.99, 12000.00, 50, 4, 'Bose', 0.25, true, false, 4.7, 156, 5400),
|
|
319
|
+
('WATCH-001', 'Apple Watch Ultra 2', 'apple-watch-ultra-2', 'Apple Watch Ultra 2, the most rugged and capable Apple Watch.', 'Adventure smartwatch', 34999.99, NULL, 29000.00, 40, 1, 'Apple', 0.06, true, true, 4.8, 89, 6700),
|
|
320
|
+
('WATCH-002', 'Samsung Galaxy Watch 6', 'samsung-galaxy-watch-6', 'Samsung Galaxy Watch 6 Classic with rotating bezel.', 'Classic smartwatch design', 14999.99, 16999.99, 12000.00, 90, 1, 'Samsung', 0.05, true, false, 4.5, 134, 4500),
|
|
321
|
+
('TABLET-001', 'iPad Pro 12.9" M2', 'ipad-pro-12-m2', 'Apple iPad Pro 12.9-inch with M2 chip, Liquid Retina XDR.', 'Professional tablet', 54999.99, NULL, 46000.00, 35, 3, 'Apple', 0.68, true, true, 4.8, 167, 7800),
|
|
322
|
+
('TABLET-002', 'Samsung Galaxy Tab S9 Ultra', 'samsung-galaxy-tab-s9-ultra', 'Samsung Galaxy Tab S9 Ultra with S Pen, 14.6-inch display.', 'Large Android tablet', 49999.99, 54999.99, 42000.00, 25, 3, 'Samsung', 0.73, true, false, 4.6, 78, 3200),
|
|
323
|
+
('KB-001', 'Keychron K8 Pro', 'keychron-k8-pro', 'Keychron K8 Pro wireless mechanical keyboard, hot-swappable.', 'Premium mechanical keyboard', 4499.99, NULL, 3500.00, 150, 2, 'Keychron', 1.05, true, false, 4.7, 234, 8900),
|
|
324
|
+
('KB-002', 'Logitech MX Keys', 'logitech-mx-keys', 'Logitech MX Keys wireless illuminated keyboard.', 'Comfortable typing keyboard', 3999.99, 4499.99, 3200.00, 120, 2, 'Logitech', 0.81, true, false, 4.6, 189, 6700),
|
|
325
|
+
('MOUSE-001', 'Logitech MX Master 3S', 'logitech-mx-master-3s', 'Logitech MX Master 3S wireless performance mouse.', 'Ergonomic wireless mouse', 4299.99, NULL, 3400.00, 180, 2, 'Logitech', 0.14, true, true, 4.8, 312, 11200),
|
|
326
|
+
('MOUSE-002', 'Apple Magic Mouse', 'apple-magic-mouse', 'Apple Magic Mouse with Multi-Touch surface.', 'Minimalist Apple mouse', 3499.99, NULL, 2800.00, 95, 2, 'Apple', 0.10, true, false, 4.2, 156, 5600),
|
|
327
|
+
('MONITOR-001', 'LG UltraFine 32UN880', 'lg-ultrafine-32un880', 'LG 32-inch UltraFine 4K Ergo monitor with USB-C.', 'Ergonomic 4K monitor', 24999.99, 27999.99, 20000.00, 30, 2, 'LG', 9.80, true, true, 4.7, 89, 4300),
|
|
328
|
+
('MONITOR-002', 'Dell UltraSharp U2723QE', 'dell-ultrasharp-u2723qe', 'Dell 27-inch 4K USB-C Hub monitor with IPS Black.', 'Professional USB-C monitor', 22999.99, NULL, 18500.00, 25, 2, 'Dell', 6.64, true, false, 4.8, 67, 3100),
|
|
329
|
+
('CHARGER-001', 'Anker 737 GaNPrime', 'anker-737-ganprime', 'Anker 737 120W GaN charger with 3 ports.', 'High-power GaN charger', 2999.99, 3499.99, 2400.00, 300, 1, 'Anker', 0.19, true, false, 4.6, 445, 12300),
|
|
330
|
+
('CASE-001', 'Apple Leather Case iPhone 15 Pro', 'apple-leather-case-iphone-15-pro', 'Apple genuine leather case for iPhone 15 Pro.', 'Premium iPhone case', 2499.99, NULL, 2000.00, 250, 3, 'Apple', 0.03, true, false, 4.5, 189, 7800),
|
|
331
|
+
('TSHIRT-001', 'Basic Cotton T-Shirt', 'basic-cotton-tshirt-men', 'Premium cotton basic t-shirt for men. Available in multiple colors.', 'Comfortable everyday tee', 299.99, 399.99, 150.00, 500, 6, 'BasicWear', 0.20, true, false, 4.4, 567, 23400),
|
|
332
|
+
('TSHIRT-002', 'Premium V-Neck Tee', 'premium-vneck-tee-women', 'Soft premium v-neck t-shirt for women.', 'Elegant v-neck design', 349.99, NULL, 180.00, 450, 7, 'StyleCo', 0.18, true, false, 4.5, 423, 18900),
|
|
333
|
+
('JEANS-001', 'Slim Fit Denim Jeans', 'slim-fit-denim-jeans-men', 'Classic slim fit denim jeans for men. Stretch comfort.', 'Timeless denim style', 799.99, 999.99, 400.00, 200, 6, 'DenimX', 0.65, true, true, 4.6, 234, 9800),
|
|
334
|
+
('DRESS-001', 'Floral Summer Dress', 'floral-summer-dress', 'Beautiful floral print summer dress. Light and breezy.', 'Perfect for summer', 599.99, NULL, 300.00, 150, 7, 'SummerStyle', 0.30, true, true, 4.7, 178, 7600),
|
|
335
|
+
('COFFEE-001', 'Nespresso Vertuo Next', 'nespresso-vertuo-next', 'Nespresso Vertuo Next coffee machine. One-touch brewing.', 'Premium coffee maker', 4999.99, 5499.99, 4000.00, 60, 9, 'Nespresso', 4.00, true, true, 4.6, 312, 11200),
|
|
336
|
+
('BLENDER-001', 'Vitamix E310', 'vitamix-e310', 'Vitamix E310 professional-grade blender.', 'Professional blender', 12999.99, NULL, 10500.00, 35, 9, 'Vitamix', 5.20, true, false, 4.9, 145, 5600),
|
|
337
|
+
('CHAIR-001', 'Herman Miller Aeron', 'herman-miller-aeron', 'Herman Miller Aeron ergonomic office chair, size B.', 'Iconic ergonomic chair', 54999.99, 59999.99, 45000.00, 15, 10, 'Herman Miller', 19.00, true, true, 4.8, 89, 4300),
|
|
338
|
+
('DESK-001', 'IKEA BEKANT Standing Desk', 'ikea-bekant-standing-desk', 'IKEA BEKANT sit/stand desk, 160x80 cm.', 'Adjustable standing desk', 12999.99, NULL, 10000.00, 40, 10, 'IKEA', 35.00, true, false, 4.4, 234, 8900),
|
|
339
|
+
('BOOK-001', 'Clean Code', 'clean-code-robert-martin', 'Clean Code by Robert C. Martin. A handbook of agile software craftsmanship.', 'Software development classic', 349.99, NULL, 200.00, 100, 12, 'Pearson', 0.80, true, true, 4.9, 567, 23400)
|
|
340
|
+
ON CONFLICT (sku) DO NOTHING;
|
|
341
|
+
|
|
342
|
+
-- Orders (100 orders)
|
|
343
|
+
DO $$
|
|
344
|
+
DECLARE
|
|
345
|
+
i INTEGER;
|
|
346
|
+
cust_id INTEGER;
|
|
347
|
+
ord_status VARCHAR(30);
|
|
348
|
+
pay_status VARCHAR(30);
|
|
349
|
+
ord_total DECIMAL(12,2);
|
|
350
|
+
ord_date TIMESTAMP WITH TIME ZONE;
|
|
351
|
+
BEGIN
|
|
352
|
+
FOR i IN 1..100 LOOP
|
|
353
|
+
-- Random customer
|
|
354
|
+
SELECT id INTO cust_id FROM app.customers ORDER BY RANDOM() LIMIT 1;
|
|
355
|
+
|
|
356
|
+
-- Random status
|
|
357
|
+
ord_status := (ARRAY['pending', 'processing', 'shipped', 'delivered', 'completed', 'cancelled'])[floor(random() * 6 + 1)];
|
|
358
|
+
pay_status := CASE ord_status
|
|
359
|
+
WHEN 'cancelled' THEN 'refunded'
|
|
360
|
+
WHEN 'pending' THEN 'pending'
|
|
361
|
+
ELSE 'paid'
|
|
362
|
+
END;
|
|
363
|
+
|
|
364
|
+
-- Random total
|
|
365
|
+
ord_total := round((random() * 50000 + 500)::numeric, 2);
|
|
366
|
+
|
|
367
|
+
-- Random date in last 90 days
|
|
368
|
+
ord_date := NOW() - (random() * INTERVAL '90 days');
|
|
369
|
+
|
|
370
|
+
INSERT INTO app.orders (order_number, customer_id, status, payment_status, payment_method, subtotal, tax_amount, shipping_amount, discount_amount, total_amount, shipping_address, created_at, updated_at)
|
|
371
|
+
VALUES (
|
|
372
|
+
'ORD-' || TO_CHAR(ord_date, 'YYYYMMDD') || '-' || LPAD(i::text, 4, '0'),
|
|
373
|
+
cust_id,
|
|
374
|
+
ord_status,
|
|
375
|
+
pay_status,
|
|
376
|
+
(ARRAY['credit_card', 'debit_card', 'bank_transfer', 'cash_on_delivery'])[floor(random() * 4 + 1)],
|
|
377
|
+
ord_total * 0.82,
|
|
378
|
+
ord_total * 0.18,
|
|
379
|
+
CASE WHEN ord_total > 1000 THEN 0 ELSE 49.99 END,
|
|
380
|
+
CASE WHEN random() > 0.7 THEN ord_total * 0.1 ELSE 0 END,
|
|
381
|
+
ord_total,
|
|
382
|
+
(SELECT jsonb_build_object(
|
|
383
|
+
'full_name', ca.full_name,
|
|
384
|
+
'street', ca.street_address,
|
|
385
|
+
'city', ca.city,
|
|
386
|
+
'postal_code', ca.postal_code
|
|
387
|
+
) FROM app.customer_addresses ca WHERE ca.customer_id = cust_id LIMIT 1),
|
|
388
|
+
ord_date,
|
|
389
|
+
ord_date
|
|
390
|
+
) ON CONFLICT DO NOTHING;
|
|
391
|
+
END LOOP;
|
|
392
|
+
END $$;
|
|
393
|
+
|
|
394
|
+
-- Order items (2-4 items per order)
|
|
395
|
+
DO $$
|
|
396
|
+
DECLARE
|
|
397
|
+
ord RECORD;
|
|
398
|
+
prod RECORD;
|
|
399
|
+
item_count INTEGER;
|
|
400
|
+
qty INTEGER;
|
|
401
|
+
BEGIN
|
|
402
|
+
FOR ord IN SELECT id, total_amount FROM app.orders LOOP
|
|
403
|
+
item_count := floor(random() * 3 + 2);
|
|
404
|
+
|
|
405
|
+
FOR prod IN SELECT id, name, sku, price FROM app.products ORDER BY RANDOM() LIMIT item_count LOOP
|
|
406
|
+
qty := floor(random() * 3 + 1);
|
|
407
|
+
|
|
408
|
+
INSERT INTO app.order_items (order_id, product_id, product_name, product_sku, quantity, unit_price, total_price)
|
|
409
|
+
VALUES (ord.id, prod.id, prod.name, prod.sku, qty, prod.price, prod.price * qty)
|
|
410
|
+
ON CONFLICT DO NOTHING;
|
|
411
|
+
END LOOP;
|
|
412
|
+
END LOOP;
|
|
413
|
+
END $$;
|
|
414
|
+
|
|
415
|
+
-- Product reviews
|
|
416
|
+
DO $$
|
|
417
|
+
DECLARE
|
|
418
|
+
prod RECORD;
|
|
419
|
+
cust RECORD;
|
|
420
|
+
review_count INTEGER;
|
|
421
|
+
rating_val INTEGER;
|
|
422
|
+
BEGIN
|
|
423
|
+
FOR prod IN SELECT id FROM app.products LOOP
|
|
424
|
+
review_count := floor(random() * 8 + 2);
|
|
425
|
+
|
|
426
|
+
FOR cust IN SELECT id FROM app.customers ORDER BY RANDOM() LIMIT review_count LOOP
|
|
427
|
+
rating_val := floor(random() * 2 + 4); -- 4 or 5 stars mostly
|
|
428
|
+
|
|
429
|
+
INSERT INTO app.product_reviews (product_id, customer_id, rating, title, content, is_verified_purchase, is_approved, helpful_count, created_at)
|
|
430
|
+
VALUES (
|
|
431
|
+
prod.id,
|
|
432
|
+
cust.id,
|
|
433
|
+
rating_val,
|
|
434
|
+
CASE rating_val
|
|
435
|
+
WHEN 5 THEN 'Excellent product!'
|
|
436
|
+
WHEN 4 THEN 'Very good, recommended'
|
|
437
|
+
WHEN 3 THEN 'Decent product'
|
|
438
|
+
ELSE 'Could be better'
|
|
439
|
+
END,
|
|
440
|
+
CASE rating_val
|
|
441
|
+
WHEN 5 THEN 'Absolutely love it! Exceeded my expectations. Fast delivery and great quality.'
|
|
442
|
+
WHEN 4 THEN 'Good quality product. Works as expected. Would buy again.'
|
|
443
|
+
WHEN 3 THEN 'It is okay for the price. Does the job but nothing special.'
|
|
444
|
+
ELSE 'Not what I expected. Quality could be improved.'
|
|
445
|
+
END,
|
|
446
|
+
random() > 0.3,
|
|
447
|
+
true,
|
|
448
|
+
floor(random() * 50),
|
|
449
|
+
NOW() - (random() * INTERVAL '60 days')
|
|
450
|
+
) ON CONFLICT DO NOTHING;
|
|
451
|
+
END LOOP;
|
|
452
|
+
END LOOP;
|
|
453
|
+
END $$;
|
|
454
|
+
|
|
455
|
+
-- Inventory movements
|
|
456
|
+
INSERT INTO app.inventory_movements (product_id, movement_type, quantity, quantity_before, quantity_after, reference_type, notes, created_by, created_at)
|
|
457
|
+
SELECT
|
|
458
|
+
p.id,
|
|
459
|
+
'stock_in',
|
|
460
|
+
100,
|
|
461
|
+
p.stock_quantity - 100,
|
|
462
|
+
p.stock_quantity,
|
|
463
|
+
'purchase_order',
|
|
464
|
+
'Initial stock',
|
|
465
|
+
'system',
|
|
466
|
+
NOW() - INTERVAL '30 days'
|
|
467
|
+
FROM app.products p;
|
|
468
|
+
|
|
469
|
+
-- Coupons
|
|
470
|
+
INSERT INTO app.coupons (code, description, discount_type, discount_value, min_order_amount, max_discount_amount, usage_limit, starts_at, expires_at, is_active) VALUES
|
|
471
|
+
('WELCOME10', 'Welcome discount - 10% off', 'percentage', 10, 500, 500, 1000, NOW() - INTERVAL '30 days', NOW() + INTERVAL '90 days', true),
|
|
472
|
+
('SUMMER25', 'Summer sale - 25% off', 'percentage', 25, 1000, 2500, 500, NOW(), NOW() + INTERVAL '60 days', true),
|
|
473
|
+
('FLAT500', 'Flat 500 TL off', 'fixed', 500, 2500, NULL, 200, NOW(), NOW() + INTERVAL '30 days', true),
|
|
474
|
+
('VIP50', 'VIP member discount', 'percentage', 50, 5000, 10000, 50, NOW(), NOW() + INTERVAL '365 days', true),
|
|
475
|
+
('FREESHIP', 'Free shipping', 'fixed', 49.99, 100, NULL, NULL, NOW() - INTERVAL '60 days', NOW() + INTERVAL '30 days', true)
|
|
476
|
+
ON CONFLICT (code) DO NOTHING;
|
|
477
|
+
|
|
478
|
+
-- ============================================
|
|
479
|
+
-- VIEWS
|
|
480
|
+
-- ============================================
|
|
481
|
+
|
|
482
|
+
-- Order summary view
|
|
483
|
+
CREATE OR REPLACE VIEW app.order_summary AS
|
|
484
|
+
SELECT
|
|
485
|
+
o.id,
|
|
486
|
+
o.order_number,
|
|
487
|
+
c.first_name || ' ' || c.last_name as customer_name,
|
|
488
|
+
c.email as customer_email,
|
|
489
|
+
c.tier as customer_tier,
|
|
490
|
+
o.status,
|
|
491
|
+
o.payment_status,
|
|
492
|
+
o.total_amount,
|
|
493
|
+
COUNT(oi.id) as item_count,
|
|
494
|
+
SUM(oi.quantity) as total_items,
|
|
495
|
+
o.created_at as order_date
|
|
496
|
+
FROM app.orders o
|
|
497
|
+
JOIN app.customers c ON o.customer_id = c.id
|
|
498
|
+
LEFT JOIN app.order_items oi ON o.id = oi.order_id
|
|
499
|
+
GROUP BY o.id, o.order_number, c.first_name, c.last_name, c.email, c.tier, o.status, o.payment_status, o.total_amount, o.created_at;
|
|
500
|
+
|
|
501
|
+
-- Product sales summary
|
|
502
|
+
CREATE OR REPLACE VIEW app.product_sales_summary AS
|
|
503
|
+
SELECT
|
|
504
|
+
p.id,
|
|
505
|
+
p.sku,
|
|
506
|
+
p.name,
|
|
507
|
+
p.category_id,
|
|
508
|
+
cat.name as category_name,
|
|
509
|
+
p.price,
|
|
510
|
+
p.stock_quantity,
|
|
511
|
+
COALESCE(SUM(oi.quantity), 0) as total_sold,
|
|
512
|
+
COALESCE(SUM(oi.total_price), 0) as total_revenue,
|
|
513
|
+
COALESCE(COUNT(DISTINCT oi.order_id), 0) as order_count,
|
|
514
|
+
p.rating_avg,
|
|
515
|
+
p.view_count
|
|
516
|
+
FROM app.products p
|
|
517
|
+
LEFT JOIN app.categories cat ON p.category_id = cat.id
|
|
518
|
+
LEFT JOIN app.order_items oi ON p.id = oi.product_id
|
|
519
|
+
LEFT JOIN app.orders o ON oi.order_id = o.id AND o.status NOT IN ('cancelled')
|
|
520
|
+
GROUP BY p.id, p.sku, p.name, p.category_id, cat.name, p.price, p.stock_quantity, p.rating_avg, p.view_count;
|
|
521
|
+
|
|
522
|
+
-- Customer lifetime value
|
|
523
|
+
CREATE OR REPLACE VIEW app.customer_lifetime_value AS
|
|
524
|
+
SELECT
|
|
525
|
+
c.id,
|
|
526
|
+
c.email,
|
|
527
|
+
c.first_name || ' ' || c.last_name as full_name,
|
|
528
|
+
c.tier,
|
|
529
|
+
c.loyalty_points,
|
|
530
|
+
COUNT(DISTINCT o.id) as total_orders,
|
|
531
|
+
COALESCE(SUM(o.total_amount), 0) as lifetime_value,
|
|
532
|
+
COALESCE(AVG(o.total_amount), 0) as avg_order_value,
|
|
533
|
+
MIN(o.created_at) as first_order_date,
|
|
534
|
+
MAX(o.created_at) as last_order_date,
|
|
535
|
+
c.created_at as customer_since
|
|
536
|
+
FROM app.customers c
|
|
537
|
+
LEFT JOIN app.orders o ON c.id = o.customer_id AND o.status NOT IN ('cancelled')
|
|
538
|
+
GROUP BY c.id, c.email, c.first_name, c.last_name, c.tier, c.loyalty_points, c.created_at;
|
|
539
|
+
|
|
540
|
+
-- Daily sales report
|
|
541
|
+
CREATE OR REPLACE VIEW app.daily_sales AS
|
|
542
|
+
SELECT
|
|
543
|
+
DATE(o.created_at) as sale_date,
|
|
544
|
+
COUNT(DISTINCT o.id) as order_count,
|
|
545
|
+
SUM(o.total_amount) as total_sales,
|
|
546
|
+
AVG(o.total_amount) as avg_order_value,
|
|
547
|
+
COUNT(DISTINCT o.customer_id) as unique_customers
|
|
548
|
+
FROM app.orders o
|
|
549
|
+
WHERE o.status NOT IN ('cancelled', 'pending')
|
|
550
|
+
GROUP BY DATE(o.created_at)
|
|
551
|
+
ORDER BY sale_date DESC;
|
|
552
|
+
|
|
553
|
+
-- ============================================
|
|
554
|
+
-- PERMISSIONS
|
|
555
|
+
-- ============================================
|
|
556
|
+
GRANT USAGE ON SCHEMA app TO postgres;
|
|
557
|
+
GRANT ALL ON ALL TABLES IN SCHEMA app TO postgres;
|
|
558
|
+
GRANT ALL ON ALL SEQUENCES IN SCHEMA app TO postgres;
|
|
559
|
+
GRANT SELECT ON ALL TABLES IN SCHEMA app TO postgres;
|
|
560
|
+
|
|
561
|
+
-- ============================================
|
|
562
|
+
-- ANALYZE FOR QUERY PLANNER
|
|
563
|
+
-- ============================================
|
|
564
|
+
ANALYZE app.categories;
|
|
565
|
+
ANALYZE app.customers;
|
|
566
|
+
ANALYZE app.customer_addresses;
|
|
567
|
+
ANALYZE app.products;
|
|
568
|
+
ANALYZE app.orders;
|
|
569
|
+
ANALYZE app.order_items;
|
|
570
|
+
ANALYZE app.product_reviews;
|
|
571
|
+
ANALYZE app.inventory_movements;
|
|
572
|
+
ANALYZE app.coupons;
|
|
573
|
+
|
|
574
|
+
-- ============================================
|
|
575
|
+
-- GENERATE QUERY STATISTICS
|
|
576
|
+
-- ============================================
|
|
577
|
+
-- Run sample queries to populate pg_stat_statements
|
|
578
|
+
SELECT COUNT(*) FROM app.customers WHERE tier = 'gold';
|
|
579
|
+
SELECT * FROM app.products WHERE price > 10000 ORDER BY price DESC LIMIT 10;
|
|
580
|
+
SELECT * FROM app.order_summary WHERE status = 'completed' LIMIT 20;
|
|
581
|
+
SELECT * FROM app.product_sales_summary ORDER BY total_revenue DESC LIMIT 10;
|
|
582
|
+
SELECT * FROM app.customer_lifetime_value ORDER BY lifetime_value DESC LIMIT 10;
|
|
583
|
+
SELECT * FROM app.daily_sales LIMIT 30;
|
|
584
|
+
SELECT c.name, COUNT(p.id) FROM app.categories c LEFT JOIN app.products p ON c.id = p.category_id GROUP BY c.id, c.name;
|
|
585
|
+
SELECT customer_tier, COUNT(*), SUM(total_amount) FROM app.order_summary GROUP BY customer_tier;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# PostgreSQL Docker Compose for LibreDB Studio Development/Testing
|
|
2
|
+
#
|
|
3
|
+
# Usage:
|
|
4
|
+
# docker compose -f docker/postgres.yml up -d
|
|
5
|
+
# docker compose -f docker/postgres.yml down
|
|
6
|
+
# docker compose -f docker/postgres.yml down -v # Remove volumes too
|
|
7
|
+
#
|
|
8
|
+
# Connection:
|
|
9
|
+
# Host: localhost
|
|
10
|
+
# Port: 5432
|
|
11
|
+
# Database: postgres (or libredb_dev)
|
|
12
|
+
# User: postgres
|
|
13
|
+
# Password: postgres
|
|
14
|
+
|
|
15
|
+
services:
|
|
16
|
+
postgres:
|
|
17
|
+
image: postgres:17-alpine
|
|
18
|
+
container_name: libredb-postgres
|
|
19
|
+
restart: unless-stopped
|
|
20
|
+
|
|
21
|
+
# Enable pg_stat_statements and other monitoring extensions
|
|
22
|
+
command: >
|
|
23
|
+
postgres
|
|
24
|
+
-c shared_preload_libraries=pg_stat_statements
|
|
25
|
+
-c pg_stat_statements.track=all
|
|
26
|
+
-c pg_stat_statements.max=10000
|
|
27
|
+
-c track_activities=on
|
|
28
|
+
-c track_counts=on
|
|
29
|
+
-c track_io_timing=on
|
|
30
|
+
-c track_functions=all
|
|
31
|
+
-c log_statement=none
|
|
32
|
+
-c log_duration=off
|
|
33
|
+
-c log_min_duration_statement=1000
|
|
34
|
+
|
|
35
|
+
environment:
|
|
36
|
+
POSTGRES_USER: postgres
|
|
37
|
+
POSTGRES_PASSWORD: postgres
|
|
38
|
+
POSTGRES_DB: postgres
|
|
39
|
+
# Create additional database for development
|
|
40
|
+
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
|
|
41
|
+
|
|
42
|
+
ports:
|
|
43
|
+
- "5432:5432"
|
|
44
|
+
|
|
45
|
+
volumes:
|
|
46
|
+
# Persistent data volume
|
|
47
|
+
- libredb_postgres_data:/var/lib/postgresql/data
|
|
48
|
+
# Init scripts (executed in alphabetical order on first run)
|
|
49
|
+
- ./postgres-init:/docker-entrypoint-initdb.d:ro
|
|
50
|
+
|
|
51
|
+
healthcheck:
|
|
52
|
+
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
|
|
53
|
+
interval: 10s
|
|
54
|
+
timeout: 5s
|
|
55
|
+
retries: 5
|
|
56
|
+
start_period: 10s
|
|
57
|
+
|
|
58
|
+
# Resource limits (adjust as needed)
|
|
59
|
+
deploy:
|
|
60
|
+
resources:
|
|
61
|
+
limits:
|
|
62
|
+
memory: 512M
|
|
63
|
+
reservations:
|
|
64
|
+
memory: 256M
|
|
65
|
+
|
|
66
|
+
volumes:
|
|
67
|
+
libredb_postgres_data:
|
|
68
|
+
name: libredb_postgres_data
|