This document outlines the coding standards, conventions, folder layout, and error handling patterns for AudioBlock_Backend. Following these standards ensures consistency, security, and maintainability across all features.
- Classes, Entities, DTOs, Controllers, Services: Use
PascalCasematching the class name (e.g.,SongController.ts,User.ts,AuthService.ts,RegisterUserDto.ts). - Routes & Utility Files: Use
camelCaseorkebab-case(e.g.,authRoutes.ts,songRoutes.ts,authMiddleware.ts,sanitizeInput.ts). - Directories: Use lower-case plural nouns (e.g.,
controllers/,services/,entities/,middlewares/,validators/).
- Variables, Functions, Methods:
camelCase(e.g.,getUserById,prepareSongMintTx,isValidWalletAddress). - Classes, Interfaces, Enums:
PascalCase(e.g.,UserRole,AppError,RoyaltyPayoutStatus). - Global Constants & Enum Values:
UPPER_SNAKE_CASE(e.g.,MAX_FILE_SIZE_BYTES,JWT_EXPIRATION_HOURS,VALIDATION_FAILED). - Database Tables & Columns:
snake_caseorplural_snake_casein SQL / TypeORM entity decorators (e.g.@Entity('song_collaborators'),@Column({ name: 'artist_id' })).
src/
├── app.ts # Express application setup & middleware assembly
├── index.ts # Server bootstrap & database/redis connection
├── config/ # Environment variables, database, redis, constants
├── controllers/ # Thin HTTP controllers (parse params -> invoke service -> respond)
├── services/ # Core business logic layer & external service adapters
│ └── ServiceRegistry.ts # DI container / service registry
├── entities/ # TypeORM entity definitions mapping to PostgreSQL
├── dtos/ # Request body DTO classes with class-validator decorators
├── middlewares/ # Auth, validation, rate limiters, logging, malware scanner
├── routes/ # Express Router modules mapping HTTP endpoints to controllers
├── errors/ # AppError class and error enum definitions
├── workers/ & jobs/ # Asynchronous job processors (audio transcoding, payouts)
└── utils/ # Reusable helper functions, logger, response wrappers
All operational errors must be thrown as instances of AppError using static factory methods:
import { AppError } from '../errors/AppError';
// 400 Bad Request / Validation
throw AppError.validation('Invalid input parameters', detailsArray);
// 401 Unauthorized
throw AppError.authentication('Invalid or expired authentication token');
// 403 Forbidden
throw AppError.authorization('Email verification required for this action');
// 404 Not Found
throw AppError.notFound('Requested song does not exist');
// 409 Conflict
throw AppError.conflict('User with this email already exists');All HTTP error responses generated by handleError(req, res, error) return a consistent JSON payload:
{
"success": false,
"message": "Validation failed",
"type": "VALIDATION_FAILED",
"details": [
{
"field": "artist.name",
"message": "name should not be empty",
"value": ""
}
]
}- Always use
async/awaitsyntax instead of raw.then()/.catch()chains. - Wrap asynchronous operations in
try/catchblocks within controllers and background handlers. - Never allow unhandled promise rejections; ensure all routes pass errors to
handleError(req, res, err).
We enforce strict TypeScript and formatting rules via ESLint and Prettier:
- Indentation & Formatting: 2 spaces, single quotes, semicolons enabled (
.prettierrc). - Complexity Limits:
- Maximum Cyclomatic Complexity: 15 per function.
- Maximum Function Length: 50 lines.
- Maximum File Length: 300 lines (split large files into sub-modules).
- Maximum Parameters: 5 parameters per function (use options objects for >3 parameters).
- Type Safety: Explicit return types required for all public service and controller methods; avoid
anywherever possible.