feat: Add constraint management API and configuration

- Add constraint-management feature to features.json
- Create /api/admin/constraints endpoint (GET, POST, DELETE)
- Support UNIQUE and CHECK constraints
- Add getConstraintTypes() utility function
- Add integration tests for constraints API
- Add unit tests for constraint types
- Follow CODE_STYLE.md guidelines

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-08 03:42:13 +00:00
parent a91f6d95fd
commit 5fb035e29c
5 changed files with 472 additions and 0 deletions

View File

@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest';
import {
getConstraintTypes,
getDataTypes,
getEnabledFeaturesByPriority,
getFeatureById,
@@ -257,6 +258,47 @@ describe('FeatureConfig', () => {
});
});
describe('getConstraintTypes', () => {
it('should return array of constraint types', () => {
const constraintTypes = getConstraintTypes();
expect(Array.isArray(constraintTypes)).toBe(true);
});
it('should return constraint types with required properties', () => {
const constraintTypes = getConstraintTypes();
constraintTypes.forEach(constraintType => {
expect(constraintType).toHaveProperty('name');
expect(constraintType).toHaveProperty('description');
expect(constraintType).toHaveProperty('requiresColumn');
expect(constraintType).toHaveProperty('requiresExpression');
expect(typeof constraintType.name).toBe('string');
expect(typeof constraintType.description).toBe('string');
expect(typeof constraintType.requiresColumn).toBe('boolean');
expect(typeof constraintType.requiresExpression).toBe('boolean');
});
});
it('should include UNIQUE constraint type', () => {
const constraintTypes = getConstraintTypes();
const uniqueConstraint = constraintTypes.find(ct => ct.name === 'UNIQUE');
expect(uniqueConstraint).toBeDefined();
expect(uniqueConstraint?.requiresColumn).toBe(true);
expect(uniqueConstraint?.requiresExpression).toBe(false);
});
it('should include CHECK constraint type', () => {
const constraintTypes = getConstraintTypes();
const checkConstraint = constraintTypes.find(ct => ct.name === 'CHECK');
expect(checkConstraint).toBeDefined();
expect(checkConstraint?.requiresColumn).toBe(false);
expect(checkConstraint?.requiresExpression).toBe(true);
});
});
describe('Feature endpoints', () => {
it('should have valid endpoint structure for database-crud', () => {
const feature = getFeatureById('database-crud');

View File

@@ -33,6 +33,13 @@ export type NavItem = {
featureId: string;
};
export type ConstraintType = {
name: string;
description: string;
requiresColumn: boolean;
requiresExpression: boolean;
};
export function getFeatures(): Feature[] {
return featuresConfig.features.filter(f => f.enabled);
}
@@ -45,6 +52,10 @@ export function getDataTypes(): DataType[] {
return featuresConfig.dataTypes;
}
export function getConstraintTypes(): ConstraintType[] {
return (featuresConfig as any).constraintTypes || [];
}
export function getNavItems(): NavItem[] {
return featuresConfig.navItems.filter(item => {
const feature = getFeatureById(item.featureId);