Conversation
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>
📝 WalkthroughWalkthroughComprehensive 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
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
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ 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. Comment |
There was a problem hiding this comment.
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, choreskills/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 rulesskills/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_amountskills/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:145skills/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 fixesCLAUDE.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 referenceskills/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: Changemethods=['GET']tomethods=['POST']or remove the parameter.The
methodsparameter is valid fortype='json'routes, but JSON-RPC endpoints should use HTTP POST. Line 12 specifiesmethods=['GET'], which is semantically incorrect for a JSON-RPC endpoint—the first route should either omit themethodsparameter (allowing all methods, though POST is expected) or explicitly usemethods=['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
textfor 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, ormarkdown.✅ 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.,
textorbash) 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
textfor directory trees.✅ Suggested fix
-``` +```text module_name/ ... -``` +```skills/frontend-patterns.md-132-136 (1)
132-136: Fix the variable reference in the example.The
updateNamemethod referencesthis.state.formData.partner.name, but thesetup()method above shows the state variable asthis.formData(line 120), notthis.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.loaderwith-d $ODOO_DBbut the correct syntax for Odoo test runner typically usesodoo-binor 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 -20agents/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]udoonly matches inline comments, not docstrings. A method usingsudo()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 fiAlternatively, consider this a best-effort check and document its limitation in the description.
hooks/hooks.json-6-14 (1)
6-14: Interactivereadmay block in non-interactive environments.The
read -rcommand 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 containingThe regex
^[^#]*print(will match legitimate code likedef print_report(self):orself.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 printand.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-addonsis 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 methodsNote: 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 usingast-grepfor more accurate field detection.The current approach uses basic
grepfor finding field definitions and references, which may produce false positives (e.g., matchingfields.in comments or strings). Consider usingast-grepfor 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 fieldsrules/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_loggerimport.The error handling example uses
_loggerbut 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
pythonas 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.,
textorplaintext) 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_modelsexample references helper functions that aren't defined:extract_string_value(),is_field_definition(), andget_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/, andcontrollers/, but pylint only checksmodels/. 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 andmapped()just forces it upfront.
228-231: API decorator example uses deprecated pattern.The
@api.model_create_multidecorator example shows it as "Odoo 12+", but in Odoo 15, the standardcreate()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.infofor debugging, but_logger.infois 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()` statementsagents/tdd-guide.md (1)
407-427: Alternative test command might be more reliable.The shown test commands use
python3 -m odoo.tests.loaderwhich may not be the standard approach in all Odoo 15 Docker setups. The alternative usingodooCLI with--test-enableis shown but could be emphasized as the more reliable option.💡 Emphasize standard approach
Consider reordering to show the standard
odoocommand 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_nameREADME.md (1)
92-92: Placeholder URL needs to be updated or clearly marked.The clone URL contains
YOUR_USERNAMEwhich 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.gitagents/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/loginand form filling. While this works, Odoo's Playwright tests typically use theauthenticatehelper 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_PORTwhich 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 PlaywrightPagetype instead ofany.Using
anyloses TypeScript's type checking benefits. Import and use thePagetype 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.infowarning is too aggressive.While
_logger.debugis preferred for verbose logging,_logger.infois 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.
| // Verify saved | ||
| await expect(page.locator('.o_form_view')).toContainText('Test Partner E2E') | ||
| await expect(page.locator('.o_form_saved')).toBeVisible() | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's read the full context of the test file
cat -n agents/e2e-runner.md | head -150Repository: 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 jsRepository: 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 2Repository: 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.
| ### 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 | ||
| ``` |
There was a problem hiding this comment.
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:
- Relying on automatic prefetching (just use
search([])) - Using
read()with specific field lists - Using
prefetchcontext 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.
| ### 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.
| "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" | ||
| } |
There was a problem hiding this comment.
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.
| ## 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 | ||
|
|
There was a problem hiding this comment.
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.
| ## 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).
| ## 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 | ||
| ``` |
There was a problem hiding this comment.
🧩 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 2Repository: 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 reportAlternatively, 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.
| ### 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 | ||
| ``` |
There was a problem hiding this comment.
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.
| ### 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.** |
There was a problem hiding this comment.
🧩 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.constrainsor 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=Trueshould 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 conditionalrequiredshould 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.
|
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 |
|
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! 🙏 |
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
…another-one Fix markdownlint errors (MD038, MD058, MD025, MD034)
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)
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)
- 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>
* 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>
* 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>
Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.