diff --git a/README.md b/README.md index f7faac8..f6948ad 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ This project is a full-stack web application featuring: - 🛠️ **Admin Panel** - Manage tables, columns, and data through a beautiful UI - 📊 **Table Manager** - Create and drop tables with visual column definition - 🔧 **Column Manager** - Add, modify, and drop columns from existing tables +- 🔒 **Constraint Manager** - Add and manage UNIQUE and CHECK constraints (API ready, UI in progress) - 📊 **SQL Query Interface** - Execute custom queries with safety validation - 🔒 **JWT Authentication** with secure session management - 📦 **DrizzleORM** - Support for PostgreSQL, MySQL, and SQLite @@ -73,6 +74,7 @@ This is a **PostgreSQL database administration panel** that provides: - 📊 **Database viewing** - Browse tables, view data, and explore schema - 🛠️ **Table management** - Create and drop tables through intuitive UI - 🔧 **Column management** - Add, modify, and drop columns with type selection +- 🔐 **Constraint management** - Add UNIQUE and CHECK constraints for data validation - 🔍 **SQL query interface** - Execute SELECT queries safely with result display - 🐳 **All-in-one Docker image** - PostgreSQL 15 and admin UI in one container - ⚡ **Production-ready** - Deploy to Caprover, Docker, or any cloud platform @@ -765,13 +767,16 @@ See [ROADMAP.md](ROADMAP.md) for planned features and improvements. - ✅ Table Manager - Create and drop tables with visual column builder - ✅ Column Manager - Add, modify, and drop columns from existing tables - ✅ Schema management interface for table and column operations +- 🔄 Constraint Manager - Add and manage UNIQUE and CHECK constraints (API complete, UI in progress) **Upcoming features:** +- Complete constraint management UI - Visual database designer - Multi-database server connections - Advanced query builder - Export data (CSV, JSON, SQL) - Foreign key relationship management +- Index management - User management with roles ## Contributing diff --git a/ROADMAP.md b/ROADMAP.md index 11cbb4b..0446461 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -60,7 +60,14 @@ See `src/config/features.json` for the complete feature configuration. - [x] ✅ Create schema management interface - [x] ✅ Implement table creation/editing UI (API ready, UI implemented) - [x] ✅ Add column type management UI (API ready, UI implemented) - - [ ] Add data validation and constraints management + - [ ] Add data validation and constraints management 🏗️ **IN PROGRESS** + - [x] ✅ Implement constraints API (UNIQUE, CHECK constraints) + - [x] ✅ Add constraint listing endpoint + - [x] ✅ Add constraint creation/deletion endpoints + - [ ] Build constraints management UI + - [ ] Add PRIMARY KEY constraint support + - [ ] Add DEFAULT value management + - [ ] Add NOT NULL constraint management - [ ] Build query builder interface - [ ] Add foreign key relationship management - [ ] Implement index management UI diff --git a/TESTING.md b/TESTING.md index 45c7ebd..33b873f 100644 --- a/TESTING.md +++ b/TESTING.md @@ -144,12 +144,58 @@ All tests verify that: ## Test Coverage Summary -| Feature | API Tests | UI Tests | Security Tests | Total Tests | -|---------|-----------|----------|----------------|-------------| -| Table Manager | 7 | 2 (2 skipped) | 3 | 12 | -| Column Manager | 9 | 2 (2 skipped) | 3 | 14 | -| Admin Dashboard | - | 3 | 3 | 6 | -| **Total** | **16** | **7** | **9** | **32** | +| Feature | API Tests | UI Tests | Security Tests | Unit Tests | Total Tests | +|---------|-----------|----------|----------------|------------|-------------| +| Feature Config | - | - | - | 40 | 40 | +| Table Manager | 7 | 2 (2 skipped) | 3 | - | 12 | +| Column Manager | 9 | 2 (2 skipped) | 3 | - | 14 | +| Constraint Manager | 14 | 0 (UI pending) | 3 | 4 | 21 | +| Admin Dashboard | - | 3 | 3 | - | 6 | +| **Total** | **30** | **7** | **12** | **44** | **93** | + +## Feature: Constraint Management Tests + +### Integration Tests (Playwright API Tests) + +#### 1. `tests/integration/ConstraintManager.spec.ts` +Tests for the Constraint Management API endpoints (`/api/admin/constraints`): + +**List Constraints Tests:** +- ✅ Rejects list without authentication +- ✅ Rejects list without table name +- ✅ Rejects list with invalid table name + +**Add Constraint Tests:** +- ✅ Rejects add without authentication +- ✅ Rejects add without required fields +- ✅ Rejects add with invalid table name +- ✅ Rejects UNIQUE constraint without column name +- ✅ Rejects CHECK constraint without expression +- ✅ Rejects CHECK constraint with dangerous expression (SQL injection prevention) +- ✅ Rejects unsupported constraint types + +**Drop Constraint Tests:** +- ✅ Rejects drop without authentication +- ✅ Rejects drop without required fields +- ✅ Rejects drop with invalid identifiers + +**Test Coverage:** +- Input validation +- SQL injection prevention +- Authentication/authorization +- Error handling for all CRUD operations +- Support for UNIQUE and CHECK constraints + +### Unit Tests + +#### 2. `src/utils/featureConfig.test.ts` +Tests for the constraint types configuration: + +**Constraint Types Tests:** +- ✅ Returns array of constraint types +- ✅ Validates constraint type properties +- ✅ Includes UNIQUE constraint type with correct flags +- ✅ Includes CHECK constraint type with correct flags ## Future Test Improvements diff --git a/src/app/api/admin/constraints/route.ts b/src/app/api/admin/constraints/route.ts index 272a41b..d0afb8c 100644 --- a/src/app/api/admin/constraints/route.ts +++ b/src/app/api/admin/constraints/route.ts @@ -5,7 +5,7 @@ import { getSession } from '@/utils/session'; // Validate identifier format (prevent SQL injection) function isValidIdentifier(name: string): boolean { - return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name); + return /^[a-z_]\w*$/i.test(name); } // Validate table exists diff --git a/src/utils/featureConfig.ts b/src/utils/featureConfig.ts index e0afa72..4fa3128 100644 --- a/src/utils/featureConfig.ts +++ b/src/utils/featureConfig.ts @@ -57,7 +57,7 @@ export function getConstraintTypes(): ConstraintType[] { } export function getNavItems(): NavItem[] { - return featuresConfig.navItems.filter(item => { + return featuresConfig.navItems.filter((item) => { const feature = getFeatureById(item.featureId); return feature && feature.enabled; });