# Database Naming Standards

> Database Naming Standards

- Skill: `construct-ai-primary/database-naming-standards` (Agent Skill)
- Install (CLI): `npx skillmds@latest add construct-ai-primary/database-naming-standards`
- Raw SKILL.md: https://api.skillmd.com/api/skills/construct-ai-primary/database-naming-standards/raw
- Safety review: PASS (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Construct-AI-primary (https://skillmd.com/u/construct-ai-primary)
- Updated: 2026-08-19
- Page: https://skillmd.com/skills/construct-ai-primary/database-naming-standards

---


# Database Naming Standards

## Overview

**Core principle:** Enforce comprehensive naming conventions for all database objects ensuring consistency, maintainability, and efficient discovery across the Construct AI database schema.

**Critical standards:** All database objects follow standardized patterns enforced by automated validation tools through the Supabase Table Creation Agent.

## When to Use This Skill

**Trigger Conditions:**
- Before creating any new database tables, views, or indexes
- When designing database schemas for new features
- Before implementing database migrations
- When reviewing database schema changes
- During database refactoring or optimization
- When onboarding new team members to database development
- When troubleshooting database object discovery issues

**Mandatory Application:**
- Required for all new database object creation
- Must be enforced by Supabase Table Creation Agent
- Required for database schema reviews
- Must be validated before production deployment
- Required for database naming consistency audits

## Step-by-Step Procedure

### Step 1: Understand Naming Convention Categories
**Master the core naming patterns and their applications:**

```javascript
// Core naming convention categories
const namingConventions = {
  tableNaming: {
    disciplineTables: {
      pattern: 'a_{discipline_code}_{entity}_{descriptor}',
      examples: [
        'a_01900_procurement_orders',
        'a_00850_civileng_specifications',
        'a_02400_safety_incidents'
      ],
      validation: /^a_\d{5}_[a-z]+_[a-z_]+$/
    },
    
    coreTables: {
      pattern: 'a_{entity}_{descriptor}',
      examples: [
        'a_users',
        'a_projects',
        'a_tasks'
      ],
      validation: /^a_[a-z]+(_[a-z]+)*$/
    },
    
    relationshipTables: {
      pattern: 'a_{entity1}_{entity2}_{relation}',
      examples: [
        'a_users_projects_assignments',
        'a_projects_contracts_links'
      ],
      validation: /^a_[a-z]+_[a-z]+_[a-z]+$/
    },
    
    vectorTables: {
      pattern: 'a_{discipline_code}_{entity}_vector',
      examples: [
        'a_01900_procurement_vector',
        'a_00850_civileng_vector'
      ],
      validation: /^a_\d{5}_[a-z]+_vector$/
    },
    
    temporaryTables: {
      pattern: 't_{purpose}_{descriptor}',
      examples: [
        't_session_cache',
        't_etl_processing_queue'
      ],
      validation: /^t_[a-z]+(_[a-z]+)*$/
    }
  },

  columnNaming: {
    primaryKeys: {
      pattern: '{singular_table_entity}_id',
      examples: [
        'user_id',
        'project_id',
        'procurement_order_id'
      ]
    },
    
    foreignKeys: {
      pattern: '{referenced_table_entity}_id',
      examples: [
        'user_id', // REFERENCES users.user_id
        'created_by_user_id',
        'organization_id'
      ]
    },
    
    dataColumns: {
      pattern: '{descriptor}_{data_type} or {entity}_{descriptor}',
      examples: [
        'first_name',
        'email_address',
        'is_active',
        'created_at'
      ]
    },
    
    statusColumns: {
      pattern: '{entity}_status or {entity}_type',
      examples: [
        'user_status',
        'contract_type',
        'organization_role'
      ]
    }
  },

  indexNaming: {
    primaryKeys: 'Generated by PostgreSQL as {table_name}_pkey',
    uniqueIndexes: 'idx_{table_name}_{column1}_{column2}_unique',
    performanceIndexes: 'idx_{table_name}_{column1}_{column2}',
    foreignKeyIndexes: 'idx_{table_name}_{referenced_table}_{column}'
  },

  constraintNaming: {
    uniqueConstraints: 'uk_{table_name}_{column1}_{column2}',
    checkConstraints: 'chk_{table_name}_{condition}_name',
    foreignKeyConstraints: 'fk_{table_name}_{referenced_table}_{column}'
  }
};

// Discipline code reference
const disciplineCodes = {
  '01900': 'Procurement',
  '02400': 'Safety',
  '01100': 'Ethics',
  '00850': 'Civil Engineering',
  '02050': 'IT',
  '01300': 'Governance',
  '01200': 'Finance',
  '01500': 'HR',
  '01750': 'Legal',
  '01800': 'Operations'
};
```

**Convention Categories:**
- Table naming patterns (discipline, core, relationship, vector, temporary)
- Column naming standards (primary keys, foreign keys, data columns, status columns)
- Index naming conventions (primary, unique, performance, foreign key)
- Constraint naming patterns (unique, check, foreign key)

### Step 2: Validate Table Name Compliance
**Ensure new table names follow established patterns:**

```javascript
// Table name validation function
function validateTableName(tableName, context) {
  const validation = {
    isValid: false,
    pattern: null,
    suggestions: [],
    disciplineCode: null,
    errors: []
  };

  // Check for required prefix
  if (!tableName.startsWith('a_') && !tableName.startsWith('t_') && !tableName.startsWith('v_')) {
    validation.errors.push('Table name must start with a_, t_, or v_ prefix');
    validation.suggestions.push(`Add appropriate prefix: a_${tableName}, t_${tableName}, or v_${tableName}`);
    return validation;
  }

  // Validate discipline-specific tables (a_XXXXX_*)
  if (tableName.startsWith('a_') && /^\d{5}/.test(tableName.substring(2))) {
    const disciplineMatch = tableName.match(/^a_(\d{5})_([a-z]+)_([a-z_]+)$/);
    if (disciplineMatch) {
      const [, code, entity, descriptor] = disciplineMatch;
      if (isValidDisciplineCode(code)) {
        validation.isValid = true;
        validation.pattern = 'discipline';
        validation.disciplineCode = code;
      } else {
        validation.errors.push(`Invalid discipline code: ${code}`);
        validation.suggestions.push('Use valid 5-digit discipline code from reference table');
      }
    } else {
      validation.errors.push('Discipline table pattern: a_XXXXX_entity_descriptor');
      validation.suggestions.push(`Correct format: a_XXXXX_${tableName.substring(tableName.indexOf('_', 3) + 1)}`);
    }
  }

  // Validate core tables (a_*)
  else if (tableName.startsWith('a_') && !/^\d{5}/.test(tableName.substring(2))) {
    if (/^a_[a-z]+(_[a-z]+)*$/.test(tableName)) {
      validation.isValid = true;
      validation.pattern = 'core';
    } else {
      validation.errors.push('Core table pattern: a_entity_descriptor (snake_case only)');
      validation.suggestions.push(`Use snake_case: ${tableName.replace(/([A-Z])/g, '_$1').toLowerCase()}`);
    }
  }

  // Validate temporary tables (t_*)
  else if (tableName.startsWith('t_')) {
    if (/^t_[a-z]+(_[a-z]+)*$/.test(tableName)) {
      validation.isValid = true;
      validation.pattern = 'temporary';
    } else {
      validation.errors.push('Temporary table pattern: t_purpose_descriptor');
      validation.suggestions.push(`Use snake_case: ${tableName.replace(/([A-Z])/g, '_$1').toLowerCase()}`);
    }
  }

  // Check for camelCase violations
  if (tableName.match(/[A-Z][a-z]/)) {
    validation.errors.push('Table names must use snake_case, not camelCase');
    validation.suggestions.push(`Convert to snake_case: ${tableName.replace(/([A-Z])/g, '_$1').toLowerCase()}`);
  }

  return validation;
}

// Validate discipline code
function isValidDisciplineCode(code) {
  const validCodes = [
    '00250', '00300', '00400', '00425', '00430', '00435',
    '00825', '00835', '00850', '00855', '00860', '00870',
    '00871', '00872', '00877', '00880', '00882', '00883',
    '00884', '00885', '00886', '00888', '00889', '00890',
    '00895', '00900', '01000', '01100', '01200', '01300',
    '01400', '01500', '01600', '01700', '01750', '01800',
    '01850', '01900', '02000', '02025', '02035', '02050',
    '02075', '02200', '02250', '02400', '02500', '03000'
  ];
  return validCodes.includes(code);
}

// Generate table name suggestions
function generateTableNameSuggestions(entity, descriptor, disciplineCode = null) {
  const suggestions = [];

  if (disciplineCode) {
    suggestions.push(`a_${disciplineCode}_${entity}_${descriptor}`);
    suggestions.push(`a_${disciplineCode}_${entity}${descriptor ? `_${descriptor}` : ''}`);
  } else {
    suggestions.push(`a_${entity}_${descriptor}`);
    suggestions.push(`a_${entity}${descriptor ? `_${descriptor}` : ''}`);
  }

  return suggestions;
}
```

**Table Validation:**
- Prefix validation (a_, t_, v_)
- Discipline code verification for domain-specific tables
- Pattern matching for different table types
- Snake_case enforcement (no camelCase)
- Automatic suggestion generation

### Step 3: Validate Column Name Standards
**Ensure column names follow proper naming conventions:**

```javascript
// Column name validation function
function validateColumnName(columnName, tableName, context) {
  const validation = {
    isValid: false,
    type: null,
    suggestions: [],
    errors: []
  };

  // Primary key validation
  if (columnName.endsWith('_id') && context.isPrimaryKey) {
    const expectedName = getSingularEntityName(tableName) + '_id';
    if (columnName === expectedName) {
      validation.isValid = true;
      validation.type = 'primary_key';
    } else {
      validation.errors.push(`Primary key should be: ${expectedName}`);
      validation.suggestions.push(expectedName);
    }
  }

  // Foreign key validation
  else if (columnName.endsWith('_id') && context.isForeignKey) {
    const referencedTable = context.referencedTable;
    const expectedName = getSingularEntityName(referencedTable) + '_id';
    if (columnName === expectedName) {
      validation.isValid = true;
      validation.type = 'foreign_key';
    } else {
      validation.errors.push(`Foreign key should reference: ${expectedName}`);
      validation.suggestions.push(expectedName);
    }
  }

  // Status/type column validation
  else if (columnName.includes('_status') || columnName.includes('_type')) {
    const entity = columnName.replace(/_(status|type)$/, '');
    if (isValidEntityName(entity)) {
      validation.isValid = true;
      validation.type = columnName.includes('_status') ? 'status_column' : 'type_column';
    } else {
      validation.errors.push('Status/type columns should follow: entity_status or entity_type');
      validation.suggestions.push(`${entity}_status`, `${entity}_type`);
    }
  }

  // Standard column validation
  else {
    if (/^[a-z]+(_[a-z]+)*$/.test(columnName)) {
      validation.isValid = true;
      validation.type = 'data_column';
    } else {
      validation.errors.push('Column names must use snake_case');
      validation.suggestions.push(columnName.replace(/([A-Z])/g, '_$1').toLowerCase());
    }
  }

  // Audit column validation
  if (context.isAuditColumn) {
    const auditColumns = [
      'created_by_user_id', 'created_at',
      'updated_by_user_id', 'updated_at',
      'deleted_by_user_id', 'deleted_at'
    ];
    if (!auditColumns.includes(columnName)) {
      validation.errors.push('Audit columns must follow standard naming');
      validation.suggestions.push(...auditColumns);
    }
  }

  return validation;
}

// Get singular entity name from table name
function getSingularEntityName(tableName) {
  // Remove prefix
  let entity = tableName.replace(/^(a|t|v)_/, '');
  
  // Remove discipline code if present
  entity = entity.replace(/^\d{5}_/, '');
  
  // Convert to singular (basic plural removal)
  if (entity.endsWith('ies')) {
    entity = entity.slice(0, -3) + 'y';
  } else if (entity.endsWith('s') && !entity.endsWith('ss')) {
    entity = entity.slice(0, -1);
  }
  
  return entity;
}

// Validate entity name
function isValidEntityName(entity) {
  return /^[a-z]+(_[a-z]+)*$/.test(entity) && !entity.includes('table') && !entity.includes('data');
}
```

**Column Validation:**
- Primary key naming standards
- Foreign key reference patterns
- Status and type column conventions
- Snake_case enforcement
- Audit column standards

### Step 4: Validate Index and Constraint Names
**Ensure indexes and constraints follow naming standards:**

```javascript
// Index and constraint validation
function validateIndexAndConstraints(schema) {
  const validation = {
    indexes: [],
    constraints: [],
    errors: [],
    suggestions: []
  };

  // Validate indexes
  for (const index of schema.indexes) {
    const indexValidation = validateIndexName(index.name, index.table, index.columns);
    validation.indexes.push(indexValidation);
    
    if (!indexValidation.isValid) {
      validation.errors.push(...indexValidation.errors);
      validation.suggestions.push(...indexValidation.suggestions);
    }
  }

  // Validate constraints
  for (const constraint of schema.constraints) {
    const constraintValidation = validateConstraintName(constraint.name, constraint.type, constraint.table);
    validation.constraints.push(constraintValidation);
    
    if (!constraintValidation.isValid) {
      validation.errors.push(...constraintValidation.errors);
      validation.suggestions.push(...constraintValidation.suggestions);
    }
  }

  return validation;
}

// Validate index name
function validateIndexName(indexName, tableName, columns) {
  const validation = {
    isValid: false,
    type: null,
    suggestions: [],
    errors: []
  };

  // Primary key index (auto-generated)
  if (indexName === `${tableName}_pkey`) {
    validation.isValid = true;
    validation.type = 'primary_key';
  }

  // Unique index
  else if (indexName.includes('_unique')) {
    const expectedPattern = `idx_${tableName}_${columns.join('_')}_unique`;
    if (indexName === expectedPattern) {
      validation.isValid = true;
      validation.type = 'unique_index';
    } else {
      validation.errors.push(`Unique index should be: ${expectedPattern}`);
      validation.suggestions.push(expectedPattern);
    }
  }

  // Performance index
  else if (indexName.startsWith(`idx_${tableName}_`)) {
    const columnPart = indexName.replace(`idx_${tableName}_`, '');
    const expectedColumns = columnPart.split('_');
    if (arraysEqual(expectedColumns, columns)) {
      validation.isValid = true;
      validation.type = 'performance_index';
    } else {
      const expectedName = `idx_${tableName}_${columns.join('_')}`;
      validation.errors.push(`Performance index should be: ${expectedName}`);
      validation.suggestions.push(expectedName);
    }
  }

  // Foreign key index
  else if (indexName.includes('_id')) {
    const column = columns[0];
    if (column && column.endsWith('_id')) {
      const referencedEntity = column.replace('_id', '');
      const expectedName = `idx_${tableName}_${referencedEntity}_id`;
      if (indexName === expectedName) {
        validation.isValid = true;
        validation.type = 'foreign_key_index';
      } else {
        validation.errors.push(`Foreign key index should be: ${expectedName}`);
        validation.suggestions.push(expectedName);
      }
    }
  }

  else {
    validation.errors.push('Index name does not follow naming conventions');
    validation.suggestions.push(`idx_${tableName}_${columns.join('_')}`);
  }

  return validation;
}

// Validate constraint name
function validateConstraintName(constraintName, type, tableName) {
  const validation = {
    isValid: false,
    suggestions: [],
    errors: []
  };

  switch (type) {
    case 'UNIQUE':
      if (constraintName.startsWith('uk_')) {
        validation.isValid = true;
      } else {
        validation.errors.push('Unique constraints should start with uk_');
        validation.suggestions.push(`uk_${constraintName}`);
      }
      break;

    case 'CHECK':
      if (constraintName.startsWith('chk_')) {
        validation.isValid = true;
      } else {
        validation.errors.push('Check constraints should start with chk_');
        validation.suggestions.push(`chk_${constraintName}`);
      }
      break;

    case 'FOREIGN KEY':
      if (constraintName.startsWith('fk_')) {
        validation.isValid = true;
      } else {
        validation.errors.push('Foreign key constraints should start with fk_');
        validation.suggestions.push(`fk_${constraintName}`);
      }
      break;

    default:
      validation.errors.push(`Unknown constraint type: ${type}`);
  }

  return validation;
}

// Utility function to compare arrays
function arraysEqual(a, b) {
  if (a.length !== b.length) return false;
  return a.every((val, index) => val === b[index]);
}
```

**Index and Constraint Validation:**
- Primary key index patterns
- Unique index naming standards
- Performance index conventions
- Foreign key index patterns
- Constraint naming by type (unique, check, foreign key)

### Step 5: Automated Validation with Supabase Agent
**Use the Supabase Table Creation Agent for comprehensive validation:**

```javascript
// Supabase Table Creation Agent integration
class DatabaseNamingValidator {
  constructor() {
    this.disciplineCodes = this.loadDisciplineCodes();
    this.validationRules = this.loadValidationRules();
  }

  // Complete schema validation
  async validateSchema(schema) {
    const validationReport = {
      tables: [],
      columns: [],
      indexes: [],
      constraints: [],
      overallCompliance: 0,
      criticalIssues: [],
      recommendations: []
    };

    // Validate all tables
    for (const table of schema.tables) {
      const tableValidation = await this.validateTable(table);
      validationReport.tables.push(tableValidation);
      
      if (!tableValidation.isValid) {
        validationReport.criticalIssues.push({
          type: 'table_naming',
          table: table.name,
          issues: tableValidation.errors
        });
      }
    }

    // Validate all columns
    for (const column of schema.columns) {
      const columnValidation = await this.validateColumn(column);
      validationReport.columns.push(columnValidation);
    }

    // Validate indexes and constraints
    const indexConstraintValidation = await this.validateIndexesAndConstraints(schema);
    validationReport.indexes = indexConstraintValidation.indexes;
    validationReport.constraints = indexConstraintValidation.constraints;

    // Calculate overall compliance
    validationReport.overallCompliance = this.calculateCompliance(validationReport);
    validationReport.recommendations = this.generateRecommendations(validationReport);

    return validationReport;
  }

  // Validate individual table
  async validateTable(table) {
    const validation = {
      name: table.name,
      isValid: true,
      errors: [],
      warnings: [],
      suggestions: []
    };

    // Basic naming validation
    const nameValidation = validateTableName(table.name, { discipline: table.discipline });
    if (!nameValidation.isValid) {
      validation.isValid = false;
      validation.errors.push(...nameValidation.errors);
      validation.suggestions.push(...nameValidation.suggestions);
    }

    // Check for required audit columns
    const hasAuditColumns = this.checkAuditColumns(table.columns);
    if (!hasAuditColumns) {
      validation.warnings.push('Missing standard audit columns (created_by, updated_by, etc.)');
    }

    // Check for primary key
    const hasPrimaryKey = table.columns.some(col => col.isPrimaryKey);
    if (!hasPrimaryKey) {
      validation.errors.push('Table must have a primary key');
      validation.isValid = false;
    }

    return validation;
  }

  // Check for required audit columns
  checkAuditColumns(columns) {
    const requiredAuditColumns = [
      'created_by_user_id',
      'created_at',
      'updated_by_user_id',
      'updated_at'
    ];

    return requiredAuditColumns.every(auditCol => 
      columns.some(col => col.name === auditCol)
    );
  }

  // Calculate overall compliance percentage
  calculateCompliance(validationReport) {
    const totalItems = 
      validationReport.tables.length + 
      validationReport.columns.length + 
      validationReport.indexes.length + 
      validationReport.constraints.length;

    const validItems = 
      validationReport.tables.filter(t => t.isValid).length +
      validationReport.columns.filter(c => c.isValid).length +
      validationReport.indexes.filter(i => i.isValid).length +
      validationReport.constraints.filter(c => c.isValid).length;

    return totalItems > 0 ? (validItems / totalItems) * 100 : 0;
  }

  // Generate recommendations
  generateRecommendations(validationReport) {
    const recommendations = [];

    if (validationReport.overallCompliance < 80) {
      recommendations.push('Critical: Overall compliance below 80%. Address naming issues before deployment.');
    }

    if (validationReport.criticalIssues.length > 0) {
      recommendations.push(`Address ${validationReport.criticalIssues.length} critical naming issues.`);
    }

    if (validationReport.tables.some(t => !t.isValid)) {
      recommendations.push('Review table naming conventions and correct invalid names.');
    }

    recommendations.push('Use Supabase Table Creation Agent for all new table creation to ensure compliance.');

    return recommendations;
  }
}

// Agent usage example
async function createTableWithValidation(tableSchema) {
  const agent = new SupabaseTableCreationAgent();
  const validator = new DatabaseNamingValidator();
  
  // First validate the schema
  const validation = await validator.validateSchema({ tables: [tableSchema] });
  
  if (validation.overallCompliance < 100) {
    throw new Error(`Schema validation failed: ${validation.criticalIssues.length} critical issues found`);
  }
  
  // If validation passes, create the table
  return await agent.createTable(tableSchema);
}
```

**Agent Integration:**
- Complete schema validation before creation
- Automated compliance checking
- Critical issue identification
- Recommendation generation
- Integration with table creation workflow

### Step 6: Generate Compliance Report and Recommendations
**Create comprehensive compliance assessment and improvement plan:**

```javascript
// Generate compliance report
function generateComplianceReport(validationResults, schema) {
  const report = {
    executiveSummary: {
      overallCompliance: validationResults.overallCompliance,
      totalIssues: validationResults.criticalIssues.length,
      complianceLevel: getComplianceLevel(validationResults.overallCompliance),
      deploymentReadiness: validationResults.overallCompliance >= 95 ? 'READY' : 'REQUIRES_FIXES'
    },
    
    detailedFindings: {
      tableCompliance: generateTableComplianceSummary(validationResults.tables),
      columnCompliance: generateColumnComplianceSummary(validationResults.columns),
      indexCompliance: generateIndexComplianceSummary(validationResults.indexes),
      constraintCompliance: generateConstraintComplianceSummary(validationResults.constraints)
    },
    
    criticalIssues: validationResults.criticalIssues,
    
    improvementPlan: {
      immediateActions: [],
      shortTermGoals: [],
      longTermObjectives: [],
      preventiveMeasures: []
    },
    
    successMetrics: {
      targetCompliance: 98,
      currentCompliance: validationResults.overallCompliance,
      issuesResolved: 0,
      tablesCreatedViaAgent: 0
    }
  };

  // Generate improvement plan
  report.improvementPlan = generateImprovementPlan(validationResults);
  
  // Add success metrics
  report.successMetrics = calculateSuccessMetrics(validationResults, schema);

  return report;
}

// Get compliance level description
function getComplianceLevel(percentage) {
  if (percentage >= 98) return 'EXCELLENT';
  if (percentage >= 95) return 'GOOD';
  if (percentage >= 90) return 'FAIR';
  if (percentage >= 80) return 'POOR';
  return 'CRITICAL';
}

// Generate improvement plan
function generateImprovementPlan(validationResults) {
  const plan = {
    immediateActions: [],
    shortTermGoals: [],
    longTermObjectives: [],
    preventiveMeasures: []
  };

  // Immediate actions for critical issues
  if (validationResults.criticalIssues.length > 0) {
    plan.immediateActions.push(
      `Fix ${validationResults.criticalIssues.length} critical naming issues`,
      'Review schema changes with database team',
      'Update documentation for corrected naming patterns'
    );
  }

  // Short-term goals
  plan.shortTermGoals = [
    'Achieve 95% naming compliance across all database objects',
    'Implement automated validation in CI/CD pipeline',
    'Train team members on naming standards',
    'Create naming standards quick reference guide'
  ];

  // Long-term objectives
  plan.longTermObjectives = [
    'Maintain 98%+ naming compliance for all new database objects',
    'Automate schema documentation generation',
    'Implement intelligent naming suggestions in development tools',
    'Establish database naming standards certification program'
  ];

  // Preventive measures
  plan.preventiveMeasures = [
    'Use Supabase Table Creation Agent for all table creation',
    'Implement pre-commit naming validation hooks',
    'Regular compliance audits and reporting',
    'Continuous improvement of naming standards based on usage patterns'
  ];

  return plan;
}

// Calculate success metrics
function calculateSuccessMetrics(validationResults, schema) {
  return {
    targetCompliance: 98.0,
    currentCompliance: validationResults.overallCompliance,
    issuesResolved: validationResults.criticalIssues.length,
    tablesCreatedViaAgent: schema.tables.filter(t => t.created_via_agent).length,
    complianceTrend: calculateComplianceTrend(validationResults),
    topIssueCategories: identifyTopIssueCategories(validationResults)
  };
}

// Generate detailed compliance summaries
function generateTableComplianceSummary(tables) {
  const summary = {
    totalTables: tables.length,
    compliantTables: tables.filter(t => t.isValid).length,
    nonCompliantTables: tables.filter(t => !t.isValid).length,
    topIssues: [],
    recommendations: []
  };

  // Calculate percentages
  summary.compliancePercentage = (summary.compliantTables / summary.totalTables) * 100;

  // Identify top issues
  const issueCounts = {};
  tables.forEach(table => {
    table.errors.forEach(error => {
      issueCounts[error] = (issueCounts[error] || 0) + 1;
    });
  });

  summary.topIssues = Object.entries(issueCounts)
    .sort(([,a], [,b]) => b - a)
    .slice(0, 5)
    .map(([issue, count]) => ({ issue, count }));

  // Generate recommendations
  if (summary.compliancePercentage < 90) {
    summary.recommendations.push('Critical: Table naming compliance below 90%');
  }

  summary.recommendations.push('Use Supabase Table Creation Agent for all new tables');
  summary.recommendations.push('Review existing tables for naming consistency opportunities');

  return summary;
}
```

**Compliance Reporting:**
- Executive summary with compliance levels
- Detailed findings by object type
- Critical issues identification
- Improvement plan generation
- Success metrics calculation

## Success Criteria

- [ ] Database object names validated against standards
- [ ] Table names follow appropriate patterns (discipline, core, relationship, vector, temporary)
- [ ] Column names use proper conventions (primary keys, foreign keys, data columns, status columns)
- [ ] Index names follow performance and uniqueness patterns
- [ ] Constraint names use type-specific prefixes
- [ ] Supabase Table Creation Agent used for validation
- [ ] Compliance report generated with improvement recommendations
- [ ] Critical naming issues identified and addressed

## Common Pitfalls

1. **Discipline Code Errors** - Using invalid or incorrect 5-digit discipline codes
2. **CamelCase Violations** - Using camelCase instead of required snake_case
3. **Missing Prefixes** - Forgetting required a_, t_, or v_ prefixes
4. **Inconsistent Entity Names** - Using different names for the same entity across tables
5. **Audit Column Omissions** - Missing required created_by, updated_by, etc. columns
6. **Index Naming Confusion** - Mixing up performance vs unique index naming patterns
7. **Foreign Key Reference Issues** - Incorrect foreign key column naming

## Cross-References

### Related Procedures
- [Database Schema Management](skills/database-schema-management/SKILL.md) - Schema design and optimization
- [Systematic Debugging](skills/systematic-debugging/SKILL.md) - Database issue troubleshooting
- [Verification Before Completion](skills/verification-before-completion/SKILL.md) - Schema validation

### Related Skills
- `database-schema-management` - Database design and schema creation
- `systematic-debugging` - Database issue investigation
- `verification-before-completion` - Schema validation and verification

### Related Agents
- `Supabase Table Creation Agent` - Automated table creation with validation
- `DevForge_AI_Team` - Database development assistance
- `QualityForge_AI_Team` - Database quality assurance and validation
