Haimanot25/dboard: Enterprise database admin panel with multi-DB support, AI-powered dashboard generation, real-time da

github.com · 2026-08-04 · by Long Nguyen ·github
Enterprise database admin panel with multi-DB support, AI-powered dashboard generation, real-time data grids, SQL console, and role-based access control. - Haimanot25/dboard

Haimanot25/dboard

Enterprise database admin panel with multi-DB support, AI-powered dashboard generation, real-time data grids, SQL console, and role-based access control. - Haimanot25/dboard

1 stars · 0 forks · 0 watchers

README

DBoard 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.

Screenshots

Dashboard with charts, metrics, and real-time data

SQL query editor with syntax highlighting and saved queries

Database monitoring with live metrics and table inventory

Schema comparison between two databases

Features

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

Supported Databases

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

Quick Start Prerequisites

Node.js 20+ (recommended: use nvm) npm, yarn, or pnpm Git

Installation

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 and register your first account. Docker Quick Start

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.

Environment Variables

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.

Architecture Tech Stack

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

Project Structure 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

Component Architecture ┌─────────────────────────────────────────────────────────────┐ │ DashboardShell │ │ ┌──────────┐ ┌──────────────────────────────────────────┐ │ │ │ │ │ TopNav │ │ │ │ Sidebar │ │ [Menu] [Page Title] [Search⌘K] [🌙] [▼] │ │ │ │ │ ├──────────────────────────────────────────┤ │ │ │ [Dash] │ │ │ │ │ │ [Admin] │ │ Page Content │ │ │ │ [Settings│ │ (children prop) │ │ │ │ [DB Mon] │ │ │ │ │ │ │ │ │ │ │ │ ──────── │ │ │ │ │ │ ★ Favs │ │ │ │ │ │ │ │ │ │ │ │ ──────── │ │ │ │ │ │ [User] │ │ │ │ │ │ [🌙][≡] │ │ │ │ │ └──────────┘ └──────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘

Data Flow 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) │ └──────────────┘ └──────────────┘

Database Schema DBoard uses SQLite (via Prisma) to store application metadata. The schema contains 16 models: User

Field Type Attributes

id String @id @default(cuid())

email 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 Connection

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

Dashboard

Field Type Attributes

id String @id @default(cuid())

name String

description String?

userId String Owner

createdAt DateTime @default(now())

updatedAt DateTime @updatedAt

DashboardChart

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

ApiKey

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

QueryHistory

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())

SchemaConfig

Field Type Attributes

id String @id @default(cuid())

connectionId String @unique

config String JSON schema configuration

AuditLog

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?

Webhook

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

ConnectionShare

Field Type Attributes

id String @id @default(cuid())

connectionId String

sharedWithId String

sharedById String

permission String @default("read") — read, write, admin

@@unique([connectionId, sharedWithId])

DashboardShare

Field Type Attributes

id String @id @default(cuid())

dashboardId String

sharedWithId String

sharedById String

permission String @default("read")

@@unique([dashboardId, sharedWithId])

SavedView

Field Type Attributes

id String @id @default(cuid())

name String

connectionId String

tableName String

config String JSON view configuration

userId String

AiProvider

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])

AiModel

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])

Alert

Field Type Attributes

id String @id @default(cuid())

name String

connectionId String

tableName String

condition String Alert condition

enabled Boolean @default(true)

webhookUrl String?

email String?

lastTriggeredAt DateTime?

userId String

AdminPage

Field Type Attributes

id String @id @default(cuid())

name String

description String?

userId String

connectionId String

config String @default("{}") — JSON page config

Favorite

Field Type Attributes

id String @id @default(cuid())

userId String

kind String "dashboard" or "adminPage"

targetId String

@@unique([userId, kind, targetId])

Security DBoard implements multiple layers of security to protect your data: SSRF Protection 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). Encryption 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)

CSRF Protection File: src/lib/csrf.ts All state-changing endpoints (POST/PUT/DELETE)

source

github.com · 8 images · 126 links

Comments (0)

No comments yet