# Naming Conventions

## Overview

Consistent naming conventions improve code readability and maintainability. This document defines the naming standards for all code elements in the Building Management System.

## Classes

### General Rules

| Type | Convention | Example |
|------|------------|---------|
| Class | PascalCase | `ProductService`, `UserController` |
| Interface | PascalCase + Suffix | `ProductRepositoryContract` |
| Trait | PascalCase | `Filterable`, `Loggable` |
| Enum | PascalCase | `OrderStatus`, `PaymentMethod` |

### Domain-Specific Classes

| Type | Pattern | Example |
|------|---------|---------|
| Model | Singular noun | `Product`, `Invoice`, `User` |
| Controller | Noun + Controller | `ProductController`, `InvoiceController` |
| Service | Noun + Service(s) | `ProductService`, `UserServices` |
| Repository | Noun + Repository | `ProductRepository`, `CategoryRepository` |
| Contract | Noun + RepositoryContract | `ProductRepositoryContract` |
| DTO | Noun + DTO | `ProductDTO`, `CreateUserDTO` |
| Observer | Noun + Observer | `ProductObserver`, `LeaveObserver` |
| Event | PastTense/Action | `ProductCreated`, `OrderApproved` |
| Listener | Action verb phrase | `LogProductCreation`, `SendNotification` |
| Request | Action + Noun + Request | `StoreProductRequest`, `UpdateUserRequest` |
| Resource | Noun + Resource | `ProductResource`, `UserResource` |
| Policy | Noun + Policy | `ProductPolicy`, `InvoicePolicy` |
| Middleware | Descriptive name | `CheckBranchSetup`, `VerifyAccountingBalance` |
| Exception | Descriptive + Exception | `InsufficientBalanceException` |

### Examples

```php
// Models - Singular, descriptive
class Product extends Model {}
class PurchaseOrder extends Model {}
class MaintenanceVisit extends Model {}

// Services - Can use singular or plural "Service(s)"
class ProductService {}
class UserServices {}
class InventoryValuationService {}

// DTOs - Clearly indicate data structure
class ProductDTO {}
class CreateInvoiceDTO {}
class UpdateEmployeeDTO {}

// Events - Past tense for completed actions
class ProductCreated {}
class OrderApproved {}
class PaymentReceived {}

// Listeners - Verb phrase describing action
class LogProductCreation {}
class SendWelcomeEmail {}
class UpdateInventoryBalance {}
```

## Methods

### General Rules

- Use **camelCase**
- Start with a verb
- Be descriptive but concise

### CRUD Operations

```php
// Standard CRUD names
public function index()      // List resources
public function show($id)    // Show single resource
public function store()      // Create new resource
public function update($id)  // Update existing resource
public function destroy($id) // Delete resource

// Service layer equivalents
public function list()       // Get collection
public function find($id)    // Find by ID
public function create()     // Create new
public function update()     // Update existing
public function delete()     // Delete
```

### Query Methods

```php
// Find methods - return single or null
public function find(int $id): ?Product
public function findOrFail(int $id): Product
public function findBySlug(string $slug): ?Product
public function findByCode(string $code): ?Product

// Get methods - return collections
public function getAll(): Collection
public function getActive(): Collection
public function getByCategory(int $categoryId): Collection

// Check methods - return boolean
public function exists(int $id): bool
public function hasStock(int $productId): bool
public function isActive(): bool
public function canBeDeleted(): bool
```

### Action Methods

```php
// Process/handle actions
public function process(Order $order): void
public function approve(Leave $leave): void
public function reject(Request $request): void
public function cancel(Reservation $reservation): void

// Calculate methods
public function calculate(Invoice $invoice): float
public function calculateTax(float $amount): float
public function calculateDiscount(Order $order): float

// Send/notify methods
public function send(Notification $notification): void
public function notify(User $user, string $message): void
public function broadcast(Event $event): void

// Sync/update methods
public function sync(array $data): void
public function refresh(): void
public function recalculate(): void
```

### Scope Methods

```php
// Model scopes - prefix with "scope"
public function scopeActive($query)
public function scopePending($query)
public function scopeForCompany($query, int $companyId)
public function scopeCreatedBetween($query, Carbon $start, Carbon $end)
public function scopeWithStatus($query, string $status)
```

## Variables and Properties

### General Rules

- Use **camelCase**
- Be descriptive
- Avoid abbreviations (except common ones like `id`, `url`, `html`)

```php
// Good
$userName = 'John';
$totalAmount = 100.50;
$isActive = true;
$createdAt = now();

// Avoid
$un = 'John';       // Too abbreviated
$ta = 100.50;       // Unclear
$flag = true;       // Non-descriptive
$dt = now();        // Ambiguous
```

### Property Naming

```php
class Invoice
{
    // Clear, descriptive names
    private int $customerId;
    private float $totalAmount;
    private float $taxAmount;
    private bool $isPaid;
    private ?Carbon $paidAt;

    // Collections - use plural
    private Collection $items;
    private array $payments;

    // Related models - use singular
    private Customer $customer;
    private ?User $approvedBy;
}
```

### Constants

```php
class OrderStatus
{
    // UPPER_SNAKE_CASE for constants
    public const STATUS_PENDING = 'pending';
    public const STATUS_APPROVED = 'approved';
    public const STATUS_CANCELLED = 'cancelled';

    public const MAX_ITEMS_PER_ORDER = 100;
    public const DEFAULT_TAX_RATE = 0.15;
}

// In models
class Product extends Model
{
    public const TYPE_PHYSICAL = 'physical';
    public const TYPE_DIGITAL = 'digital';
    public const TYPE_SERVICE = 'service';
}
```

## Database

### Tables

```sql
-- snake_case, plural
CREATE TABLE products (...)
CREATE TABLE purchase_orders (...)
CREATE TABLE maintenance_visits (...)

-- Pivot tables: singular names alphabetically
CREATE TABLE product_category (...)
CREATE TABLE order_product (...)
CREATE TABLE role_user (...)
```

### Columns

```sql
-- snake_case
id                  -- Primary key
name                -- Simple names
total_amount        -- Compound names
is_active           -- Boolean prefix
created_at          -- Timestamps
updated_at
deleted_at          -- Soft deletes

-- Foreign keys: singular_table_id
customer_id
product_id
created_by_user_id  -- When ambiguous
```

### Indexes and Constraints

```sql
-- Pattern: table_columns_type
CREATE INDEX products_category_id_index ON products(category_id);
CREATE INDEX orders_status_created_at_index ON orders(status, created_at);
CREATE UNIQUE INDEX users_email_unique ON users(email);

-- Foreign key constraints
ALTER TABLE orders
ADD CONSTRAINT orders_customer_id_foreign
FOREIGN KEY (customer_id) REFERENCES customers(id);
```

## Routes and URLs

### API Routes

```php
// kebab-case for URL segments
// Plural for resource collections

Route::prefix('api/v1')->group(function () {
    // Resource routes
    Route::apiResource('products', ProductController::class);
    Route::apiResource('purchase-orders', PurchaseOrderController::class);
    Route::apiResource('maintenance-visits', MaintenanceVisitController::class);

    // Nested resources
    Route::apiResource('customers.orders', CustomerOrderController::class);
    Route::apiResource('projects.materials', ProjectMaterialController::class);

    // Custom actions - use verbs
    Route::post('orders/{order}/approve', [OrderController::class, 'approve']);
    Route::post('invoices/{invoice}/send', [InvoiceController::class, 'send']);
    Route::get('reports/sales-summary', [ReportController::class, 'salesSummary']);
});
```

### Route Names

```php
// Pattern: domain.resource.action
Route::name('catalog.')->group(function () {
    Route::get('products', [ProductController::class, 'index'])
        ->name('products.index');

    Route::post('products', [ProductController::class, 'store'])
        ->name('products.store');

    Route::get('products/{product}', [ProductController::class, 'show'])
        ->name('products.show');
});

// Usage
route('catalog.products.index');
route('catalog.products.show', ['product' => $id]);
```

## Configuration and Environment

### Environment Variables

```env
# UPPER_SNAKE_CASE
# Prefix with category

# Application
APP_NAME=Building
APP_ENV=local
APP_DEBUG=true

# Database
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=building

# Cache
CACHE_DRIVER=redis
CACHE_PREFIX=building_

# Third-party services
PUSHER_APP_ID=123456
PUSHER_APP_KEY=abc123
```

### Configuration Files

```php
// config/inventory.php
return [
    // snake_case keys
    'default_valuation_method' => 'fifo',
    'low_stock_threshold' => 10,
    'enable_batch_tracking' => true,

    // Nested arrays
    'valuation_methods' => [
        'fifo' => 'First In, First Out',
        'lifo' => 'Last In, First Out',
        'weighted_average' => 'Weighted Average',
    ],
];

// Usage
config('inventory.default_valuation_method');
config('inventory.valuation_methods.fifo');
```

## File Names

### PHP Files

```
// Match class name exactly
ProductController.php
ProductService.php
ProductDTO.php
ProductRepositoryContract.php

// Traits
Filterable.php
Loggable.php
InteractWithResponse.php

// Configuration
inventory.php
permission.php
```

### Migration Files

```
// Pattern: date_action_table_description.php
2024_01_15_100000_create_products_table.php
2024_01_15_100001_create_categories_table.php
2024_01_15_100002_add_status_to_orders_table.php
2024_01_15_100003_create_product_category_pivot_table.php
2024_01_15_100004_modify_price_column_in_products_table.php
```

### Views and Resources

```
// kebab-case for blade files
resources/views/
├── products/
│   ├── index.blade.php
│   ├── show.blade.php
│   ├── create.blade.php
│   └── edit.blade.php
├── components/
│   ├── alert-box.blade.php
│   └── data-table.blade.php
└── layouts/
    └── app.blade.php
```

## Abbreviations Guide

### Acceptable Abbreviations

| Abbreviation | Full Word |
|--------------|-----------|
| `id` | Identifier |
| `url` | Uniform Resource Locator |
| `api` | Application Programming Interface |
| `dto` | Data Transfer Object |
| `db` | Database |
| `auth` | Authentication/Authorization |
| `config` | Configuration |
| `max` | Maximum |
| `min` | Minimum |
| `qty` | Quantity (in database only) |

### Avoid These Abbreviations

| Instead Of | Use |
|------------|-----|
| `usr` | `user` |
| `msg` | `message` |
| `btn` | `button` |
| `num` | `number` |
| `val` | `value` |
| `tmp` | `temporary` |
| `cnt` | `count` |
| `amt` | `amount` |

## Domain-Specific Terms

Maintain consistency with these domain terms:

| Term | Usage |
|------|-------|
| `Invoice` | Sales document |
| `PurchaseOrder` | Procurement document |
| `Receipt` | Payment receipt |
| `Voucher` | Journal voucher |
| `Asset` | Maintenance asset |
| `Visit` | Maintenance visit |
| `Employee` | Staff member |
| `Contractor` | External worker |
| `Supplier` | Vendor/provider |
| `Customer` | Client/buyer |
