1. Clean Code Philosophy: Meaningful > Short
We adhere strictly to Robert C. Martin's Clean Code principles. A name should immediately reveal intent, documentation, and reason for existence. Optimize for readability, not typing speed.
β Avoid
def calc(x, y):let data = fetch();$usr = User::find();const temp = 42;
β Prefer
def calculate_total_amount(subtotal, tax):let userProfile = fetchUserProfile();$activeUser = User::find();const MAX_RETRY_COUNT = 42;
"The ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. Making it easy to read makes it easier to write." β Robert C. Martin
2. Boolean Naming: Questions, Not Statements
Boolean variables and functions must read like a yes/no question.
Prefixes
is_β is_activehas_β has_permissioncan_β can_editshould_β should_send_emailwas_β was_processed
π« Never Use
- flag
- status
- check
- value
// Good
let isSubscribed = true;
if (user.hasPermission('edit')) { }
// Bad
let subscribed = true;
if (user.permissionCheck('edit')) { }
3. Python (Django) Naming Standards
π Python Philosophy: "Explicit is better than implicit." Follows PEP 8 strictly.
Classes & Models
# Classes: PascalCase, singular for models
class SupplierProposal(models.Model):
pass
class InvoiceService:
pass
Functions, Variables & Constants
# Functions/Variables: snake_case
def calculate_total_amount(subtotal, tax):
total_amount = subtotal + tax
return total_amount
# Constants: UPPER_SNAKE_CASE
MAX_RETRY_COUNT = 3
DEFAULT_TIMEOUT = 30
Files & Directories
# Files: snake_case.py
supplier_service.py
invoice_views.py
# Directories: snake_case
payment_gateway/
user_management/
Database (Django ORM)
# Tables: snake_case plural (auto-generated)
# supplier_proposals, auth_user
# Primary Key: id
# Foreign Key: model_id (supplier_id)
# Boolean Fields: is_, has_ prefixes
OOP Specifics (Python)
class PaymentService:
def _private_method(self): # Single underscore = "protected"
pass
def __very_private(self): # Double underscore = name mangling
pass
class AbstractNotificationService: # Abstract class
pass
class LoggingMixin: # Mixin
pass
4. PHP (Laravel & Dolibarr)
π£ Laravel Standards
// Classes: PascalCase (singular)
class OrderController extends Controller { }
class SupplierProposal extends Model { }
// Methods: camelCase
public function calculateTotalAmount() { }
// Variables: camelCase
$totalAmount = 100;
$activeUser = User::find(1);
// Constants: UPPER_CASE
const MAX_ATTEMPTS = 3;
// Files: PascalCase.php
OrderController.php
SupplierProposal.php
Database (Laravel)
// Tables: snake_case plural
supplier_proposals, order_items
// Primary Key: id
// Foreign Key: model_id (user_id)
// Pivot Tables: singular_alphabetical (role_user)
OOP (Laravel)
// Private properties
private $internalValue;
// Traits
trait LoggableTrait { }
// Interfaces
interface PaymentInterface { }
// Abstract Classes
abstract class AbstractPaymentService { }
π’ Dolibarr (Legacy Context)
// Tables: llx_ prefix
llx_supplier_proposal
llx_facture
// Primary Key: rowid
// Foreign Key: fk_<table> (fk_soc)
// Classes: PascalCase
class SupplierProposal
// Files: lowercase .class.php
supplierproposal.class.php
5. JavaScript / TypeScript (React, Next.js, Angular)
π΅ React & Next.js
// Components: PascalCase
const SupplierCard = () => { ... };
export default SupplierCard;
// Hooks: use + PascalCase
const useSupplierData = (id) => { ... };
// Functions: camelCase
const calculateTotal = () => { ... };
// Variables: camelCase
let totalAmount = 100;
// Constants: UPPER_CASE
const API_BASE_URL = 'https://api.example.com';
// Files - Components: PascalCase.tsx
// SupplierCard.tsx, InvoiceList.tsx
// Files - Hooks: camelCase.ts
// useSupplierData.ts, useAuth.ts
// Folders: kebab-case
// supplier-management/, user-dashboard/
β οΈ Critical Hook Rule: Hooks must always start with "use" and be called unconditionally at the top level.
π Angular
// Classes: PascalCase
export class InvoiceComponent { }
// Selectors: kebab-case
@Component({
selector: 'app-invoice',
})
// Services: PascalCase
export class InvoiceService { }
// Files: kebab-case
invoice.component.ts
invoice.service.ts
6. Global Database Standards
Tables
snake_case (plural)
supplier_proposals
Primary Key
id
Dolibarr: rowid
Foreign Key
<entity>_id
supplier_id
Timestamps
created_atupdated_at
Soft Delete
deleted_at
Boolean
is_activehas_access
π« Never use prefixes like
tbl_, data_, or info_.
7. OOP Principles & Naming
- Services β end with
Service(PaymentService) - Repositories β end with
Repository(UserRepository) - Controllers β end with
Controller(InvoiceController) - Interfaces β end with
Interface(PaymentInterface) - Abstract Classes β start with
Abstract(AbstractNotificationService) - Traits/Mixins β end with
TraitorMixin(LoggableTrait)
SOLID Reminder: One class = one responsibility. Prefer composition over inheritance.
8. Critical Infrastructure: File Storage Policy
π« NEVER store physical files on the application server
Local disk storage (/uploads, /public/files) is strictly prohibited.
β Allowed Storage Backends
- Database BLOB β for small files only
- NAS (Network Attached Storage) β mounted network drive
- Object Storage β S3, MinIO, Google Cloud Storage
- CDN β for public assets
Streaming Pattern
Client Request
β API Gateway
β Authentication
β Authorization
β Stream from Storage (never direct path)
β Response
Why? Horizontal scalability, stateless servers, backup consistency, and microservice readiness.
9. General Formatting & Commit Rules
Formatting
- Indentation: 4 spaces (no tabs)
- Line length: 100β120 characters max
- Nesting: maximum 3 levels deep
- Early returns: prefer guard clauses
- No dead code: remove commented blocks
Commit Message Convention
feat: add supplier proposal service
fix: correct tax calculation logic
refactor: rename invoice repository
docs: update naming convention guide
test: add unit tests for payment service
chore: update dependencies
π Final Rule
Code is read far more often than it is written. Optimize for clarity, consistency, and maintainabilityβnever for typing speed.