An open API service indexing awesome lists of open source software.

https://github.com/montrellcruse/quorum-sql

Collaborative SQL query management with version control and peer review. Self-hosted or cloud-ready.
https://github.com/montrellcruse/quorum-sql

postgresql query-manager react sql supabase tailwindcss typescript vite

Last synced: about 2 months ago
JSON representation

Collaborative SQL query management with version control and peer review. Self-hosted or cloud-ready.

Awesome Lists containing this project

README

          


Quorum Logo

Collaborative SQL Query Management



Version Control & Peer Review for SQL



Manage, version, and approve SQL queries with your team. Self-hosted or cloud-ready.


[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![CI](https://github.com/montrellcruse/quorum-sql/actions/workflows/ci.yml/badge.svg)](https://github.com/montrellcruse/quorum-sql/actions/workflows/ci.yml)
[![Security](https://github.com/montrellcruse/quorum-sql/actions/workflows/security.yml/badge.svg)](https://github.com/montrellcruse/quorum-sql/actions/workflows/security.yml)
![React](https://img.shields.io/badge/React-18-61dafb?style=flat-square&logo=react)
![TypeScript](https://img.shields.io/badge/TypeScript-5-3178c6?style=flat-square&logo=typescript)
![Vite](https://img.shields.io/badge/Vite-7-646cff?style=flat-square&logo=vite)
![PostgreSQL](https://img.shields.io/badge/PostgreSQL-16-336791?style=flat-square&logo=postgresql)
![Tailwind CSS](https://img.shields.io/badge/Tailwind-3-38bdf8?style=flat-square&logo=tailwindcss)

## πŸ“– About

**Quorum** is a team-based SQL query management platform with built-in version control and approval workflows. The name reflects the core featureβ€”configurable approval quotas (a *quorum* is the minimum needed for a decision).

Unlike shared folders or wikis, Quorum provides:
- **Git-like version history** for every query change
- **Mandatory peer review** before queries go live
- **Team isolation** with database-level security
- **Full audit trail** of who changed what and when

Perfect for data teams, analytics engineers, and anyone who needs governance over shared SQL.

## ✨ Key Features

| Feature | Description |
|---------|-------------|
| **πŸ”’ Team Isolation** | Multi-tenant architecture with Row-Level Security (RLS). Teams only see their own data. |
| **πŸ“ Version Control** | Complete change history with diff views and rollback capability. |
| **βœ… Approval Workflows** | Configurable approval quotas per team. Require 1, 2, or more reviewers. |
| **πŸ‘₯ Peer Review** | Self-approval prevented at the database level. Changes require teammates. |
| **πŸ”‘ Role-Based Access** | Admin and member roles with granular permissions. |
| **🏠 Self-Hosted Option** | Run on your own infrastructure with Docker. No vendor lock-in. |
| **☁️ Cloud Ready** | Deploy to Supabase for managed PostgreSQL and authentication. |
| **πŸ“ Folder Organization** | Hierarchical folders to organize queries by project, team, or domain. |

## πŸš€ Quick Start

### Option 1: Guided Setup (Recommended)

```bash
git clone https://github.com/montrellcruse/quorum-sql.git
cd quorum-sql
pnpm install
pnpm dev
```

Visit **http://localhost:8080/setup** and follow the configuration wizard.

### Option 2: Docker (Self-Hosted)

```bash
git clone https://github.com/montrellcruse/quorum-sql.git
cd quorum-sql
docker compose up -d db server
pnpm install && pnpm dev
```

Open **http://localhost:8080** to access the application.

## πŸ› οΈ Deployment Options

| Mode | Best For | Auth | Database |
|------|----------|------|----------|
| **Self-Hosted** | Full control, air-gapped environments | Local accounts | PostgreSQL via Docker |
| **Supabase Cloud** | Quick start, managed infrastructure | Supabase Auth + Google OAuth | Supabase PostgreSQL |

## πŸ’» Tech Stack

- **Frontend**: [React 18](https://react.dev/) with [Vite 7](https://vitejs.dev/)
- **Language**: [TypeScript 5](https://www.typescriptlang.org/)
- **Styling**: [Tailwind CSS 3](https://tailwindcss.com/) + [shadcn/ui](https://ui.shadcn.com/)
- **Backend**: [Fastify](https://fastify.dev/) REST API
- **Database**: [PostgreSQL 16](https://www.postgresql.org/) with Row-Level Security
- **ORM/Client**: [Supabase JS](https://supabase.com/docs/reference/javascript) or direct REST
- **Validation**: [Zod 4](https://zod.dev/)
- **State**: [TanStack Query](https://tanstack.com/query)

## πŸ—οΈ Architecture

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Frontend β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ React β”‚ β”‚ TanStack β”‚ β”‚ Tailwind CSS β”‚ β”‚
β”‚ β”‚ Router β”‚ β”‚ Query β”‚ β”‚ + shadcn/ui β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ REST API (Fastify) β”‚ β”‚ Supabase Client (Cloud) β”‚
β”‚ - JWT Auth β”‚ β”‚ - Supabase Auth β”‚
β”‚ - Rate Limiting β”‚ β”‚ - Google OAuth β”‚
β”‚ - CORS β”‚ β”‚ - Real-time (optional) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PostgreSQL β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ 8 Tables β”‚ β”‚ 37+ RLS β”‚ β”‚ Security Definer β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ Policies β”‚ β”‚ Functions β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

## πŸ“Š Database Schema

8 tables with comprehensive Row-Level Security:

| Table | Purpose |
|-------|---------|
| `profiles` | User information synced with auth |
| `teams` | Team settings + approval quotas |
| `team_members` | User-team relationships with roles |
| `team_invitations` | Pending invitations by email |
| `folders` | Hierarchical query organization |
| `sql_queries` | Versioned query storage |
| `query_history` | Complete change audit trail |
| `query_approvals` | Approval tracking per version |

See [supabase/ERD.md](supabase/ERD.md) for the full entity relationship diagram.

## βš™οΈ Configuration

### Environment Variables

Copy `.env.example` to `.env` and configure:

```bash
# Database Provider: 'rest' (self-hosted) or 'supabase' (cloud)
VITE_DB_PROVIDER=rest

# Self-Hosted Mode
VITE_API_BASE_URL=http://localhost:8787
VITE_AUTH_PROVIDERS=local

# OR Supabase Mode
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=your-anon-key

# Common Settings
VITE_ALLOWED_EMAIL_DOMAIN=@yourcompany.com
VITE_APP_NAME=Quorum
```

### Setup Wizard

The setup wizard at `/setup` guides you through:

1. **Choose Provider** β€” Self-Hosted or Supabase Cloud
2. **Configure Settings** β€” Email domain restrictions, app name
3. **Generate Config** β€” Download your `.env` file

## πŸ“ˆ Observability

Frontend telemetry supports:

- **Sentry** error tracking (`VITE_SENTRY_DSN`, `VITE_SENTRY_ENV`, `VITE_SENTRY_TRACES_SAMPLE_RATE`)
- **PostHog** product analytics (`VITE_POSTHOG_KEY`, `VITE_POSTHOG_HOST`)

### Error-to-issue automation (Sentry β†’ GitHub)

Sentry is initialized in `src/lib/telemetry.ts`, but GitHub issue creation is configured in Sentry, not in this repo.
Follow the placeholder runbook to enable or document the integration: `runbooks/sentry-github.md`.

## πŸ“œ Scripts

| Command | Description |
|---------|-------------|
| `pnpm dev` | Start development server on port 8080 |
| `pnpm build` | Build for production |
| `pnpm lint` | Run ESLint |
| `pnpm preview` | Preview production build |
| `pnpm test` | Run server unit tests |
| `pnpm test:e2e` | Run end-to-end tests (Playwright) |

## πŸ”’ Security

Quorum is built with security as a core principle:

- **37+ RLS Policies** β€” Database-level access control on all tables
- **Team Isolation** β€” Users only see their teams' data
- **Peer Review Enforcement** β€” Self-approval prevented at database level
- **Domain Restriction** β€” Configurable email domain authentication
- **Strong Password Policy** β€” Minimum 8 chars with uppercase, lowercase, number, and special character requirements plus common password blocklist
- **SQL Injection Protection** β€” Parameterized queries throughout
- **XSS Protection** β€” React's automatic escaping + CSP headers (enforced in both dev and production)
- **Security Definer Functions** β€” Controlled privilege elevation with `SET search_path`
- **Rate Limiting** β€” Per-route rate limits on all endpoints via `@fastify/rate-limit`
- **Non-Root Docker** β€” Container runs as `node` user, not root

See [SECURITY.md](SECURITY.md) for the complete security policy and audit history.

## πŸ“ Project Structure

```
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ components/ # React components
β”‚ β”‚ β”œβ”€β”€ setup/ # Setup wizard
β”‚ β”‚ └── ui/ # shadcn/ui components
β”‚ β”œβ”€β”€ contexts/ # Auth & Team React contexts
β”‚ β”œβ”€β”€ pages/ # Route page components
β”‚ β”œβ”€β”€ hooks/ # Custom React hooks
β”‚ └── integrations/ # Supabase client config
β”œβ”€β”€ server/ # Fastify REST API
β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”œβ”€β”€ routes/ # API route handlers
β”‚ β”‚ └── middleware/ # Auth, rate limiting
β”‚ └── package.json
β”œβ”€β”€ supabase/
β”‚ β”œβ”€β”€ migrations/ # Squashed baseline migration
β”‚ β”œβ”€β”€ schema.sql # Schema documentation
β”‚ └── ERD.md # Entity relationship diagram
β”œβ”€β”€ docker-compose.yml # Docker services config
└── .env.example # Environment template
```

## 🀝 Contributing

Contributions are welcome! Please follow these steps:

1. **Fork** the repository
2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)
3. **Test** your changes (`pnpm lint && pnpm build`)
4. **Commit** with a clear message (`git commit -m 'Add amazing feature'`)
5. **Push** to your branch (`git push origin feature/amazing-feature`)
6. **Open** a Pull Request

See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.

## πŸ“„ License

This project is licensed under the MIT License β€” see [LICENSE](LICENSE) for details.

## πŸ†˜ Support

- **Issues**: [GitHub Issues](https://github.com/montrellcruse/quorum-sql/issues)
- **Security**: [SECURITY.md](SECURITY.md) for vulnerability reporting
- **Database Docs**: [supabase/README.md](supabase/README.md)

---


Built for teams who care about SQL governance