diff --git a/.serena/.gitignore b/.serena/.gitignore deleted file mode 100644 index 14d86ad..0000000 --- a/.serena/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/cache diff --git a/.serena/memories/coding_conventions.md b/.serena/memories/coding_conventions.md deleted file mode 100644 index bee54c6..0000000 --- a/.serena/memories/coding_conventions.md +++ /dev/null @@ -1,103 +0,0 @@ -# Coding Conventions & Standards - -## PHP Standards -- PHP 8.1+ features (typed properties, match expressions) -- Always declare return types for public methods -- No comments unless explaining complex logic -- Use `esc()` when outputting user data in views - -## Naming Conventions - -| Type | Convention | Example | -|------|------------|---------| -| Classes | PascalCase | `Admin`, `UserController` | -| Methods/Variables | camelCase | `getUsers()`, `$userId` | -| Constants | UPPER_SNAKE_CASE | `DB_HOST` | -| Database tables | UPPER_SNAKE_CASE | `GDC_CMOD.dbo.USERS` | -| Views | lowercase_underscores | `admin/index.php` | -| Routes | lowercase | `/admin/users` | - -## Controller Patterns - -```php -namespace App\Controllers; - -class Admin extends BaseController { - public function index() { } -} - -// API Controllers use ResponseTrait -use App\Controllers\BaseController; -use CodeIgniter\API\ResponseTrait; - -class Users extends BaseController { - use ResponseTrait; - protected $db; - - public function __construct() { - $this->db = \Config\Database::connect(); - helper(['url', 'form', 'text']); - } -} -``` - -## Database Operations - -```php -$this->db = \Config\Database::connect(); - -// Parameterized queries only -$query = $this->db->query("SELECT * FROM table WHERE id = ?", [$id]); -$row = $query->getRowArray(); -$results = $query->getResultArray(); - -// Transactions -$this->db->transBegin(); -try { - $this->db->query("INSERT INTO ...", [$data]); - $this->db->transCommit(); -} catch (\Throwable $e) { - $this->db->transRollback(); -} -``` - -## Request/Response Patterns - -```php -// GET input -$date1 = $this->request->getVar('date1') ?? date('Y-m-d'); - -// POST JSON -$input = $this->request->getJSON(true); - -// JSON response -return $this->respond(['data' => $results]); -return $this->response->setJSON(['message' => 'Success']); - -// View response -return view('admin/index', $data); - -// Redirect with errors -return redirect()->back()->with('errors', ['key' => 'message']); -``` - -## Session Structure - -```php -session()->set([ - 'isLoggedIn' => true, - 'userid' => (string) $user['USERID'], - 'userroleid' => (int) $user['USERROLEID'], - 'userrole' => (string) $role, -]); -``` - -## Security Guidelines -- Use parameterized queries (never interpolate directly) -- Hash passwords with `password_hash()` / `password_verify()` -- Validate and sanitize all input before use -- Use `esc()` when outputting user data in views - -## Validation Endpoints -- `POST /api/{resource}/validate/{id}` - validate a record -- `DELETE /api/{resource}/validate/{id}` - unvalidate a record diff --git a/.serena/memories/project_commands.md b/.serena/memories/project_commands.md deleted file mode 100644 index bda0170..0000000 --- a/.serena/memories/project_commands.md +++ /dev/null @@ -1,134 +0,0 @@ -# Development Commands - -## Testing -```bash -# Run all tests -composer test -./vendor/bin/phpunit - -# Run single test file -./vendor/bin/phpunit tests/unit/HealthTest.php - -# Run single test method -./vendor/bin/phpunit tests/unit/HealthTest.php --filter testIsDefinedAppPath - -# Generate code coverage report -./vendor/bin/phpunit --colors --coverage-text=tests/coverage.txt --coverage-html=tests/coverage/ -d memory_limit=1024m -``` - -## Development Server -```bash -# Start development server -php spark serve -``` - -## Code Generation (CLI) -```bash -# Create controller -php spark make:controller Admin - -# Create model -php spark make:model User -``` - -## Routing -```bash -# List all routes -php spark list -``` - -## Git Commands (Windows) -```bash -# Check git status -git status - -# Check git diff -git diff - -# View recent commits -git log - -# Add files to staging -git add . - -# Create commit -git commit -m "message" - -# Push to remote -git push - -# Pull from remote -git pull -``` - -## File System Commands (Windows) -```bash -# List directory contents -ls -dir - -# Change directory -cd directory_name - -# Create directory -mkdir directory_name - -# Copy files -copy source destination - -# Move files -move source destination - -# Remove files -del filename -rm filename - -# Find files by name -dir /s /b filename - -# Search content in files -findstr /s /i "search_term" *.php -``` - -## CodeIgniter-Specific -```bash -# Clear cache -php spark cache:clear - -# Clear view cache -php spark cache:clear - -# Install dependencies -composer install -composer update - -# Dump autoload -composer dump-autoload -``` - -## What to do after completing a task - -1. **Run tests** - ```bash - composer test - ``` - -2. **Check for errors** - - Review any output from tests - - Check for lint errors or warnings - -3. **Verify the changes** - - Test the functionality manually - - Check if any routes or filters were affected - -4. **Update documentation** (if needed) - - Add new routes to documentation - - Update CHECKLIST.md if it's a new feature - -5. **Commit changes** (only when explicitly asked) - ```bash - git add . - git commit -m "describe changes" - ``` - -**Important**: Never commit changes unless explicitly asked by the user. diff --git a/.serena/memories/project_overview.md b/.serena/memories/project_overview.md deleted file mode 100644 index 0079917..0000000 --- a/.serena/memories/project_overview.md +++ /dev/null @@ -1,38 +0,0 @@ -# GDC CMOD - Laboratory Management System - -## Purpose -CodeIgniter 4 PHP application for laboratory management (GDC CMOD - Laboratory Request Management System). Handles specimen collection tracking, request validation, and result management with role-based access control. - -## Tech Stack -- **Framework**: CodeIgniter 4 (PHP 8.1+) -- **Database**: SQL Server (primary) + Firebird/InterBase (legacy patient data via ODBC) -- **Frontend**: TailwindCSS + DaisyUI 5 + Alpine.js + Font Awesome 7 -- **Testing**: PHPUnit 10.x -- **Server**: Windows (XAMPP/IIS) - -## Database Architecture -- **Primary DB**: SQL Server (`GDC_CMOD.dbo`) via Microsoft ODBC Driver (MSOLEDBSQL) -- **Legacy DB**: Firebird/InterBase (`GLENEAGLES` via ODBC) -- **Connection**: `\Config\Database::connect()` returns MySQLi connection (configured as SQLSRV) -- **No CI4 Models**: Uses raw SQL queries via `Database::connect()->query()` - -## Key Database Tables -- `GDC_CMOD.dbo.USERS` - Users with `USERID`, `USERROLEID`, `PASSWORD` -- `GDC_CMOD.dbo.CM_REQUESTS` - Validation tracking (`ISVAL1`, `ISVAL2`, validation users/dates) -- `GDC_CMOD.dbo.TUBES` - Sample collection status -- `GDC_CMOD.dbo.V_DASHBOARD_DEV` - Dashboard data view -- `glendb.dbo.*` - Legacy Firebird patient data - -## Architecture Overview -- **Session-based authentication** with role-based access control (RBAC) -- **Dual-level validation** system requiring 2 different users to validate the same request -- **Role groups** filter middleware for routing control -- **API endpoints** for JSON responses -- **Page controllers** for HTML views - -## Current Pending Features (CHECKLIST.md) -- Restrict Print/Save-to-PDF to CS Role only -- Add Dedicated Print Button -- Update PDF Report Metadata (Replace 'Printed By' with validating user's name) -- Reprint Label functionality -- Print Result Audit (Track when result reports are printed/exported) diff --git a/.serena/memories/project_structure.md b/.serena/memories/project_structure.md deleted file mode 100644 index 3e15dae..0000000 --- a/.serena/memories/project_structure.md +++ /dev/null @@ -1,107 +0,0 @@ -# Project Structure - -## Directory Layout -``` -gdc_cmod/ -├── app/ # Application code -│ ├── Controllers/ # Controllers (API & Pages) -│ │ ├── Pages/ # Page controllers by role -│ │ │ ├── AdminController.php -│ │ │ ├── CsController.php -│ │ │ ├── LabController.php -│ │ │ ├── PhlebotomistController.php -│ │ │ └── SuperuserController.php -│ │ ├── ApiDashboard.php -│ │ ├── ApiRequestsAuditController.php -│ │ ├── ApiValidateController.php -│ │ ├── AuthController.php -│ │ ├── BaseController.php -│ │ ├── ErrorPage.php -│ │ ├── Home.php -│ │ ├── LabelController.php -│ │ ├── RequestsController.php -│ │ ├── SamplesController.php -│ │ └── UsersController.php -│ ├── Config/ # Configuration -│ │ ├── App.php -│ │ ├── Database.php -│ │ ├── Filters.php # Filter definitions -│ │ ├── Routes.php # Route definitions -│ │ └── ... -│ ├── Database/ # Database configurations -│ ├── Filters/ # Custom filters -│ │ ├── GuestFilter.php -│ │ ├── RoleFilter.php -│ │ └── .gitkeep -│ ├── Helpers/ # Helper functions -│ ├── Language/ # Language files -│ ├── Libraries/ # Custom libraries -│ ├── Models/ # Models (none used in this project) -│ ├── ThirdParty/ # Third-party code -│ └── Views/ # Views -│ ├── admin/ # Admin views -│ ├── cs/ # CS views -│ ├── errors/ # Error pages -│ ├── lab/ # Lab views -│ ├── phlebo/ # Phlebo views -│ ├── shared/ # Shared components -│ ├── superuser/ # Superuser views -│ └── ... -├── public/ # Web root -│ ├── index.php # Front controller -│ ├── .htaccess -│ ├── web.config -│ ├── css/ # Local CSS -│ └── js/ # Local JavaScript -├── tests/ # PHPUnit tests -│ ├── _support/ # Test support files -│ ├── database/ # Database tests -│ ├── session/ # Session tests -│ ├── unit/ # Unit tests -│ └── README.md -├── writable/ # Writeable directories -├── vendor/ # Composer dependencies -├── .env # Environment variables (git ignored) -├── env # Example environment file -├── .gitignore # Git ignore rules -├── AGENTS.md # Agent guidelines (this file) -├── CHECKLIST.md # Feature checklist -├── CLAUDE.md # Claude Code guidelines -├── composer.json # Composer dependencies -├── composer.lock # Locked dependencies -├── phpunit.xml.dist # PHPUnit configuration -├── preload.php # PHP OpCache preload -├── README.md # Project README -├── spark # CodeIgniter CLI tool -└── LICENSE # MIT License -``` - -## Key Files & Their Purposes - -### Configuration -- **app/Config/Database.php** - Database connections (SQL Server + Firebird ODBC) -- **app/Config/Filters.php** - Filter definitions (RoleFilter, GuestFilter) -- **app/Config/Routes.php** - Route definitions (API and page routes) -- **app/Config/App.php** - Application settings (baseURL, etc.) - -### Controllers -- **Pages/[Role]Controller.php** - Page controllers for each role -- **Api[Resource]Controller.php** - API controllers for JSON endpoints -- **AuthController.php** - Authentication (login/logout) -- **UsersController.php** - User management API -- **RequestsController.php** - Request validation API -- **SamplesController.php** - Sample collection API - -### Filters -- **app/Filters/RoleFilter.php** - Check user role on protected routes -- **app/Filters/GuestFilter.php** - Redirect logged-in users from public pages - -### Views -- **views/shared/** - Shared components used across roles -- **views/{role}/** - Role-specific views -- **views/login.php** - Login page - -### Tests -- **tests/unit/** - Unit tests (HealthTest, etc.) -- **tests/database/** - Database tests -- **tests/session/** - Session tests diff --git a/.serena/memories/rbac_system.md b/.serena/memories/rbac_system.md deleted file mode 100644 index aac6b89..0000000 --- a/.serena/memories/rbac_system.md +++ /dev/null @@ -1,104 +0,0 @@ -# Role-Based Access Control (RBAC) - -## Role Definitions - -| Role ID | Name | Route Prefix | Permissions | -|---------|------|--------------|-------------| -| 0 | Superuser | `/superuser` | Full access + Users CRUD | -| 1 | Admin | `/admin` | Full access + Users CRUD | -| 2 | Lab | `/lab` | Request validation, Sample collection | -| 3 | Phlebo | `/phlebo` | Specimen collection, Dashboard | -| 4 | CS | `/cs` | Dashboard, Status Monitoring, Patient Inquiry | - -## Route Filtering - -### Role Filter -```php -// Single role -['filter' => 'role:1'] - -// Multiple roles -['filter' => 'role:1,2'] -``` - -### Filter Usage - -**app/Filters/RoleFilter.php** -- Checks `session()->get('isLoggedIn')` - redirects to `/login` if not logged in -- Checks role ID against allowed roles from route arguments -- Redirects to `/unauthorized` if role not authorized - -**app/Filters/GuestFilter.php** -- Redirects logged-in users to role-based dashboard -- Use for public-only routes (e.g., `/login`) - -## Route Prefixes & Controllers - -### Superuser (Role 0) -- `/superuser` - Pages\SuperuserController::index -- `/superuser/users` - Pages\SuperuserController::users -- `/superuser/validate` - Pages\SuperuserController::validatePage - -### Admin (Role 1) -- `/admin` - Pages\AdminController::index -- `/admin/users` - Pages\AdminController::users -- `/admin/validate` - Pages\AdminController::validationPage - -### Lab (Role 2) -- `/lab` - Pages\LabController::index -- `/lab/validate` - Pages\LabController::validationPage - -### Phlebo (Role 3) -- `/phlebo` - Pages\PhlebotomistController::index - -### CS (Role 4) -- `/cs` - Pages\CsController::index - -## Validation System (Dual-Level) - -Validation requires 2 different users to validate the same request: - -**First Validation:** -- Sets `ISVAL1=1` -- Records `VAL1USER` (username) -- Records `VAL1DATE` (datetime) - -**Second Validation (different user):** -- Sets `ISVAL2=1` -- Records `VAL2USER` (username) -- Records `VAL2DATE` (datetime) - -**Validation Permission:** -- Available to Role 0, 1, 2 (Superuser, Admin, Lab) - -## Unvalidation -- Available to Role 0, 1 (Superuser, Admin) -- Sets `ISVAL1=0` and `ISVAL2=0`, clears validation user/date fields - -## Authentication Flow - -1. **AuthController::login()** - Verifies credentials against `GDC_CMOD.dbo.USERS`, sets session -2. **RoleFilter** - Runs on protected routes, checks `session()->get('isLoggedIn')` and role ID -3. **GuestFilter** - Runs on public routes, redirects logged-in users to dashboard - -## API Endpoint Permissions - -### Users Management -- **Access**: Role 0, 1 (Superuser, Admin) -- **Endpoints**: GET, POST, PATCH, DELETE on `/api/users` - -### Requests -- **Access**: Role 0, 1, 2, 3, 4 (All Roles) -- **Endpoints**: - - `GET /api/requests` - Dashboard data - - `POST /api/requests/validate/:id` - Validate request - - `DELETE /api/requests/validate/:id` - Unvalidate request - - `GET /api/requests/:id/audit` - Audit trail - -### Samples -- **Access**: All Roles for collect/show -- **Unreceive**: Role 0, 1 only -- **Endpoints**: - - `POST /api/samples/collect/:accessnumber` - Mark sample collected - - `GET /api/samples/:accessnumber` - Show sample info - - `DELETE /api/samples/receive/:accessnumber` - Unreceive sample diff --git a/.serena/memories/routes_patterns.md b/.serena/memories/routes_patterns.md deleted file mode 100644 index 30d70de..0000000 --- a/.serena/memories/routes_patterns.md +++ /dev/null @@ -1,136 +0,0 @@ -# Route Patterns - -## Route File Structure -File: **app/Config/Routes.php** - -## Public Routes -```php -$routes->get('/', 'Home::index'); -$routes->get('/login', 'AuthController::loginPage', ['filter' => 'guest']); -$routes->post('/login', 'AuthController::login', ['filter' => 'guest']); -$routes->get('/logout', 'AuthController::logout'); -$routes->patch('/setPassword', 'AuthController::setPassword'); -``` - -## Label Routes (Public) -```php -$routes->get('label/coll/(:any)', 'LabelController::coll/$1'); -$routes->get('label/dispatch/(:any)/(:any)', 'LabelController::dispatch/$1/$2'); -$routes->get('label/all/(:any)', 'LabelController::print_all/$1'); -``` - -## API Routes (Protected by Role Filter) -File: **app/Config/Routes.php** - `$routes->group('api', ...)` block - -### Users Management -```php -$routes->group('users', ['filter' => 'role:0,1'], function ($routes) { - $routes->get('', 'UsersController::index'); // Get all users - $routes->post('', 'UsersController::create'); // Create user - $routes->patch('(:any)', 'UsersController::update/$1'); // Update user - $routes->delete('(:any)', 'UsersController::delete/$1'); // Delete user -}); -``` - -### Requests -```php -$routes->group('requests', ['filter' => 'role:0,1,2,3,4'], function ($routes) { - $routes->get('', 'RequestsController::index'); // Dashboard data - $routes->get('(:any)/audit', 'ApiRequestsAuditController::show/$1'); // Audit trail - $routes->post('validate/(:any)', 'RequestsController::val/$1'); // Validate request - $routes->delete('validate/(:any)', 'RequestsController::unval/$1'); // Unvalidate request -}); -``` - -### Validate API -```php -$routes->group('validate', ['filter' => 'role:0,1,2'], function ($routes) { - $routes->get('unvalidated', 'ApiValidateController::unvalidated'); // Get unvalidated requests -}); -``` - -### Samples -```php -$routes->group('samples', function ($routes) { - // Collect & Show - All Roles - $routes->group('', ['filter' => 'role:0,1,2,3,4'], function ($routes) { - $routes->post('collect/(:any)', 'SamplesController::collect/$1'); - $routes->get('(:any)', 'SamplesController::show/$1'); - }); - - // Unreceive - Only Superuser (0) and Admin (1) - $routes->group('', ['filter' => 'role:0,1'], function ($routes) { - $routes->delete('receive/(:any)', 'SamplesController::unreceive/$1'); - }); -}); -``` - -## Page Routes (Protected by Role Filter) - -### Superuser (Role 0) -```php -$routes->group('superuser', ['filter' => 'role:0'], function ($routes) { - $routes->get('', 'Pages\SuperuserController::index'); - $routes->get('users', 'Pages\SuperuserController::users'); - $routes->get('validate', 'Pages\SuperuserController::validatePage'); -}); -``` - -### Admin (Role 1) -```php -$routes->group('admin', ['filter' => 'role:1'], function ($routes) { - $routes->get('', 'Pages\AdminController::index'); - $routes->get('users', 'Pages\AdminController::users'); - $routes->get('validate', 'Pages\AdminController::validationPage'); -}); -``` - -### Lab (Role 2) -```php -$routes->group('lab', ['filter' => 'role:2'], function ($routes) { - $routes->get('', 'Pages\LabController::index'); - $routes->get('validate', 'Pages\LabController::validationPage'); -}); -``` - -### Phlebo (Role 3) -```php -$routes->group('phlebo', ['filter' => 'role:3'], function ($routes) { - $routes->get('', 'Pages\PhlebotomistController::index'); -}); -``` - -### CS (Role 4) -```php -$routes->group('cs', ['filter' => 'role:4'], function ($routes) { - $routes->get('', 'Pages\CsController::index'); -}); -``` - -## Error Handling -```php -$routes->set404Override(function () { - $response = service('response'); - $response->setStatusCode(404); - echo view('errors/notfound'); -}); -$routes->get('/unauthorized', 'ErrorPage::unauthorized'); -``` - -## Route Filter Order -1. **Before filters** (run before request): - - `forcehttps` - Force HTTPS - - `pagecache` - Web page caching - - `role` - Role-based access (on protected routes) - - `guest` - Guest-only (on public routes) - -2. **After filters** (run after response): - - `pagecache` - Web page caching - - `performance` - Performance metrics - - `toolbar` - Debug toolbar - -## Route Naming Conventions -- API endpoints: kebab-case, under `/api/` prefix -- Page routes: kebab-case, grouped by role -- Resource endpoints: standard REST pattern (`/resource/{id}`) -- Action endpoints: kebab-case, snake_case for parameters diff --git a/.serena/project.yml b/.serena/project.yml deleted file mode 100644 index 45b857a..0000000 --- a/.serena/project.yml +++ /dev/null @@ -1,132 +0,0 @@ -# the name by which the project can be referenced within Serena -project_name: "gdc_cmod" - - -# list of languages for which language servers are started; choose from: -# al bash clojure cpp csharp -# csharp_omnisharp dart elixir elm erlang -# fortran fsharp go groovy haskell -# java julia kotlin lua markdown -# matlab nix pascal perl php -# powershell python python_jedi r rego -# ruby ruby_solargraph rust scala swift -# terraform toml typescript typescript_vts vue -# yaml zig -# (This list may be outdated. For the current list, see values of Language enum here: -# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py -# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.) -# Note: -# - For C, use cpp -# - For JavaScript, use typescript -# - For Free Pascal/Lazarus, use pascal -# Special requirements: -# Some languages require additional setup/installations. -# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers -# When using multiple languages, the first language server that supports a given file will be used for that file. -# The first language is the default language and the respective language server will be used as a fallback. -# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored. -languages: -- php - -# the encoding used by text files in the project -# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings -encoding: "utf-8" - -# whether to use project's .gitignore files to ignore files -ignore_all_files_in_gitignore: true - -# list of additional paths to ignore in all projects -# same syntax as gitignore, so you can use * and ** -ignored_paths: [] - -# whether the project is in read-only mode -# If set to true, all editing tools will be disabled and attempts to use them will result in an error -# Added on 2025-04-18 -read_only: false - -# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details. -# Below is the complete list of tools for convenience. -# To make sure you have the latest list of tools, and to view their descriptions, -# execute `uv run scripts/print_tool_overview.py`. -# -# * `activate_project`: Activates a project by name. -# * `check_onboarding_performed`: Checks whether project onboarding was already performed. -# * `create_text_file`: Creates/overwrites a file in the project directory. -# * `delete_lines`: Deletes a range of lines within a file. -# * `delete_memory`: Deletes a memory from Serena's project-specific memory store. -# * `execute_shell_command`: Executes a shell command. -# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced. -# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type). -# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type). -# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes. -# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file. -# * `initial_instructions`: Gets the initial instructions for the current project. -# Should only be used in settings where the system prompt cannot be set, -# e.g. in clients you have no control over, like Claude Desktop. -# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol. -# * `insert_at_line`: Inserts content at a given line in a file. -# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol. -# * `list_dir`: Lists files and directories in the given directory (optionally with recursion). -# * `list_memories`: Lists memories in Serena's project-specific memory store. -# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building). -# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context). -# * `read_file`: Reads a file within the project directory. -# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store. -# * `remove_project`: Removes a project from the Serena configuration. -# * `replace_lines`: Replaces a range of lines within a file with new content. -# * `replace_symbol_body`: Replaces the full definition of a symbol. -# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen. -# * `search_for_pattern`: Performs a search for a pattern in the project. -# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase. -# * `switch_modes`: Activates modes by providing a list of their names -# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information. -# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task. -# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed. -# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store. -excluded_tools: [] - -# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default) -included_optional_tools: [] - -# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools. -# This cannot be combined with non-empty excluded_tools or included_optional_tools. -fixed_tools: [] - -# list of mode names to that are always to be included in the set of active modes -# The full set of modes to be activated is base_modes + default_modes. -# If the setting is undefined, the base_modes from the global configuration (serena_config.yml) apply. -# Otherwise, this setting overrides the global configuration. -# Set this to [] to disable base modes for this project. -# Set this to a list of mode names to always include the respective modes for this project. -base_modes: - -# list of mode names that are to be activated by default. -# The full set of modes to be activated is base_modes + default_modes. -# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply. -# Otherwise, this overrides the setting from the global configuration (serena_config.yml). -# This setting can, in turn, be overridden by CLI parameters (--mode). -default_modes: - -# initial prompt for the project. It will always be given to the LLM upon activating the project -# (contrary to the memories, which are loaded on demand). -initial_prompt: "" - -# override of the corresponding setting in serena_config.yml, see the documentation there. -# If null or missing, the value from the global config is used. -symbol_info_budget: - -# The language backend to use for this project. -# If not set, the global setting from serena_config.yml is used. -# Valid values: LSP, JetBrains -# Note: the backend is fixed at startup. If a project with a different backend -# is activated post-init, an error will be returned. -language_backend: - -# list of regex patterns which, when matched, mark a memory entry as read‑only. -# Extends the list from the global configuration, merging the two lists. -read_only_memory_patterns: [] - -# line ending convention to use when writing source files. -# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default) -# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings. -line_ending: diff --git a/TODO.md b/TODO.md deleted file mode 100644 index e33f6a3..0000000 --- a/TODO.md +++ /dev/null @@ -1,44 +0,0 @@ -# Project Checklist: Glen RME & Lab Management System - -**Last Updated:** 20260212 - -Pending: -- sample other for MCU is annoying -- report2 go to cmod - -Completed: -- Update User Role levels (Standardize roles: Superuser, Admin, Lab, Phlebo, CS) -- Role-Based Dashboard Filtering (Filter by patient_status or service_type) -- Fix Table Sorting (Enable sorting by "No Register" and "Patient Name") -- Fix Language Toggle (Toggle lab result preview between Indonesian and English) -- Apply Row Color-Coding (Color-code "No Register" column) -- Initialize RME Sidebar Menu (Create menu items) -- Dashboard Performance (When getting data more than 100 rows, it load too slow) -- Dashboard for Lab -> no test with only number, remove request with empty test -- Dashboard for Others -> complete -- Refactor same views/*role* to views/shared -- Move all CDN to local -- Remove 'status' field on dashboard -- Restrict 'Validate' to Lab, Admin, Superuser -- Hide/Disable 'Validation' button after 2nd validation (Prevent redundant validation actions) -- Restrict 'UnValidate' to Admin, Superuser -- Remove 'UnCollect' -- Audit Trail (Track all actions: validation, unvalidation, collection, uncollection) -- Create Validate Page -- Sync color with old gdc_cmod -- Add Val1 Val2 on the result -- Show Print / PDF button when val1 val2 done -- Restrict Print/Save-to-PDF to CS Role only (Admin, Lab, CS can print/save) -- Add Receive to Audit -- Put all action to dropdown on request / dashboard -- Auto generate PDF on second val -- Validate delay when loading result -- Reprint Label (Add functionality to reprint labels) -- Create Eng Result UI UX on request dashboard -- Test and fix PDF Generation -- Print Result Audit (Track when result reports are printed/exported, log user and timestamp) -- Test and fix Reprint label -- fasten the load of val page -- preview result for validate for su adm lab -- auto generate pdf after 2 val from preview -- add datetime val1 val2 \ No newline at end of file diff --git a/new_table.sql b/new_table.sql deleted file mode 100644 index de3d3fe..0000000 --- a/new_table.sql +++ /dev/null @@ -1,29 +0,0 @@ -USE [GDC_CMOD] -GO - -/****** Object: Table [dbo].[AUDIT_EVENTS] Script Date: 1/23/2026 4:38:31 PM ******/ -SET ANSI_NULLS ON -GO - -SET QUOTED_IDENTIFIER ON -GO - -CREATE TABLE [dbo].[AUDIT_EVENTS]( - [ACCESSNUMBER] [varchar](20) NOT NULL, - [EVENT_TYPE] [varchar](20) NOT NULL, - [USERID] [varchar](50) NOT NULL, - [EVENT_AT] [datetime] NOT NULL, - [REASON] [varchar](500) NULL, - CONSTRAINT [PK_AUDIT_EVENTS] PRIMARY KEY CLUSTERED -( - [ACCESSNUMBER] ASC, - [EVENT_TYPE] ASC, - [EVENT_AT] ASC -)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] -) ON [PRIMARY] -GO - -ALTER TABLE [dbo].[AUDIT_EVENTS] ADD DEFAULT (getdate()) FOR [EVENT_AT] -GO - - diff --git a/script.php b/script.php deleted file mode 100644 index a43a353..0000000 --- a/script.php +++ /dev/null @@ -1,172 +0,0 @@ -\n"; - echo "Example: php script.php batch.txt\n\n"; - echo "File format: One accessnumber per line\n"; - exit(1); -} - -$inputFile = $argv[1]; - -if (!file_exists($inputFile)) { - echo "Error: File not found: $inputFile\n"; - exit(1); -} - -// Base URL for CI4 endpoint -// Using batch/pdf endpoint (no auth required) -// Dev: localhost/gdc_cmod/ | Prod: glenlis/cmod/ -$baseUrl = 'http://localhost/gdc_cmod/batch/pdf'; - -// Read accessnumbers from file -$lines = file($inputFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); -if ($lines === false) { - echo "Error: Could not read file: $inputFile\n"; - exit(1); -} - -$accessnumbers = array_filter(array_map('trim', $lines)); -$total = count($accessnumbers); - -if ($total === 0) { - echo "Error: No accessnumbers found in file\n"; - exit(1); -} - -echo "Processing $inputFile\n"; -echo "Found $total access number(s) via $baseUrl\n"; -echo str_repeat("-", 60) . "\n"; - -// Statistics -$stats = [ - 'success' => 0, - 'failed' => 0, - 'details' => [] -]; - -// Process each accessnumber -foreach ($accessnumbers as $index => $accessnumber) { - $current = $index + 1; - $startTime = microtime(true); - echo "[$current/$total] $accessnumber... "; - - try { - $url = "$baseUrl/$accessnumber/pdf"; - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_TIMEOUT, 60); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_HEADER, true); // Include headers in output - - $response = curl_exec($ch); - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - $redirectUrl = curl_getinfo($ch, CURLINFO_REDIRECT_URL); - $finalUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); - $curlError = curl_error($ch); - curl_close($ch); - - if ($curlError) { - throw new \Exception("cURL error: $curlError"); - } - - // Debug: Show redirect info - if ($httpCode !== 200) { - $debug = "HTTP $httpCode"; - if ($redirectUrl) { - $debug .= " -> $redirectUrl"; - } - if ($finalUrl !== $url) { - $debug .= " (final: $finalUrl)"; - } - throw new \Exception($debug); - } - - // Remove headers from response body - $headerSize = strpos($response, "\r\n\r\n"); - if ($headerSize !== false) { - $response = substr($response, $headerSize + 4); - } - - $data = json_decode($response, true); - - if (!isset($data['success']) || !$data['success']) { - $error = $data['error'] ?? 'Unknown error'; - throw new \Exception($error); - } - - $jobId = $data['jobId'] ?? 'unknown'; - $lang = $data['lang'] ?? 'Unknown'; - $isRegen = $data['isRegen'] ?? false; - $regenText = $isRegen ? ' (regen)' : ''; - - $elapsed = round((microtime(true) - $startTime) * 1000); - echo "QUEUED (job: $jobId, lang: $lang$regenText, ${elapsed}ms)\n"; - - $stats['success']++; - $stats['details'][] = [ - 'accessnumber' => $accessnumber, - 'status' => 'success', - 'jobId' => $jobId, - 'language' => $lang, - 'time_ms' => $elapsed - ]; - - } catch (\Exception $e) { - $elapsed = round((microtime(true) - $startTime) * 1000); - echo "FAILED (" . $e->getMessage() . ", ${elapsed}ms)\n"; - - $stats['failed']++; - $stats['details'][] = [ - 'accessnumber' => $accessnumber, - 'status' => 'failed', - 'error' => $e->getMessage(), - 'time_ms' => $elapsed - ]; - } -} - -echo str_repeat("-", 60) . "\n"; -echo "Complete: " . $stats['success'] . " queued, " . $stats['failed'] . " failed\n"; - -// Save detailed log -$logFile = 'batch_pdf_' . date('Ymd_His') . '.log'; -$logContent = "Batch PDF Generation Log\n"; -$logContent .= "Generated: " . date('Y-m-d H:i:s') . "\n"; -$logContent .= "Input file: $inputFile\n"; -$logContent .= "Endpoint: $baseUrl\n"; -$logContent .= "Total: $total, Success: {$stats['success']}, Failed: {$stats['failed']}\n"; -$logContent .= str_repeat("-", 60) . "\n"; - -foreach ($stats['details'] as $detail) { - $logContent .= $detail['accessnumber'] . " | " . $detail['status']; - if (isset($detail['jobId'])) { - $logContent .= " | job: " . $detail['jobId']; - $logContent .= " | lang: " . $detail['language']; - } - if (isset($detail['error'])) { - $logContent .= " | error: " . $detail['error']; - } - $logContent .= " | " . $detail['time_ms'] . "ms\n"; -} - -file_put_contents($logFile, $logContent); -echo "Log saved to: $logFile\n"; - -exit($stats['failed'] > 0 ? 1 : 0); diff --git a/test_batch.txt b/test_batch.txt deleted file mode 100644 index 00494aa..0000000 --- a/test_batch.txt +++ /dev/null @@ -1,2 +0,0 @@ -202403110001 -202403110002