From c93728209191e0e3210d983305f9c9700d0ece46 Mon Sep 17 00:00:00 2001 From: tocmo0nlord Date: Thu, 28 May 2026 03:40:33 +0000 Subject: [PATCH] Upload files to "activeblue_familylaw" --- activeblue_familylaw/CLAUDE.md | 362 ++++++++++++++++++++++++++------- 1 file changed, 291 insertions(+), 71 deletions(-) diff --git a/activeblue_familylaw/CLAUDE.md b/activeblue_familylaw/CLAUDE.md index 97ced44..82282b7 100644 --- a/activeblue_familylaw/CLAUDE.md +++ b/activeblue_familylaw/CLAUDE.md @@ -8,7 +8,12 @@ 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** in Miami-Dade County (11th Circuit). +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/` @@ -22,13 +27,63 @@ License: LGPL-3 | Item | Value | |---|---| -| Odoo instance | `odoo.activeblue.net` (Docker, multi-tenant) | -| Target database | `avc` (accessed via `avc.activeblue.net`) | +| 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 | Ollama at `192.168.2.9:11434` | -| Reverse proxy | Traefik on CT 112 (`192.168.1.53`) | +| 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 3–5 applicable FL statutes identified and linked to `fl.statute` records +- Top 3–5 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 @@ -38,35 +93,46 @@ activeblue_familylaw/ ├── __manifest__.py ├── __init__.py ├── models/ -│ ├── fl_ai_engine.py ← Ollama-powered case analysis -│ ├── fl_analysis.py ← AI analysis records -│ ├── fl_argument.py ← Legal argument tracking -│ ├── fl_case.py ← Core case model (fl.case) -│ ├── fl_caselaw.py ← FL case law library -│ ├── fl_child.py ← Minor children records -│ ├── fl_deadline.py ← Procedural deadline tracking -│ ├── fl_deposition.py ← Deposition scheduling -│ ├── fl_discovery.py ← Discovery requests/responses -│ ├── fl_document.py ← Court document management -│ ├── 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_statute.py ← FL statute reference index -│ └── fl_support.py ← FL 61.30 child support calc +│ ├── 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 -│ ├── 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_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 +│ ├── 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 +│ ├── portal_*.xml ← Client-facing portal templates │ └── website_intake_templates.xml -├── report/ ← 12 QWeb PDF court documents +├── 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) @@ -80,23 +146,24 @@ activeblue_familylaw/ │ ├── 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 -│ ├── ir_sequence.xml ← Case number sequences +│ ├── 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 routes +├── 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 + ├── fl_calculator.js ← Interactive FL 61.30 widget + └── fl_timeline.js ← Visual case timeline ``` --- @@ -107,49 +174,176 @@ All models use the `fl.` prefix. | Model | Description | |---|---| -| `fl.case` | Root entity — case type, parties, status, AI complexity score | +| `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 | +| `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 | +| `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` -- `complexity`: `low` | `medium` | `high` | `extreme` (set by AI engine or rule-based fallback) -- `issue_tag_ids`: Many2many `fl.issue.tag` — used by AI engine and discovery suggestion wizard +- `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 + 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 --- -## AI Engine +## Case Stage Machine -`fl_ai_engine.py` calls **Ollama** for case analysis. +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. -- Ollama endpoint: `http://192.168.2.9:11434` -- Used for: complexity scoring, case law relevance, argument generation -- Rule-based fallback when Ollama is unavailable -- Analysis results stored in `fl.analysis` records -- AI tab on `fl.case` form shows current analysis + trigger button +| 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 | -The discovery suggestion wizard (`fl_discovery_suggest_wizard.py`) reads AI complexity or falls -back to rule-based logic. It has 50+ templates across 10 trigger categories: -`base`, `modification`, `dissolution`, `paternity`, `alimony`, `custody`, -`imputation` (Barner v. Barner), `self_employment`, `domestic_violence`, -`respondent_counsel`, `complex_only`. +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: + ```python + _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/`) 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. --- @@ -160,14 +354,14 @@ Declared in `__manifest__.py`: 'depends': [ 'base', 'mail', 'portal', 'website', 'contacts', 'calendar', 'project', - 'crm', 'account', 'hr_expense', - # 'sign' — enable when confirmed installed - # 'queue_job' — OCA, install separately if needed + '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` and `queue_job` are commented out intentionally — do not add them back without -confirming they're installed on the target instance. +`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. --- @@ -185,22 +379,37 @@ confirming they're installed on the target instance. - 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 the `_get_templates()` method in `fl_discovery_suggest_wizard.py` -- Each template has: `type`, `directed_to`, `description`, `rationale`, `trigger`, `min_complexity` -- Triggers are string labels — keep them consistent with existing ones +- 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 -### AI Engine -- Always handle `requests.exceptions.ConnectionError` from Ollama gracefully -- Use the rule-based fallback when Ollama is down — never let AI failures block user workflow -- Log AI calls to chatter on `fl.case` for auditability - ### 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 the official form labels exactly +- 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 | --- @@ -208,8 +417,9 @@ confirming they're installed on the target instance. - Odoo AI agent / Master AI system → `tocmo0nlord/odoo-ai` (separate repo) - IRC bot → `tocmo0nlord/irc-bot` -- Traefik / infrastructure config → CT 112 directly +- 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 --- @@ -224,7 +434,17 @@ docker compose restart odoo # 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 +```bash +# In Odoo shell (Settings → Technical → Parameters → System Parameters) +# Key: fl_ai.claude_api_key +# Value: sk-ant-... +```