docs(fusion_clock): use actual docker env names (odoo-modsdev-app/modsdev) in NFC plan

This commit is contained in:
gsinghpal
2026-05-14 00:14:51 -04:00
parent 70f855d91b
commit 91d3a3f9d1

View File

@@ -11,11 +11,11 @@
**Reference spec:** [docs/superpowers/specs/2026-05-13-nfc-clock-kiosk-design.md](../specs/2026-05-13-nfc-clock-kiosk-design.md) **Reference spec:** [docs/superpowers/specs/2026-05-13-nfc-clock-kiosk-design.md](../specs/2026-05-13-nfc-clock-kiosk-design.md)
**Dev environment:** **Dev environment:**
- Odoo container: `odoo-dev-app` - Odoo container: `odoo-modsdev-app`
- Database: `fusion-dev` - Database: `modsdev`
- Local URL: http://localhost:8069 - Local URL: http://localhost:8069
- Module reload: `docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init` - Module reload: `docker exec odoo-modsdev-app odoo -d modsdev -u fusion_clock --stop-after-init`
- Run tests: `docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -i fusion_clock` - Run tests: `docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -i fusion_clock`
--- ---
@@ -112,7 +112,7 @@ class TestNfcModels(TransactionCase):
- [ ] **Step 3: Run the test to confirm it fails** - [ ] **Step 3: Run the test to confirm it fails**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -i fusion_clock 2>&1 | tail -40 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -i fusion_clock 2>&1 | tail -40
``` ```
Expected: errors about `x_fclk_nfc_card_uid` not being a valid field on `hr.employee`. Expected: errors about `x_fclk_nfc_card_uid` not being a valid field on `hr.employee`.
@@ -147,7 +147,7 @@ In `fusion_clock/models/hr_employee.py`, insert after the existing `x_fclk_kiosk
- [ ] **Step 5: Run the test to confirm it passes** - [ ] **Step 5: Run the test to confirm it passes**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40
``` ```
Expected: `0 failed, 0 error(s)` for the three test methods. Expected: `0 failed, 0 error(s)` for the three test methods.
@@ -231,7 +231,7 @@ Tests are in the same file, no additional import needed.
- [ ] **Step 3: Run the tests to confirm they fail** - [ ] **Step 3: Run the tests to confirm they fail**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30
``` ```
Expected: `nfc_kiosk` not a valid Selection value; `x_fclk_check_in_photo` not a valid field. Expected: `nfc_kiosk` not a valid Selection value; `x_fclk_check_in_photo` not a valid field.
@@ -332,7 +332,7 @@ The two updated fields should look like:
- [ ] **Step 6: Run the tests to confirm they pass** - [ ] **Step 6: Run the tests to confirm they pass**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30
``` ```
Expected: 6 tests pass (3 from Task 1 + 3 new). Expected: 6 tests pass (3 from Task 1 + 3 new).
@@ -380,7 +380,7 @@ class TestNfcKioskCompanyField(TransactionCase):
- [ ] **Step 2: Run the test to confirm it fails** - [ ] **Step 2: Run the test to confirm it fails**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30
``` ```
Expected: `x_fclk_nfc_kiosk_location_id` not a valid field on `res.company`. Expected: `x_fclk_nfc_kiosk_location_id` not a valid field on `res.company`.
@@ -423,7 +423,7 @@ from . import res_company
- [ ] **Step 5: Run the tests to confirm they pass** - [ ] **Step 5: Run the tests to confirm they pass**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30
``` ```
Expected: 8 tests pass (6 from previous tasks + 2 new). Expected: 8 tests pass (6 from previous tasks + 2 new).
@@ -469,7 +469,7 @@ Open `fusion_clock/data/ir_config_parameter_data.xml`. Find the closing `</odoo>
- [ ] **Step 2: Reload the module and confirm parameters are present** - [ ] **Step 2: Reload the module and confirm parameters are present**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init 2>&1 | tail -10 docker exec odoo-modsdev-app odoo -d modsdev -u fusion_clock --stop-after-init 2>&1 | tail -10
``` ```
Expected: clean reload, no errors. Expected: clean reload, no errors.
@@ -477,7 +477,7 @@ Expected: clean reload, no errors.
Then verify in odoo-shell: Then verify in odoo-shell:
```bash ```bash
docker exec -it odoo-dev-app odoo shell -d fusion-dev --no-http << 'EOF' docker exec -it odoo-modsdev-app odoo shell -d modsdev --no-http << 'EOF'
ICP = env['ir.config_parameter'].sudo() ICP = env['ir.config_parameter'].sudo()
for k in ['fusion_clock.enable_nfc_kiosk', 'fusion_clock.nfc_photo_required', 'fusion_clock.nfc_enroll_password', 'fusion_clock.nfc_kiosk_debug']: for k in ['fusion_clock.enable_nfc_kiosk', 'fusion_clock.nfc_photo_required', 'fusion_clock.nfc_enroll_password', 'fusion_clock.nfc_kiosk_debug']:
print(k, '=', repr(ICP.get_param(k))) print(k, '=', repr(ICP.get_param(k)))
@@ -585,7 +585,7 @@ Open `fusion_clock/views/res_config_settings_views.xml`. Find the last `</block>
- [ ] **Step 3: Reload and verify in browser** - [ ] **Step 3: Reload and verify in browser**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init 2>&1 | tail -5 docker exec odoo-modsdev-app odoo -d modsdev -u fusion_clock --stop-after-init 2>&1 | tail -5
``` ```
Then in browser, navigate to http://localhost:8069/odoo/settings → Fusion Clock app → scroll to "NFC Clock Kiosk" block. Confirm: Then in browser, navigate to http://localhost:8069/odoo/settings → Fusion Clock app → scroll to "NFC Clock Kiosk" block. Confirm:
@@ -670,7 +670,7 @@ from . import test_clock_nfc_kiosk
- [ ] **Step 3: Run the test to confirm it fails** - [ ] **Step 3: Run the test to confirm it fails**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30
``` ```
Expected: 404 errors on `/fusion_clock/kiosk/nfc` (route not yet defined). Expected: 404 errors on `/fusion_clock/kiosk/nfc` (route not yet defined).
@@ -771,7 +771,7 @@ Edit `fusion_clock/__manifest__.py`. In the `'data'` list, add `'views/kiosk_nfc
- [ ] **Step 8: Run the tests to confirm they pass** - [ ] **Step 8: Run the tests to confirm they pass**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30
``` ```
Expected: both new tests pass. Expected: both new tests pass.
@@ -842,7 +842,7 @@ class TestUidNormalization(TransactionCase):
- [ ] **Step 2: Run the test to confirm it fails** - [ ] **Step 2: Run the test to confirm it fails**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30
``` ```
Expected: `AttributeError: type object 'FusionClockNfcKiosk' has no attribute '_normalize_uid'`. Expected: `AttributeError: type object 'FusionClockNfcKiosk' has no attribute '_normalize_uid'`.
@@ -882,7 +882,7 @@ class FusionClockNfcKiosk(http.Controller):
- [ ] **Step 4: Run the tests to confirm they pass** - [ ] **Step 4: Run the tests to confirm they pass**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30
``` ```
Expected: 7 normalization tests pass. Expected: 7 normalization tests pass.
@@ -982,7 +982,7 @@ class TestEnrollEndpoint(HttpCase):
- [ ] **Step 2: Run the tests to confirm they fail** - [ ] **Step 2: Run the tests to confirm they fail**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40
``` ```
Expected: 404 on `/fusion_clock/kiosk/nfc/enroll`. Expected: 404 on `/fusion_clock/kiosk/nfc/enroll`.
@@ -1049,7 +1049,7 @@ Append to `fusion_clock/controllers/clock_nfc_kiosk.py` (inside the `FusionClock
- [ ] **Step 4: Run the tests to confirm they pass** - [ ] **Step 4: Run the tests to confirm they pass**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40
``` ```
Expected: 4 enroll tests pass. Expected: 4 enroll tests pass.
@@ -1150,7 +1150,7 @@ class TestTapEndpointHappyPath(HttpCase):
- [ ] **Step 2: Run the test to confirm it fails** - [ ] **Step 2: Run the test to confirm it fails**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40
``` ```
Expected: 404 on `/fusion_clock/kiosk/nfc/tap`. Expected: 404 on `/fusion_clock/kiosk/nfc/tap`.
@@ -1267,7 +1267,7 @@ Append to `fusion_clock/controllers/clock_nfc_kiosk.py` (inside the `FusionClock
- [ ] **Step 4: Run the tests to confirm they pass** - [ ] **Step 4: Run the tests to confirm they pass**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40
``` ```
Expected: both tap tests pass. Expected: both tap tests pass.
@@ -1370,7 +1370,7 @@ class TestTapEndpointErrors(HttpCase):
- [ ] **Step 2: Run the tests to confirm they fail** - [ ] **Step 2: Run the tests to confirm they fail**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40
``` ```
Expected: most error tests pass already (the controller already returns `card_unknown`, `clock_disabled`, etc.) but `test_debounce_silent_second_tap` fails because debounce isn't implemented yet. Expected: most error tests pass already (the controller already returns `card_unknown`, `clock_disabled`, etc.) but `test_debounce_silent_second_tap` fails because debounce isn't implemented yet.
@@ -1413,7 +1413,7 @@ Then in the `nfc_tap` method, immediately AFTER the `normalized = self._normaliz
- [ ] **Step 4: Run the tests to confirm they pass** - [ ] **Step 4: Run the tests to confirm they pass**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40
``` ```
Expected: all 6 error tests pass. Expected: all 6 error tests pass.
@@ -1506,7 +1506,7 @@ class TestTapPhotoHandling(HttpCase):
- [ ] **Step 2: Run the tests to confirm they fail** - [ ] **Step 2: Run the tests to confirm they fail**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40
``` ```
Expected: photo_required rejection test fails because the endpoint doesn't enforce it; photo-saved test fails because photo isn't decoded/saved. Expected: photo_required rejection test fails because the endpoint doesn't enforce it; photo-saved test fails because photo isn't decoded/saved.
@@ -1559,7 +1559,7 @@ And in the clock-out branch:
- [ ] **Step 4: Run the tests to confirm they pass** - [ ] **Step 4: Run the tests to confirm they pass**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -40
``` ```
Expected: all 3 photo tests pass. Expected: all 3 photo tests pass.
@@ -1619,7 +1619,7 @@ class TestEmployeeSearch(HttpCase):
- [ ] **Step 2: Run the test to confirm it fails** - [ ] **Step 2: Run the test to confirm it fails**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30
``` ```
Expected: 404 on `/fusion_clock/kiosk/nfc/employee_search`. Expected: 404 on `/fusion_clock/kiosk/nfc/employee_search`.
@@ -1639,7 +1639,7 @@ Append to `fusion_clock/controllers/clock_nfc_kiosk.py` (inside the class):
- [ ] **Step 4: Run the test to confirm it passes** - [ ] **Step 4: Run the test to confirm it passes**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -30
``` ```
Expected: search test passes. Expected: search test passes.
@@ -1929,7 +1929,7 @@ Edit `fusion_clock/__manifest__.py`. In the `'web.assets_frontend'` list, add th
- [ ] **Step 3: Reload module and verify SCSS compiles** - [ ] **Step 3: Reload module and verify SCSS compiles**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init 2>&1 | grep -i -E "(error|warning|nfc_kiosk)" | head -20 docker exec odoo-modsdev-app odoo -d modsdev -u fusion_clock --stop-after-init 2>&1 | grep -i -E "(error|warning|nfc_kiosk)" | head -20
``` ```
Expected: no SCSS compilation errors. If you see "could not be parsed", check for missing semicolons or typos. Expected: no SCSS compilation errors. If you see "could not be parsed", check for missing semicolons or typos.
@@ -2003,7 +2003,7 @@ Open `fusion_clock/views/kiosk_nfc_templates.xml` and REPLACE the entire file co
- [ ] **Step 2: Reload module** - [ ] **Step 2: Reload module**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init 2>&1 | tail -5 docker exec odoo-modsdev-app odoo -d modsdev -u fusion_clock --stop-after-init 2>&1 | tail -5
``` ```
- [ ] **Step 3: Smoke test in browser** - [ ] **Step 3: Smoke test in browser**
@@ -2011,7 +2011,7 @@ docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init 2>
In Chrome, open http://localhost:8069 and log in as an admin/manager. Then enable the kiosk via odoo-shell: In Chrome, open http://localhost:8069 and log in as an admin/manager. Then enable the kiosk via odoo-shell:
```bash ```bash
docker exec -it odoo-dev-app odoo shell -d fusion-dev --no-http << 'EOF' docker exec -it odoo-modsdev-app odoo shell -d modsdev --no-http << 'EOF'
env['ir.config_parameter'].sudo().set_param('fusion_clock.enable_nfc_kiosk', 'True') env['ir.config_parameter'].sudo().set_param('fusion_clock.enable_nfc_kiosk', 'True')
env.cr.commit() env.cr.commit()
EOF EOF
@@ -2191,7 +2191,7 @@ Edit `fusion_clock/__manifest__.py`. The `web.assets_frontend` list should now i
- [ ] **Step 3: Reload + smoke test in browser** - [ ] **Step 3: Reload + smoke test in browser**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init 2>&1 | tail -5 docker exec odoo-modsdev-app odoo -d modsdev -u fusion_clock --stop-after-init 2>&1 | tail -5
``` ```
Hard-refresh http://localhost:8069/fusion_clock/kiosk/nfc (Ctrl+Shift+R). Expected: Hard-refresh http://localhost:8069/fusion_clock/kiosk/nfc (Ctrl+Shift+R). Expected:
@@ -2318,7 +2318,7 @@ In `fusion_clock/static/src/js/fusion_clock_nfc_kiosk.js`, REPLACE the setup wiz
- [ ] **Step 2: Reload + verify in Chrome on Android** - [ ] **Step 2: Reload + verify in Chrome on Android**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init 2>&1 | tail -5 docker exec odoo-modsdev-app odoo -d modsdev -u fusion_clock --stop-after-init 2>&1 | tail -5
``` ```
Open the kiosk URL in Chrome on an Android phone (HTTPS required — see note below). Click "Tap to enable NFC reader". Browser will prompt for NFC permission → grant it. Tap any contactless card. Open the kiosk URL in Chrome on an Android phone (HTTPS required — see note below). Click "Tap to enable NFC reader". Browser will prompt for NFC permission → grant it. Tap any contactless card.
@@ -2424,7 +2424,7 @@ Then UPDATE the setup button click handler to also start the camera:
- [ ] **Step 2: Reload + smoke test on a real device** - [ ] **Step 2: Reload + smoke test on a real device**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init 2>&1 | tail -5 docker exec odoo-modsdev-app odoo -d modsdev -u fusion_clock --stop-after-init 2>&1 | tail -5
``` ```
On the Android phone with NFC, hard-refresh the kiosk page. Click activation button. Browser prompts for NFC, then for Camera. Grant both. Tap a contactless card. On the Android phone with NFC, hard-refresh the kiosk page. Click activation button. Browser prompts for NFC, then for Camera. Grant both. Tap a contactless card.
@@ -2634,13 +2634,13 @@ Then UPDATE the `window.__nfcKiosk` exposure at the bottom to include the enroll
- [ ] **Step 2: Reload + smoke test on real device** - [ ] **Step 2: Reload + smoke test on real device**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init 2>&1 | tail -5 docker exec odoo-modsdev-app odoo -d modsdev -u fusion_clock --stop-after-init 2>&1 | tail -5
``` ```
Set the enroll password: Set the enroll password:
```bash ```bash
docker exec -it odoo-dev-app odoo shell -d fusion-dev --no-http << 'EOF' docker exec -it odoo-modsdev-app odoo shell -d modsdev --no-http << 'EOF'
env['ir.config_parameter'].sudo().set_param('fusion_clock.nfc_enroll_password', '1234') env['ir.config_parameter'].sudo().set_param('fusion_clock.nfc_enroll_password', '1234')
env.cr.commit() env.cr.commit()
EOF EOF
@@ -2692,7 +2692,7 @@ In `fusion_clock/static/src/js/fusion_clock_nfc_kiosk.js`, immediately BEFORE th
- [ ] **Step 2: Enable debug mode and verify** - [ ] **Step 2: Enable debug mode and verify**
```bash ```bash
docker exec -it odoo-dev-app odoo shell -d fusion-dev --no-http << 'EOF' docker exec -it odoo-modsdev-app odoo shell -d modsdev --no-http << 'EOF'
env['ir.config_parameter'].sudo().set_param('fusion_clock.nfc_kiosk_debug', 'True') env['ir.config_parameter'].sudo().set_param('fusion_clock.nfc_kiosk_debug', 'True')
env.cr.commit() env.cr.commit()
EOF EOF
@@ -2705,7 +2705,7 @@ Hard-refresh the kiosk page. Click activation. Once at IDLE, press Ctrl+Shift+T.
- [ ] **Step 3: Disable debug mode again** - [ ] **Step 3: Disable debug mode again**
```bash ```bash
docker exec -it odoo-dev-app odoo shell -d fusion-dev --no-http << 'EOF' docker exec -it odoo-modsdev-app odoo shell -d modsdev --no-http << 'EOF'
env['ir.config_parameter'].sudo().set_param('fusion_clock.nfc_kiosk_debug', 'False') env['ir.config_parameter'].sudo().set_param('fusion_clock.nfc_kiosk_debug', 'False')
env.cr.commit() env.cr.commit()
EOF EOF
@@ -2746,14 +2746,14 @@ to:
- [ ] **Step 2: Reload one final time** - [ ] **Step 2: Reload one final time**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init 2>&1 | tail -10 docker exec odoo-modsdev-app odoo -d modsdev -u fusion_clock --stop-after-init 2>&1 | tail -10
``` ```
If the asset cache appears stale (CSS not updating, old JS), follow the CLAUDE.md escalation: If the asset cache appears stale (CSS not updating, old JS), follow the CLAUDE.md escalation:
```bash ```bash
docker exec -it odoo-dev-app psql -U odoo -d fusion-dev -c "DELETE FROM ir_attachment WHERE url LIKE '/web/assets/%';" docker exec -it odoo-modsdev-app psql -U odoo -d modsdev -c "DELETE FROM ir_attachment WHERE url LIKE '/web/assets/%';"
docker exec odoo-dev-app odoo -d fusion-dev -u fusion_clock --stop-after-init docker exec odoo-modsdev-app odoo -d modsdev -u fusion_clock --stop-after-init
``` ```
Then in the browser, DevTools → right-click refresh → "Empty Cache and Hard Reload". Then in the browser, DevTools → right-click refresh → "Empty Cache and Hard Reload".
@@ -2761,7 +2761,7 @@ Then in the browser, DevTools → right-click refresh → "Empty Cache and Hard
- [ ] **Step 3: Run the full test suite one last time** - [ ] **Step 3: Run the full test suite one last time**
```bash ```bash
docker exec odoo-dev-app odoo -d fusion-dev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -50 docker exec odoo-modsdev-app odoo -d modsdev --test-tags fusion_clock --stop-after-init -u fusion_clock 2>&1 | tail -50
``` ```
Expected: 0 failures, 0 errors across all NFC tests. Expected: 0 failures, 0 errors across all NFC tests.