CL6/CL7 AI self-check engine
- New fusion.repair.ai.service AbstractModel with single guardrailed
suggest_self_check(category_id, symptoms, urgency) entry point.
- Hard-escalation FIRST (before any AI call): stairlift / porch lift +
safety symptoms (smoke / burning / spark / stuck / motor), OR any
mention of fire / injury / hurt / bleeding / trapped, OR urgency=safety
-> escalate immediately regardless of AI availability.
- AI call via fusion.api.service.call_openai() (consumer='fusion_repairs',
feature='client_self_triage') with try/fallback per project rule -
no hard fusion_api dep, no install error if it's missing.
- Strict response validation: JSON schema check, max 3 steps, max 200
chars per field, forbidden-phrase regex (diagnose, you have, medical
condition, stop using, consult doctor, price patterns) - on any
failure falls back to deterministic rules.
- 24h in-memory cache keyed by (category, symptom_hash) so repeat calls
during AI cost-cap incidents come from cache.
- System prompt + JSON schema published as ir.config_parameter so office
can refine without code changes (default prompt + schema in spec
Appendix A).
- New fusion.repair.self.check.rule model + 17 seeded rules across all
7 product categories (data/self_check_data.xml) - these are the
deterministic fallback AND the canonical seed if AI is disabled.
- New /repair/self_check jsonrpc route (auth=public) gated by the
per-IP rate-limit; defensive input bounds (max 5 symptoms, 500 chars
each) defend against prompt-injection bloat.
CL15 weekend safety escalation + on-call paging
- New fusion.repair.on.call.service AbstractModel with:
* find_next_on_call(exclude=...) -> lowest x_fc_on_call_priority
* page_on_call(repair) -> sends mail to next available + writes
x_fc_on_call_token / x_fc_on_call_paged_user_id / paged_at on the
repair, posts chatter
* acknowledge(repair, user) -> records ack, posts chatter
* cron_escalate_unacknowledged() -> every 5 min, re-pages the next
priority for repairs paged >15 min ago without ack
- Auto-fires from intake service whenever x_fc_urgency='safety' is
submitted. _is_business_hours() defaults to "page" when no calendar
is set or after working hours.
- New email_template_on_call_page with 4px red accent + acknowledge
CTA button linking to /repair/on-call/ack/<token>.
- /repair/on-call/ack/<token> http route (auth=user, must be the paged
manager OR any internal user) records the ack and renders confirmation.
- 5-minute cron 'Fusion Repairs: Escalate unacknowledged on-call pages'
with configurable window via fusion_repairs.on_call_escalate_minutes
(default 15).
- New repair.order fields x_fc_on_call_token, x_fc_on_call_paged_user_id,
x_fc_on_call_paged_at, x_fc_on_call_acknowledged_user_ids,
x_fc_on_call_acknowledged_at - all copy=False so duplicates start fresh.
CL17 QR sticker generator
- New fusion.repair.qr.sticker.wizard TransientModel takes a Many2many
of stock.lot records (optionally filtered by product).
- QWeb PDF report fusion_repairs.report_qr_stickers prints a 4-up
sticker sheet on letter paper: 80mm x 50mm per sticker with the
QR code (38mm), product name, serial number, and the canonical
portal URL (from web.base.url + fusion_repairs.client_portal_url).
- QR encodes /repair?sn=<serial> which the public client portal
already pre-fills via the ?sn= query param.
- Uses the qrcode library if available; renders 'QR lib missing'
placeholder otherwise so the PDF still prints.
- New menu Configuration > Generate QR Stickers + standalone wizard.
Verified end-to-end on local westin-v19:
CL6 stairlift+smoke -> escalate=True source=escalated reason=safety
CL6 bed (no AI) -> fallback returned escalate=True (safe default)
CL15 admin paged for RO-202605-10 with 27-char token
CL17 sticker URL: /repair?sn=001124032521528404
QR data URI: data:image/png;base64,iVBORw... (PNG OK)
Bumped to 19.0.1.2.0 (minor bump - new public-facing capabilities).
Co-authored-by: Cursor <cursoragent@cursor.com>
3.7 KiB
3.7 KiB
| 1 | id | name | model_id:id | group_id:id | perm_read | perm_write | perm_create | perm_unlink |
|---|---|---|---|---|---|---|---|---|
| 2 | access_repair_product_category_user | Repair Category User Read | model_fusion_repair_product_category | group_fusion_repairs_user | 1 | 0 | 0 | 0 |
| 3 | access_repair_product_category_manager | Repair Category Manager Full | model_fusion_repair_product_category | group_fusion_repairs_manager | 1 | 1 | 1 | 1 |
| 4 | access_repair_intake_template_user | Intake Template User Read | model_fusion_repair_intake_template | group_fusion_repairs_user | 1 | 0 | 0 | 0 |
| 5 | access_repair_intake_template_manager | Intake Template Manager Full | model_fusion_repair_intake_template | group_fusion_repairs_manager | 1 | 1 | 1 | 1 |
| 6 | access_repair_intake_question_user | Intake Question User Read | model_fusion_repair_intake_question | group_fusion_repairs_user | 1 | 0 | 0 | 0 |
| 7 | access_repair_intake_question_manager | Intake Question Manager Full | model_fusion_repair_intake_question | group_fusion_repairs_manager | 1 | 1 | 1 | 1 |
| 8 | access_repair_intake_answer_user | Intake Answer User Full | model_fusion_repair_intake_answer | group_fusion_repairs_user | 1 | 1 | 1 | 0 |
| 9 | access_repair_intake_answer_manager | Intake Answer Manager Full | model_fusion_repair_intake_answer | group_fusion_repairs_manager | 1 | 1 | 1 | 1 |
| 10 | access_repair_intake_answer_tech_portal | Intake Answer Technician Read | model_fusion_repair_intake_answer | fusion_tasks.group_field_technician | 1 | 0 | 0 | 0 |
| 11 | access_repair_intake_wizard_user | Intake Wizard User Full | model_fusion_repair_intake_wizard | group_fusion_repairs_user | 1 | 1 | 1 | 1 |
| 12 | access_repair_intake_wizard_equipment_user | Intake Wizard Equipment User Full | model_fusion_repair_intake_wizard_equipment | group_fusion_repairs_user | 1 | 1 | 1 | 1 |
| 13 | access_repair_service_catalog_user | Catalogue User Read | model_fusion_repair_service_catalog | group_fusion_repairs_user | 1 | 0 | 0 | 0 |
| 14 | access_repair_service_catalog_manager | Catalogue Manager Full | model_fusion_repair_service_catalog | group_fusion_repairs_manager | 1 | 1 | 1 | 1 |
| 15 | access_repair_warranty_user | Warranty User Read | model_fusion_repair_warranty_coverage | group_fusion_repairs_user | 1 | 0 | 0 | 0 |
| 16 | access_repair_warranty_manager | Warranty Manager Full | model_fusion_repair_warranty_coverage | group_fusion_repairs_manager | 1 | 1 | 1 | 1 |
| 17 | access_repair_visit_report_wizard_user | Visit Report Wizard User | model_fusion_repair_visit_report_wizard | group_fusion_repairs_user | 1 | 1 | 1 | 1 |
| 18 | access_repair_visit_report_wizard_line_user | Visit Report Line User | model_fusion_repair_visit_report_wizard_line | group_fusion_repairs_user | 1 | 1 | 1 | 1 |
| 19 | access_repair_maintenance_user | Maintenance Contract User Read | model_fusion_repair_maintenance_contract | group_fusion_repairs_user | 1 | 0 | 0 | 0 |
| 20 | access_repair_maintenance_dispatcher | Maintenance Contract Dispatcher | model_fusion_repair_maintenance_contract | group_fusion_repairs_dispatcher | 1 | 1 | 1 | 0 |
| 21 | access_repair_maintenance_manager | Maintenance Contract Manager Full | model_fusion_repair_maintenance_contract | group_fusion_repairs_manager | 1 | 1 | 1 | 1 |
| 22 | access_repair_order_repairs_user | Repair Order Repairs User Read/Write | repair.model_repair_order | group_fusion_repairs_user | 1 | 1 | 1 | 0 |
| 23 | access_repair_order_repairs_manager | Repair Order Repairs Manager Full | repair.model_repair_order | group_fusion_repairs_manager | 1 | 1 | 1 | 1 |
| 24 | access_technician_task_repairs_user | Technician Task Repairs User Schedule | fusion_tasks.model_fusion_technician_task | group_fusion_repairs_user | 1 | 1 | 1 | 0 |
| 25 | access_technician_task_repairs_manager | Technician Task Repairs Manager Full | fusion_tasks.model_fusion_technician_task | group_fusion_repairs_manager | 1 | 1 | 1 | 1 |
| 26 | access_repair_self_check_rule_user | Self-Check Rule User Read | model_fusion_repair_self_check_rule | group_fusion_repairs_user | 1 | 0 | 0 | 0 |
| 27 | access_repair_self_check_rule_manager | Self-Check Rule Manager Full | model_fusion_repair_self_check_rule | group_fusion_repairs_manager | 1 | 1 | 1 | 1 |
| 28 | access_qr_sticker_wizard_user | QR Sticker Wizard User Full | model_fusion_repair_qr_sticker_wizard | group_fusion_repairs_user | 1 | 1 | 1 | 1 |