Skip to main content

General Codebase Standards

Introduction​

This document outlines general coding and structural standards followed within our codebases.
The goal is to ensure consistency, readability, maintainability, and scalability across all projects.

Internal Conventions​

  • Naming

    • Variables and functions: camelCase.
    • Use of PascalCase for files and folders (except specific codebases that have components which use snake_case or kebab-case).
    • Database naming (tables, fields, constraints, ...etc): snake_case.
    • Constants: UPPER_SNAKE_CASE.
  • Code Style

    • Indentation: 4 spaces.
    • Keep line length under 100 characters.
  • Documentation

    • Every module should include a README.md if it's reusable, or if it has technical debt behind it.
    • Functions and classes must have docstrings/comments where appropriate, including todo comments.
  • Other Conventions

    • Creating scripts and macros for frequently used bash commands.
    • Thorough review of packages: Popularity on GitHub (stars and forks), last maintenance date, thorough documentation and tutorial availability.
    • Use of project linters and static analysis tools (PHPCSF for PHP styling, PHPStan for PHP static analysis, ESLint/Prettier for JavaScript/TypeScript) to ensure code consistency and catch issues early.
    • Use of security analysis tools to detect vulnerabilities in code and dependencies (php-security-checker for PHP, npm audit for JavaScript/TypeScript).

Software Patterns​

  • General Principles

    • Principle of Least Surprise – Code should behave in a way that is intuitive and expected for other developers.
    • DRY (Don’t Repeat Yourself) – Avoid code duplication by reusing functions, components, and modules.
    • Occam's Razor (Rule of Simplicity) – Keep solutions as simple as possible while still solving the problem.
    • YAGNI (You Aren’t Gonna Need It) – Don’t implement features until they are actually required.
    • SOLID Principles – Ensuring maintainable and extensible code.
    • Separation of Concerns (SoC) – Each module or class should handle a single, well-defined responsibility.
    • Convention over Configuration (CoC) – Prefer established conventions to minimize boilerplate and decision fatigue.
    • Fail Fast – Detect and report errors as early as possible to reduce debugging complexity.
    • Security by Design – Treat security as a first-class concern throughout development.
    • Scalability and Maintainability – Optimize code for long-term health, ensuring it can grow and adapt.
    • Never Trust User Input – Always validate, sanitize, and escape data coming from users, APIs, or external systems before processing or storing it.
  • Layered Architecture

    • Separation of concerns into controllers, services, repositories, and models.
  • Dependency Injection

    • Avoiding of tight coupling by injecting dependencies instead of hardcoding them.
  • Error Handling

    • Centralized error handling – Throw exceptions from any layer and handle in one place.
    • Extra exception handling should be localised to the same layer before throwing again.
    • Use of custom exception classes where appropriate.
  • Configuration Management

    • Default configuration with environment variables serving as overrides.
    • Storage of secrets in environment variables.
    • Never committing sensitive data into version control.

RESTful APIs​

  • End-to-End Type Safety

    • Use DTOs (Data Transfer Objects) for both request and response payloads.
    • Define generalized DTOs (e.g., UserDTO) that can be composed of smaller, specific ones (e.g., UserProfileDTO, UserSettingsDTO).
    • DTOs should explicitly define required vs optional fields.
    • When extending DTOs, new fields must be optional by default to avoid breaking existing clients.
  • HTTP Methods & Verbs

    • GET – Fetch resources without side effects.
    • POST – Create a new resource.
    • PUT – Update an existing resource fully.
    • PATCH – Update a resource partially.
    • DELETE – Remove a resource.
  • Semantic Error Codes

    • 200 OK – Successful response; the request was processed as expected.
    • 400 Bad Request – Invalid/missing request parameters or any validation errors.
    • 401 Unauthorized – Missing or invalid authentication.
    • 402 Payment Required – Client must settle payment or subscription requirements before access.
    • 403 Forbidden – Authenticated but not authorized.
    • 404 Not Found – Resource does not exist.
    • 405 Method Not Allowed – The HTTP method used is not supported for this endpoint.
    • 425 Too Early – The server has the resource but refuses to process the request because it may be accessed prematurely (e.g., replayed or before the resource is fully ready).
    • 429 Too Many Requests – The server rejected the request because the client has exceeded the allowed rate limit in a given time window.
    • 500 Internal Server Error – Unhandled errors (should be logged & traced).
    • 501 Not Implemented – The server does not support the request method or functionality.
    • 503 Service Unavailable – Server temporarily unavailable (maintenance or overload).
  • Consistency & Documentation

    • Always return a standardized response format (e.g., { data, message }).
    • DTO validation errors should return at least a message, and optionally a structured list of fields with messages.

These cover standards from big names that we've adopted, ranging from rules that help write maintainable software, to security/reliability-first approaches.