# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands ```bash # Development server php spark serve # Database migrations php spark migrate # Run pending migrations php spark migrate:rollback # Rollback last batch php spark db seed CmodQcSeeder # Seed initial data # Run tests ./vendor/bin/phpunit # All tests ./vendor/bin/phpunit tests/unit/SomeTest.php # Specific test file ./vendor/bin/phpunit --coverage-html coverage/ # With coverage report ``` ## Architecture This is a CodeIgniter 4 Quality Control management system with: - **Backend**: PHP 8.1+, CodeIgniter 4 - **Database**: SQL Server (uses `SQLSRV` driver) - **Frontend**: TailwindCSS + Alpine.js + DaisyUI (CDN-based, no build step) - **Testing**: PHPUnit 10 - **Icons**: FontAwesome 7 ### Key Components **Models** (`app/Models/`): - `BaseModel` - Custom base model with automatic camelCase/snake_case conversion - `findAll()`, `find()`, `first()` return camelCase keys - `insert()`, `update()` accept camelCase, convert to snake_case for DB - Organized in subdirectories: `Master/`, `Qc/` **Controllers** (`app/Controllers/`): - `PageController` - Renders page views with `main_layout` - `Api\*` - Consolidated entry API controllers (DashboardApi, EntryApi, ReportApi) - `Master\*` - CRUD for master data (MasterDepts, MasterTests, MasterControls) - `Qc\*` - QC domain controllers (ControlTests, Results, ResultComments) **Views** (`app/Views/`): - PHP templates extending `layout/main_layout` - Alpine.js components in `x-data` blocks - DaisyUI components for UI **Helpers** (`app/Helpers/`): - `stringcase_helper.php` - `camel_to_snake_array()`, `snake_to_camel_array()` - The `stringcase` helper is auto-loaded in `BaseController` ### Database Schema Tables use soft deletes (`deleted_at`) and timestamps (`created_at`, `updated_at`): - `dict_depts`, `dict_tests`, `dict_controls` - Master data - `control_tests` - Control-test associations with QC parameters (mean, sd) - `results` - Daily test results - `result_comments` - Comments per result ## Conventions ### Case Convention - **Frontend/JS/API**: camelCase - **Backend PHP variables**: camelCase - **Database**: snake_case - Models handle automatic conversion; use helpers for manual conversions ### API Response Format ```php return $this->respond([ 'status' => 'success', 'message' => 'fetch success', 'data' => $rows ], 200); ``` ### Controller Pattern ```php namespace App\Controllers\Master; use CodeIgniter\API\ResponseTrait; use App\Controllers\BaseController; class DeptsController extends BaseController { use ResponseTrait; protected $model; protected $rules; public function __construct() { $this->model = new MasterDeptsModel(); $this->rules = ['name' => 'required|min_length[1]']; } public function index() { $keyword = $this->request->getGet('keyword'); $rows = $this->model->search($keyword); return $this->respond([...], 200); } public function create() { $input = camel_to_snake_array($this->request->getJSON(true)); if (!$this->validate($this->rules)) { return $this->failValidationErrors($this->validator->getErrors()); } $id = $this->model->insert($input, true); return $this->respondCreated(['status' => 'success', 'message' => $id]); } } ``` ### Model Pattern ```php namespace App\Models\Master; use App\Models\BaseModel; class MasterDeptsModel extends BaseModel { protected $table = 'dict_depts'; protected $primaryKey = 'dept_id'; protected $allowedFields = ['dept_name', 'deleted_at']; protected $useTimestamps = true; protected $useSoftDeletes = true; public function search(?string $keyword) { if ($keyword) { $this->like('dept_name', $keyword); } return $this->findAll(); } } ``` ### Routes Pattern - Page routes: `$routes->get('/path', 'PageController::method');` - API routes: `$routes->group('api', function($routes) { ... });` - API sub-groups: `api/master`, `api/qc` ## Frontend Patterns - Alpine.js `x-data` for component state (inline or in ` endSection(); ?> ``` ## Things to Avoid 1. Don't skip soft deletes (`deleted_at`) 2. Don't mix concerns - controllers handle HTTP, models handle data 3. Don't forget case conversion - use helpers or BaseModel ## Response Style - Use emojis in responses where appropriate to add visual appeal 😊 - Keep responses concise and helpful