Two fixes + a memory entry in CLAUDE.md.
=== Dark mode ===
User: "when I change the theme the whole background does not turn
dark like the other pages does". Digging through Odoo 19 source:
/_dependencies/web_enterprise/static/src/scss/
bootstrap_overridden.dark.scss
primary_variables.dark.scss
secondary_variables.dark.scss
Odoo doesn't flip dark mode via a runtime .o_dark_mode class on the
DOM — it compiles a SEPARATE asset bundle where $o-webclient-color-
scheme: dark is set, which redefines every --bs-* token with dark
values. When the user toggles dark mode, Odoo swaps the whole CSS
bundle.
So my previous :root[data-bs-theme="dark"] { --fp-page-bg: #13161a; }
block was DEAD CODE — nothing ever sets data-bs-theme on the root.
Fixed: tokens now fall through to Bootstrap's --bs-* semantic tokens
before hitting a hex default, so they auto-invert when Odoo swaps
bundles. Three-level fallback chain:
$fp-page : var(--fp-page-bg,
var(--bs-tertiary-bg, #f3f4f6));
$fp-card : var(--fp-card-bg,
var(--bs-card-bg,
var(--o-view-background-color, #ffffff)));
$fp-border : var(--fp-border-color,
var(--bs-border-color, #d8dadd));
$fp-ink : var(--fp-ink, var(--bs-body-color, #1f2937));
Dead .o_dark_mode block removed. No runtime selector needed.
=== Quick View button ===
User: "Quick View button color is white with white button in light
mode." Cause: Bootstrap's .btn-primary loads AFTER our custom CSS
in the bundle and resets color: #fff, background: var(--bs-btn-bg)
— which clobbered our $fp-accent / $fp-ink assignment because a
later rule at the same specificity wins.
Fix: split the primary button into its own rule with higher
specificity (.o_fp_manager .o_fp_manager_head_actions .btn.btn-primary)
and !important on the three key properties — so Bootstrap can't
shout us down. Hover uses brightness(1.08) for a subtle darken
without needing another color assignment.
=== CLAUDE.md additions ===
Added two new rules documenting the lessons so this isn't relearned:
Rule 8 — Odoo 19 forbids @import in custom SCSS (silent warning,
falls back to cached bundle). Register partials in the assets list
in load order; SCSS variables cascade through the bundle.
"Card Styling — Copy Odoo's Kanban Pattern" section explaining:
- Don't rely on --bs-border-color directly for card surfaces
- Chain through $fp-* → --fp-* → --bs-* → hex
- 3-layer contrast rule (page → container → card)
- Reference _fp_shopfloor_tokens.scss as canonical
"Asset Bundle Cache Busting" section with 4-step escalation path
for when CSS changes don't show up in browser.
Verified: bundle regenerated to /web/assets/b48ab17/web.assets_backend.min.css
(id 1945). Card rule compiled with full fallback chain visible.
Primary button carries !important modifier for bg/border/color.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
72 lines
3.9 KiB
Markdown
72 lines
3.9 KiB
Markdown
# Odoo Modules — Claude Code Instructions
|
|
|
|
## Project
|
|
27 custom Odoo 19 modules for Fusion Central (Westin Healthcare + NEXA Systems).
|
|
|
|
## Critical Rules — Odoo 19
|
|
1. **NEVER code from memory** — Always read a reference file from Docker first:
|
|
```bash
|
|
docker exec odoo-dev-app cat /usr/lib/python3/dist-packages/odoo/addons/<module>/static/src/<path>
|
|
```
|
|
2. **Frontend JS**: Use `Interaction` class from `@web/public/interaction`, registered via `registry.category("public.interactions")`. NOT IIFE/DOMContentLoaded.
|
|
3. **Backend OWL**: Use standalone `rpc()` from `@web/core/network/rpc`. NOT `useService("rpc")`. `static props = []` not `{}`.
|
|
4. **HTTP routes**: `type="jsonrpc"` — NOT `type="json"` (deprecated).
|
|
5. **res.config.settings**: Only boolean/integer/float/char/selection/many2one/datetime. NO Date fields.
|
|
6. **res.groups**: NO `users` field, NO `category_id` field.
|
|
7. **Search views**: NO `group expand="0"` syntax.
|
|
8. **SCSS imports**: `@import "./partial"` is FORBIDDEN in Odoo 19 custom SCSS. It prints a warning and silently falls back to the old cached bundle. Register every SCSS file (including `_partial.scss` tokens) as a separate entry in `web.assets_backend`. Put tokens first; Odoo concatenates bundle files so SCSS variables/mixins from the first file are visible to every later file.
|
|
|
|
## Card Styling — Copy Odoo's Kanban Pattern
|
|
Don't rely on `var(--bs-border-color)` or `var(--bs-body-bg)` for card surfaces — they drift between themes/addons and often render **invisible**. Odoo's own kanban (`.o_kanban_record`) uses **explicit hex** values:
|
|
```css
|
|
background-color: white;
|
|
border: 1px solid #d8dadd;
|
|
```
|
|
For custom OWL dashboards / client actions use the same approach:
|
|
- Define a `_tokens.scss` partial with explicit hex values wrapped in a CSS custom property:
|
|
```scss
|
|
$fp-card: var(--fp-card-bg, #ffffff);
|
|
$fp-border: var(--fp-border-color, #d8dadd);
|
|
```
|
|
- Reference those tokens everywhere (never `var(--bs-border-color)` directly)
|
|
- Override the custom properties for dark mode at the bottom of the tokens file:
|
|
```scss
|
|
:root[data-bs-theme="dark"], body.o_dark_mode, .o_dark_mode {
|
|
--fp-card-bg: #22262d;
|
|
--fp-border-color: #343942;
|
|
}
|
|
```
|
|
- Three-layer contrast: **page** (grayest) → **container/column** (mid) → **card** (brightest). That's what makes cards pop.
|
|
- Reference implementation: `fusion_plating_shopfloor/static/src/scss/_fp_shopfloor_tokens.scss`.
|
|
|
|
## Asset Bundle Cache Busting
|
|
Odoo content-hashes the compiled bundle URL (`/web/assets/<hash>/...`). When CSS changes but the hash doesn't update, the browser serves the old bundle. Fixes in order of escalation:
|
|
1. Bump the module `version` in `__manifest__.py`
|
|
2. `DELETE FROM ir_attachment WHERE url LIKE '/web/assets/%';` then restart odoo
|
|
3. Call `env['ir.qweb']._get_asset_bundle('web.assets_backend').css()` in odoo-shell to force regeneration
|
|
4. Hard-refresh browser with cache clear (DevTools → right-click refresh → *Empty Cache and Hard Reload*); on mobile clear website data
|
|
|
|
## Naming
|
|
- New fields: `x_fc_*` prefix
|
|
- Legacy fields: `x_studio_*`
|
|
- Canadian English for all user-facing text
|
|
- Currency: `$` sign with Monetary fields + currency_id
|
|
|
|
## Cursor-Managed Modules
|
|
- **fusion_clock** is currently being modified in Cursor — always read files fresh before editing, don't assume you know the current state
|
|
|
|
## Workflow
|
|
- Local dev: `docker exec odoo-dev-app odoo -d fusion-dev -u <module> --stop-after-init`
|
|
- Local URL: http://localhost:8069
|
|
- Test before deploying. Edit existing files — don't create unnecessary new ones.
|
|
|
|
## Supabase Knowledge Base
|
|
Before starting unfamiliar work, check Supabase for context:
|
|
```bash
|
|
PGPASSWORD='a09e12e0995dc29446631fa458f3d4b3' psql -h 100.74.28.73 -p 5433 -U postgres -d postgres
|
|
```
|
|
- `fusionapps.decisions` — past architecture decisions
|
|
- `fusionapps.issues` — known issues and fixes
|
|
- `fusionapps.code_snippets` — reference code
|
|
- `fusionapps.quick_commands` — deployment and admin commands
|