# AGENTS.md - AI Agent Guidelines for TinyQC

## Important: Always Use Serena Tools

**When editing this codebase, prefer Serena tools over regular file operations:**
- Use `find_symbol` to locate code rather than grep/glob when possible
- Use `replace_symbol_body` for entire method/class changes
- Use `replace_content` with regex for targeted edits
- Use `get_symbols_overview` before reading full files
- Serena tools provide structured, semantically-aware code editing

## Build/Lint/Test Commands

```bash

never start dev server just use the base_url from .env file

# Run all tests
./vendor/bin/phpunit
composer test

# Run single test file
./vendor/bin/phpunit tests/unit/HealthTest.php

# Run with coverage
./vendor/bin/phpunit --coverage-html coverage/

# Run specific test method
./vendor/bin/phpunit --filter testMethodName

# Run migrations
php spark migrate
php spark migrate:rollback

# Clear cache
php spark cache:clear
```

## Technology Stack

| Layer | Technology |
|-------|------------|
| Backend | CodeIgniter 4 (PHP 8.1+) |
| Frontend | Alpine.js + TailwindCSS + DaisyUI |
| Database | SQL Server |

## Code Style Guidelines

### PHP

**Imports** - Order: CodeIgniter, App namespace, use statements
```php
<?php
namespace App\Controllers\Qc;

use CodeIgniter\API\ResponseTrait;
use App\Controllers\BaseController;
use App\Models\Qc\ResultsModel;
```

**Formatting**
- PSR-12 standard
- 4 spaces indentation (no tabs)
- No type hints (follow existing patterns)

**Naming**
- Classes: PascalCase (e.g., `ResultsController`)
- Methods: camelCase (e.g., `getByDateAndControl`)
- Variables: camelCase (e.g., `$resultId`)
- Database: snake_case (e.g., `control_id`)

**Comments**
- Minimal/none - write self-documenting code

**Error Handling**
```php
try {
    $rows = $this->model->findAll();
    return $this->respond(['status' => 'success', 'message' => 'fetch success', 'data' => $rows], 200);
} catch (\Exception $e) {
    return $this->failServerError($e->getMessage());
}
```

### Controllers

**Structure**
- Extend `BaseController`, use `ResponseTrait`
- Define `$model` and `$rules` in `__construct()`
- CRUD pattern: `index()`, `show($id)`, `create()`, `update($id)`, `delete($id)`

**Input Handling**
```php
$input = $this->request->getJSON(true);
$input = camel_to_snake_array($input);  // Convert before DB
```

**Response Format**
```php
return $this->respond([
    'status' => 'success',
    'message' => 'fetch success',
    'data' => $rows
], 200);
```

**Validation**
```php
if (!$this->validate($this->rules)) {
    return $this->failValidationErrors($this->validator->getErrors());
}
```

### Models

**Structure**
- Extend `App\Models\BaseModel` (auto camel/snake conversion)
- Always enable: `$useSoftDeletes = true`, `$useTimestamps = true`
- Define: `$table`, `$primaryKey`, `$allowedFields`

**Example**
```php
protected $table = 'results';
protected $primaryKey = 'result_id';
protected $allowedFields = ['control_id', 'test_id', 'res_date', 'res_value'];
```

### Database Conventions

- Primary keys: `{table_singular}_id` (e.g., `result_id`, `control_id`)
- Foreign keys: Match referenced PK name
- Master tables: Prefix with `master_`
- All tables: `created_at`, `updated_at`, `deleted_at`

### Frontend

**JavaScript**
- No jQuery - use Fetch API
- camelCase in JavaScript, snake_case in PHP/DB
- Use Alpine.js: `x-data`, `x-model`, `x-show`, `x-for`, `@click`

**DaisyUI**
- Use DaisyUI components (btn, input, modal, dropdown, etc.)
- TailwindCSS for utilities

**Base URL**
```javascript
const BASEURL = '<?= base_url(''); ?>';  // or window.BASEURL
```

## File Naming

| Component | Pattern | Example |
|-----------|---------|---------|
| Controller | `PascalCase + Controller` | `ResultsController` |
| Model | `PascalCase + Model` | `ResultsModel` |
| Migration | `YYYY-MM-DD-XXXXXX_Description.php` | `2026-01-15-000001_Results.php` |
| View | `module/action.php` | `entry/daily.php` |

## Things to Avoid

- jQuery, over-engineering, skipping soft deletes, hardcoding
- Don't mix concerns (Controllers handle HTTP, Models handle data)
- Don't forget camel/snake conversion at boundaries
- Don't add unnecessary comments

## Post-Change Requirements

After changes: run `./vendor/bin/phpunit`, update README.md for new features
