# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is a Laboratory Information Management System (LIMS) module for Odoo 18 ERP, specifically designed for clinical laboratories. The module manages patients, samples, analyses, and test results. ## Key Technologies - **Odoo 18**: ERP framework (Python-based) - **PostgreSQL 15**: Database - **Docker & Docker Compose**: Containerization - **Gitea**: Version control and issue tracking ## Development Commands ### Starting the Environment ```bash # Start all services docker-compose up -d # MANDATORY: View initialization logs to check for errors docker-compose logs odoo_init # Stop and clean everything (removes volumes) docker-compose down -v ``` **IMPORTANT**: Odoo initialization takes approximately 5 minutes. When using docker-compose commands, set timeout to 5 minutes (300000ms) to avoid premature timeouts. ### Instance Persistence Policy After successful installation/update, the instance must remain active for user validation. Do NOT stop the instance until user explicitly confirms testing is complete. ### MANDATORY Testing Rule **CRITICAL**: After EVERY task that modifies code, models, views, or data: 1. Restart the ephemeral instance: `docker-compose down -v && docker-compose up -d` 2. Check initialization logs for errors: `docker-compose logs odoo_init | grep -i "error\|traceback\|exception"` 3. Verify successful completion: `docker-compose logs odoo_init | tail -30` 4. Only proceed to next task if no errors are found 5. If errors are found, fix them before continuing ### Development Workflow per Task When implementing issues with multiple tasks, follow this workflow for EACH task: 1. **Stop instance**: `docker-compose down -v` 2. **Implement the task**: Make code changes 3. **Start instance**: `docker-compose up -d` (timeout: 300000ms) 4. **Validate logs**: Check for errors in initialization 5. **Commit & Push**: `git add -A && git commit -m "feat(#X): Task description" && git push` 6. **Comment on issue**: Update issue with task completion 7. **Mark task completed**: Update todo list 8. **Proceed to next task**: Only if no errors found ### Database Operations #### Direct PostgreSQL Access ```bash # Connect to PostgreSQL docker exec -it lims_db psql -U odoo -d odoo ``` #### Python Script Method (Recommended) For complex queries, use Python scripts with Odoo ORM: 1. Create script (e.g., `test/verify_products.py`): ```python import odoo import json def verify_lab_order_products(cr): cr.execute("""SELECT ... FROM sale_order ...""") return cr.fetchall() if __name__ == '__main__': db_name = 'lims_demo' registry = odoo.registry(db_name) with registry.cursor() as cr: results = verify_lab_order_products(cr) print(json.dumps(results, indent=4)) ``` 2. Copy to container: ```bash docker cp test/verify_products.py lims_odoo:/tmp/verify_products.py ``` 3. Execute: ```bash docker-compose exec odoo python3 /tmp/verify_products.py ``` ### Gitea Integration ```bash # Create issue python utils/gitea_cli_helper.py create-issue --title "Title" --body "Description\nSupports multiple lines" # Create PR with inline description python utils/gitea_cli_helper.py create-pr --head "feature-branch" --base "dev" --title "Title" --body "Description" # Create PR with description from file python utils/gitea_cli_helper.py create-pr dev --title "feat(#31): Sample lifecycle" --description-file pr_description.txt # Comment on issue python utils/gitea_cli_helper.py comment-issue --issue-number 123 --body "Comment text" # Close issue python utils/gitea_cli_helper.py close-issue --issue-number 123 # Get issue details and comments python utils/gitea_cli_helper.py get-issue --issue-number 8 # List all open issues python utils/gitea_cli_helper.py list-open-issues ``` ## Mandatory Reading At the start of each work session, read these documents to understand requirements and technical design: - `documents/requirements/RequerimientoInicial.md` - `documents/requirements/ToBeDesing.md` ## Code Architecture ### Module Structure - **lims_management/models/**: Core business logic - `partner.py`: Patient and healthcare provider management - `product.py`: Analysis types and categories - `sale_order.py`: Analysis orders and sample management - `stock_lot.py`: Sample tracking and lifecycle - `analysis_range.py`: Normal ranges for test results ### Odoo 18 Specific Conventions #### View Definitions - **CRITICAL**: Use `` instead of `` - using `` causes `ValueError: Wrong value for ir.ui.view.type: 'tree'` - View mode in actions must be `list,form` not `tree,form` #### Visibility Attributes - Use `invisible` attribute directly instead of `attrs`: ```xml ``` #### Context with ref() - Use `eval` attribute when using `ref()` in action contexts: ```xml {'default_categ_id': ref('module.xml_id')} ``` #### XPath in View Inheritance - Use flexible XPath expressions for robustness: ```xml [('is_analysis', '=', True)] ``` ### Data Management - **Initial Data**: `lims_management/data/` - Sequences, categories, basic configuration - **Demo Data**: - XML files in `lims_management/demo/` - Python scripts in `test/` directory for complex demo data creation - Use `noupdate="1"` for demo data to prevent reloading ### Security Model - Access rights defined in `security/ir.model.access.csv` - Field-level security in `security/security.xml` - Group-based permissions: Laboratory Technician, Manager, etc. ## Environment Variables Required in `.env` file: - `GITEA_API_KEY`: Personal Access Token for Gitea - `GITEA_API_KEY_URL`: Gitea API base URL (e.g., `https://gitea.grupoconsiti.com/api/v1/`) - `GITEA_USERNAME`: Gitea username (repository owner) - `GITEA_REPO_NAME`: Repository name (e.g., `clinical_laboratory`) ## Important Patterns ### Sample Lifecycle States ```python STATE_PENDING_COLLECTION = 'pending_collection' STATE_COLLECTED = 'collected' STATE_IN_ANALYSIS = 'in_analysis' STATE_COMPLETED = 'completed' STATE_CANCELLED = 'cancelled' ``` ### Barcode Generation - 13-digit format: YYMMDDNNNNNNC - Uses `barcode` Python library for Code-128 generation - Stored as PDF with human-readable text ### Demo Data Creation #### XML Files (Simple Data) - Use for basic records without complex dependencies - Place in `lims_management/demo/` - Use `noupdate="1"` to prevent reloading - **IMPORTANT**: Do NOT create sale.order records in XML demo files - use Python scripts instead #### Python Scripts (Complex Data) For data with dependencies or business logic: #### Test Scripts - **IMPORTANT**: Always create test scripts inside the `test/` folder within the project directory - Example: `test/test_sample_generation.py` - This ensures scripts are properly organized and accessible 1. Create script: ```python import odoo def create_lab_requests(cr): env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {}) # Use ref() to get existing records patient1 = env.ref('lims_management.demo_patient_1') hemograma = env.ref('lims_management.analysis_hemograma') # Create records with business logic env['sale.order'].create({ 'partner_id': patient1.id, 'is_lab_request': True, 'order_line': [(0, 0, { 'product_id': hemograma.product_variant_id.id, 'product_uom_qty': 1 })] }) if __name__ == '__main__': db_name = 'lims_demo' registry = odoo.registry(db_name) with registry.cursor() as cr: create_lab_requests(cr) cr.commit() ``` 2. Integrate in initialization or run separately ## Git Workflow ### Pre-commit Hook Automatically installed via `scripts/install_hooks.sh`: - Prevents commits to 'main' or 'dev' branches - Enforces feature branch workflow ### Branch Naming - Feature branches: `feature/XX-description` (where XX is issue number) - Always create PRs to 'dev' branch, not 'main'