Files
famlaw/activeblue_familylaw/models/fl_analysis.py
tocmo0nlord 7bc0cc8554 Add conflict-of-interest check engine; gate stage advancement at Intake
- New fl.conflict.check model: screens petitioner/respondent/party_ids names
  against parties on other open cases (exact partner match + difflib fuzzy
  match at 0.85 threshold); skips folded/closed stages
- Runs automatically as the first action in fl.case.create; logs conflicts to
  chatter with matched-case detail and never silently passes
- fl.case gains conflict_check_passed/conflict_check_id/conflict_check_ids;
  write() blocks advancing stage_id past Intake until the check passes
- Admin-only action_override requires a written justification, stamps user/date,
  and flips conflict_check_passed True with a chatter audit entry
- Add conflict check form/tree/search views, action, Cases sub-menu item,
  case form banner + Run Conflict Check button, and Kanban conflict badge
- ACL entries for fl.conflict.check (admin full, paralegal no-delete)
- Finish Claude migration cleanup in fl_analysis.py (model_used default,
  docstring/help text)
- Add .gitignore for Python artifacts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 18:19:32 +00:00

77 lines
2.5 KiB
Python

from odoo import fields, models
class FlAnalysis(models.Model):
"""AI case analysis record. Written by the Claude API engine (fl.ai.engine)."""
_name = 'fl.analysis'
_description = 'AI Case Analysis Result'
_order = 'create_date desc'
case_id = fields.Many2one(
'fl.case', ondelete='cascade', index=True
)
analysis_date = fields.Datetime(
string='Analysis Date',
default=fields.Datetime.now
)
model_used = fields.Char(
string='AI Model',
default='claude-sonnet-4-20250514'
)
# ── Results (referenced by fl_case related fields) ─────────────────────
attorney_referral_flag = fields.Boolean(
string='Attorney Referral Recommended',
default=False
)
attorney_referral_reason = fields.Text(
string='Attorney Referral Reason'
)
plain_english_summary = fields.Text(
string='Plain English Summary (EN)',
help='3-5 sentence summary of case analysis — no legal jargon'
)
plain_english_summary_es = fields.Text(
string='Plain English Summary (ES)',
help='Resumen en español — sin jerga legal'
)
# ── Analysis Detail (Phase 5) ──────────────────────────────────────────
petitioner_arguments = fields.Text(
string='Petitioner Arguments (JSON)'
)
respondent_counterarguments = fields.Text(
string='Respondent Counter-Arguments (JSON)'
)
procedural_risks = fields.Text(
string='Procedural Risks (JSON)'
)
matched_caselaw_ids = fields.Many2many(
'fl.caselaw',
'fl_analysis_caselaw_rel',
'analysis_id', 'caselaw_id',
string='Matched Case Law'
)
confidence_level = fields.Selection([
('high', 'High'),
('medium', 'Medium'),
('low', 'Low'),
], string='Confidence Level')
case_complexity = fields.Selection([
('simple', 'Simple'),
('moderate', 'Moderate'),
('complex', 'Complex'),
], string='Case Complexity')
raw_response = fields.Text(
string='Raw AI Response',
help='Full JSON response from the Claude API — for debugging'
)
error_message = fields.Text(
string='Error (if analysis failed)'
)
state = fields.Selection([
('pending', 'Pending'),
('complete', 'Complete'),
('failed', 'Failed'),
], string='Status', default='pending')