<!--
Sync Impact Report:
Version change: 0.0.0 → 1.0.0 (Initial Ratification)
Modified principles: N/A (initial constitution)
Added sections:
  - Project Identity (1. هوية المشروع)
  - Architectural Principles (2. مبادئ المعمارية)
  - Database Constitution (3. قواعد قاعدة البيانات)
  - API Constitution (4. قواعد الـ API)
  - Security Constitution (5. قواعد الأمان)
  - Code Quality Constitution (6. قواعد جودة الكود)
  - Business Rules (7. قواعد الأعمال)
  - Project Structure (8. هيكل المشروع)
  - Git Workflow (9. Git Workflow)
  - Boundaries System (10. الـ Boundaries الإلزامية)
  - Approved Specs Roadmap (11. خارطة الـ Specs)
  - Decision Log (12. تاريخ القرارات)
Removed sections: N/A
Templates requiring updates:
  ✅ .specify/templates/plan-template.md - Constitution Check section aligns
  ✅ .specify/templates/spec-template.md - No conflicts
  ✅ .specify/templates/tasks-template.md - No conflicts
  ⚠ .specify/templates/commands/*.md - No commands directory found
Follow-up TODOs:
  - TODO(RATIFICATION_DATE): Session date not recorded in source document
-->

# Tamkeen Constitution
> **الوثيقة التأسيسية للمشروع | Spec-Driven Development**
> المسار: `.specify/memory/constitution.md`
> الحالة: ✅ مُعتمدة
> الإصدار: 1.0.0

---

## 1. Project Identity

| Field | Value |
|-------|-------|
| **Project Name** | Tamkeen |
| **Type** | Installment Finance System |
| **Project Mode** | API-first Backend (consumed via Mobile App) |
| **Single User** | Admin (System Manager) |
| **Methodology** | Spec-Driven Development (SDD) via Spec Kit |
| **Stack** | Laravel 11+ · PHP 8.2+ · MySQL 8+ |
| **Timezone** | `Asia/Damascus` (UTC+3) |
| **Currency Precision** | `DECIMAL(10, 2)` via `bcmath` extension |

---

## 2. Core Principles

### I. Clean Architecture — Strict Layers

```
Request → FormRequest (Validation)
        → Controller (Thin — orchestration only)
        → Service (Business Logic)
        → Repository (Data Access)
        → Model (Eloquent — no business logic here)
        → Resource (API Transformation)
        → Response
```

**Mandatory Rules:**
- ❌ No business logic inside Controller or Model
- ❌ No Eloquent queries directly in Controller
- ❌ No raw SQL except at extreme necessity with justifying comment
- ✅ Each Service expresses exactly one Use Case
- ✅ Repository is the sole database gateway

### II. Domain Separation

Each Domain contains:
```
app/
└── Domains/
    └── {DomainName}/
        ├── Models/
        ├── Repositories/
        │   ├── Contracts/        ← Interface
        │   └── Eloquent/         ← Implementation
        ├── Services/
        ├── Http/
        │   ├── Controllers/
        │   ├── Requests/
        │   └── Resources/
        └── DTOs/                 ← Data Transfer Objects
```

### III. Financial Data Principles (NON-NEGOTIABLE)

- ✅ **bcmath** is mandatory for all financial calculations
- ✅ All monetary values stored as `DECIMAL(10, 2)` in database
- ✅ No `float` or `double` in any financial calculation — ever
- ✅ Rounding always **up** (`bcmath` scale=2, PHP_ROUND_HALF_UP)
- ✅ **Append-only Ledger** principle for payments — no modification, only cancel and re-enter

### IV. Immutability Rules

| Entity | Rule |
|--------|------|
| Contract | After signing → Immutable (no data modification) |
| Payment | Append-only — Deletion in reverse order only (LIFO) |
| Installment Schedule | No modification after contract creation |
| Agent Shares Log | Append-only — no deletion from log |

### V. Code Quality Standards

- ✅ **PHPUnit** for Unit Tests
- ✅ **Feature Tests** for every API Endpoint
- ✅ Calculator tests (SP-06) must be pure Unit Tests — no database
- ✅ Payment Engine tests cover: happy path + errors + boundaries
- ✅ Coverage target: **80% minimum**
- ❌ No deletion of failing test — must fix or get explicit approval

---

## 3. Database Constitution

### 3.1 General Rules

- ✅ All IDs: `BIGINT UNSIGNED AUTO_INCREMENT`
- ✅ Timestamps: `created_at`, `updated_at` via `timestamps()`
- ✅ Monetary values: `DECIMAL(10, 2)` — not `FLOAT`
- ✅ Statuses: `ENUM` or `TINYINT` with constants in Model
- ❌ **No Soft Deletes in any entity** — final decision, non-negotiable
- ❌ No deletion of Agents — neither soft nor hard
- ❌ No deletion of Customers if they have linked contracts

### 3.2 Indexing Strategy

```sql
-- Mandatory on all Foreign Keys
-- Mandatory on frequently filtered fields
-- Most important: payment_date (not due_date) for time filters
-- agent_id in contracts
-- customer_id in contracts
-- status in contracts and installments
```

### 3.3 Migration Rules

- ✅ Each Migration executes in transaction
- ✅ No modification to existing migration — instead: new migration
- ✅ Seed data separate from migrations
- ✅ Migration order respects Foreign Key dependencies

---

## 4. API Constitution

### 4.1 Response Format — Unified

```json
// Success
{
  "success": true,
  "message": "Operation successful",
  "data": { ... },
  "meta": { ... }    // for pagination
}

// Error
{
  "success": false,
  "message": "Error message",
  "errors": { ... }  // for validation errors
}
```

### 4.2 HTTP Status Codes

| Condition | Code |
|-----------|------|
| Successful fetch | 200 |
| Successful creation | 201 |
| Successful with no data | 204 |
| Validation Error | 422 |
| Not found | 404 |
| Unauthorized | 401 |
| Forbidden (business rule) | 403 |
| Server error | 500 |

### 4.3 Pagination

- **Type**: Cursor-based (not Offset)
- **Reason**: Better performance with large data
- **Default page size**: 20 records
- **Maximum**: 100 records

### 4.4 API Versioning

- All routes under prefix `/api/v1/`
- Admin routes under `/api/v1/admin/`

### 4.5 Helper Functions — Mandatory Response Helpers

All API responses **must** use the helper functions from `app/Helpers/ApiResponseHelper.php`:

**Success Responses:**
| Helper | Use Case |
|--------|----------|
| `success(data: [...], msg: '...')` | Default success (200) |
| `resourceCreatedResponse(msg, data)` | Resource creation (201) |
| `noContentResponse()` | Success with no content (204) |

**Error Responses:**
| Helper | Use Case |
|--------|----------|
| `error('message', statusCode)` | Generic error (default 500) |
| `notFoundResponse('message')` | Resource not found (404) |
| `modelNotFoundResponse(Model::class)` | Model not found (404) |
| `unauthorizedResponse('message')` | Authentication required (401) |
| `forbiddenResponse('message')` | Access denied (403) |
| `badRequestResponse('message')` | Bad request (400) |
| `conflictResponse('message')` | Conflict (409) |
| `unprocessableResponse(array\|string)` | Validation error (422) |
| `generalFailureResponse('message', code)` | Server error (500) |

**Convention:** Always use **named parameters** for `success()`:
```php
return success(data: $result, msg: 'Operation completed');
return success(msg: 'Logged out successfully');
```

**For Exceptions:** Use `app/Helpers/CostumeErrorResponse.php` functions via the config mapping in `config/ExceptionClassToMethod.php`.

**⚠️ ADD NEW HELPERS — NEVER INLINE:** If no suitable helper exists for a response type, add a new one to `ApiResponseHelper.php` first, then use it. Never create ad-hoc response arrays or helper calls inline in Controllers/Services.

---

## 5. Security Constitution

- ✅ **Laravel Sanctum** for Authentication (Token-based)
- ✅ Every route under `auth:sanctum` Middleware except `/login`
- ✅ All inputs pass through FormRequest before reaching Controller
- ✅ Mass Assignment protected — explicit `$fillable` in every Model
- ❌ No credentials in code — environments via `.env` only
- ❌ No plaintext API token storage — hashed only
- ✅ Rate Limiting on `/login` (5 attempts/minute)

---

## 6. Immutable Business Rules

### 6.1 Contract Rules

| Rule | Details |
|------|---------|
| Initial Payment | Must be **less** than Purchase Amount (not equal) |
| Max Installments | 60 installments (5 years) |
| Min Installments | 1 installment |
| Contract Deletion | Allowed **only** if: unsigned + no payments recorded |
| Contract Modification After Signing | **Absolutely prohibited** |

### 6.2 Payment Rules (Append-only Ledger)

| Rule | Details |
|------|---------|
| Addition | Free — payment can be added at any time |
| Deletion | **LIFO only** — cannot delete payment if newer payment exists |
| Modification | **Prohibited** — no edit, only delete and re-enter |
| Deletion Impact | Recalculates from deleted payment forward automatically |

**LIFO Example:**
```
[Payment-1] → [Payment-2] → [Payment-3]
To delete payment-1: must first delete payment-3 then payment-2 then payment-1
```

### 6.3 Agent and Investor Rules

| Rule | Details |
|------|---------|
| Agent becomes investor | Automatically when shares value > 0 |
| Fixed share value | 200 USD |
| Investor profit ratio | 5% of collected amounts |
| Profit calculation | Computed (no separate table) = `SUM(collected) × 0.05` |
| Agent deletion | **Absolutely prohibited** (neither soft nor hard) |
| Shares log | Append-only — every transaction (add/withdraw shares) logged |

### 6.4 Customer Rules

| Rule | Details |
|------|---------|
| Customer data modification | Allowed even with active contracts |
| Customer deletion | **Prohibited** if has contracts (active or completed) |
| Soft Delete | **Cancelled** — does not exist in system |

### 6.5 Timezone

- All dates stored in `Asia/Damascus` timezone
- Time filters depend on `payment_date` (not `due_date`)
- Application config: `config/app.php` → `timezone = 'Asia/Damascus'`

---

## 7. Project Structure

```
tamkeen/
├── app/
│   ├── Domains/
│   │   ├── Auth/
│   │   ├── Customer/
│   │   ├── Agent/
│   │   ├── Contract/
│   │   ├── Payment/
│   │   └── Analytics/
│   ├── Shared/
│   │   ├── Http/
│   │   │   └── Resources/BaseResource.php
│   │   ├── Traits/
│   │   └── Exceptions/
├── config/
├── database/
│   ├── migrations/
│   └── seeders/
├── routes/
│   └── api.php
├── tests/
│   ├── Unit/
│   └── Feature/
└── .specify/
    ├── memory/
    │   └── constitution.md     ← this file
    └── specs/
```

---

## 8. Git Workflow

```
main          ← production-ready only
  └── develop ← integration branch
        └── feat/SP-{N}-{slug}   ← each Spec in independent branch
        └── fix/{slug}
```

**Commit Format (Conventional Commits):**
```
feat(SP-07): add contract creation with auto-installment generation
fix(SP-08): correct LIFO payment deletion validation
chore(SP-02): add payment_date index to payments table
test(SP-06): add edge case for single-installment contract
```

---

## 9. Boundaries System (3-Tier)

### ✅ ALWAYS — Always, no exceptions
- Run tests before any commit
- Use `bcmath` in any financial calculation
- Return Unified Response from every endpoint
- Validate Business Rules in Service layer
- Document every public method with PHPDoc
- Use FormRequest for all validation

### ⚠️ ASK FIRST — Requires explicit approval
- Any database schema modification after migration
- Adding new library/package
- Changing documented Business Rule in this Constitution
- Any change to Unified Response format
- Changing Pagination strategy

### 🚫 NEVER — Absolutely prohibited
- Writing Business Logic inside Controller or Model
- Using `float` or `double` in financial calculations
- Ignoring LIFO rule when deleting payments
- Allowing contract modification after signing
- Bypassing Repository layer and accessing database directly from Controller
- Committing any credentials or API keys
- Deleting failing test instead of fixing it

---

## 10. Approved Specs Roadmap

```
Phase 1: Foundation
  SP-01 │ Authentication (Sanctum + Login API)
  SP-02 │ Database Foundation (All Migrations + Indexes)
  SP-03 │ Base Architecture (Resources + Repositories + Exception Handler)

Phase 2: Core Domain
  SP-04 │ Customer Management (CRUD + Search)
  SP-05 │ Agent Management + Investor Logic

Phase 3: Engine
  SP-06 │ Installment Calculator (Pure Domain Service + Unit Tests)
  SP-07 │ Contract Management (Create + Delete)
  SP-08 │ Payment Engine (Append-only + LIFO Deletion)

Phase 4: Intelligence
  SP-09 │ Customer Listing + Filters + Financial Summary
  SP-10 │ Analytics & Reporting
  SP-11 │ Notification Templates (WhatsApp)
```

**Dependency Chain:**
```
SP-01 → SP-02 → SP-03 → SP-04 ──────────────────────┐
                       └→ SP-05 ──────────────────────┤
                                 └→ SP-06              │
                                      └→ SP-07         │
                                           └→ SP-08    │
                                                ├→ SP-09 ←─┘
                                                ├→ SP-10
                                                └→ SP-11
```

---

## 11. Decision Log

| Date | Decision | Reason |
|------|----------|--------|
| Session 1 | Cancel Soft Delete entirely | Simplify architecture + business requirements |
| Session 1 | No deletion of Agents (Hard or Soft) | Agent is historical entity not deleted |
| Session 1 | LIFO for payments | Preserve Ledger sequence |
| Session 1 | Computed profits (no separate table) | YAGNI + simplification |
| Session 1 | Cursor Pagination | Performance with large data |
| Session 1 | payment_date for filters | Actual payment date, not due date |
| Session 1 | Share value = 200 USD fixed | Working currency |
| Session 1 | Agent = investor when shares > 0 | Automatic without manual flag |

---

*This file is the first and last reference for any decision. Any conflict between partial spec and this file → this file takes precedence.*

**Version**: 1.0.0 | **Ratified**: TODO(RATIFICATION_DATE): Session date not recorded | **Last Amended**: 2026-06-01