Standards
This section describes naming standards and conventions used throughout the Platform to ensure consistency, maintainability, and clarity across all development teams and projects.
Overview of Standards
Consistent standards across our platform enable:
- Team Collaboration: Common language and patterns across teams
- Code Maintainability: Predictable structure and naming
- Onboarding Efficiency: New team members understand conventions quickly
- Tool Integration: Automated tooling works reliably with consistent patterns
- Reduced Cognitive Load: Developers can focus on business logic, not naming decisions
Naming Philosophy
Our naming standards follow these core principles:
1. Clarity Over Brevity
Prefer descriptive names that clearly communicate intent:
// <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Clear intent
const userAuthenticationService = new AuthenticationService();
const isEmailAddressValid = validateEmail(email);
// <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid: Unclear abbreviations
const usrAuthSvc = new AuthSvc();
const isEmlValid = valEml(email);
2. Consistency Across Contexts
Use the same terminology for the same concepts:
// <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Consistent terminology
class UserRepository { /* ... */ }
class UserService { /* ... */ }
class UserController { /* ... */ }
// <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid: Mixed terminology for same domain
class PersonRepository { /* ... */ }
class UserService { /* ... */ }
class AccountController { /* ... */ }
3. Domain-Driven Language
Use terminology that reflects the business domain:
// <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Business domain language
class OrderFulfillmentService {
async processPayment(order: Order): Promise<PaymentResult> { /* ... */ }
async scheduleShipment(order: Order): Promise<ShipmentSchedule> { /* ... */ }
}
// <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid: Technical-only language
class DataProcessor {
async executeTransaction(data: Record<string, any>): Promise<any> { /* ... */ }
async updateRecords(data: Record<string, any>): Promise<any> { /* ... */ }
}
API and Service Standards
REST API Naming Conventions
Resource Naming
Use nouns for resources, following RESTful principles:
<CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good:
GET /api/v1/users
POST /api/v1/users
GET /api/v1/users/{id}
PUT /api/v1/users/{id}
DELETE /api/v1/users/{id}
GET /api/v1/users/{id}/orders
POST /api/v1/users/{id}/orders
<XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid:
GET /api/v1/getUsers
POST /api/v1/createUser
GET /api/v1/user_details/{id}
HTTP Method Usage
- GET: Retrieve resources (idempotent, safe)
- POST: Create new resources
- PUT: Update entire resources (idempotent)
- PATCH: Partial resource updates
- DELETE: Remove resources (idempotent)
Status Code Standards
// Success responses
200 OK // Successful GET, PUT, PATCH
201 Created // Successful POST
204 No Content // Successful DELETE, no body
// Client error responses
400 Bad Request // Invalid request syntax/data
401 Unauthorized // Authentication required
403 Forbidden // Valid request, insufficient permissions
404 Not Found // Resource doesn't exist
409 Conflict // Resource conflict (e.g., duplicate creation)
422 Unprocessable // Valid syntax, semantic errors
// Server error responses
500 Internal Server Error // Unexpected server error
502 Bad Gateway // Invalid upstream response
503 Service Unavailable // Temporary service issue
GraphQL Standards
Schema Naming
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Clear, consistent schema design
type User {
id: ID!
firstName: String!
lastName: String!
emailAddress: String!
createdAt: DateTime!
updatedAt: DateTime!
}
type Query {
user(id: ID!): User
users(filter: UserFilter, sort: UserSort, pagination: Pagination): UserConnection
}
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
deleteUser(id: ID!): DeleteUserPayload!
}
# <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid: Inconsistent or unclear naming
type Person {
uid: String
fname: String
surname: String
email: String
created: String
modified: String
}
gRPC Service Standards
Service Definition
// <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Clear service and method naming
syntax = "proto3";
package user.v1;
service UserService {
rpc GetUser(GetUserRequest) returns (GetUserResponse);
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
rpc CreateUser(CreateUserRequest) returns (CreateUserResponse);
rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse);
rpc DeleteUser(DeleteUserRequest) returns (DeleteUserResponse);
}
message User {
string id = 1;
string first_name = 2;
string last_name = 3;
string email_address = 4;
google.protobuf.Timestamp created_at = 5;
google.protobuf.Timestamp updated_at = 6;
}
Database Standards
Table and Column Naming
-- <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Consistent table and column naming
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
email_address VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
is_email_verified BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE TABLE user_roles (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
role_name VARCHAR(50) NOT NULL,
granted_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
granted_by BIGINT REFERENCES users(id)
);
-- <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid: Inconsistent naming patterns
CREATE TABLE User (
ID INT PRIMARY KEY,
FirstName NVARCHAR(100),
LastName NVARCHAR(100),
Email NVARCHAR(255),
PwdHash NVARCHAR(255),
EmailValid BIT,
DateCreated DATETIME,
DateModified DATETIME
);
Index Naming Conventions
-- <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Descriptive index names
CREATE INDEX idx_users_email_address ON users(email_address);
CREATE INDEX idx_users_created_at ON users(created_at);
CREATE INDEX idx_user_roles_user_id ON user_roles(user_id);
CREATE UNIQUE INDEX uniq_user_roles_user_role ON user_roles(user_id, role_name);
-- <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid: Generic or unclear index names
CREATE INDEX idx1 ON users(email_address);
CREATE INDEX user_idx ON users(created_at);
Code Organization Standards
Project Structure
Organize code in a predictable, scalable structure:
src/
├── components/ # Reusable UI components
│ ├── common/ # Generic components
│ ├── forms/ # Form-specific components
│ └── layout/ # Layout components
├── services/ # Business logic and API clients
│ ├── api/ # API communication layer
│ ├── auth/ # Authentication services
│ └── validation/ # Input validation services
├── types/ # TypeScript type definitions
│ ├── api/ # API response/request types
│ ├── domain/ # Business domain types
│ └── common/ # Shared utility types
├── utils/ # Helper functions and utilities
│ ├── formatters/ # Data formatting utilities
│ ├── validators/ # Validation utilities
│ └── constants/ # Application constants
└── hooks/ # Custom React hooks (if applicable)
├── api/ # API-related hooks
└── common/ # General-purpose hooks
File Naming Conventions
TypeScript/JavaScript Files
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good:
UserService.ts
OrderController.ts
EmailValidator.ts
ApiClient.ts
UserRepository.ts
userProfile.component.tsx
orderSummary.component.tsx
emailInput.component.tsx
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Also acceptable (kebab-case):
user-service.ts
order-controller.ts
email-validator.ts
api-client.ts
# <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid:
userservice.ts
orderCtrl.ts
emailval.ts
api.ts
Component Files
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good:
UserProfile.tsx
OrderSummary.tsx
NavigationMenu.tsx
LoadingSpinner.tsx
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Also acceptable:
UserProfile/index.tsx
OrderSummary/index.tsx
Environment and Configuration Standards
Environment Variables
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Clear, hierarchical naming
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=app_development
DATABASE_USERNAME=app_user
DATABASE_PASSWORD=secure_password
REDIS_URL=redis://localhost:6379
REDIS_TTL_SECONDS=3600
API_BASE_URL=https://api.example.com
API_TIMEOUT_SECONDS=30
API_MAX_RETRIES=3
LOG_LEVEL=info
LOG_FORMAT=json
# <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid: Unclear or inconsistent naming
DB_HOST=localhost
DB_P=5432
DATABASE=app_dev
USER=app_user
PASS=secure_password
REDIS=redis://localhost:6379
CACHE_TIME=3600
Configuration File Structure
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Clear, hierarchical naming
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=app_development
DATABASE_USERNAME=app_user
DATABASE_PASSWORD=secure_password
REDIS_URL=redis://localhost:6379
REDIS_TTL_SECONDS=3600
API_BASE_URL=https://api.example.com
API_TIMEOUT_SECONDS=30
API_MAX_RETRIES=3
LOG_LEVEL=info
LOG_FORMAT=json
# <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid: Unclear or inconsistent naming
DB_HOST=localhost
DB_P=5432
DATABASE=app_dev
USER=app_user
PASS=secure_password
REDIS=redis://localhost:6379
CACHE_TIME=3600
Documentation Standards
Code Comments
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Explain why, not what
/**
* Validates email address format and checks against disposable email providers.
* We block disposable emails to reduce spam and improve user quality.
*/
async function validateEmailAddress(email: string): Promise<boolean> {
// Check basic email format first (fast path)
if (!EMAIL_REGEX.test(email)) {
return false;
}
// Check against disposable email provider list (requires API call)
const domain = email.split('@')[1];
return !await isDisposableEmailDomain(domain);
}
# <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid: Explaining obvious code
/**
* This function validates an email address.
* It takes an email string as input.
* It returns a boolean.
*/
async function validateEmailAddress(email: string): Promise<boolean> {
// Check if email matches regex
if (!EMAIL_REGEX.test(email)) {
// Return false if it doesn't match
return false;
}
// Split email by @ symbol
const domain = email.split('@')[1];
// Return whether domain is not disposable
return !await isDisposableEmailDomain(domain);
}
API Documentation
/**
* @openapi
* /api/v1/users:
* post:
* summary: Create a new user account
* description: |
* Creates a new user account with the provided information.
* Email address must be unique and will be verified via email.
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/CreateUserRequest'
* responses:
* 201:
* description: User account created successfully
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/User'
* 400:
* description: Invalid input data
* 409:
* description: Email address already exists
*/
Testing Standards
Test File Naming
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good:
UserService.test.ts
OrderController.test.ts
EmailValidator.test.ts
UserProfile.test.tsx
UserService.integration.test.ts
OrderWorkflow.e2e.test.ts
# <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid:
test_userservice.ts
userservice_spec.ts
TestUserService.ts
Test Structure
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Clear, descriptive test structure
describe('UserService', () => {
describe('createUser', () => {
it('should create user with valid data', async () => {
// Arrange
const userData = {
firstName: 'John',
lastName: 'Doe',
emailAddress: 'john.doe@example.com'
};
// Act
const result = await userService.createUser(userData);
// Assert
expect(result.id).toBeDefined();
expect(result.emailAddress).toBe(userData.emailAddress);
expect(result.isEmailVerified).toBe(false);
});
it('should throw ValidationError when email is invalid', async () => {
// Arrange
const invalidUserData = {
firstName: 'John',
lastName: 'Doe',
emailAddress: 'invalid-email'
};
// Act & Assert
await expect(userService.createUser(invalidUserData))
.rejects
.toThrow(ValidationError);
});
});
});
Error Handling Standards
Error Types and Messages
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Specific error types with clear messages
export class ValidationError extends Error {
constructor(
message: string,
public field: string,
public code: string = 'VALIDATION_ERROR'
) {
super(message);
this.name = 'ValidationError';
}
}
export class NotFoundError extends Error {
constructor(
resource: string,
identifier: string,
public code: string = 'NOT_FOUND'
) {
super(`${resource} with identifier '${identifier}' not found`);
this.name = 'NotFoundError';
}
}
// Usage
throw new ValidationError('Email address format is invalid', 'emailAddress');
throw new NotFoundError('User', userId);
Security Standards
Input Validation
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Comprehensive input validation
import Joi from 'joi';
const createUserSchema = Joi.object({
firstName: Joi.string()
.trim()
.min(1)
.max(100)
.pattern(/^[a-zA-Z\s\-']+$/)
.required()
.messages({
'string.pattern.base': 'First name can only contain letters, spaces, hyphens, and apostrophes'
}),
lastName: Joi.string()
.trim()
.min(1)
.max(100)
.pattern(/^[a-zA-Z\s\-']+$/)
.required(),
emailAddress: Joi.string()
.email()
.max(255)
.required()
.messages({
'string.email': 'Must be a valid email address'
}),
password: Joi.string()
.min(8)
.max(128)
.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/)
.required()
.messages({
'string.pattern.base': 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character'
})
});
Performance Standards
Caching Naming Conventions
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Hierarchical cache key structure
const cacheKeys = {
user: {
profile: (userId: string) => `user:${userId}:profile`,
permissions: (userId: string) => `user:${userId}:permissions`,
settings: (userId: string) => `user:${userId}:settings`,
},
session: {
data: (sessionId: string) => `session:${sessionId}:data`,
permissions: (sessionId: string) => `session:${sessionId}:permissions`,
},
api: {
response: (endpoint: string, params: string) => `api:${endpoint}:${params}`,
}
};
# Usage
const userProfile = await cache.get(cacheKeys.user.profile(userId));
await cache.set(cacheKeys.user.profile(userId), profile, { ttl: 3600 });
Monitoring and Logging Standards
Structured Logging
# <CheckCircle className="w-4 h-4 mr-1 inline text-green-600" /> Good: Structured, searchable logs
logger.info('User authentication attempt', {
userId: user.id,
emailAddress: user.emailAddress,
ipAddress: req.ip,
userAgent: req.headers['user-agent'],
timestamp: new Date().toISOString(),
operation: 'user.authentication'
});
logger.error('Database connection failed', {
error: error.message,
stack: error.stack,
databaseHost: config.database.host,
databaseName: config.database.name,
operation: 'database.connection',
timestamp: new Date().toISOString()
});
# <XCircle className="w-4 h-4 mr-1 inline text-red-600" /> Avoid: Unstructured, hard-to-search logs
logger.info(`User ${user.emailAddress} logged in from ${req.ip}`);
logger.error(`DB error: ${error.message}`);
The standards detailed in the sections below provide specific implementation guidance for different aspects of platform development, ensuring consistency across all projects and teams.
🗃️ Naming
2 items