I built an open-source admin panel builder for existing databases DBoard, an open-source admin panel builder created by developer Haimanot25, uses AI to generate admin panels, dashboards, forms, and queries from natural language prompts for existing databases, supporting PostgreSQL, MySQL, MongoDB, SQLite, Supabase, and SQL Server. The tool, available on GitHub, offers zero-code CRUD interfaces, AI-powered dashboards, a SQL console, schema diff, database monitoring, and self-hosting via Docker, with features like CSRF protection, AES-256-GCM encryption, and audit logs. Build admin panels and dashboards for any database — zero code, AI-powered. DBoard connects to your existing database and uses AI to instantly generate admin panels, dashboards, forms, and queries from a simple natural language prompt. No coding required. Connect PostgreSQL, MySQL, MongoDB, SQLite, or Supabase — describe what you want in plain English — and DBoard builds it. Edit rows with validated forms, visualize data with auto-generated charts, run queries with a built-in SQL console, and share dashboards with your team. /Haimanot25/dboard/blob/main/public/ss/screenshot-dashboard.png Dashboard with charts, metrics, and real-time data /Haimanot25/dboard/blob/main/public/ss/screenshot-query-editor.png SQL query editor with syntax highlighting and saved queries /Haimanot25/dboard/blob/main/public/ss/screenshot-db-monitor.png Database monitoring with live metrics and table inventory /Haimanot25/dboard/blob/main/public/ss/screenshot-schema-diff.png Schema comparison between two databases Zero-Code Admin Panels — Generate full CRUD interfaces from a natural language prompt — no templates, no configuration AI-Powered Dashboards — "Show me monthly revenue by product category" → instant chart with no SQL needed Multi-Database — Connect PostgreSQL, MySQL, SQLite, MongoDB, Supabase, or SQL Server through one unified interface Database-First — Works with your existing database. No data migration, no vendor lock-in, no schema redesign SQL Console — Write and execute queries with syntax highlighting, saved queries, history, and AI-powered generation Data Grid — Browse, search, filter, sort, inline edit, bulk delete, and import/export CSV, JSON, Excel, PDF Schema Diff — Compare schemas across two databases and visualize differences instantly DB Monitor — Real-time health checks, table inventory, row counts, and performance metrics Sharing & Collaboration — Share connections and dashboards with read/write/admin permissions Webhooks — Send real-time notifications to Slack, Discord, PagerDuty, or custom HTTP endpoints API Keys — Generate scoped API keys for programmatic access to your databases Secure — CSRF protection, SSRF guard, AES-256-GCM encryption at rest, rate limiting, audit logs Self-Hosted — Your data never leaves your server. Deploy with Docker in one command Dark Mode — Eye-friendly dark theme with 6 built-in color presets and full customization | Database | Status | Default Port | Adapter | Notes | |---|---|---|---|---| | PostgreSQL | ✅ | 5432 | SQL Knex | Full support including pg stat views | | MySQL | ✅ | 3306 | SQL Knex | Full support | | SQLite | ✅ | — | SQL Knex | File-based, no network config | | MongoDB | ✅ | 27017 | Native | Document introspection, aggregation | | Supabase | ✅ | — | REST API | Uses Supabase JS client | | SQL Server | ✅ | 1433 | SQL Knex | Full support via mssql driver | - Node.js 20+ recommended: use nvm https://github.com/nvm-sh/nvm - npm, yarn, or pnpm - Git 1. Clone the repository git clone https://github.com/Haimanot25/dboard.git cd dboard 2. Install dependencies npm install 3. Copy environment file cp .env.example .env 4. Generate secrets paste output into .env openssl rand -base64 32 Use for NEXTAUTH SECRET openssl rand -base64 32 Use for ENCRYPTION KEY 5. Initialize the database npx prisma generate npx prisma db push 6. Start the development server npm run dev Open http://localhost:3000 http://localhost:3000 and register your first account. Set secrets in your shell export NEXTAUTH SECRET=$ openssl rand -base64 32 export ENCRYPTION KEY=$ openssl rand -base64 32 Start with Docker Compose docker compose up -d Open http://localhost:3000 http://localhost:3000 . | Variable | Description | Required | Default | |---|---|---|---| DATABASE URL | SQLite URL for Prisma application metadata | Yes | file:./dev.db | NEXTAUTH SECRET | Secret for NextAuth.js session encryption | Yes | — | NEXTAUTH URL | Canonical URL for NextAuth.js | Yes | http://localhost:3000 | ENCRYPTION KEY | Key for encrypting database passwords and API keys AES-256-GCM | Yes | — | ALLOW PRIVATE DB HOSTS | Set to 1 to allow connections to localhost/private IPs dev only | No | 0 | Production:Generate strong secrets with openssl rand -base64 32 . Never use default or placeholder values. | Layer | Technology | |---|---| | Framework | Next.js 14 App Router | | Language | TypeScript 5 strict mode | | Database ORM | Prisma 5 | | Authentication | NextAuth.js 4 Credentials + JWT | | UI Components | shadcn/ui Radix UI + Tailwind CSS | | State Management | TanStack React Query 5 | | Table Grid | TanStack React Table 8 | | Drag & Drop | @dnd-kit | | Command Palette | cmdk | | Charts | Custom SVG Bar, Line, Pie, Sparkline, Heatmap | | Testing | Vitest unit + Playwright E2E | | Linting | ESLint + eslint-plugin-security | | Dead Code Detection | Knip | dboard/ ├── .github/ │ └── workflows/ci.yml CI/CD pipeline 7 jobs ├── docs/ Screenshots and documentation assets ├── e2e/ Playwright E2E tests │ ├── auth.spec.ts │ ├── connections.spec.ts │ ├── dashboard.spec.ts │ ├── data-browse.spec.ts │ └── query.spec.ts ├── prisma/ │ ├── schema.prisma Database schema 16 models │ └── seed.ts Database seed script ├── public/ Static assets logos, favicon ├── scripts/ │ └── seed-demo-db.sql Demo database seed SQL ├── src/ │ ├── app/ │ │ ├── auth / Auth route group │ │ │ ├── login/ │ │ │ └── layout.tsx │ │ ├── dashboard / Dashboard route group │ │ │ ├── connections/ Connection management │ │ │ │ ├── page.tsx List connections │ │ │ │ └── id / Connection detail │ │ │ │ ├── tables/ Browse tables │ │ │ │ ├── query/ SQL editor │ │ │ │ ├── schema/ Schema viewer │ │ │ │ ├── settings/ Connection settings │ │ │ │ └── edit/ Edit connection │ │ │ ├── dashboards/ Dashboard management │ │ │ │ ├── page.tsx List dashboards │ │ │ │ └── id / Dashboard detail │ │ │ ├── admin-pages/ Admin page management │ │ │ ├── settings/ Application settings │ │ │ │ ├── ai/ AI provider config │ │ │ │ ├── profile/ User profile │ │ │ │ ├── theme/ Theme editor │ │ │ │ ├── plugins/ Plugin manager │ │ │ │ ├── audit-logs/ Audit log viewer │ │ │ │ ├── notifications/ │ │ │ │ ├── templates/ Dashboard templates │ │ │ │ └── backup/ Backup & restore │ │ │ ├── db-monitor/ Database monitoring │ │ │ ├── ai/ AI generation page │ │ │ ├── schema-diff/ Schema comparison │ │ │ └── profile/ User profile page │ │ ├── api/ API routes 80 endpoints │ │ │ ├── auth/ Authentication │ │ │ ├── connections/ Connection CRUD + health + info │ │ │ ├── dashboards/ Dashboard CRUD + charts + shares │ │ │ ├── data/ Table data CRUD + bulk operations │ │ │ ├── query/ SQL execution + saved + history + AI │ │ │ ├── schema/ Introspection + diff + config │ │ │ ├── ai/ AI generation + providers │ │ │ ├── settings/ Profile + notifications │ │ │ ├── admin-pages/ Admin page CRUD │ │ │ ├── views/ Saved views │ │ │ ├── favorites/ Favorite toggle │ │ │ ├── shares/ Connection sharing │ │ │ ├── webhooks/ Webhook CRUD + actions │ │ │ ├── api-keys/ API key CRUD │ │ │ ├── activity/ Activity feed │ │ │ ├── audit-logs/ Audit log viewer │ │ │ ├── alerts/ Alert management │ │ │ ├── plugins/ Plugin registry │ │ │ ├── theme/ Theme presets │ │ │ ├── csrf/ CSRF token │ │ │ ├── export/ Data export │ │ │ ├── import/ Data import │ │ │ └── dashboard-templates/ │ │ ├── layout.tsx Root layout │ │ ├── providers.tsx React Query + Theme providers │ │ └── globals.css Global styles │ ├── components/ │ │ ├── layout/ Layout components │ │ │ ├── DashboardShell.tsx │ │ │ ├── Sidebar.tsx │ │ │ └── TopNav.tsx │ │ ├── ui/ shadcn/ui primitives │ │ ├── shared/ Shared components │ │ ├── dashboard/ Dashboard components │ │ ├── data-grid/ Data grid components │ │ ├── connections/ Connection components │ │ ├── query/ Query editor components │ │ ├── schema/ Schema components │ │ ├── settings/ Settings components │ │ ├── ai/ AI components │ │ └── db-monitor/ Database monitoring components │ ├── hooks/ 20 custom React hooks │ ├── lib/ │ │ ├── ai/ AI providers and generation │ │ ├── db/ │ │ │ ├── drivers/ Database adapters │ │ │ ├── encryption.ts AES-256-GCM encryption │ │ │ ├── ssrf-guard.ts SSRF protection │ │ │ └── plugins/ Adapter plugin system │ │ ├── theme/ Theme system │ │ ├── widgets/ Widget plugin registry │ │ ├── webhooks/ Webhook plugin registry │ │ ├── schema/ Schema caching │ │ ├── crud/ Query builder │ │ ├── auth.ts Authentication config │ │ ├── auth-helpers.ts Auth utilities │ │ ├── csrf.ts CSRF protection │ │ ├── permissions.ts Permission system │ │ ├── api-keys.ts API key management │ │ ├── audit.ts Audit logging │ │ ├── rate-limit.ts Rate limiting │ │ ├── with-rate-limit.ts Rate limit middleware │ │ ├── login-rate-limit.ts Login rate limiting │ │ ├── sql-guard.ts SQL write detection │ │ ├── prisma.ts Prisma client │ │ └── utils.ts Utility functions │ ├── types/ TypeScript type definitions │ └── generated/ Prisma generated client ├── tests/ Unit/integration tests ├── .env.example Environment template ├── .eslintrc.json ESLint config ├── .gitignore Git ignore rules ├── .gitleaks.toml Secret scanning config ├── components.json shadcn/ui config ├── docker-compose.yml Docker Compose config ├── Dockerfile Multi-stage Docker build ├── knip.json Dead code detection config ├── next.config.mjs Next.js config + security headers ├── package.json Dependencies and scripts ├── playwright.config.ts E2E test config ├── postcss.config.mjs PostCSS config ├── tailwind.config.ts Tailwind CSS config ├── tsconfig.json TypeScript config ├── vitest.config.ts Vitest test config ├── CONTRIBUTING.md Contributing guidelines ├── CODE OF CONDUCT.md Code of conduct ├── LICENSE MIT License ├── SECURITY.md Security policy ├── CHANGELOG.md Version history └── README.md This file ┌─────────────────────────────────────────────────────────────┐ │ DashboardShell │ │ ┌──────────┐ ┌──────────────────────────────────────────┐ │ │ │ │ │ TopNav │ │ │ │ Sidebar │ │ Menu Page Title Search⌘K 🌙 ▼ │ │ │ │ │ ├──────────────────────────────────────────┤ │ │ │ Dash │ │ │ │ │ │ Admin │ │ Page Content │ │ │ │ Settings│ │ children prop │ │ │ │ DB Mon │ │ │ │ │ │ │ │ │ │ │ │ ──────── │ │ │ │ │ │ ★ Favs │ │ │ │ │ │ │ │ │ │ │ │ ──────── │ │ │ │ │ │ User │ │ │ │ │ │ 🌙 ≡ │ │ │ │ │ └──────────┘ └──────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ Browser Request │ ▼ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ │ Next.js │───▶│ Auth Check │───▶│ CSRF Check │ │ Middleware │ │ JWT/API Key │ │ Origin │ └─────────────┘ └──────────────┘ └──────────────┘ │ ▼ ┌──────────────┐ ┌──────────────┐ │ Rate Limit │───▶│ Route │ │ IP+Path │ │ Handler │ └──────────────┘ └──────────────┘ │ ▼ ┌──────────────┐ ┌──────────────┐ │ Prisma │───▶│ SQLite │ │ Metadata │ │ App DB │ └──────────────┘ └──────────────┘ │ ▼ ┌──────────────┐ ┌──────────────┐ │ Adapter │───▶│ Target DB │ │ PG/MySQL/.. │ User's DB │ └──────────────┘ └──────────────┘ DBoard uses SQLite via Prisma to store application metadata. The schema contains 16 models: | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | String | @unique | | | name | String? | | | password | String? | PBKDF2 hash salt:hash | | role | String | @default "editor" — viewer, editor, admin | | createdAt | DateTime | @default now | | updatedAt | DateTime | @updatedAt | Relations: connections, dashboards, adminPages, apiKeys, auditLogs, queryHistory, savedViews, alerts, aiProviders, favorites, connectionShares, dashboardShares | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | name | String | Display name | | type | String | @default "postgresql" — postgresql, mysql, sqlite, mongodb, supabase, mssql | | host | String | @default "localhost" | | port | Int | @default 5432 | | database | String | Database name | | username | String | | | encryptedPassword | String? | AES-256-GCM encrypted | | ssl | Boolean | @default false | | readOnly | Boolean | @default false | | poolMin | Int | @default 0 | | poolMax | Int | @default 10 | | poolIdleTimeout | Int | @default 30000 | | queryTimeoutMs | Int | @default 30000 | | userId | String | Owner | | createdAt | DateTime | @default now | | updatedAt | DateTime | @updatedAt | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | name | String | | | description | String? | | | userId | String | Owner | | createdAt | DateTime | @default now | | updatedAt | DateTime | @updatedAt | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | dashboardId | String | | | title | String | | | type | String | @default "bar" — bar, line, pie, table, sparkline, heatmap | | connectionId | String | | | query | String | SQL query | | config | String | @default "{}" — JSON config | | width | Int | @default 1 — grid columns | | height | Int | @default 1 — grid rows | | x | Int | @default 0 — grid position | | y | Int | @default 0 — grid position | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | name | String | | | key | String | @unique — dbo + 64 hex chars | | lastChars | String | Last 8 chars for display | | permissions | String | @default "read" — read, write, admin | | connectionId | String | Scoped to one connection | | userId | String | Owner | | expiresAt | DateTime? | | | lastUsedAt | DateTime? | Fire-and-forget update | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | connectionId | String | | | userId | String | | | sql | String | | | durationMs | Int | @default 0 | | rowCount | Int | @default 0 | | error | String? | | | saved | Boolean | @default false | | createdAt | DateTime | @default now | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | connectionId | String | @unique | | config | String | JSON schema configuration | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | connectionId | String | | | userId | String | | | action | String | e.g., "connection.created", "row.updated" | | tableName | String? | | | recordId | String? | | | details | String? | JSON details | | ip | String? | | | dashboardId | String? | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | name | String | | | url | String | Target URL | | events | String | @default "row.created,row.updated,row.deleted" | | connectionId | String | | | enabled | Boolean | @default true | | secret | String? | For signature verification | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | connectionId | String | | | sharedWithId | String | | | sharedById | String | | | permission | String | @default "read" — read, write, admin | @@unique connectionId, sharedWithId | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | dashboardId | String | | | sharedWithId | String | | | sharedById | String | | | permission | String | @default "read" | @@unique dashboardId, sharedWithId | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | name | String | | | connectionId | String | | | tableName | String | | | config | String | JSON view configuration | | userId | String | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | userId | String | | | name | String | @default "chatgpt" | | displayName | String | @default "ChatGPT / OpenAI" | | encryptedApiKey | String? | AES-256-GCM encrypted | | baseUrl | String? | | | isEnabled | Boolean | @default true | | sortOrder | Int | @default 0 | @@unique userId, name | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | providerId | String | | | modelId | String | | | displayName | String | | | isDefault | Boolean | @default false | | sortOrder | Int | @default 0 | @@unique providerId, modelId | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | name | String | | | connectionId | String | | | tableName | String | | | condition | String | Alert condition | | enabled | Boolean | @default true | | webhookUrl | String? | | | String? | || | lastTriggeredAt | DateTime? | | | userId | String | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | name | String | | | description | String? | | | userId | String | | | connectionId | String | | | config | String | @default "{}" — JSON page config | | Field | Type | Attributes | |---|---|---| | id | String | @id @default cuid | | userId | String | | | kind | String | "dashboard" or "adminPage" | | targetId | String | | @@unique userId, kind, targetId | DBoard implements multiple layers of security to protect your data: File: src/lib/db/ssrf-guard.ts All outbound database and webhook connections are validated against Server-Side Request Forgery: Private IP blocking — Blocks RFC 1918 addresses 10.x, 172.16-31.x, 192.168.x , loopback 127.x , link-local 169.254.x , and IPv6 ULA/link-local DNS validation — Resolves hostnames before connecting; blocks connections if any resolved address is private DNS rebinding protection — Validates resolved addresses match expectations Protocol enforcement — Only HTTP/HTTPS allowed for webhooks Configuration: Set ALLOW PRIVATE DB HOSTS=1 in .env to allow localhost connections development only . File: src/lib/db/encryption.ts | Property | Value | |---|---| | Algorithm | AES-256-GCM authenticated encryption | | Key Derivation | crypto.scryptSync with salt "dboard-v1" | | IV | 16 random bytes per encryption | | Output Format | hex iv :hex authTag :hex ciphertext | Used to encrypt: - Database passwords Connection.encryptedPassword - AI provider API keys AiProvider.encryptedApiKey File: src/lib/csrf.ts All state-changing endpoints POST/PUT/DELETE validate that the Origin header matches the Host header. Skipped for API key authentication non-browser clients . File: src/lib/auth.ts | Property | Value | |---|---| | Password Hashing | PBKDF2 with SHA-512 | | Iterations | 600,000 | | Salt | 16 random bytes per password | | Comparison | crypto.timingSafeEqual timing-attack resistant | | Session Strategy | JWT with 24-hour max age | | Custom Login Page | /login | Login Rate Limiting src/lib/login-rate-limit.ts : | Track | Max Attempts | Window | Lockout | |---|---|---|---| | Per-account email | 5 | 15 min | 15 min | | Per-IP | 30 | 15 min | 15 min | General Rate Limiting src/lib/with-rate-limit.ts : - Default: 100 requests per 60-second window per IP+path - Configurable per-route 5–30 requests per 60 seconds - Returns 429 Too Many Requests with Retry-After header File: src/lib/sql-guard.ts Protects read-only connections from write operations: — Detects INSERT, UPDATE, DELETE, DROP, ALTER, TRUNCATE, CREATE, GRANT, REVOKE, and 15+ other write keywords isWriteQuery sql — Validates query starts with SELECT, WITH, SHOW, DESCRIBE, EXPLAIN, or PRAGMA isReadQuery sql Literal stripping — Removes string literals before checking to prevent false positives from data values File: src/lib/permissions.ts | Role | Hierarchy | Capabilities | |---|---|---| | viewer | 1 | Read-only access to connection data | | editor | 2 | Read + write access default for new users | | admin | 3 | Full access including sharing and deletion | Connection access logic: - Admin role can access everything - Owner created the connection gets access; write blocked if readOnly is set - Shared access via ConnectionShare with read/write/admin permission levels File: src/lib/api-keys.ts Format: dbo prefix + 64 hex characters 32 random bytes Scope: Each key is scoped to a single connection Permissions: read 1 < write 2 < admin 3 Authentication: X-API-Key header or Authorization: Bearer dbo CSRF: Skipped for API key requests non-browser clients Expiry: Optional expiration date; checked on every request Tracking: lastUsedAt updated on each use | Provider | API Format | Base URL | Auth | Free Tier | |---|---|---|---|---| | ChatGPT / OpenAI | OpenAI Chat | https://api.openai.com/v1 | Bearer token | No | | Groq | OpenAI Chat | https://api.groq.com/openai/v1 | Bearer token | Yes | | Google Gemini | Gemini Content | https://generativelanguage.googleapis.com/v1beta | Query key | Yes | | Ollama | OpenAI Chat | http://localhost:11434 | None | Yes local | | OpenRouter | OpenAI Chat | https://router.ai/api/v1 | Bearer token | Varies | | Provider | Models | |---|---| | OpenAI | GPT-4o, GPT-4o Mini, GPT-4 Turbo, o3-mini | | Groq | GPT-OSS 120B, Llama 3 70B, Llama 3 8B, Mixtral 8x7B, Gemma 2 9B | | Gemini | Gemini 2.0 Flash, Gemini 2.0 Flash Lite, Gemini 2.5 Pro | | Ollama | Llama 3, Llama 3.1, Mistral, CodeLlama | | OpenRouter | GPT-4o Mini, GPT-4o, Claude 3.5 Sonnet, Llama 3.3 70B, DeepSeek Chat | | Type | Description | Output | |---|---|---| query | Generate SQL from natural language | Raw SQL string | dashboard | Generate a multi-chart dashboard | Dashboard + chart configs | panel | Generate a CRUD admin panel | Panel config with columns, filters, actions | form | Generate form fields from schema | Form field configuration | - Navigate to Settings → AI - Select a provider e.g., Groq for free usage - Enter your API key encrypted at rest with AES-256-GCM - Set a default model - Use in the SQL editor AI tab or AI generation page DBoard supports three types of plugins: Connect to databases beyond the built-in six. Each adapter must implement the DatabaseAdapter interface: interface DatabaseAdapter { connect config: ConnectionConfig : Promise