Skip to content

Odoo 15 adaptation#4

Closed
baoha-erptek wants to merge 2 commits intoaffaan-m:mainfrom
baoha-erptek:odoo-15-adaptation
Closed

Odoo 15 adaptation#4
baoha-erptek wants to merge 2 commits intoaffaan-m:mainfrom
baoha-erptek:odoo-15-adaptation

Conversation

@baoha-erptek
Copy link
Copy Markdown

@baoha-erptek baoha-erptek commented Jan 20, 2026

Summary by CodeRabbit

Release Notes

  • Documentation
    • Comprehensive updates to agent documentation, command guides, and examples throughout the repository.
    • Added new skill documentation with detailed development guidance.
    • Reorganized configuration and tool settings to reflect updated patterns.
    • Expanded rule documentation and examples for consistency.
    • Removed obsolete documentation sections; updated references accordingly.

✏️ Tip: You can customize this high-level summary in your review settings.

Bao Ha and others added 2 commits January 20, 2026 04:50
Transform JavaScript/React/Next.js focused configs to Odoo 15 Python development:

**Removed (4 files):**
- agents/build-error-resolver.md (no build step in Odoo)
- skills/frontend-patterns.md (React/Next.js not applicable)
- skills/clickhouse-io.md (project-specific analytics)
- commands/build-fix.md (no build step in Odoo)

**Added (8 files):**
- skills/odoo-15-developer/ directory with complete reference:
  - SKILL.md, core-philosophy.md, models-orm.md, views-xml.md
  - testing.md, security.md, patterns.md, commands.md

**Adapted (35+ files):**
- Agents: Two-phase testing, ACL validation, ORM patterns, Playwright with Odoo selectors
- Skills: Python/PEP8 conventions, ORM patterns, Odoo security
- Commands: Docker-based workflows, coverage.py, vulture/pylint
- Rules: ACLs, record rules, sudo documentation, N+1 prevention
- Hooks: Python linting, _logger.info warnings, XML validation
- MCP configs: PostgreSQL, Playwright, removed Vercel/Railway/Supabase

**Key Patterns:**
- Two-Phase Testing (Phase 1: DB verification, Phase 2: ORM unit tests)
- Environment variable placeholders ($ODOO_CONTAINER, $ODOO_DB, $ODOO_PORT)
- TransactionCase for Odoo tests
- ir.model.access.csv and record rules for security
- Documented sudo() requirements

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive frontend development guide for Odoo 15:
- OWL component structure and lifecycle
- useState, useRef, useService hooks
- QWeb template directives
- Frontend services (ORM, notification, dialog, action)
- Registry patterns (action, field, service)
- Patching existing components
- Form view customization
- Best practices for Odoo 15 frontend

Update README.md and user-CLAUDE.md to reference new skill.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

Comprehensive transformation of a generic Claude Code template repository into an Odoo 15-specific development framework. Renames agents, updates documentation, adds specialized skills, modifies configuration, and replaces TypeScript/multi-stack examples with Odoo Python/ORM patterns throughout.

Changes

Cohort / File(s) Summary
Core Documentation
README.md, CLAUDE.md, CONTRIBUTING.md
Reframed for Odoo 15 audiences; narrowed scope from generic Claude Code to Odoo module development; updated examples, environment variables (ODOO_CONTAINER, ODOO_DB, ODOO_PORT), and workflows.
Agent Specifications
agents/architect.md, agents/code-reviewer.md, agents/doc-updater.md, agents/e2e-runner.md, agents/planner.md, agents/refactor-cleaner.md, agents/security-reviewer.md, agents/tdd-guide.md
Updated descriptions and core responsibilities to emphasize Odoo-specific tasks (ACLs, ORM patterns, manifest dependencies, two-phase testing). Replaced generic frameworks with Odoo 15 patterns and Python examples.
Removed Agents
agents/build-error-resolver.md
Removed TypeScript-focused build error documentation (532 lines).
Command Documentation
commands/code-review.md, commands/e2e.md, commands/plan.md, commands/refactor-clean.md, commands/tdd.md, commands/test-coverage.md, commands/update-codemaps.md, commands/update-docs.md
Expanded and reoriented for Odoo workflows; introduced Docker commands, security checklists, two-phase testing, and module-specific examples. Replaced generic tooling (npm, TypeScript) with Python/Odoo equivalents.
Removed Commands
commands/build-fix.md
Removed TypeScript build-fixing guide (29 lines).
Rules & Patterns
rules/agents.md, rules/coding-style.md, rules/git-workflow.md, rules/hooks.md, rules/patterns.md, rules/performance.md, rules/security.md, rules/testing.md
Refactored coding standards, security guidelines, git workflows, and performance patterns to emphasize Odoo module conventions (ORM, ACLs, record rules, two-phase testing, constraints). Updated code examples from JavaScript/TypeScript to Python.
Skills Documentation
skills/backend-patterns.md, skills/coding-standards.md, skills/frontend-patterns.md, skills/project-guidelines-example.md, skills/security-review/SKILL.md, skills/tdd-workflow/SKILL.md
Replaced multi-stack patterns (Node.js/React) with Odoo ORM, OWL components, and module-centric guidance. Expanded with new subsections and concrete Python/XML examples.
Removed Skills
skills/clickhouse-io.md
Removed analytics database patterns (429 lines).
New Odoo 15 Skills
skills/odoo-15-developer/* (SKILL.md, commands.md, core-philosophy.md, models-orm.md, patterns.md, security.md, testing.md, views-xml.md)
Added comprehensive Odoo 15 developer skill documentation including environment setup, two-phase testing, ORM patterns, security, XML views, and command reference (1,762 lines total).
Examples & Configuration
examples/CLAUDE.md, examples/user-CLAUDE.md, hooks/hooks.json, mcp-configs/mcp-servers.json
Updated example CLAUDE.md files for Odoo module context; expanded hooks.json with Python/Odoo linting and security checks; refactored mcp-servers.json to include Odoo-related servers (postgres, playwright) and remove cloud platform integrations.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

The diff is substantial and heterogeneous: 50+ documentation files undergo semantic transformation from generic Claude Code context to Odoo 15 specificity. While changes follow consistent patterns (renaming, reorienting examples, updating tooling references), each file demands context-aware verification to ensure Odoo patterns are accurate, security guidance aligns with OCA standards, and two-phase testing approach is correctly articulated. No executable code changes mitigate review burden, but breadth and domain-shift complexity justify elevated effort.

Poem

🐰 From Claude's wide canvas we hop and refine,
Odoo's fifteen-fold module paths now align!
ORM patterns gleam, ACLs hold tight,
Two phases of testing—our testing's now bright! 🌿
The rabbit rejoices, the codebase now flows,
With Odoo's great wisdom, our framework now grows.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Odoo 15 adaptation' directly and clearly summarizes the main objective of the pull request, which is to adapt the repository from a generic Claude Code framework to be specifically tailored for Odoo 15 development.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🤖 Fix all issues with AI agents
In `@agents/e2e-runner.md`:
- Around line 118-121: Remove the invalid `.o_form_saved` selector used in the
test assertions and instead verify form save by checking for the form's readonly
state or a success notification; update the assertion that references
page.locator('.o_form_saved') (near the existing expect calls using
page.locator('.o_form_view')) to assert either
page.locator('.o_form_view.o_form_readonly') is visible or
page.locator('.o_notification') is visible so the test reliably detects the Odoo
15 save behavior.

In `@commands/code-review.md`:
- Around line 111-121: The example incorrectly calls the non-existent Odoo ORM
method .with_prefetch() on the result of self.env['sale.order'].search([]);
remove the .with_prefetch() call and either rely on Odoo's automatic prefetching
(use orders = self.env['sale.order'].search([])), or explicitly fetch needed
fields via read(fields=[...]) on the sale.order records, or use the prefetch
context pattern when appropriate; update references to orders and partner access
(order.partner_id.name) accordingly to avoid the AttributeError.

In `@mcp-configs/mcp-servers.json`:
- Around line 49-56: Replace the hardcoded credentials in the "postgres"
service's env POSTGRES_CONNECTION_STRING by using a placeholder instead of
"odoo:odoo" (e.g., "postgresql://<USER>:<PASS>@localhost:5432/<DB>" or reference
an env variable placeholder pattern consistent with the file), update the
"postgres" object to read the connection string from that placeholder, and
add/update the top-level _comments section to include an explicit example format
for POSTGRES_CONNECTION_STRING showing the placeholder pattern and not real
credentials so downstream users know the expected format.

In `@rules/git-workflow.md`:
- Around line 95-105: Replace the incorrect Odoo test command in the "Pre-Commit
Checklist" that currently uses `python3 -m odoo.tests.loader module_name.tests`
with the standard Odoo test invocation; update it to use the odoo-bin
entrypoint, for example: `docker exec $ODOO_CONTAINER python3 odoo-bin
--test-enable -i module_name --stop-after-init` (ensure the checklist line
referencing the test command is updated accordingly).

In `@rules/testing.md`:
- Around line 62-78: The test commands in the TDD Workflow use the old module
"odoo.tests.loader"; update the commands to use the official Odoo 15 invocation
"python3 -m odoo" and add the standard test flags: include the database
parameter (-d $ODOO_DB), enable tests with --test-enable, update the module with
-u MODULE_NAME and stop after init with --stop-after-init; do the same for the
coverage invocation by replacing "-m odoo.tests.loader MODULE_NAME.tests" with
"-m odoo -d $ODOO_DB --test-enable -u MODULE_NAME --stop-after-init" while
preserving the coverage --source path and subsequent coverage report step.

In `@skills/odoo-15-developer/testing.md`:
- Around line 282-297: The commands incorrectly call python3 -m
odoo.tests.loader; replace them to run tests via the odoo-bin entrypoint using
the --test-enable flag and appropriate options: use odoo-bin -d $ODOO_DB -i
MODULE_NAME --test-enable --stop-after-init to run all module tests, odoo-bin -d
$ODOO_DB -u MODULE_NAME --test-enable --stop-after-init to run/upgrade a module
and run its tests, and use --test-tags (e.g. --test-tags post_install or
--test-tags /test_calculation) when targeting specific tagged tests or classes;
update the examples in this section to reference $ODOO_CONTAINER, odoo-bin,
MODULE_NAME, $ODOO_DB, --test-enable, --test-tags, and --stop-after-init
accordingly.

In `@skills/odoo-15-developer/views-xml.md`:
- Around line 10-19: Update the "CRITICAL RULE - Field Requirements" section to
stop blanket-prohibiting Python required=True and instead explain the correct
practice: use Python required=True for true data/business invariants that must
be enforced at the DB level, and use XML required="1" or conditional required
via attrs for view-specific or conditional UI validation (e.g., edit vs create,
readonly fields, conditional visibility). Mention the tradeoffs (DB NOT NULL vs
UI-only enforcement) and explicitly reference the symbols `required=True`,
`required="1"`, and `attrs` so readers can locate examples in the doc.
🟡 Minor comments (18)
skills/odoo-15-developer/commands.md-205-209 (1)

205-209: Add language specifier to code block.

The commit message format code block should specify a language for proper syntax highlighting and markdown compliance.

📝 Suggested fix
-```
+```text
 [module_name] type(scope): description
 
 Type: feat, fix, refactor, docs, test, chore
skills/odoo-15-developer/security.md-180-185 (1)

180-185: Add language specifier to code block.

The file structure code block should specify a language for proper syntax highlighting and markdown compliance.

📝 Suggested fix
-```
+```text
 module_name/
 └── security/
     ├── ir.model.access.csv    # Model access rights
     └── security.xml           # Groups, record rules
skills/odoo-15-developer/core-philosophy.md-170-174 (1)

170-174: Add language specifier to code block.

The database reference format block should specify a language for proper syntax highlighting and markdown compliance.

📝 Suggested fix
-```
+```text
 # Format: table.column
 hr_employee.department_id
 custom_model.total_amount
skills/odoo-15-developer/core-philosophy.md-162-165 (1)

162-165: Add language specifier to code block.

The code reference format block should specify a language for proper syntax highlighting and markdown compliance.

📝 Suggested fix
-```
+```text
 # Format: module/file.py:line_number
 custom_module/models/custom_model.py:145
skills/odoo-15-developer/commands.md-197-201 (1)

197-201: Add language specifier to code block.

The branch naming patterns code block should specify a language for proper syntax highlighting and markdown compliance.

📝 Suggested fix
-```
+```text
 feature/TICKET-XXXX-description  # New features
 bugfix/TICKET-XXXX-description   # Bug fixes
 hotfix/critical-description      # Critical fixes
CLAUDE.md-11-21 (1)

11-21: Add language specifier to code block.

The directory structure code block should specify a language for proper syntax highlighting and markdown compliance.

📝 Suggested fix
-```
+```text
 agents/           # Subagent definitions with frontmatter (name, tools, model)
 skills/           # Workflow definitions and domain knowledge
   odoo-15-developer/  # Complete Odoo 15 development reference
skills/odoo-15-developer/security.md-76-85 (1)

76-85: Fix table formatting issue.

Line 84 has an extra pipe separator creating 3 columns when the table header defines only 2 columns. This breaks the table structure.

📝 Suggested fix
 | Pattern | Description |
 |---------|-------------|
 | `[(1, '=', 1)]` | All records (no filter) |
 | `[('user_id', '=', user.id)]` | Current user's records |
 | `[('company_id', '=', company_id)]` | Current company records |
 | `[('department_id', '=', user.department_id.id)]` | Same department |
-| `['|', ('user_id', '=', user.id), ('public', '=', True)]` | Own OR public |
+| `['\|', ('user_id', '=', user.id), ('public', '=', True)]` | Own OR public |

Note: Also escaped the pipe character within the domain to prevent it being interpreted as a table separator.

rules/patterns.md-3-48 (1)

3-48: Change methods=['GET'] to methods=['POST'] or remove the parameter.

The methods parameter is valid for type='json' routes, but JSON-RPC endpoints should use HTTP POST. Line 12 specifies methods=['GET'], which is semantically incorrect for a JSON-RPC endpoint—the first route should either omit the methods parameter (allowing all methods, though POST is expected) or explicitly use methods=['POST'] to match JSON-RPC conventions.

skills/tdd-workflow/SKILL.md-285-289 (1)

285-289: Add language identifiers to fenced blocks.

markdownlint MD040 flags these blocks. Use text for the tree and user story block.

✅ Suggested fix
-```
+```text
 module_name/
 ...
-```
+```

-```
+```text
 As a [role], I want to [action], so that [benefit]
 ...
-```
+```

Also applies to: 378-381

agents/planner.md-38-41 (1)

38-41: Specify languages for fenced code blocks.

markdownlint reports missing language identifiers (MD040). Use explicit language tags like text, python, or markdown.

✅ Suggested fix
-```
+```text
 ...
-```
+```

-```python
+```python
 ...
-```
+```

Also applies to: 156-161, 189-193

commands/tdd.md-101-107 (1)

101-107: Add language identifiers to fenced code blocks.

markdownlint flags these blocks as missing languages. Use explicit identifiers (e.g., text or bash) to satisfy MD040.

✅ Suggested fix
-```
+```text
 User: /tdd I need a method to calculate available credit for partners
 ...
-```
+```text
 ✅ TDD session complete!
-```
+```

Also applies to: 228-230

agents/architect.md-22-25 (1)

22-25: Add language identifier to the module layout block.

MD040 reports missing language. Use text for directory trees.

✅ Suggested fix
-```
+```text
 module_name/
 ...
-```
+```
skills/frontend-patterns.md-132-136 (1)

132-136: Fix the variable reference in the example.

The updateName method references this.state.formData.partner.name, but the setup() method above shows the state variable as this.formData (line 120), not this.state.formData.

🐛 Proposed fix
 // State updates are reactive
 updateName(name) {
-    this.state.formData.partner.name = name;  // Triggers re-render
+    this.formData.partner.name = name;  // Triggers re-render
 }
agents/tdd-guide.md-76-84 (1)

76-84: Docker command may fail - missing option flag.

The docker exec command uses python3 -m odoo.tests.loader with -d $ODOO_DB but the correct syntax for Odoo test runner typically uses odoo-bin or requires the full command structure. This command pattern might not work as shown.

Run the following script to verify the correct Odoo test command syntax:

#!/bin/bash
# Check if the odoo.tests.loader module accepts -d flag
docker exec -it $ODOO_CONTAINER python3 -m odoo.tests.loader --help 2>&1 | head -20
agents/e2e-runner.md-183-184 (1)

183-184: Date input format may vary by user locale.

Odoo date fields render based on user locale settings. Directly filling '2024-01-01' may fail if the user has a different date format configured (e.g., DD/MM/YYYY).

Suggested pattern using datepicker interaction
// Option 1: Use localized format from env or fixture
const dateFrom = process.env.DATE_FORMAT === 'EU' ? '01/01/2024' : '2024-01-01'
await page.fill('.modal [data-name="date_from"] input', dateFrom)

// Option 2: Use datepicker widget directly
await page.click('.modal [data-name="date_from"] .o_datepicker_button')
await page.click('.datepicker-days td.day:has-text("1")')
hooks/hooks.json-119-128 (1)

119-128: sudo() documentation check may miss docstring documentation.

The pattern #.*[Ss]udo only matches inline comments, not docstrings. A method using sudo() documented in its docstring would still trigger a warning.

Suggested enhancement
# Also check for docstring documentation
if grep -q '\\.sudo()' "$file" 2>/dev/null; then
  if ! grep -qE '(#.*[Ss]udo|\"\"\".*[Ss]udo|sudo.*\"\"\")' "$file" 2>/dev/null; then
    echo "[Hook] WARNING: Undocumented sudo() usage in $file" >&2
  fi
fi

Alternatively, consider this a best-effort check and document its limitation in the description.

hooks/hooks.json-6-14 (1)

6-14: Interactive read may block in non-interactive environments.

The read -r command waits for user input, which will hang indefinitely in CI/automated contexts where stdin isn't available. Consider adding a timeout or checking for TTY availability.

Suggested improvement
-            "command": "#!/bin/bash\ninput=$(cat)\necho '[Hook] Confirm Odoo module update command' >&2\necho '[Hook] Press Enter to continue or Ctrl+C to abort...' >&2\nread -r\necho \"$input\""
+            "command": "#!/bin/bash\ninput=$(cat)\nif [ -t 0 ]; then\n  echo '[Hook] Confirm Odoo module update command' >&2\n  echo '[Hook] Press Enter to continue or Ctrl+C to abort...' >&2\n  read -r\nfi\necho \"$input\""
hooks/hooks.json-87-96 (1)

87-96: Pattern may produce false positives for function names containing print.

The regex ^[^#]*print( will match legitimate code like def print_report(self): or self.print_invoice() as false positives.

Suggested improved pattern
-  print_stmts=$(grep -n '^[^#]*print(' \"$file_path\" 2>/dev/null || true)
+  print_stmts=$(grep -nP '(?<!def |\\.)\\bprint\\s*\\(' \"$file_path\" 2>/dev/null || true)

This uses a negative lookbehind to exclude def print and .print( method calls.

🧹 Nitpick comments (27)
mcp-configs/mcp-servers.json (1)

34-38: Consider using a placeholder pattern for consistency.

The path /mnt/extra-addons is environment-specific and should follow the same placeholder convention used elsewhere in this file (e.g., YOUR_*_HERE).

Suggested change
     "filesystem": {
       "command": "npx",
-      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/mnt/extra-addons"],
+      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/YOUR_ADDONS_PATH_HERE"],
       "description": "Filesystem operations for Odoo addons (set your addons path)"
     },
rules/testing.md (1)

118-121: Optional: Fix markdown formatting style.

The markdown uses underscores for emphasis (e.g., _compute_*) when asterisks would be more consistent with the surrounding style.

📝 Proposed formatting fix
 **Critical (100% coverage required):**
-- `_compute_*` methods
-- `_check_*` constraint methods
+- `*_compute_**` methods
+- `*_check_**` constraint methods
 - Business logic methods

Note: This is a stylistic preference flagged by markdownlint. The current format is still readable.

skills/odoo-15-developer/views-xml.md (1)

153-165: Suggest adding missing imports for completeness.

The Excel export example is functionally correct but would benefit from showing the required imports for developers who copy this pattern.

📦 Add missing imports
+import xlsxwriter
+from odoo import api
+from odoo.tools.translate import _
+
 # Good - Excel export via Odoo's reporting engine
 `@api.model`
 def export_xlsx(self, options, response=None):
commands/refactor-clean.md (1)

48-80: Consider using ast-grep for more accurate field detection.

The current approach uses basic grep for finding field definitions and references, which may produce false positives (e.g., matching fields. in comments or strings). Consider using ast-grep for AST-aware searching.

🔍 Improved field detection with ast-grep
 ### Unused Fields Detection
 
-```python
+```bash
-# Find fields defined in Python
-grep -rn "fields\." --include="*.py" models/ | grep "="
+# Find field definitions using AST-aware search
+ast-grep --pattern 'class $_ (models.Model):
+  $$$
+  $FIELD = fields.$TYPE($$$)
+  $$$'
 
 # Find fields referenced in views
 grep -rn "name=\"" --include="*.xml" views/
-
-# Cross-reference to find unused fields
rules/coding-style.md (2)

49-69: Optional: Add language identifier to code block.

The directory structure code block would benefit from a language identifier for proper syntax highlighting.

📝 Add language identifier
-```
+```text
 module_name/
 ├── __init__.py
 ├── __manifest__.py

71-88: Suggest adding missing _logger import.

The error handling example uses _logger but doesn't show the required import. For developers copying this pattern, the import should be included.

📦 Add missing import
+import logging
 from odoo.exceptions import UserError, ValidationError, AccessError
+from odoo.tools.translate import _
+
+_logger = logging.getLogger(__name__)
 
 def action_confirm(self):
rules/patterns.md (1)

112-141: Suggest adding missing imports for wizard pattern.

The wizard pattern is correctly implemented but would benefit from showing the required imports.

📦 Add missing imports
 from odoo import api, fields, models
+from odoo.exceptions import UserError
+from odoo.tools.translate import _
 
 class MassUpdateWizard(models.TransientModel):
skills/frontend-patterns.md (1)

783-801: Add language identifier to fenced code block.

The fenced code block showing the module structure should have a language identifier for proper rendering.

📝 Proposed fix
-```
+```plaintext
 my_module/
 ├── static/
 │   └── src/

Based on static analysis hints.

skills/coding-standards.md (1)

75-88: Add language identifier to fenced code block.

The fenced code block at line 75 should specify python as the language for proper syntax highlighting.

📝 Proposed fix
-```
+```python
 # Good: PascalCase class, descriptive model name
 class SaleOrderLine(models.Model):

Based on static analysis hints.

commands/test-coverage.md (1)

183-205: Optional: Add language identifier to fenced code block.

The fenced code block containing the ASCII art coverage report could have a language identifier (e.g., text or plaintext) to satisfy linting tools, though this is purely cosmetic.

Minor formatting improvement
-```
+```text
 ╔══════════════════════════════════════════════════════════════╗
 ║              Test Coverage Report: module_name               ║
commands/update-codemaps.md (1)

29-79: Document incomplete helper functions in the example.

The analyze_models example references helper functions that aren't defined: extract_string_value(), is_field_definition(), and get_field_type(). Consider adding a brief note that these are conceptual examples and helper functions are omitted for brevity, or provide stub implementations.

Add clarifying comment
 def analyze_models(module_path: str) -> dict:
-    """Extract model information from Python files."""
+    """Extract model information from Python files.
+    
+    Note: Helper functions (extract_string_value, is_field_definition, 
+    get_field_type) are omitted for brevity.
+    """
     models = {}
commands/code-review.md (1)

48-54: Consider expanding pylint coverage to match flake8 scope.

The flake8 command checks models/, wizards/, and controllers/, but pylint only checks models/. For consistency and comprehensive coverage, consider checking all three directories with pylint as well.

♻️ Proposed fix
 # Run pylint with Odoo plugin
-pylint --load-plugins=pylint_odoo models/
+pylint --load-plugins=pylint_odoo models/ wizards/ controllers/
commands/update-docs.md (1)

159-169: Add language identifier to code block.

The code block is missing a language identifier, which affects syntax highlighting and accessibility.

♻️ Proposed fix
 #### action_renew()
 
 Renew the certification for another year.
 
-```
+```python
 certification.action_renew()
</details>

Based on static analysis hints.

</blockquote></details>
<details>
<summary>agents/code-reviewer.md (4)</summary><blockquote>

`3-3`: **Minor typo: "_logger.info misuse" could be clearer.**

The description mentions "_logger.info misuse" but this could be more precise. Consider "_logger.info overuse for debugging" to clarify that the issue is using .info for debug messages rather than .debug.



<details>
<summary>✏️ Suggested improvement</summary>

```diff
-description: Python/Odoo code quality and security reviewer. Use PROACTIVELY when reviewing PRs, checking for ORM anti-patterns, security issues, and Odoo best practices. Detects N+1 queries, missing _description, raw SQL, and _logger.info misuse.
+description: Python/Odoo code quality and security reviewer. Use PROACTIVELY when reviewing PRs, checking for ORM anti-patterns, security issues, and Odoo best practices. Detects N+1 queries, missing _description, raw SQL, and _logger.info overuse for debugging.

75-84: Good N+1 prevention pattern, but clarify prefetch behavior.

The example correctly demonstrates N+1 prevention, but the comment "Single query via prefetch" might be misleading. The mapped() call doesn't execute a single query—it triggers Odoo's prefetch mechanism which batches related field reads. Consider adding a note that prefetch works automatically for iteration and mapped() just forces it upfront.


228-231: API decorator example uses deprecated pattern.

The @api.model_create_multi decorator example shows it as "Odoo 12+", but in Odoo 15, the standard create() method already handles batch creation without needing this decorator explicitly in most cases. The decorator is still valid but the comment might confuse developers.

📝 Clarification needed

Consider updating the comment to clarify when this decorator is actually needed:

-# `@api.model_create_multi` - Batch create (Odoo 12+)
+# `@api.model_create_multi` - Batch create optimization (override when customizing create)
 `@api.model_create_multi`
 def create(self, vals_list):
     return super().create(vals_list)

322-339: Shell commands need path context and may produce false positives.

The grep commands for finding print statements, raw SQL, etc. don't specify where to run from or exclude common false-positive sources like test files, migrations, or vendor code.

🔧 Improved commands with filtering
# Check for print statements (exclude tests and migrations)
grep -r "print(" --include="*.py" --exclude-dir={tests,migrations} .

# Check for raw SQL (exclude migrations where it's expected)
grep -r "cr.execute\|env.cr.execute" --include="*.py" --exclude-dir=migrations .

# Check for _logger.info (provide context lines)
grep -rn "_logger.info" --include="*.py" -C 2 .

# Check for missing _description (only in models directory)
find models/ -name "*.py" -exec grep -L "_description" {} \;
examples/user-CLAUDE.md (2)

90-95: Consider clarifying "Two-Phase TDD" for new users.

The testing section mentions "Two-Phase TDD" which is Odoo-specific terminology. For users new to this repository, a brief inline explanation or reference to the tdd-guide agent would help.

📚 Add context for clarity
 ### Testing
-- Two-Phase TDD: Write tests first
+- Two-Phase TDD: Write tests first (Phase 1: DB verification, Phase 2: ORM tests)
 - 80% minimum coverage
 - Use TransactionCase with setUpClass
 - Test data factories for reusable fixtures

117-122: Success metrics might be too restrictive for all scenarios.

The success metrics ban _logger.info for debugging, but _logger.info is appropriate for operational events (not debugging). The metric should clarify this distinction to avoid confusion.

🎯 Clarify logger usage metric
-- No `_logger.info` for debugging (use `_logger.debug`)
+- Use `_logger.debug` for debugging (not `_logger.info`)
+- Use `_logger.info` only for operational events
 - No `print()` statements
agents/tdd-guide.md (1)

407-427: Alternative test command might be more reliable.

The shown test commands use python3 -m odoo.tests.loader which may not be the standard approach in all Odoo 15 Docker setups. The alternative using odoo CLI with --test-enable is shown but could be emphasized as the more reliable option.

💡 Emphasize standard approach

Consider reordering to show the standard odoo command first:

# Standard: Update module with tests (recommended)
docker exec -it $ODOO_CONTAINER odoo -d $ODOO_DB \
    -u module_name \
    --test-enable \
    --stop-after-init

# Alternative: Direct test loader
docker exec -it $ODOO_CONTAINER python3 -m odoo.tests.loader \
    -d $ODOO_DB \
    --test-tags /module_name
README.md (1)

92-92: Placeholder URL needs to be updated or clearly marked.

The clone URL contains YOUR_USERNAME which users must replace. This is fine for a template, but consider making it more obvious with a comment or instruction directly in the code block.

📝 Make placeholder more obvious
 # Clone the repo
-git clone https://github.com/YOUR_USERNAME/everything-claude-code.git
+# Replace YOUR_USERNAME with your GitHub username
+git clone https://github.com/YOUR_USERNAME/everything-claude-code.git
agents/security-reviewer.md (1)

197-210: API key example is clearly marked but could be more obvious.

The hardcoded API key on line 198 is marked as "BAD" in a comment, which is good. However, static analysis tools are flagging it (as expected). Consider using a more obviously fake key to avoid confusion.

🔒 Use obviously fake key
 # BAD - Hardcoded credentials
-API_KEY = "sk-1234567890"
+API_KEY = "sk-HARDCODED-DO-NOT-USE"
commands/e2e.md (2)

93-99: Login implementation uses outdated pattern.

The login test uses direct navigation to /web/login and form filling. While this works, Odoo's Playwright tests typically use the authenticate helper or session storage for faster test setup. However, for a tutorial example, the explicit approach is clearer.


253-263: Environment setup has potential path issue.

Line 254 uses $ODOO_PORT which should be set, but if it's not set, the URL will be malformed. Consider adding validation or a default value.

🔧 Add safety with default value
 # Set Odoo URL for tests
-export ODOO_URL=http://localhost:$ODOO_PORT
+export ODOO_URL=http://localhost:${ODOO_PORT:-8069}
agents/e2e-runner.md (2)

260-262: Use proper Playwright Page type instead of any.

Using any loses TypeScript's type checking benefits. Import and use the Page type from Playwright.

Suggested fix
-type AuthFixtures = {
-  authenticatedPage: any
-}
+import { Page } from '@playwright/test'
+
+type AuthFixtures = {
+  authenticatedPage: Page
+}

289-302: Add TypeScript type annotations to helper functions.

These helper functions should include type annotations for consistency with the TypeScript examples elsewhere in the document.

Suggested typing
import { Page } from '@playwright/test'

async function waitForOdooReady(page: Page): Promise<void> {
  await page.waitForSelector('.o_loading_indicator', { state: 'hidden' })
  await page.waitForLoadState('networkidle')
}

async function waitForNotification(page: Page, text: string): Promise<void> {
  await page.waitForSelector(`.o_notification:has-text("${text}")`)
}

async function waitForFormEdit(page: Page): Promise<void> {
  await page.waitForSelector('.o_form_view:not(.o_form_readonly)')
}
hooks/hooks.json (1)

68-76: Consider if _logger.info warning is too aggressive.

While _logger.debug is preferred for verbose logging, _logger.info is appropriate for significant operational events (module installation, major state changes, etc.). The blanket warning might create noise for legitimate uses.

Consider limiting this warning to specific file patterns (e.g., exclude __init__.py, migration scripts) or making it configurable.

Comment on lines +118 to 121
// Verify saved
await expect(page.locator('.o_form_view')).toContainText('Test Partner E2E')
await expect(page.locator('.o_form_saved')).toBeVisible()
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's read the full context of the test file
cat -n agents/e2e-runner.md | head -150

Repository: affaan-m/everything-claude-code

Length of output: 5940


🏁 Script executed:

# Search for .o_form_saved usage in the repository
rg "o_form_saved" --type md --type ts --type js

Repository: affaan-m/everything-claude-code

Length of output: 157


🏁 Script executed:

# Search for other form-related selectors that might indicate save status
rg "o_form_view|o_form_readonly|o_notification" --type md --type ts --type js -A 2 -B 2

Repository: affaan-m/everything-claude-code

Length of output: 2931


🌐 Web query:

Odoo 15 web client form save CSS class selectors form-saved notification

💡 Result:

Short answer — there is no single “.form‑saved” class added to the form. Odoo uses the notification widget for save confirmations and the form “dirty” flag for unsaved state. Useful CSS selectors to target save/notification UI in Odoo 15:

  • .o_notification_manager — notification container. [1][2]
  • .o_notification — each notification box (you can scope by .o_notification.{your-class-or-widget.className} if needed). [1][2]
  • .o_notification_title, .o_notification_content — notification title and body. [1][2]
  • (unsaved/dirty flag) .oe_form_dirty or .o_form_dirty — used to detect unsaved changes on forms. [3]

If you want to style the save pop-up specifically, override CSS for .o_notification (or add a rule matching the success notification class/name produced by the Notification widget) or inject a small JS module that watches for notifications and adds your custom class to those notifications.

Sources: Odoo forum/template showing Notification QWeb (lists .o_notification, .o_notification_title, .o_notification_content and widget.className). [1][2]; OCA/third‑party mentions of the form "dirty" class used for unsaved forms. [3]

References
[1] Odoo forum — Notification QWeb template (shows o_notification, o_notification_title, o_notification_content).
[2] StackOverflow — discussion/example referencing .o_notification and .o_notification_manager.
[3] OCA / web_confirm_window_close (uses .oe_form_dirty / .o_form_dirty for unsaved forms).


Remove invalid .o_form_saved selector — it does not exist in Odoo 15.

The .o_form_saved class is not part of Odoo 15's web client. After a successful save, verify the form state using one of these patterns:

// Preferred: Wait for form to return to readonly mode
await expect(page.locator('.o_form_view.o_form_readonly')).toBeVisible()

// Alternative: Check for success notification
await expect(page.locator('.o_notification')).toBeVisible()

The first approach is more reliable as it directly confirms the form transitioned from edit mode back to readonly, which is Odoo's standard save behavior.

🤖 Prompt for AI Agents
In `@agents/e2e-runner.md` around lines 118 - 121, Remove the invalid
`.o_form_saved` selector used in the test assertions and instead verify form
save by checking for the form's readonly state or a success notification; update
the assertion that references page.locator('.o_form_saved') (near the existing
expect calls using page.locator('.o_form_view')) to assert either
page.locator('.o_form_view.o_form_readonly') is visible or
page.locator('.o_notification') is visible so the test reliably detects the Odoo
15 save behavior.

Comment on lines +111 to +121
### N+1 Queries
```python
# Bad - Query per iteration:
for order in orders:
partner_name = order.partner_id.name

# Good - Prefetch:
orders = self.env['sale.order'].search([]).with_prefetch()
for order in orders:
partner_name = order.partner_id.name
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix incorrect ORM method usage.

The code example uses .with_prefetch() which is not a standard Odoo ORM method. Odoo's ORM automatically prefetches related fields, so this method doesn't exist and will cause an AttributeError.

🔧 Proposed fix

The N+1 query issue in Odoo is typically solved by:

  1. Relying on automatic prefetching (just use search([]))
  2. Using read() with specific field lists
  3. Using prefetch context in specific scenarios
 # Bad - Query per iteration:
 for order in orders:
     partner_name = order.partner_id.name
 
 # Good - Prefetch:
-orders = self.env['sale.order'].search([]).with_prefetch()
+# Odoo automatically prefetches related fields accessed in loops
+orders = self.env['sale.order'].search([])
 for order in orders:
     partner_name = order.partner_id.name
+
+# Alternative: Use read() for better performance with many records
+order_data = self.env['sale.order'].search([]).read(['partner_id'])
+for data in order_data:
+    partner_name = data['partner_id'][1]  # [id, name] tuple
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### N+1 Queries
```python
# Bad - Query per iteration:
for order in orders:
partner_name = order.partner_id.name
# Good - Prefetch:
orders = self.env['sale.order'].search([]).with_prefetch()
for order in orders:
partner_name = order.partner_id.name
```
# Bad - Query per iteration:
for order in orders:
partner_name = order.partner_id.name
# Good - Prefetch:
# Odoo automatically prefetches related fields accessed in loops
orders = self.env['sale.order'].search([])
for order in orders:
partner_name = order.partner_id.name
# Alternative: Use read() for better performance with many records
order_data = self.env['sale.order'].search([]).read(['partner_id'])
for data in order_data:
partner_name = data['partner_id'][1] # [id, name] tuple
🤖 Prompt for AI Agents
In `@commands/code-review.md` around lines 111 - 121, The example incorrectly
calls the non-existent Odoo ORM method .with_prefetch() on the result of
self.env['sale.order'].search([]); remove the .with_prefetch() call and either
rely on Odoo's automatic prefetching (use orders =
self.env['sale.order'].search([])), or explicitly fetch needed fields via
read(fields=[...]) on the sale.order records, or use the prefetch context
pattern when appropriate; update references to orders and partner access
(order.partner_id.name) accordingly to avoid the AttributeError.

Comment on lines +49 to 56
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/your/projects"],
"description": "Filesystem operations (set your path)"
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://odoo:odoo@localhost:5432/odoo"
},
"description": "PostgreSQL direct access for Odoo database analysis"
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Replace hardcoded credentials with a placeholder.

The connection string contains embedded credentials (odoo:odoo), which static analysis correctly flagged. Even though this is a template file, hardcoded credentials can be accidentally committed to downstream repositories and encourage insecure practices.

Use the same placeholder pattern as other environment variables in this file.

Suggested fix
     "postgres": {
       "command": "npx",
       "args": ["-y", "@modelcontextprotocol/server-postgres"],
       "env": {
-        "POSTGRES_CONNECTION_STRING": "postgresql://odoo:odoo@localhost:5432/odoo"
+        "POSTGRES_CONNECTION_STRING": "YOUR_POSTGRES_CONNECTION_STRING_HERE"
       },
       "description": "PostgreSQL direct access for Odoo database analysis"
     }

Then update the _comments section to provide an example format:

-    "postgres": "Update connection string to match your Odoo database",
+    "postgres": "Set connection string, e.g.: postgresql://user:pass@localhost:5432/odoo",
🧰 Tools
🪛 Checkov (3.2.334)

[medium] 53-54: Basic Auth Credentials

(CKV_SECRET_4)

🤖 Prompt for AI Agents
In `@mcp-configs/mcp-servers.json` around lines 49 - 56, Replace the hardcoded
credentials in the "postgres" service's env POSTGRES_CONNECTION_STRING by using
a placeholder instead of "odoo:odoo" (e.g.,
"postgresql://<USER>:<PASS>@localhost:5432/<DB>" or reference an env variable
placeholder pattern consistent with the file), update the "postgres" object to
read the connection string from that placeholder, and add/update the top-level
_comments section to include an explicit example format for
POSTGRES_CONNECTION_STRING showing the placeholder pattern and not real
credentials so downstream users know the expected format.

Comment on lines +95 to +105
## Pre-Commit Checklist

Before committing Odoo code:
- [ ] Module installs without errors
- [ ] Tests pass: `docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader module_name.tests`
- [ ] No print() statements (use _logger.debug)
- [ ] ACLs defined for new models
- [ ] sudo() usage documented
- [ ] No hardcoded values
- [ ] flake8 passes with no errors

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix incorrect Odoo test command in pre-commit checklist.

Line 99 uses python3 -m odoo.tests.loader which is not the standard way to run Odoo tests. This matches the same issue found in skills/odoo-15-developer/testing.md.

🔧 Proposed fix
 Before committing Odoo code:
 - [ ] Module installs without errors
-- [ ] Tests pass: `docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader module_name.tests`
+- [ ] Tests pass: `docker exec $ODOO_CONTAINER odoo-bin -d $ODOO_DB -u module_name --test-enable --stop-after-init`
 - [ ] No print() statements (use _logger.debug)
 - [ ] ACLs defined for new models
 - [ ] sudo() usage documented
 - [ ] No hardcoded values
 - [ ] flake8 passes with no errors
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## Pre-Commit Checklist
Before committing Odoo code:
- [ ] Module installs without errors
- [ ] Tests pass: `docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader module_name.tests`
- [ ] No print() statements (use _logger.debug)
- [ ] ACLs defined for new models
- [ ] sudo() usage documented
- [ ] No hardcoded values
- [ ] flake8 passes with no errors
## Pre-Commit Checklist
Before committing Odoo code:
- [ ] Module installs without errors
- [ ] Tests pass: `docker exec $ODOO_CONTAINER odoo-bin -d $ODOO_DB -u module_name --test-enable --stop-after-init`
- [ ] No print() statements (use _logger.debug)
- [ ] ACLs defined for new models
- [ ] sudo() usage documented
- [ ] No hardcoded values
- [ ] flake8 passes with no errors
🤖 Prompt for AI Agents
In `@rules/git-workflow.md` around lines 95 - 105, Replace the incorrect Odoo test
command in the "Pre-Commit Checklist" that currently uses `python3 -m
odoo.tests.loader module_name.tests` with the standard Odoo test invocation;
update it to use the odoo-bin entrypoint, for example: `docker exec
$ODOO_CONTAINER python3 odoo-bin --test-enable -i module_name --stop-after-init`
(ensure the checklist line referencing the test command is updated accordingly).

Comment on lines +62 to +78
## TDD Workflow

1. Write test first (RED)
2. Run test - it should FAIL
2. Run test - it should FAIL:
```bash
docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader MODULE_NAME.tests
```
3. Write minimal implementation (GREEN)
4. Run test - it should PASS
5. Refactor (IMPROVE)
6. Verify coverage (80%+)
6. Verify coverage (80%+):
```bash
docker exec $ODOO_CONTAINER coverage run \
--source=/mnt/extra-addons/MODULE_NAME \
-m odoo.tests.loader MODULE_NAME.tests
docker exec $ODOO_CONTAINER coverage report
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Search for test-related files and patterns
echo "=== Looking for test files and configurations ==="
fd -e "test*.py" -e "*test.py" | head -20

echo -e "\n=== Searching for CI/CD configurations ==="
fd -e "yml" -e "yaml" | grep -E "(ci|github|gitlab|jenkins)"

echo -e "\n=== Looking for .github/workflows for test commands ==="
find .github -type f -name "*.yml" -o -name "*.yaml" 2>/dev/null

echo -e "\n=== Searching for odoo.tests references ==="
rg "odoo.*tests" --type py --type md -A 2 -B 2

Repository: affaan-m/everything-claude-code

Length of output: 11944


🌐 Web query:

Odoo 15 test runner python -m command documentation

💡 Result:

Short answer — use Odoo's CLI (odoo-bin or python -m odoo) with the testing flags. Examples:

  • Run tests for a module (install/update + run tests, then stop):
    python3 -m odoo -c /path/to/odoo.conf -d mydb --test-enable -u my_module --stop-after-init. [1][2]

  • Run a single test file:
    python3 -m odoo -c /path/to/odoo.conf -d mydb --test-file /path/to/tests/test_foo.py --stop-after-init. [1][2]

  • Filter tests by tag / class / method:
    add --test-tags=:TestClass.test_method,/module,+other_tag. (--test-tags implies --test-enable). [1][2]

Reference docs:

  • CLI options (includes --test-enable, --test-file, --test-tags, --stop-after-init). [1]
  • Testing guide (how tests are discovered, tagged, and run). [2]

Sources:
[1] Odoo 15 CLI documentation.
[2] Odoo 15 Testing documentation.


Update test execution commands to use official Odoo 15 syntax.

The commands in lines 62-78 use python3 -m odoo.tests.loader, but Odoo 15 official documentation specifies using python3 -m odoo with test flags (--test-enable, --test-tags). Update to the standard approach:

Recommended syntax
# Run all module tests
docker exec $ODOO_CONTAINER python3 -m odoo -d $ODOO_DB --test-enable -u MODULE_NAME --stop-after-init

# Run with coverage
docker exec $ODOO_CONTAINER coverage run \
    --source=/mnt/extra-addons/MODULE_NAME \
    -m odoo -d $ODOO_DB --test-enable -u MODULE_NAME --stop-after-init
docker exec $ODOO_CONTAINER coverage report

Alternatively, document why the odoo.tests.loader approach is preferred if it provides specific advantages in your setup.

🤖 Prompt for AI Agents
In `@rules/testing.md` around lines 62 - 78, The test commands in the TDD Workflow
use the old module "odoo.tests.loader"; update the commands to use the official
Odoo 15 invocation "python3 -m odoo" and add the standard test flags: include
the database parameter (-d $ODOO_DB), enable tests with --test-enable, update
the module with -u MODULE_NAME and stop after init with --stop-after-init; do
the same for the coverage invocation by replacing "-m odoo.tests.loader
MODULE_NAME.tests" with "-m odoo -d $ODOO_DB --test-enable -u MODULE_NAME
--stop-after-init" while preserving the coverage --source path and subsequent
coverage report step.

Comment on lines +282 to +297
### Phase 2: Odoo Standard Tests (MANDATORY)
```bash
# Run Odoo standard tests (must exist in module/tests/ folder)
docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader MODULE_NAME.tests.test_file

# Run specific test module
docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader \
custom_module.tests.test_calculation

# Run all module tests
docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader MODULE_NAME.tests

# Run with specific database
docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader \
MODULE_NAME.tests.test_file -d $ODOO_DB
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix incorrect Odoo test execution commands.

The commands use python3 -m odoo.tests.loader which is not the correct way to run Odoo tests. Odoo tests are run through the main odoo-bin script with the --test-enable flag.

🔧 Proposed fix
 ### Phase 2: Odoo Standard Tests (MANDATORY)
 ```bash
-# Run Odoo standard tests (must exist in module/tests/ folder)
-docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader MODULE_NAME.tests.test_file
-
-# Run specific test module
-docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader \
-    custom_module.tests.test_calculation
-
-# Run all module tests
-docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader MODULE_NAME.tests
-
-# Run with specific database
-docker exec $ODOO_CONTAINER python3 -m odoo.tests.loader \
-    MODULE_NAME.tests.test_file -d $ODOO_DB
+# Run all tests for a module
+docker exec $ODOO_CONTAINER odoo-bin -d $ODOO_DB -i MODULE_NAME --test-enable --stop-after-init
+
+# Run tests for specific module (after install)
+docker exec $ODOO_CONTAINER odoo-bin -d $ODOO_DB -u MODULE_NAME --test-enable --stop-after-init
+
+# Run tests with specific tags
+docker exec $ODOO_CONTAINER odoo-bin -d $ODOO_DB -u MODULE_NAME --test-enable --test-tags post_install --stop-after-init
+
+# Run specific test class (using test tags)
+docker exec $ODOO_CONTAINER odoo-bin -d $ODOO_DB -u MODULE_NAME --test-enable --test-tags /test_calculation --stop-after-init
🤖 Prompt for AI Agents
In `@skills/odoo-15-developer/testing.md` around lines 282 - 297, The commands
incorrectly call python3 -m odoo.tests.loader; replace them to run tests via the
odoo-bin entrypoint using the --test-enable flag and appropriate options: use
odoo-bin -d $ODOO_DB -i MODULE_NAME --test-enable --stop-after-init to run all
module tests, odoo-bin -d $ODOO_DB -u MODULE_NAME --test-enable
--stop-after-init to run/upgrade a module and run its tests, and use --test-tags
(e.g. --test-tags post_install or --test-tags /test_calculation) when targeting
specific tagged tests or classes; update the examples in this section to
reference $ODOO_CONTAINER, odoo-bin, MODULE_NAME, $ODOO_DB, --test-enable,
--test-tags, and --stop-after-init accordingly.

Comment on lines +10 to +19
### CRITICAL RULE - Field Requirements

**Define field requirements in XML views using `required="1"`, NOT in Python models using `required=True`.**

Python `required=True` causes database NULL constraints that conflict with different use cases:
- EDIT vs CREATE modes
- Readonly fields
- Conditional visibility

**Use XML `attrs` for conditional required validation instead.**
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Odoo 15 field required Python vs XML views best practices

💡 Result:

Short answer — use Python (required=True) for data integrity and database-level enforcement; use XML (required="1" or required="expr") only for view/UI-level checks or conditional/temporary requirements. Details and best practices:

  • Python (fields.… required=True)

    • Enforces NOT NULL at model/DB level — cannot be bypassed by other views or external writes; use when the field must always contain a value. [1][4]
    • Affects all views and APIs globally; changing it requires a module update and possibly a DB migration. [1][3]
  • XML (view) required="1" or required="python_expr"

    • Enforces only in that form/view (client-side); useful for view-specific or conditional requirements (e.g., required="state == 'draft'"). Can be bypassed by direct ORM/API calls. [2][6]
    • Easier to apply to existing fields without altering model code; prefer using view inheritance with position="attributes" to change the attribute. [3]
  • When to choose which

    • Make a field required=True in Python if it is a business invariant (data integrity) or used/created outside forms. [1]
    • Use XML required for UX-only constraints, conditional mandatory logic, or when you cannot/should not alter the model. [2][3]
  • Caveats and complementary patterns

    • Readonly/compute/default: a field required in Python that’s computed or readonly may cause write errors — ensure computed fields are stored or provide defaults. [4]
    • For complex validation (cross-field rules), prefer server-side @api.constrains or raise UserError — this provides reliable enforcement independent of the view. [4]
    • Don’t rely solely on client-side required for security-sensitive or integrit y-critical rules. [1][2]

References

  • Difference and DB effect explanation (Stack Overflow). [1]
  • Odoo view attribute docs: required can be a Python expression and is view-scoped. [2]
  • Odoo forum — recommended way to make existing field required in views (inherit and change attributes). [3]
  • Odoo development book on field attributes and practical cautions. [4]

If you want, I can show examples: Python model required, XML required with a conditional expression, and an @api.constrains pattern.


🌐 Web query:

Odoo required=True database constraint field requirements documentation

💡 Result:

Short answer

  • required=True on a Field (model/Python) makes the ORM enforce the value at the database/ORM level (creates a NOT NULL constraint so inserts/updates without a value will fail). [1][2]
  • required="1" (or required="True") in a view (XML) is only a UI-level requirement: it prevents saving from that view but does not alter the DB schema and can be bypassed via RPC/SQL. [1][2]
  • For relational fields, database-level non-nullability interacts with ondelete: e.g., ondelete='set null' cannot be used if the column is NOT NULL. Plan constraints accordingly. [3]

References

  • Odoo view attribute "required" (field XML attribute). [1]
  • Community explanation showing difference between model (Python) vs view (XML) required. [2]
  • Odoo ORM fields docs (field attributes, required and DB behavior; ondelete notes). [3]

Revise to reflect proper Odoo best practices for required fields.

The documentation incorrectly prescribes a blanket prohibition on Python required=True. According to Odoo best practices:

  • Python required=True should be used for fields that are business invariants—truly required at the database/data integrity level (creates NOT NULL constraint, enforced across all views and APIs)
  • XML required="1" or conditional required should be used for view-specific or conditional requirements (UI-level, can be bypassed via API/RPC)

The listed scenarios (EDIT vs CREATE modes, readonly fields, conditional visibility) are specific cases where conditional XML requirements are more appropriate, not reasons to universally avoid Python required=True. For fields that must always contain a value, Python required=True is the correct, standard practice.

Update the guidance to distinguish between unconditional (Python) and conditional/view-specific (XML) requirements rather than prohibiting one approach outright.

🤖 Prompt for AI Agents
In `@skills/odoo-15-developer/views-xml.md` around lines 10 - 19, Update the
"CRITICAL RULE - Field Requirements" section to stop blanket-prohibiting Python
required=True and instead explain the correct practice: use Python required=True
for true data/business invariants that must be enforced at the DB level, and use
XML required="1" or conditional required via attrs for view-specific or
conditional UI validation (e.g., edit vs create, readonly fields, conditional
visibility). Mention the tradeoffs (DB NOT NULL vs UI-only enforcement) and
explicitly reference the symbols `required=True`, `required="1"`, and `attrs` so
readers can locate examples in the doc.

@affaan-m
Copy link
Copy Markdown
Owner

adding support for odoo or whatnot is fine, please keep it all in the folder, do not edit the original files as they are meant to be generic for everyones usecase, if you can make these fixes and containt the odoo specific skills to just a folder without touching the remainder of the repo I can merge this

@affaan-m
Copy link
Copy Markdown
Owner

Thanks for adapting this for Odoo 15! However, this is quite specific to your use case and would add significant Odoo-specific content to this general-purpose Claude Code config repo. Consider maintaining a fork for your Odoo-specific configurations! 🙏

@affaan-m affaan-m closed this Jan 23, 2026
moyueheng added a commit to moyueheng/everything-claude-code that referenced this pull request Jan 29, 2026
675db95 feat: unify commands and skills (v1.2.0)
ca584e2 fix: escape pipe in markdown table for markdownlint
a44a055 fix: resolve ESLint errors and update tests for project-name fallback
c9ef02b docs: add requirements section and hooks field warning
0c53ad8 Revert "docs: update shorthand to shortform terminology"
c3430bd docs: add Traditional Chinese translation
fbe2e56 docs: add simplified Chinese README
7c0bc25 feat: add comprehensive CI/CD pipeline
58a97c8 docs: update shorthand to shortform terminology
04ee208 docs: add plugin manifest validation notes
e3a1306 fix: remove duplicate hooks declaration from plugin.json
81003b1 feat: use project name as session filename fallback
8996303 fix: prevent command injection in Prettier hook (affaan-m#102)
8894e1b docs: update README with skill-create and instinct commands
9bc587a feat: add skill-create and continuous-learning-v2 commands
0ced59a Merge pull request affaan-m#91 from Hor1zonZzz/fix/readme-rules-limitation
2563d1e Merge pull request affaan-m#92 from jhsong-musinsa/fix/plugin-manifest-validation
5dc1edb Merge pull request affaan-m#93 from pangerlkr/patch-3
2aac2d9 Create PLUGIN_SCHEMA_NOTES.md
cdf987d fix: use explicit file paths for agents in plugin.json
384b255 docs: add note about rules limitation in plugin installation
accbb47 feat: add proper header banner to shortform guide
ff67b03 feat: add images and rename guides to the-shortform-guide.md and the-longform-guide.md
7fc5ef1 Merge pull request affaan-m#83 from msyahidin/claude/add-golang-support-frw0Z
779085e fix: add missing agents and hooks declarations to plugin.json
5e1835a Merge pull request affaan-m#81 from pangerlkr/patch-2
2abefe6 Merge pull request affaan-m#79 from pangerlkr/patch-1
4bca615 Merge pull request affaan-m#80 from lichengzhe/fix/stop-hook-shell-error
a1f47f1 Merge pull request affaan-m#85 from roeiba/add-license-file
01ad21b docs: add missing MIT LICENSE file
c6c32cd fix: add language labels to fenced code blocks for MD040 compliance
75e1e46 feat: add comprehensive Golang language support
2feac5a docs: add The Longform Guide to Everything Claude Code
a0b84f7 Fix: Move Stop hook inline code to separate script file
1564213 docs: add The Shorthand Guide to Everything Claude Code
56ff5d4 fix: use correct unscoped agent-browser package name (affaan-m#77)
5c63fa9 feat: v1.1.0 release - session ID tracking, async hooks, new skills
5670fcd Fix plugin manifest validation errors (affaan-m#75)
1c9fa0b Add hooks.md to documentation index (affaan-m#40)
2bfd2fb feat: add cloud infrastructure security skill (affaan-m#44)
fae9716 feat(agents): add database-reviewer agent with Supabase patterns (affaan-m#48)
a2087a8 fix: remove unnecessary .sh hooks (affaan-m#41)
b9b7831 fix: multiple community-reported issues
660e0d3 fix: security and documentation fixes
a7bc5f2 revert: remove hooks declaration - auto-loaded by convention
22ad036 fix: add hooks declaration to plugin.json for proper hook loading
5230892 fix: remove version fields from marketplace.json
970f8bf feat: cross-platform support with Node.js scripts
4ec7a6b fix: remove version field to enable automatic plugin updates
0d438dd style: side-by-side guide layout matching profile README
7f4f622 feat: add star history chart and minimal badge bar
c3f1594 fix: move session-end hooks from Stop to SessionEnd
19345df fix: remove duplicate hooks field from plugin.json
73bda1a fix: use ${CLAUDE_PLUGIN_ROOT} for hook script paths
ecfbbd3 fix: use relative path './' for plugin source instead of GitHub object
ee5affb fix: remove agents field temporarily to debug validation
d362ae6 fix: use string format for repository field in plugin.json
9e8006c fix: use GitHub source object in marketplace.json
5010f82 feat: package as Claude Code plugin with marketplace distribution
4491f15 Clarify README description of the repository
e6440d3 docs: restructure README to flow shorthand → longform guides together
fa0928a Enhance README with update section and resources
2d6fd70 feat: add strategic-compact hook and update hooks.json with all hooks
f96ef1e feat: add memory persistence hooks and context files
7d3ea0f feat: add strategic compact skill
6bf102d feat: add continuous learning skill with session examples
3c1e7d9 Clarify repository purpose and additional resources
62a80df Update README with image and guide link
6eefb41 Update README with guide reading reminder
d7cf890 Fix formatting in README.md for guide link
e57979c Update README with image and guide link
45959c3 Initial release: Complete Claude Code configuration collection
REVERT: 69c0b1a Add link to Agent Skills specification website (affaan-m#160)
REVERT: be229a5 Fix links in agent skills specification (affaan-m#159)
REVERT: f232228 Split agent-skills-spec into separate authoring and client integration guides (affaan-m#148)
REVERT: 0075614 Add doc-coauthoring skill and update example skills (affaan-m#134)
REVERT: ef74077 Move example skills into dedicated folder and create minimal top-level folder structure (affaan-m#129)
REVERT: 0f77e50 Update example skills and rename 'artifacts-builder' (affaan-m#112)
REVERT: e5c6015 Add 'frontend-design' example skill (affaan-m#98)
REVERT: c74d647 Clarify Claude Code installation in README.md (#20)
REVERT: 0877bae Updates to README.md (affaan-m#9)
REVERT: b118d29 Add Claude Claude instructions to the readme (#8)
REVERT: 4d1e3f3 Add Claude Code Marketplace (affaan-m#5)
REVERT: 9b61003 Small tweak to blog link (#7)
REVERT: 10e0fbe Add initial Agent Skills Spec (#2)
REVERT: ec84104 Add 3rd Party notices (affaan-m#4)
REVERT: 67ada86 Adding more details to README (affaan-m#3)
REVERT: 83291af Reorganize the example skills (affaan-m#1)
REVERT: 37292f3 init repo

git-subtree-dir: upstream/anthropics-skills
git-subtree-split: 675db95
affaan-m pushed a commit that referenced this pull request Feb 20, 2026
…another-one

Fix markdownlint errors (MD038, MD058, MD025, MD034)
pythonstrup added a commit to pythonstrup/everything-claude-code that referenced this pull request Mar 8, 2026
Address 8 PR review issues from cubic-dev-ai and coderabbitai:

- Separate require()/run() try/catch in run-with-flags to prevent
  double-execution on run() errors (affaan-m#1)
- Resolve filePath to absolute in quality-gate (#2)
- Detect prettier key in package.json (affaan-m#3)
- Use `output != null` instead of truthy check (affaan-m#4)
- Add gofmt strict mode logging (affaan-m#5)
- Return null for unknown formatter in resolveFormatterBin (#6)
- Track and cleanup temp dirs in tests (#7)
- Add JSDoc to exported functions (#8)
pythonstrup added a commit to pythonstrup/everything-claude-code that referenced this pull request Mar 10, 2026
Address 8 PR review issues from cubic-dev-ai and coderabbitai:

- Separate require()/run() try/catch in run-with-flags to prevent
  double-execution on run() errors (affaan-m#1)
- Resolve filePath to absolute in quality-gate (#2)
- Detect prettier key in package.json (affaan-m#3)
- Use `output != null` instead of truthy check (affaan-m#4)
- Add gofmt strict mode logging (affaan-m#5)
- Return null for unknown formatter in resolveFormatterBin (#6)
- Track and cleanup temp dirs in tests (#7)
- Add JSDoc to exported functions (#8)
chris-yyau added a commit to chris-yyau/everything-claude-code that referenced this pull request Mar 20, 2026
- Fix status early return skipping pending instinct warnings (cubic #1)
- Exclude already-expired items from expiring-soon filter (cubic #2)
- Warn on unparseable pending instinct age instead of silent skip (cubic affaan-m#4)
- Log prune failures to observer.log instead of silencing (cubic affaan-m#5)

Co-Authored-By: Claude <noreply@anthropic.com>
affaan-m pushed a commit that referenced this pull request Mar 22, 2026
* feat: add pending instinct TTL pruning and /prune command

Pending instincts generated by the observer accumulate indefinitely
with no cleanup mechanism. This adds lifecycle management:

- `instinct-cli.py prune` — delete pending instincts older than 30 days
  (configurable via --max-age). Supports --dry-run and --quiet flags.
- Enhanced `status` command — shows pending count, warns at 5+,
  highlights instincts expiring within 7 days.
- `observer-loop.sh` — runs prune before each analysis cycle.
- `/prune` slash command — user-facing command for manual pruning.

Design rationale: council consensus (4/4) rejected auto-promote in
favor of TTL-based garbage collection. Frequency of observation does
not establish correctness. Unreviewed pending instincts auto-delete
after 30 days; if the pattern is real, the observer will regenerate it.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>

* fix: remove duplicate functions, broaden extension filter, fix prune output

- Remove duplicate _collect_pending_dirs and _parse_created_date defs
- Use ALLOWED_INSTINCT_EXTENSIONS (.md/.yaml/.yml) instead of .md-only
- Track actually-deleted items separately from expired for accurate output
- Update README.md and AGENTS.md command counts: 59 → 60

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>

* fix: address Copilot and CodeRabbit review findings

- Use is_dir() instead of exists() for pending path checks
- Change > to >= for --max-age boundary (--max-age 0 now prunes all)
- Use CLV2_PYTHON_CMD env var in observer-loop.sh prune call
- Remove unused source_dupes variable
- Remove extraneous f-string prefix on static string

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>

* fix: update AGENTS.md project structure command count 59 → 60

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: address cubic and coderabbit review findings

- Fix status early return skipping pending instinct warnings (cubic #1)
- Exclude already-expired items from expiring-soon filter (cubic #2)
- Warn on unparseable pending instinct age instead of silent skip (cubic #4)
- Log prune failures to observer.log instead of silencing (cubic #5)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: YAML single-quote unescaping, f-string cleanup, add /prune to README

- Fix single-quoted YAML unescaping: use '' doubling (YAML spec) not
  backslash escaping which only applies to double-quoted strings (greptile P1)
- Remove extraneous f-string prefix on static string (coderabbit)
- Add /prune to README command catalog and file tree (cubic)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>
mecemis pushed a commit to mecemis/everything-claude-code that referenced this pull request Mar 25, 2026
* feat: add pending instinct TTL pruning and /prune command

Pending instincts generated by the observer accumulate indefinitely
with no cleanup mechanism. This adds lifecycle management:

- `instinct-cli.py prune` — delete pending instincts older than 30 days
  (configurable via --max-age). Supports --dry-run and --quiet flags.
- Enhanced `status` command — shows pending count, warns at 5+,
  highlights instincts expiring within 7 days.
- `observer-loop.sh` — runs prune before each analysis cycle.
- `/prune` slash command — user-facing command for manual pruning.

Design rationale: council consensus (4/4) rejected auto-promote in
favor of TTL-based garbage collection. Frequency of observation does
not establish correctness. Unreviewed pending instincts auto-delete
after 30 days; if the pattern is real, the observer will regenerate it.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>

* fix: remove duplicate functions, broaden extension filter, fix prune output

- Remove duplicate _collect_pending_dirs and _parse_created_date defs
- Use ALLOWED_INSTINCT_EXTENSIONS (.md/.yaml/.yml) instead of .md-only
- Track actually-deleted items separately from expired for accurate output
- Update README.md and AGENTS.md command counts: 59 → 60

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>

* fix: address Copilot and CodeRabbit review findings

- Use is_dir() instead of exists() for pending path checks
- Change > to >= for --max-age boundary (--max-age 0 now prunes all)
- Use CLV2_PYTHON_CMD env var in observer-loop.sh prune call
- Remove unused source_dupes variable
- Remove extraneous f-string prefix on static string

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>

* fix: update AGENTS.md project structure command count 59 → 60

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: address cubic and coderabbit review findings

- Fix status early return skipping pending instinct warnings (cubic affaan-m#1)
- Exclude already-expired items from expiring-soon filter (cubic #2)
- Warn on unparseable pending instinct age instead of silent skip (cubic affaan-m#4)
- Log prune failures to observer.log instead of silencing (cubic affaan-m#5)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: YAML single-quote unescaping, f-string cleanup, add /prune to README

- Fix single-quoted YAML unescaping: use '' doubling (YAML spec) not
  backslash escaping which only applies to double-quoted strings (greptile P1)
- Remove extraneous f-string prefix on static string (coderabbit)
- Add /prune to README command catalog and file tree (cubic)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants