utility-app/scripts/build-legal-profile-from-ol...

193 lines
5.9 KiB
Python

import json
import re
import subprocess
from pathlib import Path
OLD_APP = Path("/mnt/storage/sftp/mcelwain/repository/word-doc-generator")
DRAFT_PROFILE = Path("diagnostics/legacy_word_doc_generator_profile_draft.json")
OUT_PROFILE = Path("tools/doc_generator/content/document_types/legal_profile.json")
TEMPLATES_OUT = Path("tools/doc_generator/content/templates/legacy")
OLD_PUBLIC = OLD_APP / "public"
def run_node_list_extractor():
js = f"""
import {{ pathToFileURL }} from 'url';
const files = [
'casePlaintiffInfo.js',
'opposingCounselInfo.js',
'judgeInfo.js',
'caseFilingAttorneyInfo.js',
'filingAttorneyInfo.js',
'debtCollectorInfo.js'
];
const base = {json.dumps(str(OLD_PUBLIC))};
const result = {{}};
for (const file of files) {{
try {{
const mod = await import(pathToFileURL(`${{base}}/${{file}}`).href);
for (const [exportName, value] of Object.entries(mod)) {{
if (value && typeof value === 'object' && !Array.isArray(value)) {{
result[exportName] = Object.keys(value).sort();
}}
}}
}} catch (err) {{
// Some optional info files may not exist.
}}
}}
console.log(JSON.stringify(result));
"""
try:
completed = subprocess.run(
["node", "--input-type=module", "-e", js],
check=True,
capture_output=True,
text=True,
)
return json.loads(completed.stdout)
except Exception:
return {}
def nice_label(name):
label = re.sub(r"([a-z])([A-Z])", r"\1 \2", name)
label = label.replace("_", " ").replace("-", " ")
label = re.sub(r"\bSsn\b", "SSN", label.title())
label = label.replace("Dob", "DOB")
return label
def apply_legal_field_metadata(field):
name = field["name"]
lower = name.lower()
# Normalize generated labels.
field["label"] = nice_label(name)
# Autocomplete fields.
if name == "casePlaintiff":
field["type"] = "autocomplete"
field["list"] = "plaintiffs"
elif name == "caseOpposingCounsel":
field["type"] = "autocomplete"
field["list"] = "opposingCounsel"
elif name == "caseDivisionJudge":
field["type"] = "autocomplete"
field["list"] = "judges"
elif name == "caseFilingAttorney":
field["type"] = "autocomplete"
field["list"] = "filingAttorneys"
elif re.fullmatch(r"debtCollector\d+Name", name):
field["type"] = "autocomplete"
field["list"] = "debtCollectors"
elif lower.endswith("state") or name in {"caseState", "homeState", "client2homeState"}:
field["type"] = "autocomplete"
field["list"] = "states"
elif name == "caseDesignation":
field["type"] = "autocomplete"
field["list"] = "caseDesignations"
# Long text fields.
if name in {"notes", "caseAppearanceInfo", "paymentOptions", "paymentOptions1", "paymentOptions2", "paymentOptions3", "paymentOptions4", "paymentOptions5"}:
field["type"] = "textarea"
return field
def walk_sections(sections):
for section in sections:
section["collapsible"] = section.get("heading") not in {
"Client Information",
"Case Information",
}
section["defaultOpen"] = section.get("heading") in {
"Client Information",
"Case Information",
}
section["fields"] = [
apply_legal_field_metadata(field)
for field in section.get("fields", [])
]
for subsection in section.get("subsections", []):
walk_sections([subsection])
def discover_templates():
templates = []
for path in sorted(TEMPLATES_OUT.rglob("*.docx")):
rel = path.relative_to(Path("tools/doc_generator/content/templates")).as_posix()
template_id = re.sub(r"[^a-zA-Z0-9]+", "_", path.stem).strip("_").lower()
label = path.relative_to(TEMPLATES_OUT).as_posix()
label = label.replace(".docx", "")
label = label.replace("/", " / ")
label = label.replace("_", " ")
templates.append({
"id": template_id,
"label": label,
"template": rel,
"outputFilename": f"{template_id}_{{caseNumber}}_{{timestamp_YYYY-MM-DD_HH-mm-ss}}.docx"
})
return templates
def main():
if not DRAFT_PROFILE.exists():
raise SystemExit(f"Missing {DRAFT_PROFILE}. Run review-old-word-doc-generator.py first.")
draft = json.loads(DRAFT_PROFILE.read_text(encoding="utf-8"))
lists_raw = run_node_list_extractor()
lists = {
"plaintiffs": lists_raw.get("casePlaintiffInfo", []),
"opposingCounsel": lists_raw.get("caseOpposingCounselInfo", []) or lists_raw.get("opposingCounselInfo", []),
"judges": lists_raw.get("judgeInfo", []),
"filingAttorneys": lists_raw.get("caseFilingAttorneyInfo", []) or lists_raw.get("filingAttorneyInfo", []),
"debtCollectors": lists_raw.get("debtCollectorInfo", []),
"states": ["MO", "KS"],
"caseDesignations": [
"Associate Circuit",
"Circuit",
"Limited Actions",
"Small Claims"
]
}
sections = draft["sections"]
walk_sections(sections)
templates = discover_templates()
profile = {
"id": "legal_profile",
"name": "Legal Profile",
"description": "Consumer debt defense legal profile generated from the legacy word-doc-generator app.",
"template": templates[0]["template"] if templates else "legacy/Canned-Emails.docx",
"outputFilename": "legal_{caseNumber}_{timestamp_YYYY-MM-DD_HH-mm-ss}.docx",
"lists": lists,
"templates": templates,
"sections": sections
}
OUT_PROFILE.parent.mkdir(parents=True, exist_ok=True)
OUT_PROFILE.write_text(json.dumps(profile, indent=2), encoding="utf-8")
print(f"Wrote {OUT_PROFILE}")
print(f"Lists: {', '.join(f'{k}={len(v)}' for k, v in lists.items())}")
print(f"Templates: {len(templates)}")
if __name__ == "__main__":
main()