database-naming-standards.md
Database naming standards that prioritize consistency with TypeScript code conventions to eliminate mapping overhead and reduce bugs
database-naming-standards.mdv1.0.07 KB
database-naming-standards.md(markdown)
1# Database Naming Standards: Code-First Approach
2
3## Overview
4
5This document establishes database naming standards that prioritize consistency with TypeScript/JavaScript code conventions. Our approach eliminates mapping overhead and reduces bugs by using identical naming across all layers.
6
7## Core Principle: Code-First Naming
8
9**The database naming follows the code naming conventions, not the reverse.**
10
11In TypeScript/JavaScript, we use camelCase for properties and methods. Therefore, our database columns, parameters, and entity properties all use camelCase to maintain perfect consistency.
12
13## Why Code-First Naming
14
15### 1. **Direct Object Mapping**
16No translation layer needed between database results and TypeScript objects:
17
18```typescript
19// ✅ PERFECT: Database result maps directly to TypeScript object
20const user = await db.queryOne<User>("SELECT id, email, firstName FROM Users WHERE id = @id", { id });
21// Result: { id: "123", email: "test@example.com", firstName: "John" }
22// No mapping required - properties match exactly
23```
24
25### 2. **Eliminates Mapping Bugs**
26Common mapping errors are completely avoided:
27
28```typescript
29// ❌ MAPPING ERRORS (with snake_case database):
30// Developer forgets to map snake_case to camelCase
31const user = {
32 id: result.id,
33 email: result.email,
34 firstName: result.first_name, // Easy to miss this mapping
35 createdAt: result.created_at // Or forget this one
36};
37
38// ✅ NO MAPPING NEEDED (with camelCase database):
39const user = result; // Direct assignment, no errors possible
40```
41
42### 3. **Reduced Development Overhead**
43- No mapping configuration to maintain
44- No translation utilities to write/debug
45- Fewer places for bugs to hide
46- Simpler code reviews
47
48### 4. **Better ORM Compatibility**
49Most TypeScript ORMs work more naturally with camelCase:
50
51```typescript
52// ✅ NATURAL: ORM properties match database directly
53@Entity('Users')
54class User {
55 @Column()
56 id: string;
57
58 @Column()
59 email: string;
60
61 @Column()
62 firstName: string; // Maps directly to database column
63}
64```
65
66### 5. **Parameter Consistency**
67SQL parameters match object properties exactly:
68
69```typescript
70// ✅ CONSISTENT: Same names throughout
71const user = { id: "123", email: "new@example.com" };
72await db.execute("UPDATE Users SET email = @email WHERE id = @id", user);
73// Object properties match parameter names exactly
74```
75
76## Database Naming Standards
77
78### Table Names
79- **PascalCase**: `Users`, `UserSessions`, `ApiKeys`, `ProjectMembers`
80- Rationale: Clear distinction from columns, matches C# entity conventions
81
82### Column Names
83- **camelCase**: `id`, `email`, `firstName`, `createdAt`, `lastLoginAt`
84- Rationale: Matches TypeScript property naming exactly
85
86### Primary Keys
87- **Always**: `id` (camelCase)
88- **Foreign Keys**: `userId`, `projectId`, `organizationId` (camelCase)
89
90### SQL Parameters
91- **camelCase**: `@id`, `@email`, `@firstName`, `@createdAt`
92- Rationale: Match column names and object properties exactly
93
94### Indexes
95- **Format**: `IX_{TableName}_{columnName}`: `IX_Users_email`, `IX_Users_createdAt`
96
97## Standard Implementation Pattern
98
99### Entity Interface
100```typescript
101interface User {
102 id: string;
103 email: string;
104 firstName: string;
105 lastName: string;
106 emailVerified: boolean;
107 emailVerificationToken?: string;
108 emailVerificationExpires?: Date;
109 createdAt: Date;
110 updatedAt?: Date;
111}
112```
113
114### Database Schema
115```sql
116CREATE TABLE Users (
117 id UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),
118 email NVARCHAR(255) NOT NULL UNIQUE,
119 firstName NVARCHAR(255) NOT NULL,
120 lastName NVARCHAR(255) NOT NULL,
121 emailVerified BIT NOT NULL DEFAULT 0,
122 emailVerificationToken UNIQUEIDENTIFIER NULL,
123 emailVerificationExpires DATETIME2 NULL,
124 createdAt DATETIME2 NOT NULL DEFAULT GETUTCDATE(),
125 updatedAt DATETIME2 NULL
126);
127```
128
129### Repository Queries
130```typescript
131// ✅ PERFECT CONSISTENCY: All names match across layers
132async findByEmail(email: string): Promise<User | null> {
133 const query = `SELECT * FROM Users WHERE email = @email`;
134 return await this.db.queryOne<User>(query, { email });
135}
136
137async updateProfile(id: string, data: { firstName?: string; lastName?: string }): Promise<User | null> {
138 const updates = Object.keys(data).map(key => `${key} = @${key}`).join(', ');
139 const query = `
140 UPDATE Users
141 SET ${updates}, updatedAt = GETUTCDATE()
142 OUTPUT INSERTED.*
143 WHERE id = @id
144 `;
145
146 const result = await this.db.query<User>(query, { ...data, id });
147 return result[0] || null;
148}
149```
150
151## Required Standard Columns
152
153### Every Entity Table Must Include:
154- `id` - Primary key (UNIQUEIDENTIFIER)
155- `createdAt` - Creation timestamp (DATETIME2, NOT NULL, DEFAULT GETUTCDATE())
156- `updatedAt` - Last update timestamp (DATETIME2, NULL)
157
158### Audit Tables Should Include:
159- `modifiedBy` - User who made the change
160- `modifiedAt` - When change was made
161- `changeReason` - Optional reason for change
162
163## AI Model Instructions
164
165### For Code Generation:
166When generating database-related code, always:
167
1681. **Use camelCase for all database columns and entity properties**
1692. **Use camelCase for all SQL parameters matching column names exactly**
1703. **Use PascalCase for table names only**
1714. **Ensure parameter names match column names exactly: `@email` matches column `email`**
1725. **Include standard columns: `id`, `createdAt`, `updatedAt`**
173
174### Template Pattern:
175```typescript
176interface EntityName {
177 id: string;
178 someProperty: string; // camelCase property
179 anotherProperty: number; // camelCase property
180 createdAt: Date;
181 updatedAt?: Date;
182}
183
184// SQL uses same naming
185const query = `
186 SELECT id, someProperty, anotherProperty, createdAt, updatedAt
187 FROM EntityNames
188 WHERE someProperty = @someProperty AND id = @id
189`;
190```
191
192## Benefits Summary
193
194### Development Benefits:
195- **Faster Development**: No mapping code to write
196- **Fewer Bugs**: No translation errors possible
197- **Simpler Debugging**: Same names in logs, database, and code
198- **Better Tooling**: IDE autocomplete works across all layers
199
200### Maintenance Benefits:
201- **Easier Refactoring**: Rename once, works everywhere
202- **Clearer Code Reviews**: No mental translation needed
203- **Reduced Complexity**: Fewer abstraction layers
204- **Better Documentation**: Same terminology throughout
205
206### Performance Benefits:
207- **No Mapping Overhead**: Direct object assignment
208- **Smaller Bundle Size**: No mapping utilities needed
209- **Better ORM Performance**: Natural property mapping
210
211## Migration Notes
212
213When updating existing systems:
2141. Rename database columns to camelCase
2152. Update all SQL queries to use camelCase parameters
2163. Update entity interfaces to match database exactly
2174. Remove any mapping/transformation code
2185. Update documentation and examples
219
220## Enforcement
221
222### Required Checks:
223- [ ] Entity interfaces use camelCase properties
224- [ ] Database columns use camelCase naming
225- [ ] SQL parameters use camelCase matching columns exactly
226- [ ] Table names use PascalCase
227- [ ] No mapping/transformation code exists between database and entities
228
229This approach prioritizes practical development concerns over naming convention traditions, resulting in cleaner, more maintainable, and less error-prone code.
Metadata
- Path
- utaba/main/guidance/development/database-naming-standards.md
- Namespace
- utaba/main/guidance/development
- Author
- utaba
- Category
- guidance
- Technology
- typescript
- Contract Version
- 1.0.0
- MIME Type
- text/markdown
- Published
- 18-Jul-2025
- Last Updated
- 18-Jul-2025