Skip to content

Latest commit

 

History

History
127 lines (95 loc) · 5.68 KB

File metadata and controls

127 lines (95 loc) · 5.68 KB

AudioBlock Backend Coding & Architecture Conventions

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.


1. Naming Conventions

File & Directory Naming

  • Classes, Entities, DTOs, Controllers, Services: Use PascalCase matching the class name (e.g., SongController.ts, User.ts, AuthService.ts, RegisterUserDto.ts).
  • Routes & Utility Files: Use camelCase or kebab-case (e.g., authRoutes.ts, songRoutes.ts, authMiddleware.ts, sanitizeInput.ts).
  • Directories: Use lower-case plural nouns (e.g., controllers/, services/, entities/, middlewares/, validators/).

Code Symbol Naming

  • 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_case or plural_snake_case in SQL / TypeORM entity decorators (e.g. @Entity('song_collaborators'), @Column({ name: 'artist_id' })).

2. Directory Layout & Layered Architecture

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

3. Error Handling & Response Patterns

Custom AppError Class

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');

Standard Error Response Format

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": ""
    }
  ]
}

4. Async & Promise Handling

  • Always use async/await syntax instead of raw .then() / .catch() chains.
  • Wrap asynchronous operations in try/catch blocks within controllers and background handlers.
  • Never allow unhandled promise rejections; ensure all routes pass errors to handleError(req, res, err).

5. ESLint, Prettier & Code Quality Thresholds

We enforce strict TypeScript and formatting rules via ESLint and Prettier:

  • Indentation & Formatting: 2 spaces, single quotes, semicolons enabled (.prettierrc).
  • Complexity Limits (enforced as errors in CI — new violations fail the build):
    • 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).
    • Existing violations are tracked in docs/refactoring_priority.md and use inline eslint-disable comments with a reference to that file.
  • Type Safety: Explicit return types required for all public service and controller methods; avoid any wherever possible.

6. CI Quality Gates

The following checks run on every pull request and must pass before merge:

Gate Tool Failure condition
Lint + Complexity ESLint Any error-level rule violation (complexity is enforced as error, max 15)
Formatting Prettier Unformatted code
Dead code knip (deadcode:production) New unused exports/dependencies
Secret scanning gitleaks Detected high-entropy strings or known secret patterns
Docker image scan Trivy Critical or high severity vulnerabilities
Node version matrix CI matrix (20, 22) Test failure on either LTS version

Suppressing false positives

  • ESLint complexity: Existing complex functions use // eslint-disable-next-line complexity with a reference to docs/refactoring_priority.md.
  • knip dead code: Existing findings are tracked in knip.config.ts via ignore entries.
  • gitleaks: Add patterns to .gitleaks.toml under [allowlist] with a comment explaining the suppression.