Files
famlaw/activeblue_familylaw/CLAUDE.md

21 KiB
Raw Blame History

CLAUDE.md — activeblue_familylaw

This file gives Claude Code the context it needs to work effectively on this project. Read this before making any changes.


What This Is

ActiveBlue Family Law (activeblue_familylaw) is a custom Odoo 18 Community module for Florida family law case management targeting pro se litigants and full law firm operations in Miami-Dade County (11th Circuit).

The module runs an entire law firm within Odoo: intake, case tracking, AI-assisted legal research, paralegal task management, discovery, court document generation, billing, and case closure. It is not a lightweight helper — it is the primary practice management system.

Repo: https://git.activeblue.net/tocmo0nlord/famlaw Module root: activeblue_familylaw/ Author: Active Blue LLC — https://avc.activeblue.net Odoo version: 18.0 License: LGPL-3


Deployment Context

Item Value
Odoo instance 192.168.2.9:8069 (Docker, local network only)
Target database db1 (accessed at 192.168.2.9:8069 — no public hostname)
Odoo version 18.0 Community
AI inference Claude API — claude-sonnet-4-20250514
Git remote https://git.activeblue.net/tocmo0nlord/famlaw

Note: This instance is local-only on the 192.168.2.x network. There is no external hostname or reverse proxy for this deployment. Traefik is not in use here. All access is direct to 192.168.2.9:8069. Do not reference CT 112, 192.168.1.53, or avc.activeblue.net for this module.


AI Agent Architecture

This module uses two distinct AI agents backed by the Claude API (claude-sonnet-4-20250514). Both agents write to the fl.case chatter for full auditability. All API calls must handle anthropic.APIError and anthropic.APIConnectionError gracefully — never let AI failures block user workflow. Log failures to chatter as a warning.

Paralegal Agent (fl_paralegal_agent.py)

Handles procedural intelligence. Runs automatically on case stage transitions and can be triggered manually from any case.

Responsibilities:

  • Florida Rules of Civil Procedure deadline calculation (service by mail +5 days, holidays excluded via Python holidays library, judicial holidays for 11th Circuit)
  • Task batch generation per stage (see Stage Machine below)
  • Statute cross-reference for active issue tags on the case
  • Mandatory disclosure checklist generation (FL-12.932)
  • Chatter summary after every bulk action
  • Non-billable AI time logging to fl.timesheet for audit trail

Prompt strategy: always include case_type, complexity, issue_tag_ids, active deadlines, and current stage. Keep system prompt under 800 tokens — pass case context as user message.

Attorney Agent (fl_attorney_agent.py)

Handles substantive legal reasoning. Fires on demand (button on AI tab of fl.case). Never runs automatically — always a deliberate user action.

Responsibilities:

  • Full case questionnaire analysis → strategy memo stored in fl.analysis
  • Top 35 applicable FL statutes identified and linked to fl.statute records
  • Top 35 relevant case law entries linked to fl.caselaw records
  • Argument drafting for the case's primary issue tags
  • Risk flag narrative (DV, hidden assets, income imputation, unrepresented respondent)
  • Child support modification: auto-detect substantial change of circumstances (§61.30(1)(b)), pull last 3 years of support schedule from case history

Prompt strategy: include full intake questionnaire responses, parties, children, financial data summary, and any prior fl.analysis records so the agent builds on prior work.

Rule-Based Fallback

Both agents fall back to rule-based logic when the Claude API is unavailable. The fallback must cover: complexity scoring, basic deadline calculation, and a minimal task batch. Never surface a raw API error to the user.


Module Structure

activeblue_familylaw/
├── __manifest__.py
├── __init__.py
├── models/
│   ├── fl_ai_engine.py               ← Shared Claude API client + retry logic
│   ├── fl_paralegal_agent.py         ← Paralegal AI agent (procedural)
│   ├── fl_attorney_agent.py          ← Attorney AI agent (substantive)
│   ├── fl_analysis.py                ← AI analysis records
│   ├── fl_argument.py                ← Legal argument tracking
│   ├── fl_case.py                    ← Core case model (fl.case) + stage machine
│   ├── fl_caselaw.py                 ← FL case law library
│   ├── fl_child.py                   ← Minor children records
│   ├── fl_conflict_check.py          ← Conflict of interest check engine
│   ├── fl_deadline.py                ← Procedural deadline tracking + auto-calc
│   ├── fl_deposition.py              ← Deposition scheduling
│   ├── fl_discovery.py               ← Discovery requests/responses
│   ├── fl_document.py                ← Court document management
│   ├── fl_efiling.py                 ← FL 11th Circuit e-filing portal integration
│   ├── fl_expense_case.py            ← Case-linked expense tracking
│   ├── fl_fee_waiver.py              ← Fee waiver eligibility
│   ├── fl_hearing.py                 ← Hearing calendar integration
│   ├── fl_income_withholding.py      ← Income withholding orders
│   ├── fl_party.py                   ← Petitioner/Respondent parties
│   ├── fl_signature_request.py       ← E-signature workflow (external, spec-compliant)
│   ├── fl_statute.py                 ← FL statute reference index
│   ├── fl_support.py                 ← FL 61.30 child support calc
│   └── fl_timesheet.py               ← Billable hours + AI audit time (wraps account.analytic.line)
├── wizard/
│   ├── fl_intake_wizard.py               ← Guided case creation + fires Attorney agent on finish
│   ├── fl_analysis_wizard.py             ← Trigger AI analysis
│   ├── fl_generate_packet_wizard.py      ← Generate filing packet
│   ├── fl_discovery_suggest_wizard.py    ← Complexity-driven discovery suggestions
│   └── fl_efiling_wizard.py              ← Prepare and submit to FL e-Filing Portal
├── views/
│   ├── fl_case_views.xml                 ← Kanban + form + list views, stage bar
│   ├── fl_conflict_check_views.xml
│   ├── fl_discovery_suggest_views.xml
│   ├── fl_efiling_views.xml
│   ├── fl_signature_request_views.xml
│   ├── fl_timesheet_views.xml
│   ├── menu_views.xml
│   ├── portal_*.xml                      ← Client-facing portal templates
│   └── website_intake_templates.xml
├── report/                               ← 12 QWeb PDF court documents
│   ├── report_financial_affidavit_short.xml   ← FL-12.902(b)
│   ├── report_financial_affidavit_long.xml    ← FL-12.902(c)
│   ├── report_child_support_worksheet.xml     ← FL-12.902(e)
│   ├── report_motion_to_modify.xml
│   ├── report_notice_deposition.xml
│   ├── report_motion_to_compel.xml
│   ├── report_income_withholding.xml
│   ├── report_fee_waiver.xml
│   ├── report_notice_ssn.xml                  ← FL-12.930(a)
│   ├── report_mandatory_disclosure.xml        ← FL-12.932
│   ├── report_default_motion.xml
│   └── report_parenting_plan.xml
├── data/
│   ├── fl_support_schedule.xml       ← Basic Support Obligation table
│   ├── fl_statute_data.xml           ← FL statute index seeds
│   ├── fl_caselaw_data.xml           ← 23 pre-loaded FL cases
│   ├── fl_deadline_rules.xml         ← Procedural deadline rules
│   ├── fl_issue_tags.xml             ← Issue taxonomy
│   ├── fl_stage_data.xml             ← Case stage records (Kanban)
│   ├── ir_sequence.xml               ← Case number sequences
│   ├── mail_templates.xml
│   └── case_task_templates.xml
├── security/
│   ├── fl_security.xml
│   └── ir.model.access.csv
├── controllers/                      ← Portal + website intake + e-filing webhook routes
└── static/src/
    ├── css/familylaw_portal.css
    └── js/
        ├── fl_calculator.js          ← Interactive FL 61.30 widget
        └── fl_timeline.js            ← Visual case timeline

Core Domain Models

All models use the fl. prefix.

Model Description
fl.case Root entity — case type, parties, status, stage, AI complexity score
fl.party Petitioner or Respondent (links to res.partner)
fl.child Minor children on the case
fl.support FL 61.30 child support calculation
fl.deadline Procedural deadlines with calendar sync + auto-calculation
fl.hearing Scheduled hearings
fl.discovery Individual discovery requests/responses
fl.discovery.suggest.wizard Complexity-driven discovery suggestion engine
fl.discovery.suggest.line One suggested discovery item
fl.deposition Deposition scheduling and tracking
fl.document Court-filed documents (linked to reports)
fl.analysis AI case analysis records (both agents write here)
fl.caselaw Florida case law library entries
fl.statute FL statute reference index
fl.fee.waiver Fee waiver eligibility and form data
fl.income.withholding Income withholding order records
fl.argument Legal argument tracking (linked to case law)
fl.conflict.check Conflict of interest check result per intake
fl.signature.request E-signature request linked to a court document
fl.efiling.submission FL e-Filing Portal submission record
fl.timesheet Billable hours + AI audit entries (wraps account.analytic.line)

Key Fields on fl.case

  • case_type: modification | dissolution | paternity
  • stage_id: Many2one fl.case.stage — drives Kanban and Paralegal agent task batches
  • complexity: low | medium | high | extreme (set by Attorney agent or rule-based fallback)
  • issue_tag_ids: Many2many fl.issue.tag — used by both agents and discovery suggestion wizard
  • domestic_violence_flag, respondent_has_counsel, income_imputation_concern: boolean flags that affect discovery templates and Attorney agent prompt
  • conflict_check_passed: Boolean — case cannot move past Intake stage until True
  • attorney_memo_id: Many2one fl.analysis — current Attorney agent strategy memo

Case Stage Machine

Stages are defined in fl_stage_data.xml and drive the Kanban view on fl.case. Each stage transition triggers the Paralegal agent to generate the next task batch.

Stage Trigger Paralegal Task Batch Generated
Intake Case created Conflict check, questionnaire completion, fee waiver assessment
Active Intake complete + conflict check passed Service of process, mandatory disclosure (FL-12.932), initial hearings
Discovery Attorney fires analysis; complexity ≥ medium Interrogatories, production requests, depositions per discovery suggest wizard
Pre-Trial Discovery closed Pretrial statement, exhibit list, witness list, mediation scheduling
Closed Final order filed Archive checklist, billing reconciliation, file retention notice

Stage transitions validate preconditions (e.g., cannot enter Active without conflict_check_passed). Use _check_stage_transition() on fl.case — raise UserError with a clear message, never silent.


Conflict of Interest Check (fl_conflict_check.py)

Run automatically on fl.case creation before any other action.

Logic:

  1. Collect name from all fl.party records on the new case (petitioner + respondent).
  2. Query all active fl.party records on other open cases.
  3. Check for name overlap (exact + fuzzy — use difflib.SequenceMatcher, threshold 0.85).
  4. If a match is found: create a fl.conflict.check record with status = 'conflict', log to chatter with matched case reference, and set fl.case.conflict_check_passed = False.
  5. If no match: set status = 'clear' and conflict_check_passed = True automatically.
  6. A user with group fl_group_manager can manually override a conflict with a written justification stored on the fl.conflict.check record.

Never silently pass a conflict. Always surface it to the user.


E-Signature Workflow (fl_signature_request.py)

Important: Odoo Sign is not within spec for Florida court document e-signatures. Florida courts require specific PDF/A-compliant documents with court-approved signature fields per the FL Supreme Court Administrative Order AOSC09-30 (amended). Do not use Odoo Sign for court filings.

Architecture:

  • fl.signature.request links to one fl.document and one res.partner (signer).
  • On creation, generate the QWeb PDF, flatten form fields except the signature block, and store as ir.attachment with mimetype = 'application/pdf'.
  • The signature block coordinates are document-type-specific — define them in a _SIGNATURE_COORDS dict keyed by report template XML ID:
    _SIGNATURE_COORDS = {
        'activeblue_familylaw.report_financial_affidavit_short': {'page': 1, 'x': 72, 'y': 680, 'w': 200, 'h': 30},
        # ... one entry per report
    }
    
  • Delivery: email the PDF to the signer via Odoo mail with a portal link. The portal page (/familylaw/sign/<token>) uses an HTML5 canvas signature pad (no external JS dependency — draw to canvas, export as PNG, embed via PyMuPDF into the PDF at the defined coordinates).
  • On completion: write signature PNG into the PDF at correct coordinates, update fl.signature.request.state = 'signed', attach the signed PDF to fl.document, and log to chatter.
  • For documents going to the FL e-Filing Portal, the signed PDF must pass: pikepdf validation for PDF/A compliance before submission is allowed.

Never use DocuSign, HelloSign, or any external e-signature SaaS — all processing must be self-hosted per HIPAA and data sovereignty requirements.


FL 11th Circuit E-Filing Integration (fl_efiling.py)

The Florida Courts e-Filing Portal (eportal.flcourts.org) exposes a REST API. Full programmatic filing is the target; the current phase implements preparation and assisted submission.

Phase 1 (current): Assisted submission

  • fl_efiling_wizard.py walks the user through preparation steps.
  • Auto-generate the court-compliant filename per 11th Circuit convention: {LastName}_{CaseNumber}_{DocumentType}_{YYYYMMDD}.pdf Example: Smith_2024-DR-012345_MotionToModify_20240915.pdf
  • Validate PDF/A compliance via pikepdf before allowing submission.
  • One-click button opens eportal.flcourts.org deep-linked to the correct case (append ?caseNumber={fl.case.court_case_number} if available).
  • Store fl.efiling.submission record with status pending_manual.

Phase 2 (planned): API submission

  • FL e-Filing Portal API endpoint: https://api.eportal.flcourts.org/ (confirm current base URL from portal documentation before implementing).
  • Authentication: username/password token exchange stored in ir.config_parameter (keys: fl_efiling.username, fl_efiling.password) — never hardcoded.
  • On successful API submission: update fl.efiling.submission.status = 'submitted', store the portal confirmation number, log to chatter.
  • On failure: log full error to chatter, set status failed, surface error message to user — never silent failure.

Deadline Engine (fl_deadline.py)

_compute_due_date() must handle:

  • Florida Rules of Civil Procedure Part II service windows:
    • 20-day answer period after service
    • 45-day mandatory disclosure window (FL-12.932)
    • 30-day response to interrogatories
    • Service by mail: add 5 days (Fla. R. Civ. P. 1.090(e))
  • Holiday exclusion: use Python holidays library with holidays.US(state='FL') plus 11th Circuit judicial holidays (hardcode the annual list in fl_deadline_rules.xml and merge at runtime).
  • _recalculate_all(case_id): callable by Paralegal agent — recalculates all open deadlines on a case when a new event is logged (hearing date set, service confirmed, etc.).
  • Calendar sync: write to calendar.event for every fl.deadline — use _sync_to_calendar() called in create and write.

Time Tracking + Billing (fl_timesheet.py)

fl.timesheet wraps account.analytic.line and adds case context.

Key fields:

  • case_id: Many2one fl.case (required)
  • employee_id: Many2one hr.employee
  • is_billable: Boolean (default True; False for AI audit entries)
  • ai_agent: Selection paralegal | attorney | None — set when the Paralegal or Attorney agent auto-logs time
  • duration_hours: Float (maps to unit_amount on account.analytic.line)

Usage:

  • Attorneys and paralegals log time manually from the case form (Timesheet tab).
  • Both AI agents log non-billable entries automatically for audit trail.
  • The case form shows a computed total_billable_hours and total_billable_amount (rate from hr.employee or a default firm rate in ir.config_parameter).
  • Invoicing flows through standard Odoo Accounting — account.analytic.line entries are picked up by account.move generation as usual.

Odoo Dependencies

Declared in __manifest__.py:

'depends': [
    'base', 'mail', 'portal', 'website',
    'contacts', 'calendar', 'project',
    'crm', 'account', 'hr_expense', 'analytic',
    # 'sign'      — DO NOT enable: not within FL court e-signature spec
    # 'queue_job' — OCA, install separately if needed for async AI calls
]

sign is intentionally excluded — Florida court e-signatures require custom PDF handling outside Odoo Sign's capabilities. queue_job is optional for async Claude API calls.


Development Conventions

Odoo 18 Patterns

  • Use fields.Html for rich text, fields.Text for plain
  • @api.depends for computed fields; always set store=True if used in search/group
  • Use _inherit not _name for extending existing Odoo models
  • All new models need entries in ir.model.access.csv AND fl_security.xml
  • XML IDs must be unique across the module — prefix everything with fl_

Views

  • Actions must be declared before <menuitem> references in menu_views.xml
  • Portal templates go in views/portal_*.xml
  • Website intake templates go in views/website_intake_templates.xml
  • Always test QWeb reports with wkhtmltopdf — paper sizes matter for court forms
  • Kanban view on fl.case must show: case number, case type, complexity badge, next deadline, and conflict check status badge

Claude API (fl_ai_engine.py)

  • Use the anthropic Python library — pip install anthropic
  • API key stored in ir.config_parameter key fl_ai.claude_api_key — never hardcoded
  • Model: always claude-sonnet-4-20250514 — do not make this a user-configurable field
  • Always handle anthropic.APIError, anthropic.APIConnectionError, anthropic.RateLimitError
  • Log all AI calls (model, tokens used, latency) to chatter as an internal note
  • Use the rule-based fallback in fl_ai_engine._fallback_complexity() when API unavailable
  • Never block user workflow on AI failure

Discovery Suggest Wizard

  • Add new discovery templates to _get_templates() in fl_discovery_suggest_wizard.py
  • Each template: type, directed_to, description, rationale, trigger, min_complexity
  • Triggers are string labels — keep consistent with existing ones
  • action_create_selected posts a chatter summary — keep it

Reports (QWeb)

  • Court form dimensions: US Letter (8.5×11 in) — set paperformat_id appropriately
  • Florida court forms reference: FL Supreme Court forms at www.flcourts.gov
  • Field labels must match official form labels exactly
  • All reports used for e-filing must be PDF/A compliant — validate with pikepdf in CI

Security Groups

Group Access
fl_group_user Create/edit own cases, read all
fl_group_paralegal All of above + manage deadlines, tasks, discovery
fl_group_attorney All of above + fire Attorney agent, manage arguments
fl_group_manager Full access + conflict override + billing

Out of Scope for This Repo

  • Odoo AI agent / Master AI system → tocmo0nlord/odoo-ai (separate repo)
  • IRC bot → tocmo0nlord/irc-bot
  • Infrastructure config → handled at Docker/network layer, not this module
  • HIPAA training eLearning module → different Odoo addon
  • Traefik configuration → not in use on .2.1 network for this module

Running / Testing

# Restart Odoo to pick up module changes
docker compose restart odoo

# Update module (from Odoo container or Settings → Apps)
# Technical → Update Apps List first if adding new files

# Check logs
docker compose logs -f odoo | grep activeblue_familylaw

# Validate PDF/A compliance on a generated report (requires pikepdf)
python3 -c "import pikepdf; pdf = pikepdf.open('/tmp/test.pdf'); print(pdf.docinfo)"

Module installs via Apps → Upload a Module or by placing it in the addons path. After any model change: Settings → Activate Developer Mode → Technical → Update Apps List → Upgrade.

Claude API key setup

# In Odoo shell (Settings → Technical → Parameters → System Parameters)
# Key: fl_ai.claude_api_key
# Value: sk-ant-...