# AI Modification Rules — Blazma LIMS

> **MANDATORY**: Any AI agent modifying this project MUST read and follow these rules.

---

## Rule 1: Read Before You Write

Before making ANY modification to this project, you MUST read:

1. `/AI_README.md` — Entry point and system summary ✅ (you are reading this)
2. `/docs/ai/system_overview.md` — Domain and purpose
3. `/docs/ai/architecture.md` — Framework layers and patterns
4. `/docs/ai/database.md` — Table schema and relationships
5. `/docs/ai/modules.md` — Module boundaries
6. The specific module documentation relevant to your change

**Do not skip this step.** The system has 320 tables, 431 models, 107 services. Skipping causes breaking changes.

---

## Rule 2: Always Scope by PROFILE_ID

This is the #1 multi-tenancy rule. **Every database query on a business table MUST include a PROFILE_ID filter.**

```php
// ✅ ALWAYS DO THIS
LAB_CATEGORY_PACKAGE::where('PROFILE_ID', $profileId)->get();
END_USER_LAB_ORDER::where('PROFILE_ID', $profileId)->where(...)->get();

// ❌ NEVER DO THIS — returns all tenants' data
LAB_CATEGORY_PACKAGE::all();
END_USER_LAB_ORDER::where('STATUS', 'active')->get();
```

**Why**: Each PROFILE is a separate laboratory organization. Cross-tenant data leakage is a critical security breach.

---

## Rule 3: Never Bypass the Service Layer

Business logic MUST live in `app/Services/`. Controllers must never contain business logic.

```php
// ✅ CORRECT
class OrderController extends Controller {
    public function create(Request $request) {
        return $this->labService->createOrder($request->validated());
    }
}

// ❌ WRONG — business logic in controller
class OrderController extends Controller {
    public function create(Request $request) {
        $order = END_USER_LAB_ORDER::create([...]);  // WRONG!
        $this->sendSMS($order);  // WRONG!
    }
}
```

**Why**: Services are reused by multiple controllers, jobs, and commands. Bypassing breaks consistency.

---

## Rule 4: Dispatch Jobs for Heavy Operations

Never run these synchronously in a request lifecycle:
- PDF report generation
- SMS/Email/WhatsApp/Push notifications
- ZATCA API calls
- HESN/NPHIES API calls
- ERP synchronization
- OpenAI API calls

```php
// ✅ CORRECT — async
ZatcaInvoice::dispatch($invoiceId);
SendSMSJob::dispatch($mobile, $message);
HESNPlusSendData::dispatch($orderId);

// ❌ WRONG — synchronous, blocks HTTP response
$this->zatcaService->generateInvoice($invoiceId);
$this->smsService->send($mobile, $message);
```

---

## Rule 5: Maintain Database Relationships

When modifying tables or creating new ones:
- Always add `PROFILE_ID` foreign key on new business tables
- Maintain existing foreign key constraints
- Add indexes on frequently-queried columns (`PROFILE_ID`, `END_USER_ID`, `LAB_CATEGORY_PACKAGE_ID`)
- Never drop indexed columns without updating queries
- New tables must follow the **UPPERCASE naming convention**

```php
// ✅ CORRECT new table migration
Schema::create('NEW_FEATURE_TABLE', function (Blueprint $table) {
    $table->id('ID');
    $table->integer('PROFILE_ID')->index();
    $table->integer('HOSPITAL_ID')->nullable()->index();
    $table->string('NAME_EN', 255)->nullable();
    $table->string('NAME_AR', 255)->nullable();
    $table->tinyInteger('IS_ACTIVE')->default(1);
    $table->timestamps();
});
```

---

## Rule 6: Respect Feature Flags

Most features are toggled per profile. Always check the flag before executing feature code.

```php
$profile = PROFILE::find($profileId);

// Check feature flag before executing
if (!$profile->ENABLE_AI_RECOMMENDATION) {
    return; // Feature disabled for this profile
}
// ... proceed with AI logic
```

Feature flags live as boolean/tinyint columns in the `PROFILE` table. Check `/docs/ai/architecture.md` section 7 for the full list.

---

## Rule 7: Maintain Bilingual Data

All user-facing content must support both Arabic and English:
- Always save `NAME_EN` AND `NAME_AR`
- Always save `DESCRIPTION_EN` AND `DESCRIPTION_AR`
- Never add a text field without its bilingual pair

```php
// ✅ CORRECT — both languages
$item = new SOME_TABLE();
$item->NAME_EN = $request->name_en;
$item->NAME_AR = $request->name_ar;  // required, even if same as EN

// ❌ WRONG — Arabic users will get empty fields
$item->NAME_EN = $request->name;
// name_ar missing!
```

---

## Rule 8: Never Hardcode Credentials

All credentials, API keys, and tokens must be in:
1. `.env` file (global credentials)
2. `PROFILE` table (per-tenant credentials)
3. `ZATCA_INTEGRATION` table (ZATCA-specific)

```php
// ✅ CORRECT
$apiKey = env('OPENAI_API_KEY');
$smsUser = $profile->UNIFONIC_USER;

// ❌ WRONG
$apiKey = 'sk-abc123...';
$smsUser = 'blazma_sms';
```

---

## Rule 9: ZATCA & NPHIES Compliance — Do Not Break

These government integrations have strict formats and legal implications:
- **ZATCA**: Do NOT modify invoice XML structure, QR code generation, or invoice numbering
- **NPHIES**: Do NOT modify FHIR resource structures or claim submission format
- Any changes to `ZatcaInvoice`, `ZatcaRefund`, or NPHIES jobs require expert review
- Always test against sandbox environments first

---

## Rule 10: Maintain Audit Trails

Many operations have audit logging. Maintain these:
- `END_USER_LAB_ORDER_HISTORY` — all order status changes
- `SYSTEM_USER_LOG` — staff actions
- `PROFILE_SIGNATURE_LOG` — signature changes
- `PROFILE_AI_TRANSACTIONS` — AI usage tracking

When adding new significant operations, add audit log entries.

---

## Rule 11: Update Documentation After Changes

After any significant change:
1. Update the relevant `/docs/ai/*.md` file
2. If new tables added → update `/docs/ai/database.md`
3. If new service/module added → update `/docs/ai/modules.md` and `/docs/ai/laravel_structure.md`
4. If new integration added → update `/docs/ai/integrations.md`
5. Run `php artisan ai:update-docs` to refresh the AI knowledge base

---

## Rule 12: Use `AI_SYSTEM_MAP.json` for Module Reference

The file `/docs/ai/AI_SYSTEM_MAP.json` provides a machine-readable map of:
- All modules and their controllers/services
- All database tables by category
- All integration services
- All queue jobs

Use it to quickly locate which files to modify for a given feature.

---

## Quick Reference: Where to Find Things

| Task | Look Here |
|------|-----------|
| Add a new test/package feature | `LabService`, `LAB_CATEGORY_PACKAGE` model, `LAB_*` tables |
| Modify order workflow | `EndUserService`, `LabService`, `END_USER_LAB_ORDER*` models |
| Add payment gateway | `PaymentService`, new `*Service`, new `*Controller`, new callback route |
| Add notification type | `Services/Notification/`, `NOTIFICATION_EVENTS` table, relevant Job |
| Modify invoice generation | `TaxService`, `InvoiceController`, `ZatcaInvoice` job |
| Add insurance claim feature | `NphiesService`, `InsuranceController`, `INSURANCE_*` tables |
| Add per-profile config | Add column to `PROFILE` table, update migrations |
| Add feature flag | Add `ENABLE_*` tinyint column to `PROFILE`, check flag in service |
| Add scheduled task | Add to `routes/console.php` |
| Add queue job | Create in `app/Jobs/`, implement `ShouldQueue`, dispatch from service |

---

## Anti-Patterns to Avoid

| Anti-Pattern | Why It's Wrong |
|--------------|---------------|
| `MODEL::all()` without PROFILE_ID | Returns all tenants' data |
| `new ServiceClass()` inside methods | Breaks dependency injection |
| Heavy logic in controllers | Breaks separation of concerns |
| Direct HTTP calls without jobs | Blocks request, no retry on failure |
| Missing `_AR` fields on new content | Breaks Arabic UI |
| Modifying ZATCA XML structure | May break government compliance |
| Skipping feature flag checks | Activates features for wrong profiles |
| Raw SQL without PROFILE_ID | Cross-tenant data exposure |

---

*These rules were established from analysis of the full Blazma codebase and database schema. They protect system integrity, multi-tenant security, and government compliance.*
