dolibarr/.agents/AGENTS.md
MDW ca789645fc
Fix: Use AI provider agnostic .agents, update commit exclusion: develop and version branches (#39189)
* qual: Update branch protection rules in AGENTS.md

Updated the branch protection rules in AGENTS.md to reflect the new policy of never committing directly to the `develop` branch or version branches matching the regex `^\d+\.\d+$`.

* Fix: Rename .claude directory to .agents

Renamed the .claude directory and its contents to .agents.
.agents is AI provider agnostic.
2026-07-15 20:40:45 +02:00

196 lines
6.9 KiB
Markdown

# AGENTS.md (English Version)
## 🎯 Objective
This project contains the full sources of the Dolibarr ERP and CRM application.
Every modification must respect:
- Dolibarr's modular architecture
- Compatibility with upstream updates
- Modern PHP best practices
---
## ⚠️ Critical Rules (DO NOT VIOLATE)
- ❌ Do not break compatibility of PHP functions and methods
- ❌ Do not introduce external dependencies without validation
- ❌ Separate page actions in the `/* Actions */` section of the PHP code and the rendering part in the `/* Views */` section
- ❌ Never commit directly to `develop` or version branch matching regex `^\d+\.\d+$`
- ❌ Never use PHP native curl functions to call a GET or POST URL, but use instead the Dolibarr function getURLContent()
- ✅ Use Dolibarr hooks whenever possible
- ✅ Respect existing naming conventions
- ✅ All database table names must use the `llx_` prefix
---
## 📁 Expected Architecture
Module structure:
`htdocs/mymodule`
├── `core/`
├── `class/`
├── `lib/`
├── `sql/`
├── `tpl/`
└── `admin/`
A template of a module directory content can be found in the `htdocs/modulebuilder/template` folder of this project.
---
## 🔍 Before Coding
Before writing any code, the agent **must**:
- Search for existing similar functions in `htdocs/core/lib/` and `htdocs/core/class/`
- Check if the concerned object class extends `CommonObject` and use its built-in methods (fetch, create, update, delete, etc.)
- Review the module's `modMyModule.class.php` for declared permissions and constants
- Run a search to ensure no equivalent function already exists in the codebase
---
## 🧠 PHP Best Practices
- PHP >= 7.3 (minimum support); PHP 8.1+ recommended for new external modules
- ⚠️ When writing a **bug fix**, always target the lowest compatible PHP version
of the branch being patched — do not use PHP 8.x syntax on a fix targeting v19 or v20
- Respect PSR-12, but **indentations must use Tabs, not Spaces**
- Write short, readable, and testable functions
- Avoid side effects
- Prefer typed properties and return types when PHP version allows
---
## 🗄️ Database
- Use Dolibarr database functions exclusively — never use PDO or MySQLi directly
- In pages: use global `$db`
- In classes: use `$this->db`
- ✅ SQL forged by PHP must escaped fields with `db->escape()`, `db->sanitize()`, or by casting values to `(int)` or `(float)`
- ✅ Always use `$db->query()` followed by `$db->fetch_object()` or `$db->fetch_array()` to retrieve results
- ✅ SQL scripts for table and index creation must be placed in `htdocs/install/mysql/tables/` (see existing files for examples)
- ❌ Never run SQL queries inside loops (avoid N+1 problem — use JOINs or batch queries instead)
- ✅ Always use `LIMIT` on list queries for performance
---
## 🔌 Hooks & Extensions
- Prioritize hooks over direct code overrides
- Before creating a new hook, verify it does not already exist:
```
grep -r "executeHooks" htdocs/ | grep 'hookName'
```
- Call hooks using the standard pattern:
```php
$hookmanager->executeHooks('actionName', $parameters, $object, $action);
```
- Name hooks clearly and descriptively (e.g., `formObjectOptions`, `addMoreActionsButtons`)
---
## 🌍 Internationalisation
- Never hardcode user-facing strings — always use `$langs->trans('Key')`
- Language files must be placed in `mymodule/langs/en_US/` (and other locales as needed)
- All code comments and variables or functions names must be in English.
- Language key names must use PascalCase (e.g., `MyModuleLabel`, not `monLibelléModule`)
- Load the language file at the top of the page: `$langs->load('mymodule@mymodule')`
---
## 🧪 Testing & Validation
Before any modification, verify:
- Creation / edition / deletion workflows
- User rights enforcement (`$user->hasRights("module", "permission")` or `$user->hasRights("module", "objectname", "permission")`)
- Multi-entity compatibility (add ` AND entity IN ('.getDolEntity("tablename").')`)
If possible:
- If doing an external module, add a PHPUnit test file in `yourmoduledir/test/phpunit/`
- If modifying the Dolibarr code project, add a PHPUnit test file into `test/phpunit/` and add the entry into file `test/phpunit/AllTests.php`.
---
## 🖥️ UI / UX
- Respect Dolibarr UI — no unsolicited redesigns
- Reuse existing components (buttons, forms, tables) from `htdocs/core/tpl/`
- ❌ No overly complex inline JS
- ✅ Place JavaScript in separate files under `mymodule/js/`
---
## 🔒 Security
- Always validate user inputs (`GET`, `POST`) via `GETPOST()` with a type parameter
- Prevent SQL injection (use `db->escape()` or cast into `(int)` or `(float)`)
- Prevent XSS injection by escaping HTML output (use `dolPrintHTML()`, `dolPrintHTMLForAttribute()`)
- Always include Dolibarr CSRF tokens in POST forms: `<input type="hidden" name="token" value="'.newToken().'">`
---
## ⚡ Performance
- Avoid SQL queries inside loops (N+1 problem)
- Use JOINs or batch queries instead of multiple sequential queries
- Apply `LIMIT` and proper indexes on list queries
- Cache repeated calls to `getDolGlobalString()` or `$conf->global->` in local variables
---
## 🧾 Logs & Debug
- Use `dol_syslog()` for all logging (with appropriate log level: `LOG_DEBUG`, `LOG_WARNING`, `LOG_ERR`)
- Do not leave `var_dump()`, `print_r()`, or `die()` in committed code
- Use Dolibarr's `setEventMessages()` to display user-facing messages
---
## 🚀 Git Workflow
- Branch strategy:
- One branch per major version (bug fixes only)
- `develop` branch for both fixes and new features
- ❌ Never commit directly to `main` or `develop` without a reviewed PR
- Commit message format: `TYPE: #issueNumber Short description`
- Types: `NEW`, `FIX` or `CLOSE`
- Example: `FIX: #1234 Correct VAT calculation on credit notes`
- Update the `ChangeLog` file with a summary of significant changes
- When fixing a bug, apply the patch on the **oldest affected branch first**,
then cherry-pick forward to newer branches and `develop`
- Do not introduce new syntax or features unavailable in the branch's minimum PHP version
---
## 🧩 What the Agent MUST Do
- Read this file before any modification
- Check if an equivalent function already exists before writing new code
- Minimize the impact of changes
- Propose modular modifications that do not affect unrelated features
---
## ❗ What the Agent MUST NOT Do
- Perform massive refactoring without an explicit request
- Change the global architecture of existing modules
- Delete code without justification and a comment explaining why
- Add external dependencies (Composer packages, JS libraries) without prior validation
- Modify the `ChangeLog` file (this file will be updated by the maintainer during the release process)
---
## 💡 Key Principle
👉 Always prioritize:
**extension > modification**
---
## 📌 In Case of Doubt
- Keep it simple
- Be conservative
- Ask for confirmation before any critical or irreversible change