From claude-odoo-dev
This skill should be used when the user asks to "manage Odoo state", "apply configuration to Odoo", "detect drift", "compare desired vs actual state", "plan/apply changes", "set up automations", "configure base.automation", "create server actions", or mentions infrastructure-as-code patterns for Odoo.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-odoo-dev:state-managementThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Declarative state management for Odoo using a Terraform-style compare/plan/apply workflow. Define desired state, detect drift from actual state, review a plan, and apply changes safely.
Declarative state management for Odoo using a Terraform-style compare/plan/apply workflow. Define desired state, detect drift from actual state, review a plan, and apply changes safely.
npm install @marcfargas/odoo-state-manager @marcfargas/odoo-client
import {
compareRecords,
generatePlan,
formatPlanForConsole,
validatePlanReferences,
applyPlan,
dryRunPlan,
} from '@marcfargas/odoo-state-manager';
import { createClient } from '@marcfargas/odoo-client';
const diffs = compareRecords(desiredRecords, actualRecords, {
fieldMetadata, // optional: skip readonly/computed fields
});
Handles Odoo field quirks: normalizes many2one [id, name] tuples, order-insensitive relational arrays.
const plan = generatePlan(diffs);
console.log(formatPlanForConsole(plan));
Output uses Terraform-like symbols: + create, ~ update, - delete. Operations are topologically sorted by dependencies.
const errors = await validatePlanReferences(plan, client);
if (errors.length === 0) {
const result = await applyPlan(plan, client, {
onProgress: (op, index, total) => console.log(`${index}/${total}: ${op.type} ${op.model}`),
});
}
const result = await dryRunPlan(plan, client);
// Validates without making changes
When creating multiple related records, use temporary IDs:
const desired = {
'ir.actions.server': [
{ __temp_id: 'action_1', name: 'My Action', model_id: /* ... */ },
],
'base.automation': [
{ name: 'My Rule', action_server_ids: ['ir.actions.server:action_1'] },
],
};
The apply step resolves ir.actions.server:action_1 to the real database ID after creation.
# Dump current state
npx odoo state dump --model res.partner --domain '[["is_company","=",true]]'
# Compare desired vs actual
npx odoo state compare --file desired-state.json
# Load state from file
npx odoo state load --file desired-state.json
dryRunPlan before applyPlan in productionformatPlanForConsole to review changes before applyingfieldMetadata from introspection to skip computed/readonly fieldsonProgress callback for visibility during applynpx claudepluginhub marcfargas/claude-odoo-devScaffolds custom Odoo modules including __manifest__.py, models, views, security; guides inheritance, ORM patterns, onchange/compute methods, and troubleshooting.
Guides scaffolding custom Odoo modules, defining models, setting up security, and following Odoo conventions for Community and Enterprise editions.
References Odoo 18 guides for Python models, ORM (search/domain/read_group), XML/CSV views, OWL/JS components, QWeb reports, security (ACL/rules), cron/actions, migrations, tests, i18n, performance. Activates on Odoo code/tracebacks/addons.