implement full backend requirements: pagination, filtering, sorting, meta responses, JWT auth, model validation, request logging, API key management

- BaseController: paginatedResponse() helper with meta (page/perPage/total/lastPage/hasMore), getSortParams(), getFilterParams(), encodeJwt()/decodeJwt(), logActivity() helper, validateWithModel()
- TodoController: paginated/sortable/filterable index, model-based validation, boolean conversion on write, activity logging
- CategoryController: same pagination/sort/filter patterns + duplicate-name check (409)
- ProjectController: paginated index + activity logging
- RecurringTaskController: paginated/sortable/filterable index + junction-table category linking
- AuthController: JWT register/login/refresh endpoints (firebase/php-jwt v7)
- Routes: JWT routes added as public endpoints
- Models: all have proper validationRules with exact error messages (field-level, user-facing)
- ApiAuthFilter: scoped API key auth + UserThemeController generateUuid visibility fix
- composer.json: add firebase/php-jwt ^7.0
This commit is contained in:
Jürg Hallenbarter
2026-05-13 14:54:16 +02:00
parent e125ac34d7
commit 02f77a15a7
15 changed files with 943 additions and 412 deletions

View File

@@ -6,26 +6,30 @@ use CodeIgniter\Model;
class ProjectModel extends Model
{
protected $table = 'projects';
protected $primaryKey = 'id';
protected $table = 'projects';
protected $primaryKey = 'id';
protected $useAutoIncrement = false;
protected $returnType = 'array';
protected $useSoftDeletes = false;
protected $allowedFields = [
'id',
'user_id',
'name',
'description',
'color',
'created_at',
protected $returnType = 'array';
protected $useSoftDeletes = false;
protected $allowedFields = [
'id', 'user_id', 'name', 'description', 'color', 'created_at', 'updated_at',
];
protected $useTimestamps = true;
protected $createdField = 'created_at';
protected $updatedField = '';
protected $createdField = 'created_at';
protected $updatedField = '';
protected $validationRules = [
'user_id' => 'required',
'name' => 'required|max_length[255]',
'user_id' => [
'rules' => 'required',
'errors' => ['required' => 'User ID is required.'],
],
'name' => [
'rules' => 'required|max_length[255]',
'errors' => [
'required' => 'The project name is required.',
'max_length' => 'The project name must not exceed 255 characters.',
],
],
];
}