Align case stages to 5-stage spec and add Paralegal AI agent
Stage alignment: - Replace the 11 procedural stages with the spec's 5-stage machine (Intake/Active/Discovery/Pre-Trial/Closed); only Closed is folded - Make fl_stage_data.xml updatable (drop noupdate) so the rename applies on upgrade; keep fl_stage_intake/discovery/closed XML ids - Update case search filters to the new stage names (Intake/Active/Discovery/Pre-Trial) Issue-tag bug fix (fl_ai_engine): - Rule-based tagging and caselaw matching compared snake_case keys against the human-readable seeded tag names, so they never matched and issue_tag_ids was never populated. Add RULE_KEY_TO_TAG_NAME and translate keys to real names before all fl.issue.tag / fl.caselaw lookups Paralegal agent (fl.paralegal.agent, AbstractModel): - on_stage_change(): fast rule-based pass fired automatically on stage entry and case creation — generates the stage task batch (idempotent), recalculates filing/service deadlines, cross-references statutes by issue tag + case type, posts a chatter summary. No Claude call, so it never blocks the workflow - run_manual(): full pass adding a best-effort Claude procedural briefing with rule-based fallback; wired to a "Paralegal Review" button on the case form - AI audit-time logging is guarded behind a fl.timesheet existence check (model not built yet) - fl.case.write fires on_stage_change only when stage_id actually changes; create() generates the Intake batch Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -824,9 +824,12 @@ class FlCase(models.Model):
|
||||
# 4. Handle DV flag
|
||||
if record.domestic_violence_flag:
|
||||
record._handle_dv_flag()
|
||||
# 5. Paralegal agent — generate the Intake stage task batch
|
||||
self.env['fl.paralegal.agent'].on_stage_change(record)
|
||||
return records
|
||||
|
||||
def write(self, vals):
|
||||
stage_changed_recs = self.browse()
|
||||
# Block advancing past Intake until conflict check has passed
|
||||
if vals.get('stage_id'):
|
||||
new_stage = self.env['fl.case.stage'].browse(vals['stage_id'])
|
||||
@@ -841,7 +844,13 @@ class FlCase(models.Model):
|
||||
"conflict-of-interest check has not passed. Resolve or "
|
||||
"override the conflict before changing the stage."
|
||||
) % rec.name)
|
||||
stage_changed_recs = self.filtered(
|
||||
lambda r: r.stage_id.id != new_stage.id
|
||||
)
|
||||
result = super().write(vals)
|
||||
# Fire the paralegal agent (rule-based) when a case enters a new stage
|
||||
for rec in stage_changed_recs:
|
||||
self.env['fl.paralegal.agent'].on_stage_change(rec)
|
||||
# Recalculate service-anchored deadlines when service_date is set/changed
|
||||
if 'service_date' in vals:
|
||||
for rec in self:
|
||||
@@ -1136,3 +1145,17 @@ class FlCase(models.Model):
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
def action_run_paralegal(self):
|
||||
self.ensure_one()
|
||||
self.env['fl.paralegal.agent'].run_manual(self)
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'title': _('Paralegal Agent'),
|
||||
'message': _('Procedural review complete — see the case chatter.'),
|
||||
'type': 'success',
|
||||
'sticky': False,
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user