Initial skills documentation — 25 categories, all SKILL.md + references + scripts

This commit is contained in:
root
2026-07-15 17:42:20 -04:00
commit 1b4fcd4427
976 changed files with 188344 additions and 0 deletions
@@ -0,0 +1,130 @@
# Agent D.R.E — Chatbot Specification
## Architecture
- **Name:** Agent D.R.E (Debt Recovery Expert)
- **Knowledge base:** Built once by Claude Opus 4.7 from DRE docs
- **Runtime:** Llama 3.2 3B (local, Ollama on Core) — ~$0.0002/query
- **Lead capture:** Name + email required before unlocking
## Client States
### New Visitor (not logged in)
- Lead capture form displayed on chat open
- Bot asks for: name, company, email, phone (name + email required)
- "Start Chat" button records lead data and unlocks conversation
- Only public FAQ answers (no case-specific data)
### Logged-in Client
- Greeting personalized: "Welcome back, {Company}! Your claim against {Debtor} is in Tier {N} ({TierName}). I can answer questions or send a message to your recovery team."
- Shows active claim info: claim number, debtor name, current tier
- Buttons: My case status, Next steps, 📨 Message team
- Can answer: current tier, timeline estimate, document upload assistance
- PII verification: asks for claim number before sharing case-sensitive details
### Returning Visitor (not logged in — cookie ok)
- Cookie-based greeting remembered
- Lead form still required for new session
## Personality Traits (Hard Rules)
1. **Empathetic** — Acknowledge the stress of unpaid invoices. "I understand — unpaid invoices create real pressure."
2. **Kind but firm** — Never apologize for DRE's process or fees. Supportive without being a pushover.
3. **Engaging** — Ask a leading question after every answer to keep the conversation moving. "How long has this been outstanding?" "What kind of work was done?"
4. **No promises** — Never guarantee outcome, timeline, or amount. Use: "typically," "most claims," "can be." Never: "definitely," "guaranteed," "will."
5. **No internal methods** — Never reveal AI scoring methodology, skip tracing techniques, or compliance strategy.
6. **PII verification** — Before sharing case-specific details, require claim number to verify identity.
## Reply Templates
### Fee Question
```
I understand — fees matter. Here's how it works: early
resolution (Tier 1) is 20%, and it goes up from there
based on effort required. You can use our Fee Calculator
to see exactly what you'd receive at each tier.
How much is your claim for?
```
### Timeline Question
```
Most claims at this level resolve within 30 days, but
it really depends on how the debtor responds. Some pay
quickly at Tier 1 — others need a certified letter.
Has this been outstanding for a while?
```
### Required Docs
```
The basics: a copy of the contract, proof of delivery
or completed work, and any invoices or correspondence
showing the debt.
If you're ready, you can upload those right on the
Submit Claim form. Need the link?
```
### Tier/Status (Logged-In)
```
Your claim against {Debtor} is currently in Tier {N} —
{TierName}. A {action} was sent on {date}. That means
this tier wraps up around {date}.
```
### Next Steps (Logged-In)
```
After Tier {N} wraps up, we move to Tier {N+1} ({Name})
where we {action}. That typically prompts payment from
debtors who've been stalling. Most cases resolve by
Tier {N} without needing a lawyer.
```
### Document Upload (Logged-In)
```
You can upload additional documents right from your
dashboard — there's a + Upload Document button on
your active claim.
```
### Out of Scope
```
That's a great question — it's a bit outside what I can
help with here. If you'd like, you can submit a claim
and our team will review it.
Ready to get started?
```
### PII Verification Gate (Case-Specific)
```
To share case-specific details, I'll need to confirm
your identity first. Can you provide the claim number
from your welcome email?
```
### General Fallback
```
That's a good question. I want to make sure you get
the right answer. Would you like to submit a claim
so our team can review your specific situation?
```
## Message to Team Form
| Field | Options |
|-------|---------|
| Subject | Dropdown: Question about my claim, New info about debtor, Payment received/stop recovery, Update contact info, Complaint/concern, Other |
| Body | Free text textarea (3 rows) |
| Action | Send → logs to case file + notifies DRE team |
Production: message logs to case DB and sends notification to DRE team via email/Telegram.
Confirmation message: "📨 Message sent! Your team will review it during business hours."
## Knowledge Base Separation
**PUBLIC (chatbot answers):** Fee structure, required docs, timelines, Texas construction lien overview, LPOA process, ACH payments, how to submit a claim, contact info, fee calculator link, TOS/Privacy link.
**PRIVATE (NEVER in chatbot):** AI scoring methodology, skip tracing techniques, internal weakness criteria, approval workflow, specific case data, partner firm names, fee negotiation limits, FDCPA/TDCA strategy, internal notes.
@@ -0,0 +1,38 @@
# BlueNotary vs OneNotary — DRE Evaluation (Jul 7, 2026)
## BlueNotary
| Criteria | Finding |
|----------|---------|
| **Trustpilot** | 4.7/5.0 from 1,100+ reviews |
| **BBB** | Profile exists — no red flags |
| **API access** | ❌ No public docs. "REST API" claimed on site but "See API Docs" button loops to /integrations. All dev subdomains 404. API is enterprise-only, sales-gated. |
| **Pricing** | Business Pro $37-47/seat/mo (yearly/monthly). 2 free sessions/seat/mo. Additional: $10/session, $5/additional signer. |
| **API on $37 plan?** | ❌ No — API access is enterprise/custom only |
| **Texas compliance** | Claims 50-state coverage. Notary pool of 20,000+ from 40+ states. |
| **Security** | Claims SOC 2 Type II, HIPAA, MISMO |
| **Support** | 24/7 live chat, phone during business hours |
| **White-label** | Promoted (Branded Portal, Custom Workflows) — enterprise only |
| **Verdict** | 🔴 Not suitable for self-serve API integration. No published endpoints, no sandbox. |
## OneNotary
| Criteria | Finding |
|----------|---------|
| **Trustpilot** | 5.0/5.0 from 3,222 reviews |
| **BBB** | Profile exists — clean |
| **API access** | ✅ Public developer portal at dev.onenotary.us. REST endpoints, webhooks, embedded widgets. Not sales-gated. |
| **Pricing** | Pay-as-you-go: $25/session, $0/mo. Business Pro: ~$49-65/mo. |
| **API on pay-as-you-go?** | ✅ Yes — API available, portal has embedded integration options |
| **Texas compliance** | ✅ Dedicated TX page, Texas-licensed notaries |
| **Security** | SOC 2, ISO 27001, MISMO |
| **DocuSign** | Official DocuSign Notary On-Demand partner |
| **Support** | 24/7, email + live chat |
| **White-label** | Available on Business Pro tier |
| **Verdict** | ✅ Best RON provider for DRE. Start pay-as-you-go, upgrade when volume justifies. |
## Recommendation
**Start with OneNotary pay-as-you-go ($0/mo, $25/session).** Contact their sales for API documentation (they have a developer portal). When volume reaches 3+ claims/month, evaluate their Business Pro plan (~$49-65/mo).
BlueNotary's $37/mo plan looks cheaper but lacks API access. The per-signer cost advantage ($10 vs $25) is small at low volume and doesn't justify the missing API.
@@ -0,0 +1,43 @@
# Competitor Website Research: B2B Debt Collection Agency Homepages
**Date:** July 7, 2026
**Method:** Live browser analysis (browser_navigate + browser_vision + browser_snapshot) of each site's homepage
**Research output:** `/root/top5-debt-recovery-websites-research.md` (full 18KB report)
## Sites Analyzed
| # | Site | Type | Est. | Colors |
|---|------|------|------|--------|
| 1 | **IC System** (icsystem.com) | National debt recovery agency | 85 yrs | Navy + gold |
| 2 | **Cadex Solutions** (cadexsolutions.com) | Enterprise O2C/AR management | 95 yrs | Dark green/black |
| 3 | **Chaser** (chaserhq.com) | AR automation SaaS | ~10 yrs | Orange + blue |
| 4 | **TSI/Transworld** (tsico.com) | Tech-enabled revenue recovery | Large | Navy + white |
| 5 | **Caine & Weiner** (caine-weiner.com) | Global receivables management | 95 yrs | Blue + yellow |
## Key Findings for DRE
### What All 5 Have in Common
- Hero with large headline + primary CTA
- Years-in-business as #1 trust signal
- Client logo bars (Cadex strongest with 20+ Fortune 500 logos)
- Stats/counters on the homepage
- Very few people photos — abstract patterns and icons dominate
- "Ethical", "compliant", "cash flow" as top positioning words
### Color Palette Convergence
Navy/blue dominates (4/5). Gold/amber accents common. **DRE's navy + amber is right on-brand.** Cadex is the only dark-theme outlier — closest to DRE's existing dark portal.
### DRE Differentiation Opportunities (gaps across all 5)
1. **Amber + navy at scale** — no competitor uses this combo boldly
2. **Texas / Lone Star identity** — no competitor uses regional branding
3. **Real-time dashboard hero imagery** — no competitor shows a live dashboard
4. **Same-day/local service messaging** — no competitor emphasizes this
### Quick Reference: Trust Signals Ranked
1. Client logos (Cadex: 20+ Fortune 500)
2. Years in business (IC System: 85, Caine & Weiner: 95, Cadex: 95)
3. Animated stats/counters (TSI, Chaser)
4. Testimonials with recognizable brands (Caine & Weiner: Kroger, Pitney Bowes)
5. Compliance certifications (TSI: HITRUST, SOC 2, NIST)
6. CEO message with photo (Caine & Weiner)
7. ROI Calculator (Chaser — interactive tool, unique)
@@ -0,0 +1,59 @@
# IMAP-to-IMAP Mailbox Migration — SiteGround → MXroute
Migrated Jul 8, 2026: garrison@iamgmb.com (324 msgs) and greyson@iamgmb.com (74 msgs).
## SiteGround IMAP Discovery
- Host: c1113726.sgvps.net:993
- SiteGround uses `.` as folder separator (not `/`)
- Folders listed as `INBOX.Trash`, `INBOX.Sent Messages`, etc.
- IMAP LIST response format: `(flags) "." "INBOX.Trash"`
- Parsing: `decoded.rsplit('"', 2)[-2]` to extract the folder name
- The same SiteGround IP serves as the SMTP relay for all hosted domains
## Folder Mapping (SiteGround → MXroute)
| SiteGround | MXroute |
|-----------|---------|
| `INBOX` | `INBOX` |
| `INBOX.Sent Messages` + `INBOX.Sent` | `Sent` |
| `INBOX.Trash` + `INBOX.Deleted Messages` | `Trash` |
| `INBOX.spam` + `INBOX.Junk` | `Junk` |
| `INBOX.Drafts` | `Drafts` |
| `INBOX.Archive` | `Archive` |
## Count Per Folder (garrison@)
| Folder | Count |
|--------|-------|
| INBOX | 170 |
| INBOX.Trash | 118 |
| INBOX.Deleted Messages | 30 |
| INBOX.Sent Messages | 5 |
| INBOX.Sent | 1 |
## Migration Script Pattern
```python
old = imaplib.IMAP4_SSL(old_host, 993)
old.login(email, old_pw)
new = imaplib.IMAP4_SSL(new_host, 993)
new.login(email, new_pw)
# Select folder with quoting for spaces
old.select('"INBOX"')
uids = old.search(None, "ALL")[1][0].split()
for uid in uids:
r = old.fetch(uid, "(RFC822)")
if r[0] == "OK" and isinstance(r[1][0], tuple):
new.append("INBOX", None, None, r[1][0][1])
```
## Pitfalls
- SiteGround server can timeout on batches >170 msgs
- MXroute folders must be created BEFORE appending
- No IMAP deduplication on APPEND — multiple runs create duplicates
- UIDs differ between servers; append doesn't preserve old UIDs
- Test with a small batch first to catch timeout issues
- Verify ALL folders and message counts after migration
@@ -0,0 +1,106 @@
# Demand Letter Management Page
*Last updated: 2026-07-07*
## Overview
Single-file HTML mockup (`dre-demand-letters.html`) for managing DRE demand letters. Covers the full lifecycle: draft → needs approval → ready to send → sent.
## Sections
### 1. Pending Letters Table
- Filter tabs: All / Draft / Needs Approval / Ready to Send / Sent
- Columns: Claim # (mono amber), Debtor, Status badge, Authored By, Edit action
- Pending count badge in header
- Empty state when no letters match filter
### 2. Letter Composer (Left Panel)
- Claim info bar: claim #, debtor name, amount, tier, status badge, author
- Full-width textarea with mock demand letter content
- Action buttons: Regenerate with AI, Submit for Approval, Send Now
### 3. AI Chat Sidebar (Right Panel, 360px)
- Agent DRE header with online status dot
- Chat message area with user/agent styled bubbles
- 3 preset buttons: "Make it firmer", "Add lien language", "Shorten to 1 paragraph"
- Simulated AI responses that actually modify the letter text: firmer tone, lien clauses, condensed content, friendlier language
### 4. Approval Panel
- Shows author name, submitted timestamp
- **Anita-authored letters:** "Waiting on Tony or Germaine" banner, Approve/Reject buttons
- **Tony/Germaine-authored letters:** "Ready to Send" auto-approved, disabled buttons
- Rejection flow: textarea for reason, confirmation dialog, status returns to draft
### 5. Sent History (Collapsible)
- Columns: Date Sent, Debtor, Claim, Status (opened/paid/returned), Sent To
- Chevron toggle animation
### 6. Global Elements
- **Confirm dialog:** Modal overlay for destructive actions (approve, reject, send)
- **Toast notifications:** Animated slide-in, auto-dismiss (3.5s)
- **Header:** D|R|E industrial logo, page title, user badge (Germaine Admin), dark toggle (stub)
## Approval Workflow Implementation
| Action | Source | Target | Condition |
|--------|--------|--------|-----------|
| New Letter | Draft | — | Starts as draft |
| Submit for Approval | Draft | Needs Approval | Author sets submittedAt |
| Approve | Needs Approval | Ready to Send | Only allows if authored by Anita (Tony/Germaine role assumed) |
| Reject | Needs Approval | Draft | Requires reason text |
| Send Now | Ready to Send | Sent | Appends to sent history |
Letters authored by Tony or Germaine skip the needs-approval step and go directly to ready-to-send.
## Chat Intent Detection
The AI chat sidebar parses user input to detect intent and modifies letter content accordingly:
| Intent | Trigger Words | Effect |
|--------|--------------|--------|
| firmer | firm, strong, aggressive, strict | Shortens payment window, strengthens language, adds FINAL NOTICE prefix |
| lien | lien, ucc, property | Appends UCC-1, judgment lien, Notice of Lien clauses |
| shorten | short, condense, brief, paragraph | Replaces entire letter with single-paragraph summary |
| friendlier | friendly, soft, gentle, kind | Replaces "demand" with "request", softens legal warnings |
| default | everything else | Generic "updated the draft" response |
## Dark Theme Convention
- **Background:** `#0b1121` / `#0f172a` (navy)
- **Cards:** `#0f172a` with `border-gray-800`
- **Accent:** `#f59e0b` (amber) for interactive elements, status badges in needs-approval state
- **Table rows:** `border-gray-800/50`, hover `bg-navy-800/40`
- **Selected row:** `bg-navy-800/60`
- **Chat user msg:** `bg-[#1e293b]` border `#334155`
- **Chat agent msg:** `bg-[#0f172a]` with amber border
## Status Badges
| Status | Class | Colors |
|--------|-------|--------|
| Draft | badge-draft | bg-gray-700 text-gray-400 |
| Needs Approval | badge-needs-approval | bg-amber-900/30 text-amber-300 |
| Ready to Send | badge-ready | bg-emerald-900/30 text-emerald-400 |
| Sent | badge-sent | bg-blue-900/30 text-blue-300 |
## Data Model (Mock)
```js
letter = {
id: Number,
claim: String, // "DRE-2026-0142"
debtor: String, // "Marcus Bellweather"
status: String, // "draft" | "needs-approval" | "ready-to-send" | "sent"
authoredBy: String, // "Anita Rodriguez" | "Tony Martelli" | "Germaine Vance"
amount: Number, // 12840.00
tier: String, // "Standard" | "Priority" | "Premium"
submittedAt: String, // ISO timestamp or null
content: String // Letter body text
}
```
## File Location
- Source: `/root/dre-demand-letters.html`
- Self-contained single HTML file with Tailwind CSS CDN and Font Awesome icons
- No build step — open directly in browser
@@ -0,0 +1,95 @@
# DRE Credential Audit — Jul 8, 2026
Full audit of every key, token, and password across the system.
## Credential Inventory
| # | Credential | Location | Type | Test Method | Status |
|---|-----------|----------|------|-------------|--------|
| 1 | FIRECRAWL_API_KEY | ~/.hermes/.env | API Key | POST to api.firecrawl.dev/v1/search | ✅ |
| 2 | CLOUDFLARE_API_TOKEN | ~/.hermes/.env | API Token | GET cloudflare.com/client/v4/user/tokens/verify | ✅ |
| 3 | admin-ai api_key | config.yaml (admin-ai provider) | API Key | POST to admin-ai /v1/chat/completions | ✅ |
| 4 | PG_DATABASE_PASSWORD | /root/docker/twenty/.env | DB Password | docker exec psql SELECT 1 | ✅ |
| 5 | ENCRYPTION_KEY | /root/docker/twenty/.env | Encryption Key | (validated by container health) | ✅ |
| 6 | MYSQL_PASS (Apex DB) | config.yaml (mcp_servers.mysql.env) | DB Password | mysql SELECT 1 via SSH tunnel | ✅ |
| 7 | g@germainebrown.com IMAP | ~/.config/himalaya/g-germainebrown.pass | IMAP Password | imaplib LOGIN | ✅ |
| 8 | shonuff@germainebrown.com IMAP | ~/.config/himalaya/shonuff.pass | IMAP Password | imaplib LOGIN | ✅ |
| 9 | iCloud calendar password | ~/.config/himalaya/g-germainebrown-icloud-calendar.pass | App-Specific | imaplib LOGIN to p02-imap.mail.me.com | ❌ Expired — replaced Jul 8 |
| 10 | DRE email IMAP (dre@ + collections@) | (no file — used inline in dre-mail-poller.py) | IMAP Password | imaplib LOGIN to heracles.mxrouting.net | ✅ |
## Audit Pattern (Reproducible)
### Step 1: Inventory
```bash
# Check .env
grep -v "^#\|^$" /root/.hermes/.env | cut -d= -f1
# Check .config password files
find /root/.config -name "*.pass" -o -name "*.pwd" -o -name "*.token"
# Check docker .env files
find /root/docker -name ".env" -exec basename {} \; 2>/dev/null
# Check config.yaml
grep -E "api_key|password|secret|token|_key|_pass" /root/.hermes/config.yaml | grep -v "skipped\|disabled\|cron_mode"
```
### Step 2: Test
```bash
# Firecrawl
curl -s -w "\nHTTP:%{http_code}" -X POST "https://api.firecrawl.dev/v1/search" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"query":"test","limit":1}' | tail -1
# Cloudflare
curl -s -w "\nHTTP:%{http_code}" -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
-H "Authorization: Bearer $TOKEN" | tail -1
# admin-ai
curl -s -w "\nHTTP:%{http_code}" "https://admin-ai.itpropartner.com/v1/chat/completions" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"model":"deepseek-chat","messages":[{"role":"user","content":"ping"}],"max_tokens":2}' | grep -o "HTTP:[0-9]*"
# IMAP password files
python3 -c "
import imaplib, ssl
with open('/root/.config/himalaya/FILE.pass') as f: pw = f.read().strip()
ctx = ssl.create_default_context()
s = imaplib.IMAP4_SSL('HOST', 993, ssl_context=ctx, timeout=10)
s.login('user@domain.com', pw)
print('LOGIN OK')
s.logout()
"
# PostgreSQL via docker
docker exec twenty-db-1 psql -U postgres -d default -c "SELECT 1 AS test"
# MySQL via tunnel
mysql -h 127.0.0.1 -P 33060 -u USER -pPASS --skip-ssl -e "SELECT 1 AS test"
```
### Step 3: Known Issues
1. **iCloud app passwords expire** — Apple app-specific passwords for iCloud Calendar/IMAP must be regenerated at appleid.apple.com whenever they stop working. File: `g-germainebrown-icloud-calendar.pass`. Always test against `p02-imap.mail.me.com:993`. Note: Apple's IMAP rejects app-specific passwords for iCloud mail — use CalDAV PROPFIND to test (`requests.request('PROPFIND', 'https://caldav.icloud.com/', auth=(user, pw))` returns 207 on success). The CalDAV principal URL format is `/1079451706/principal/` with calendar home at `p{xx}-caldav.icloud.com:443/1079451706/calendars/`.
2. **Cron has no session env** — credentials in session-only env vars (`source .env` in terminal) are invisible to cron. Scripts running from cron must use `${VAR:-$(grep ... .env)}` pattern or access a `.pass` file directly. The `CLOUDFLARE_API_TOKEN` was only in session env — added to `.env` on Jul 8 so the service health check cron could use it.
3. **Script-saved tokens get redacted** — when a script with an inline credential value is written to disk (e.g. via `>>>` heredoc or `write_file`), Hermes' secret redaction replaces the actual value with `***`. Verify scripts contain variable references, not inline values. The `service-health-check.sh` had `Authorization: Bearer ***` baked in because of this.**
4. **Caddy file permissions** — new files created with `write_file` default to `-rw-------` (600). Caddy runs as a non-root user and returns 403. Always run `chmod 644` on new HTML files in /var/www/. Both `login.html` and `index.html` needed this fix on Jul 8.
### Child Email Migration (garrison@iamgmb.com + greyson@iamgmb.com) — Jul 8
Migrated both boys' email accounts from SiteGround to MXroute:
| Account | Old Server | New Server | Messages |
|---------|-----------|-----------|----------|
| garrison@iamgmb.com | c1113726.sgvps.net:993 | heracles.mxrouting.net:993 | 324 (5 folders) |
| greyson@iamgmb.com | c1113726.sgvps.net:993 | heracles.mxrouting.net:993 | 74 (INBOX only) |
**DNS already correct — no changes needed.** MX records pointed to MXroute, SPF included mxroute.com, DKIM configured. SiteGround removal was clean.
### Delegation Model Update — Jul 8
| Level | Before | After |
|-------|--------|-------|
| Conversation | deepseek-chat (admin-ai) | deepseek-chat (no change) |
| Delegation primary | Claude Opus 4.7 | Claude Opus 4.7 (no change) |
| Fallback 1 | *(empty)* | **Claude Opus 4.8** (admin-ai) |
| Fallback 2 | *(empty)* | Llama 3.2 3B (ollama-local) |
Opus 4.8 tested and confirmed working via delegation subagent.
@@ -0,0 +1,31 @@
# DRE Credit Reporting — Legal Analysis
## Can DRE report debtors to credit bureaus?
### Consumer debts (individuals)
**Yes** — DRE can report to Equifax, Experian, TransUnion but must:
- Send FDCPA validation notice first
- Wait 30-day dispute window before reporting
- Comply with FCRA § 1681s-2 furnisher duties (accuracy, investigation on dispute)
- Follow Texas § 392.202 dispute process (30-day investigation)
- Maintain $10K surety bond with Texas SOS (§ 392.101)
### B2B debts — corporate debtors
**No** — FCRA defines "consumer" as an individual (§ 1681a(c)). Consumer CRAs don't maintain business credit files. Use Dun & Bradstreet, Experian Business, or Equifax Business instead.
### B2B debts — personal guarantors
**Yes** — individuals who signed personal guarantees are "consumers" under FCRA (per FTC Advisory Opinion to Tatelbaum). All FCRA/FDCPA rules apply.
### B2B debts — sole proprietors
**Yes** — a sole proprietor is an individual ("consumer"). Same rules as consumer debts.
### Liability risks
- Incorrect reporting → actual damages + attorney fees + punitive
- Failure to investigate dispute → $100-$1,000 per violation (FCRA § 1681n)
- Texas Finance Code § 392.403: $4K/violation
### Business credit bureaus (recommended for B2B)
- Dun & Bradstreet Global Trade Exchange (free)
- Experian Business
- Equifax Business
- No FCRA/FDCPA restrictions, no 7-year limitation
@@ -0,0 +1,48 @@
# DRE Mail IMAP Poller
A lightweight, no-dependency IMAP poller that checks DRE mailboxes and serves as a unified inbox JSON endpoint for the DRE portal.
## Script Location
`/root/.hermes/scripts/dre-mail-poller.py`
## How It Works
- Polls both `dre@debtrecoveryexperts.com` and `collections@debtrecoveryexperts.com` on `heracles.mxrouting.net:993`
- Fetches UNSEEN messages only (leaves them unread in the mailbox)
- Parses: from, to, subject, date, body (500-char preview + full body), claim_match (DRE-\d{4}-\d{4} pattern)
- Deduplicates by `mailbox:uid` composite key
- Maintains rolling 500-entry JSON database
- Writes to `/var/www/internal/data/dre-mails.json`
## Output Format
```json
[
{
"uid": 12345,
"mailbox": "dre",
"from": "client@example.com",
"to": "dre@debtrecoveryexperts.com",
"subject": "Question about my claim DRE-2026-0142",
"date": "2026-07-08 14:30:00",
"body_preview": "Hi, I had a question about the status of...",
"body": "Full body text...",
"is_read": false,
"claim_match": "DRE-2026-0142"
}
]
```
## Cron
Runs every 60 seconds via Hermes cron job `dre-mail-poller` (no_agent mode — zero token cost). The script is self-contained Python stdlib — no pip dependencies.
## Access
Served at `internal.debtrecoveryexperts.com/data/dre-mails.json` (already covered by existing Caddy config — no changes needed).
## Portal Integration
A future inbox UI page can fetch from this endpoint and render in the portal. No build step needed — pure JS fetch from the static JSON endpoint.
## Mailbox Credentials
- IMAP: heracles.mxrouting.net:993
- dre@debtrecoveryexperts.com / collections@debtrecoveryexperts.com
- Same password for both
@@ -0,0 +1,206 @@
# DRE Canned Letter Templates — Reference
## AUTOMATED (Items 1-3)
### 1. Initial Onboarding Email
**From:** dre@debtrecoveryexperts.com
**To:** Client
**Subject:** We've Received Your Claim — DRE-2026-XXXX
> Thank you for submitting your claim with Debt Recovery Experts.
>
> Your claim has been received and logged. Here's what happens next:
>
> **Claim ID:** DRE-2026-XXXX
> **Debtor:** [Debtor Name]
> **Amount:** $X,XXX.00
>
> **Next Step:** Our AI system is reviewing your documentation. You'll hear from us within 1 business day with an assessment of your claim.
>
> In the meantime, you can upload additional documents at:
> portal.debtrecoveryexperts.com
>
> — Debt Recovery Experts
### 2. Claim Being Reviewed
**From:** dre@debtrecoveryexperts.com
**To:** Client
**Subject:** Claim DRE-2026-XXXX — Under Review
> Your claim is now being reviewed. Our team has begun analyzing the documentation you provided.
>
> **Claim ID:** DRE-2026-XXXX
> **Debtor:** [Debtor Name]
> **Status:** Under Review
>
> We're evaluating:
> • Documentation quality and completeness
> • Debtor profile and ability to pay
> • Best recovery strategy based on claim type and amount
>
> We'll follow up within 2-3 business days with our recommended next steps.
>
> — Debt Recovery Experts
### 3. Claim Accepted — LPOA Enclosed
**From:** dre@debtrecoveryexperts.com
**To:** Client
**Subject:** Claim DRE-2026-XXXX — Accepted + LPOA Attached
> Great news — your claim has been reviewed and accepted. We believe we can recover this debt.
>
> **Enclosed please find the Limited Power of Attorney (LPOA)** authorizing Debt Recovery Experts to act on your behalf in collecting this debt. Please:
>
> 1. **Review** the LPOA document
> 2. **Sign and notarize** (most banks offer free notary services)
> 3. **Return** via portal upload or reply to this email
>
> **What we need from you:**
> • Signed + notarized LPOA (attached)
> • Any additional documentation you'd like us to consider
>
> **What happens after LPOA is returned:**
> We send a soft-touch demand to the debtor. Most claims at this stage resolve without escalation.
>
> — Debt Recovery Experts
>
> **Attachments:** LPOA_DRE-2026-XXXX.pdf
---
## QUEUED — EDIT + APPROVAL REQUIRED (Items 4-8)
*These letters require: Anita drafts/edits → Tony & Germaine approve → Sent via collections@debtrecoveryexperts.com*
### 4. Soft Touch — 1st Email (Tier 1)
**From:** collections@debtrecoveryexperts.com
**To:** Debtor
**Subject:** Outstanding Balance — [Debtor Company]
> This is a friendly reminder regarding an outstanding balance with one of our clients.
>
> **Client:** [Client Name]
> **Amount Due:** $X,XXX.00
> **Invoice Reference:** [Invoice #]
>
> We understand things get overlooked. Please remit payment or contact us to discuss a resolution within 5 business days.
>
> Payment can be made at: pay.debtrecoveryexperts.com
>
> This communication is from a debt collector. Any information obtained will be used for that purpose.
>
> — Debt Recovery Experts
### 5. Formal Demand (Tier 2)
**From:** collections@debtrecoveryexperts.com
**To:** Debtor
**Subject:** FORMAL DEMAND FOR PAYMENT — [Debtor Company]
> This letter constitutes formal demand for full payment of the outstanding balance described below.
>
> **Client:** [Client Name]
> **Amount Due:** $X,XXX.00
> **Invoice Reference:** [Invoice #]
>
> Despite previous attempts to resolve this matter amicably, the amount remains unpaid.
>
> PLEASE TAKE NOTICE that if the full balance is not received within fourteen (14) calendar days, we will proceed with escalated collection measures, including but not limited to:
> • Referral to our legal department
> • Filing of a civil suit to obtain judgment
> • Placement of liens against real or personal property
>
> Contact our offices immediately to arrange payment or discuss a resolution.
>
> This communication is from a debt collector attempting to collect a debt. Any information obtained will be used for that purpose.
>
> — Debt Recovery Experts
> Collections Department
> collections@debtrecoveryexperts.com
### 6. Lien Threat (Tier 2.5 — Texas Construction)
**From:** collections@debtrecoveryexperts.com
**To:** Debtor
**Subject:** NOTICE OF INTENT TO FILE LIEN — [Property/Project]
> This letter serves as formal notice of our intent to file a lien against the property described below.
>
> **Client:** [Client Name]
> **Property/Project:** [Address or Description]
> **Unpaid Amount:** $X,XXX.00
>
> Texas Property Code allows for the filing of a mechanic's lien against real property where improvements were made and remain unpaid. We have been authorized to take the following actions:
>
> • Filing a Sworn Statement of Account with the county clerk
> • Recording a mechanic's lien against the property
> • Pursuing foreclosure on the lien if necessary
>
> A mechanic's lien will:
> • Attach to the property title
> • Affect your ability to sell or refinance
> • Appear on title searches
>
> To avoid lien filing, full payment must be received within ten (10) calendar days.
>
> This communication is from a debt collector attempting to collect a debt. Any information obtained will be used for that purpose.
>
> — Debt Recovery Experts
> Collections Department
### 7. Escalation — Final Notice (Tier 3)
**From:** collections@debtrecoveryexperts.com
**To:** Debtor
**Subject:** FINAL NOTICE — IMMEDIATE ACTION REQUIRED
> ⚠️ FINAL NOTICE — This is your last opportunity to resolve this matter before legal action.
>
> **Client:** [Client Name]
> **Amount Due:** $X,XXX.00
> **Original Invoice Date:** [Date]
>
> Multiple attempts have been made to collect this debt. Despite these efforts, the full balance remains unpaid.
>
> **UNLESS FULL PAYMENT IS RECEIVED WITHIN TEN (10) CALENDAR DAYS,** we will:
> • Refer this matter to our legal counsel
> • Initiate civil litigation to obtain a judgment
> • Pursue all available post-judgment remedies, including wage garnishment, bank account levy, and asset seizure
> • Report this debt to credit reporting agencies
>
> You may be held liable for court costs, attorney's fees, and additional interest.
>
> Contact our offices immediately. This is your final opportunity to resolve this without court intervention.
>
> This communication is from a debt collector attempting to collect a debt. Any information obtained will be used for that purpose.
>
> — Debt Recovery Experts
> Collections Department
### 8. Legal Action Notice (Tier 4)
**From:** collections@debtrecoveryexperts.com
**To:** Debtor
**Subject:** LEGAL ACTION — [Court/Claim Reference]
> This letter confirms that your account has been referred for legal action.
>
> **Client:** [Client Name]
> **Amount Due:** $X,XXX.00
> **Legal Reference:** DRE-2026-XXXX
>
> Effective immediately, this matter has been forwarded to our legal counsel for lawsuit preparation. A civil petition will be filed seeking:
>
> • Judgment for the full amount owed
> • Pre-judgment interest as allowed by law
> • Court costs and filing fees
> • Attorney's fees
>
> Upon obtaining a judgment, we will pursue collection through all available legal channels, including:
> • Wage garnishment (up to 25% of disposable earnings)
> • Bank account levy
> • Lien against real property
> • Post-judgment discovery of assets
>
> All further communication regarding this matter should be directed to our legal counsel.
>
> This communication is from a debt collector attempting to collect a debt. Any information obtained will be used for that purpose.
>
> — Debt Recovery Experts
> Legal Liaison Division
@@ -0,0 +1,34 @@
# DRE Logo and Brand — July 2026
## Chosen Logo: Concept C — Industrial Separated
**Mark:** D | R | E — bold all-caps sans-serif with pipe separators.
**Colors:**
- D: #f59e0b (Amber 500)
- R: #94a3b8 (Slate 400)
- E: #f59e0b (Amber 500)
- Pipes: #cbd5e1 on light, #475569 on dark
**Full lockup:**
```
D | R | E
DEBT RECOVERY EXPERTS (small caps, 5px letter spacing)
```
**Typography:** Inter (or similar sans-serif). D and E at weight 800, R at weight 700. Pipes at weight 200.
**Minimum sizes:** 140px wide (mark only), 220px wide (with subtitle).
**Usage contexts:**
- Dark background (navy #0f172a) — amber D/E glow, slate R, dark pipes
- Light / white background — amber D/E, slate R, light pipes
- Favicon: 48px amber square with white D
**Rejected directions:** Shield monograms (too generic), Texas star (felt overused), full wordmark typography (less distinctive).
## Preferred Look and Feel
The DRE site should look like a modern professional debt recovery firm — not an aggressive collections agency.
Brand atmosphere: calm, professional, Texas-grounded, technology-enabled (not tech-centric).
@@ -0,0 +1,109 @@
# DRE Portal — Full Technical Specifications
## Claim Numbering & Client IDs
| Type | Format | Example |
|---|---|---|
| Claim number | `DRE-YYYY-NNNN` | DRE-2026-0001 |
| Client ID | `CLT-YYYY-NNNN` | CLT-2026-0001 |
Auto-generated on claim submission / account creation.
## Closed Case Binders
Two PDF binders auto-generated on case close:
**Binder 1 — DRE Internal:** `DRE-YYYY-NNNN_CLOSED_DRE.pdf`
- Intake form, uploaded evidence, AI claim analysis, AI debtor research, AI weakness analysis, internal team notes, signed/notarized LPOA, certified mail receipts, communication log, settlement agreement, fee disclosure, payment confirmation
**Binder 2 — Client Package:** `DRE-YYYY-NNNN_CLOSED_Client.pdf`
- Claim summary, signed/notarized LPOA, settlement/payment confirmation, fee statement
- **EXCLUDES:** AI analysis, debtor research, internal notes
**Evidence Archive:** `DRE-YYYY-NNNN_evidence.zip` — original uploaded documents
PDF text is extracted on close and stored in database for full-text search.
## Full 5-Phase Workflow
### Phase 1 — Intake
- Client at debtrecoveryexperts.com fills intake form
- Form order: Your Info (name, business, email, phone) → Debtor Info → Claim Details → Document Upload
- Google reCAPTCHA verification before submit
- ToS signed via DocuSeal
- Claim number auto-assigned, enters DRE queue
### Phase 2 — AI Review
- AI Claim Analysis (Claude Opus 4.7) → score 0-100 + weakness analysis
- AI Debtor Research (ScrapingAnt + Sherlock) → LinkedIn, property records, legal history
- Texas SoS business search (if debtor is registered TX business)
- Team reviews → Approve / Request More Docs / Reject
### Phase 3 — Legal Setup
- LPOA sent via DocuSeal → notarized via Proof (online RON)
- DRE now authorized to collect
### Phase 4 — Tiered Recovery
| Tier | Action | Timeline | DRE-led? |
|---|---|---|---|
| 1 | Soft Touch — email + ACH link | Day 1-5 | ✅ Yes |
| 2 | Formal Demand — certified mail via LetterStream | Day 7-14 | ✅ Yes |
| 2.5 | Lien Threat — pre-lien notice (construction claims) | Day 15-21 | ⚠️ Notice only; filing needs attorney |
| 3 | Escalation — final notice | Day 21-30 | ✅ Yes |
| 4 | Legal Action — referral to partner law firm | Day 30+ | ❌ Referral |
### Phase 5 — Settlement
- Payment via Stripe ACH
- Fee deducted per schedule
- Costs deducted (notary, certified mail, filing fees)
- Balance disbursed → case closed → two binders auto-generated
## Fee Structure
| Tier | DRE Fee | Client Gets |
|---|---|---|
| 1 — Soft Touch | 20-25% | 75-80% |
| 2 — Formal Demand | 30% | 70% |
| 2.5 — Lien Threat | 30% (+ attorney if filed) | 70% |
| 3 — Escalation | 33% | 67% |
| 4 — Legal Action | 10% DRE + 25% law firm | 65% |
**$15,000 example:**
- Tier 1: DRE $3,300 (22%) · Client $11,700
- Tier 2: DRE $4,500 (30%) · Client $10,500
- Tier 3: DRE $4,950 (33%) · Client $10,050
- Tier 4: DRE $1,500 + Firm $3,750 · Client $9,750
## Repeat Clients
- Account system with login
- ToS signed once per client
- Pre-filled info on new claims
- Dashboard: active cases (tier progress bar), past cases with outcomes, payment history
- Download own case binders
- Optional loyalty pricing after 3+ claims
## Client Tier Progress Indicator
Visual 4-step bar in active claim card:
- Numbered circles (green=complete, blue=current, gray=pending)
- Connecting lines between circles
- Label centered under each circle
- Text summary: "✓ Tier 1 complete · Tier 2 in progress · Tier 3 pending · Tier 4 pending"
## Required Services (not yet configured)
| Service | Purpose | Status |
|---|---|---|
| Proof.com | Online notarization | ❌ Need account |
| LetterStream | Certified mail | ❌ Need account |
| Stripe Connect | ACH payments | ❌ Need keys |
| Partner law firm | Litigation (Tier 4) | ❌ Need agreement |
| Google reCAPTCHA | Anti-spam | ❌ Need site key |
## Texas Secretary of State Integration
AI Debtor Research scrapes TX SoS business search for:
- Business status, registered agent, filing date, annual report status, officers/directors
- Informs debtor profile score component
@@ -0,0 +1,25 @@
# DRE — Systems & Roles Guide
## Access Overview
| Person | CRM | Internal Dashboard | Approvals |
|--------|-----|-------------------|-----------|
| **Germaine** | Full admin | Full access | Yes — all cases & letters |
| **Tony** | Full admin (same as Germaine) | Full access | Yes — all cases & letters |
| **Anita** | Read-only | No access | No |
## Email Addresses
| Address | Display Name | Purpose |
|---------|-------------|---------|
| **hello@debtrecoveryexperts.com** | Debt Recovery Experts | General inquiries, daily business |
| **collections@debtrecoveryexperts.com** | Debt Recovery Experts | Debtor-facing — demand letters, payment links, collection updates |
| **dre@debtrecoveryexperts.com** | Debt Recovery Experts | Client-facing — DocuSeal signing requests, claim status updates, fee receipts, portal login links |
## Key URLs
| Service | URL | Login Method |
|---------|-----|-------------|
| DRE CRM | crm.debtrecoveryexperts.com | Email magic link (via Cloudflare Access) |
| DRE Portal (public) | portal.debtrecoveryexperts.com | None — public pages |
| DRE Internal | internal.debtrecoveryexperts.com | Email via Cloudflare Access |
@@ -0,0 +1,27 @@
# LetterStream API Integration
## Credentials
- API_ID: rzv56x1v
- API_KEY: 5ezy56k2ny7a8vx14u
- Account email: info@itpropartner.com
- Mode: Automation (generate PDF + CSV → certified mail with tracking + delivery confirmation)
## API Access Process
- API is NOT visible by default in the account dashboard
- Must email support@letterstream.com requesting Automation mode
- Include: company overview, use case, confirmation of dev resources
- Once approved, API documentation appears under "My Account" in the dashboard
## Cost
- Single certified letter: ~$8.34 (varies by page count + postage type)
- Pay-as-you-go, no monthly minimum
## Integration (DRE Portal)
- DRE generates demand letter as PDF in the case management system
- LetterStream API sends the letter with tracking + return receipt
- Delivery confirmation webhook updates case status automatically
## Pitfalls
- API credentials do NOT work against generic API endpoints before approval
- The documentation is account-dashboard-gated — no public URL
- All 404 responses before account approval is normal
@@ -0,0 +1,204 @@
# "+ New Letter" Modal Flow
*Created: 2026-07-08 — added to `/var/www/internal/letter-queue.html`*
## Overview
A two-screen modal that replaces the static default claim with a full client-selection → stage-appropriate-template flow. When the user clicks "New Letter" (button with `id="newLetterBtn"`), the modal opens on the client selection screen.
## Screen 1 — Client Selection
### Modal Structure
| Element | Details |
|---------|---------|
| Title | "New Letter" |
| Subtitle | "Select a client/claim to get started" |
| Search bar | Filter input with search icon, placeholder "Search by debtor name, claim #, or client..." |
| Body | Scrollable list of client rows |
### Client Data Model (JS `clients[]`)
```js
{
claim: String, // "DRE-2026-0142"
debtor: String, // "Marcus Bellweather"
amount: Number, // 12840.00
client: String, // "ABC Construction"
stage: String // "soft-touch" | "formal-demand" | "lien-threat" | "escalation" | "legal-action"
}
```
### Client Row Rendering
Each row shows:
- **Left (flex-1, truncate):** Debtor name (white, medium) + claim # (amber, mono) on line 1. Client name + amount on line 2 (gray-500, xs).
- **Right (shrink-0):** Stage badge (colored pill).
Search filter is case-insensitive and matches against `debtor`, `claim`, or `client` fields.
### Stage Badge CSS
```css
.stage-badge { display: inline-flex; align-items: center; gap: 0.25rem;
padding: 2px 10px; border-radius: 9999px; font-size: 0.7rem;
font-weight: 600; letter-spacing: 0.02em; border: 1px solid; }
.stage-soft-touch { background: rgba(59,130,246,0.15); color: #93c5fd; border-color: rgba(59,130,246,0.3); }
.stage-formal-demand { background: rgba(245,158,11,0.15); color: #fcd34d; border-color: rgba(245,158,11,0.3); }
.stage-lien-threat { background: rgba(251,146,60,0.15); color: #fdba74; border-color: rgba(251,146,60,0.3); }
.stage-escalation { background: rgba(239,68,68,0.15); color: #fca5a5; border-color: rgba(239,68,68,0.3); }
.stage-legal-action { background: rgba(168,85,247,0.15); color: #d8b4fe; border-color: rgba(168,85,247,0.3); }
```
| Stage | Color | Semantic |
|-------|-------|----------|
| soft-touch | Blue | Initial contact |
| formal-demand | Amber | First formal notice |
| lien-threat | Orange | Lien warning |
| escalation | Red | Final warning |
| legal-action | Purple | Referred to counsel |
### Demo Clients (10 claims)
| Claim | Debtor | Amount | Client | Stage |
|-------|--------|--------|--------|-------|
| DRE-2026-0142 | Marcus Bellweather | $12,840 | ABC Construction | soft-touch |
| DRE-2026-0098 | Sylvia Chen | $8,750 | Chen & Sons Roofing | formal-demand |
| DRE-2026-0105 | James Kowalski | $22,340 | Kowalski Framing LLC | lien-threat |
| DRE-2026-0081 | Patricia Okafor | $5,400 | Okafor Drywall Inc. | escalation |
| DRE-2026-0157 | Angela Torres | $16,780 | Torres Electric Co. | formal-demand |
| DRE-2026-0062 | Linda Harper | $9,200 | Harper Painting & More | lien-threat |
| DRE-2026-0074 | Robert Nguyen | $31,500 | Nguyen Construction LLC | legal-action |
| DRE-2026-0118 | Derek Simmons | $6,400 | Simmons Brick & Block | soft-touch |
| DRE-2026-0123 | Maria Gonzalez | $19,450 | Gonzalez Landscaping | escalation |
| DRE-2026-0135 | Tom Fletcher | $11,000 | Fletcher Plumbing LLC | soft-touch |
## Screen 2 — Template Selection
### Header Change
When a client is selected, the modal header updates:
- **Title:** Debtor's name (e.g. "Marcus Bellweather")
- **Subtitle:** `"{claim} · ${amount} · Current Stage: {stageLabel}"`
### Stage-to-Template Progression
Templates always progress *forward* — you never offer a template at or below the current stage. The mapping:
```js
const stageTemplates = {
'soft-touch': ['formal-demand'],
'formal-demand': ['lien-threat', 'escalation'],
'lien-threat': ['escalation', 'legal-action'],
'escalation': ['legal-action'],
'legal-action': [] // referred to counsel — no templates
};
```
### Template Display
Each template is rendered as a button with:
- **Icon** (colored Font Awesome icon, w-6 text-center)
- **Name** (white, medium, sm): e.g. "Formal Demand Letter"
- **Description** (gray-500, xs): e.g. "Generate a Soft Touch → Formal Demand Letter"
- **Arrow right** (gray-500, ml-auto)
Icons per template:
| Template | Icon |
|----------|------|
| Formal Demand | `fa-regular fa-file-lines` |
| Lien Threat | `fa-regular fa-triangle-exclamation` |
| Escalation / Final Notice | `fa-regular fa-bell` |
| Legal Action Referral | `fa-regular fa-gavel` |
### Legal-Action Stage (Disabled State)
When a client is already at legal-action stage, the template screen shows:
- Purple gavel icon centered
- "Legal Action Stage" heading
- "This claim has been referred to legal counsel. No letter templates are available."
- "Back to client list" button
### Template Content (4 templates)
Each template uses `[CLAIM]`, `[DEBTOR]`, `[AMOUNT]`, `[CLIENT]` placeholders that get replaced at selection time.
**Formal Demand** — Standard escalation from soft-touch. 14-day payment window. References previous notice. Lists collection measures (lawsuit, liens, litigation referral). Includes payment URL.
**Lien Threat** — Texas Property Code mechanic's lien warning. 10-day payment window. Explains that a filed lien attaches to title and affects sale/refinance. Construction-focused language.
**Escalation / Final Notice** — Strongest pre-legal notice. 10-day ultimatum before lawsuit referral. Lists post-judgment remedies (garnishment, levy, seizure). Mentions court costs and attorney's fees.
**Legal Action Referral** — Confirms referral to legal counsel. States that a civil petition will be filed. Includes claim/amount/legal reference. Lists what the lawsuit will seek (judgment, interest, costs, fees).
Each template gets appended with:
```
Sincerely,
Anita Rodriguez
Collections Specialist
Debt Recovery Experts
```
### Selection → Draft Creation
When a template is selected:
1. **Replace placeholders** in the template raw content
2. **Append signature block** (Anita Rodriguez)
3. **Reset composer** — textarea gets the new content, status badge set to Draft, claim info bar updated with client data and stage badge
4. **Create new letter entry** — pushed to `letters[]` with a new auto-incremented `id`, status `draft`, authoredBy `Anita Rodriguez`, tier set to current stage label
5. **Select the new letter** via `selectLetter(newId)` — updates the table with the row highlighted
6. **Close modal**
7. **Scroll to composer**`document.querySelector('.grid-layout').scrollIntoView(...)`
8. **Toast** — "New {templateLabel} drafted for {debtor}"
## Modal CSS
```css
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.7);
backdrop-filter: blur(4px); display: flex; align-items: center;
justify-content: center; z-index: 60; }
.modal-overlay.hidden { display: none; }
.modal-panel { background: #1e293b; border: 1px solid #374151;
border-radius: 16px; width: 100%; max-width: 42rem; margin: 0 1rem;
max-height: 80vh; display: flex; flex-direction: column;
box-shadow: 0 25px 60px -15px rgba(0,0,0,0.4); }
.client-row { display: flex; align-items: center; gap: 0.75rem;
padding: 10px 14px; border-radius: 10px; cursor: pointer;
transition: background 0.15s; }
.client-row:hover { background: #334155; }
.client-row.selected { background: rgba(245,158,11,0.1);
border: 1px solid rgba(245,158,11,0.25); }
.template-btn { display: flex; align-items: center; gap: 0.75rem;
width: 100%; padding: 12px 16px; border-radius: 10px; cursor: pointer;
transition: all 0.15s; text-align: left; background: #0f172a;
border: 1px solid #334155; color: #e2e8f0; }
.template-btn:hover { background: #1e293b; border-color: #f59e0b; }
.template-btn + .template-btn { margin-top: 6px; }
.templates-grid { display: grid; grid-template-columns: 1fr; gap: 6px; }
.back-btn { display: inline-flex; align-items: center; gap: 0.375rem;
color: #94a3b8; font-size: 0.8125rem; cursor: pointer;
transition: color 0.15s; }
.back-btn:hover { color: #f59e0b; }
```
## JS Functions (key)
| Function | Purpose |
|----------|---------|
| `openNewLetterModal()` | Resets state, clears search, shows modal, renders client list, focuses search |
| `closeNewLetterModal()` | Hides modal |
| `renderModalClientList()` | Filters `clients[]` by `modalSearchQuery`, renders rows or empty state |
| `showTemplatesForClient(client)` | Updates title/subtitle, renders available templates or legal-action disabled state |
| `selectTemplate(client, templateKey)` | Replaces placeholders, appends signature, creates draft letter, selects it, closes modal, scrolls to composer |
## Edge Cases
- **Empty search results:** Centered exclamation icon + "No clients match `{query}`" message
- **Legal-action clients:** Disabled template screen with "referred to counsel" message, no templates offered
- **Modal close on overlay click:** Clicking the blurred backdrop closes the modal (same as the X button)
- **Search while on templates screen:** Input is only active when `modalState === 'clients'` — typing during template selection does nothing
@@ -0,0 +1,53 @@
# DRE Portal Live Fixes Checklist
Session: Jul 8, 2026 — Germaine identified 5 issues on portal.debtrecoveryexperts.com.
All five are recurring patterns likely to resurface after rebuilds or new mockups.
## The 5 Bug Pattern
| # | Issue | Checking |
|---|-------|----------|
| 1 | **Client Dashboard link** goes nowhere or points wrong | Nav link href goes to `/login.html` or a real path, not `/dre-client-dashboard.html` if the file is served from a different root |
| 2 | **No portal login exists** | `/login.html` must exist in the public web root (not internal) |
| 3 | **"Log in" link broken** | Both the nav link AND the footer link ("Already have an account? Log in") must point to `/login.html` |
| 4 | **Document upload doesn't work** | Must have real `<input type=\"file\">` + drag/drop JS + file list rendering |
| 5 | **Agent DRE too verbose** | Responses must be elevator pitch style, not numbered process steps |
## Document upload requirements
A decorative `<div>` with drop-zone styling is not enough. Full requirements:
- Hidden `<input id="file-input" type="file" multiple accept=".pdf,.jpg,.jpeg,.png,.doc,.docx">`
- Click handler on drop zone → `fileInput.click()`
- Drag/drop event listeners: `dragover`, `dragleave`, `drop` with visual feedback (amber border, amber-50 bg)
- File list rendering with remove buttons
- 20MB size limit per file with alert
## Agent DRE elevator pitch style
When asked "how this works" or similar, respond with ONE conversational sentence ending in a follow-up question, not a numbered process list.
| Trigger | Response pattern |
|---------|-----------------|
| "how it works" | \"We handle recovery from start to finish — submit your claim, we send a demand, and keep escalating until you get paid. Most claims resolve in 15-30 days.\" |
| "fees" | \"We only get paid when you do. Fees start at 20% and scale up based on effort. Use the Fee Calculator to see your net.\" |
| "documents" | \"The basics: contract, invoices, and any correspondence about the unpaid amount. Submit what you have and we fill in the gaps.\" |
## Login page pattern (SSO-only gateway)
The DRE portal login at `/login.html` follows this exact structure:
1. SSO button linking to `internal.debtrecoveryexperts.com` (Cloudflare Access protected)
2. "or" separator
3. "New customer? Submit a claim to get started →" link back to `/`
4. Support email link at bottom: `mailto:dre@debtrecoveryexperts.com`
No username/password fields. Cloudflare Access handles auth.
## Caddy root fallback
On `portal.debtrecoveryexperts.com`, the Caddy config has:
```
try_files {path} /debt-recovery.html
```
This means the root URL `/` serves the intake form, not a login page. New visitors see the claim form first.
@@ -0,0 +1,26 @@
# Online Notary (RON) Provider Research — July 2026
## Recommendations
### Primary: OneNotary
- **Trustpilot:** 5.0/5.0 from 3,222 reviews
- **API:** Full developer portal at dev.onenotary.us
- **Security:** SOC 2, ISO 27001, MISMO certified
- **Notaries:** 45,000+ including Texas-licensed
- **24/7:** Yes
- **Cost:** $0/mo pay-as-you-go at $25/session
- **Monthly plan:** ~$49-65/mo (lowers per-signer rate)
### Secondary: BlueNotary
- **Monthly plan:** $37/mo Business Pro (2 docs included)
- **Per additional:** ~$10-15
- **Best for:** 3+ documents/month (cheaper than OneNotary at that volume)
### DO NOT USE
- **OnlineNotary.net** — 33 reviews vs claimed 1,500+, no BBB, "Medium-Risk" scam detector, no public API docs, 9AM-2AM only, no phone support
- **Proof.com Premium** — API locked to Premium tier (cost unknown, sales-gated)
## Integration Path
1. **Phase 1 (first 20 claims):** Manual — email client a OneNotary link, they notarize in ~15 min via browser
2. **Phase 2 (50+ claims):** Contact OneNotary sales for API docs → embed in DRE portal
@@ -0,0 +1,48 @@
# July 7, 2026 — DRE Portal Polish Session
## What was done
Finished and polished all 6 DRE portal pages at `/root/portal-mockup/` and deployed to `/var/www/capabilities/` (served at `portal.debtrecoveryexperts.com`).
## Page-by-page changes
### debt-recovery.html (client intake form)
- Added nav header with links to Client Dashboard, Fee Calculator, Pay
- Fixed "Log in" link → `/dre-client-dashboard.html` (was `#`)
- Wrapped form in `.form-page` div for layout compatibility
### dre-dashboard.html (internal claims queue)
- **Purged all test data** — removed Acme Corp row, claim detail panel, recovery progression, timeline, change history, AI analysis, debtor research, case comparison, next steps
- **Empty state**: "No claims yet. Claims will appear here once clients submit intake forms." — with inbox SVG, CTA button to intake form
- **Zero-value stat cards** — 0 Pending Review, 0 Active Claims, 0 Completed This Week
- Removed "AI Analysis Ready: 5" badge and "1 Pending Approval" widget
- Fixed nav links → aging, new claim, fees pages
### dre-client-dashboard.html (client portal)
- Fixed nav links → Submit Claim, Fee Calculator, Pay (all pointed to `#`)
- Renamed chatbot header: "DRE Assistant" → "Agent DRE", removed "Powered by AI" subtitle
- Fixed "Submit New Claim" → wraps in `<a href="/debt-recovery.html">`
- Fixed "Contact us" link → `/debt-recovery.html` (was `#`)
- Fixed "Privacy policy" link → `/dre-client-dashboard.html` (was `#`)
### dre-case-aging.html (aging report)
- Added nav header with links to Dashboard, Aging (active), New Claim, Fees
- Fixed all "View" links → `/dre-dashboard.html` (were `#`)
- Fixed "Escalate to Tier 4" link → `/dre-dashboard.html`
### dre-fee-calculator.html (fee calculator)
- Added nav header with links to Dashboard, Submit Claim, Fee Calculator (active), Pay
- Fee calculator logic UNCHANGED per instructions
### dre-pay.html (debtor payment page)
- Added nav header with links to Dashboard, Submit Claim, Fee Calculator
- Fixed phone number: `(---) --- ----``(832) 790-3456` with `tel:+18327903456`
- Wrapped content in `.pay-page` div for vertical centering
## Key patterns discovered
1. **All pages needed nav headers** — intake form, dashboard, and aging report were missing them entirely
2. **Many `href="#"` links** throughout all pages — each needed a real path
3. **Placeholder phone number** in pay page needed real DRE number
4. **Form pages needed `.form-page` wrapper** when adding a nav header (body was `display:flex`)
5. **Test data in internal dashboard** needed full purge to empty state — can't leave sample rows for a production-facing mockup
@@ -0,0 +1,37 @@
# DRE Session Notes — July 7, 2026
## Key decisions made this session
- **Fee calculator** added as standalone page, live calculation, 4 tiers side-by-side
- **Case aging dashboard** added — days in tier vs target, color-coded alerting
- **Debtor payment page** added — claim number + name + amount → Stripe
- **AI chatbot** designed: Agent D.R.E., lead capture for new visitors, personalized for logged-in clients
- **Approval workflow**: Germaine + Tony approvers, Anita read-only, hourly reminder cron
- **Data isolation**: AI analysis per claim, not per client. Chatbot knows public info only.
- **Closed case binders**: two per case — DRE internal (full) and client package (sans AI analysis)
- **Change tracking**: audit trail on all edits, visible in DRE dashboard
- **Lead capture in chat**: name + email required before bot answers questions
- **Logged-in chat**: personalized greeting with case context, PII verification for deeper details
- **Tier progress indicator**: 4-step visual on client dashboard with centered labels
- **Message-to-team**: structured subject dropdown, logs to case file, notifies DRE team
- **Texas mechanic's lien**: full 18-section report, pre-lien notice as Tier 2.5, resolves ~70% of construction claims
- **Law firm partnership**: as LLC, DRE can partner via referral fee agreement (DRE 10%, firm 25%)
## Services still needed
| Service | Purpose | Priority |
|---------|---------|----------|
| Proof.com | Online notarization (LPOA) | High (launch blocker) |
| LetterStream | Certified mail | High (launch blocker) |
| Stripe Connect | ACH payments + disbursement | High (launch blocker) |
| Law firm partner | Litigation | Medium (needed for Tier 4) |
| Kanary ($84/yr) | Data broker removal for Germaine | Low |
| Turnstile keys | Obtained | ✅ Done |
## Next steps for DRE
1. Set up Proof.com account
2. Set up LetterStream account
3. Set up Stripe Connect
4. Build DRE portal backend
5. Add portal.debtrecoveryexperts.com DNS
6. Build WordPress site for debtrecoveryexperts.com
@@ -0,0 +1,100 @@
# Session: July 8, 2026 (Morning — Full Audit + DRE Portal Enhancements)
## Model Changes
- **Opus 4.8 added** as delegation fallback 1 (after Opus 4.7 primary)
- Fallback chain now: Opus 4.7 → Opus 4.8 → Llama 3.2 (local)
- DeepSeek V4 Flash was NOT a fallback before — removed from chain, Ollama is the only real fallback
- **Conversation model has NO fallback chain** — only delegation chain has fallbacks
## DRE Portal Fixes & Features Built
### Internal Portal Landing Page
- Created `/var/www/internal/index.html` — dark landing with 4 card links
- Cloudflare Access policy: `Team` = any @germainebrown.com or @yahoo.com
- `try_files {path} {path}.html /index.html` added to Caddy for clean URLs
### Login Page
- Created `/var/www/capabilities/login.html` — SSO-only gateway
- Links to internal.debtrecoveryexperts.com for authentication
- "New customer" link back to intake form
### Persistent Nav — All Pages
- **Standardized to 5 links:** Home, Claims, Aging, Letters, Inbox
- **Clients removed** — DRE team doesn't use that nav link
- **Nav-link CSS** converted from @apply to real CSS everywhere
- Logo: D|R|E with colored separators (gray pipes)
### Document Upload Fix
- Added real `<input type="file">`, drag-and-drop JS, file list with remove, 20MB limit
- Was a decorative `<div>` before — did nothing on click
### Agent DRE Identity
- Both public (portal) and internal (letter queue) chatbots updated:
- Welcome message includes "Texas-registered debt collection agency"
- "what is DRE" response includes "registered with the state of Texas" and "FDCPA compliant"
- Internal chatbot got `'about'` intent detection for identity queries
### + New Letter Modal
- Two-screen modal: client search → stage-gated template selection
- Templates load with `[CLAIM]`, `[DEBTOR]`, `[AMOUNT]`, `[CLIENT]` placeholder substitution
- Stage-to-template mapping prevents backward progression:
- soft-touch → formal-demand
- formal-demand → lien-threat, escalation
- lien-threat → escalation, legal-action
- escalation → legal-action
- legal-action → disabled (referred to counsel)
### 8 Canned Letter Templates
Saved to references/dre-letter-templates.md. 1-3 auto, 4-8 queued for dual approval.
### DRE Mail IMAP Poller
- `/root/.hermes/scripts/dre-mail-poller.py`
- Polls dre@ + collections@ every 60s via IMAP
- Writes to `/var/www/internal/data/dre-mails.json`
- Cron job in no_agent mode
### Inbox UI Page
- `/var/www/internal/inbox.html` — unified inbox for both mailboxes
- Stats, search, mailbox filter, expand/collapse, mark-as-read
- Data source: `/data/dre-mails.json`
### Letter Composer Readability Fix
- All `@apply` directives replaced with real CSS in letter-queue.html
- Textarea was rendering white-on-white (invisible text)
### Custom Letters Policy
- Per user directive: custom letters should be handled through email
- The "+ New Letter" modal should only offer stage-appropriate templates, NOT a free-form text option
## Apex Fixes
### SPF: Silent Email Drop
- Apex form notifications silently dropped by MXroute filter
- SiteGround SMTP relay (c1113726.sgvps.net / 35.212.86.161) was not in SPF
- Fixed by adding `ip4:35.212.86.161` to SiteGround DNS TXT record
- Form notifications now also send to g@germainebrown.com
### NASA Form + Waiver Fixes
- Added g@germainebrown.com to both form notifications (IDs 270, 268)
- SQL UPDATE via REPLACE, verified 2 rows affected
## Credential Audit
Full audit completed Jul 8 @ ~10:00 AM. 6/7 credentials verified working.
- All .env keys, config secrets, DB passwords, IMAP passwords OK
- iCloud calendar password expired — replaced with new app-specific password
- iCloud CalDAV connection now working (principal/auth verified via PROPFIND)
## iCloud CalDAV
- Added to `/root/.config/himalaya/config.toml` as `germaine-calendar` account
- CalDAV verified via PROPFIND to caldav.icloud.com — status 207
- App-specific password stored in `g-germainebrown-icloud-calendar.pass`
- Password generated at appleid.apple.com → App-Specific Passwords
## Home Lab Reminder
- Cron set for 8 PM ET today (Jul 8): remind Germaine to spin up a Linux VM for ShoNuff SSH access
## DRE Queue Items (not yet built/finished)
1. AI Analysis page — recovery success rates, AI scores, metrics dashboard
2. Legal research: can DRE report to credit bureaus?
3. Light/dark theme toggle for internal portal
4. Internal Agent DRE on the letter queue page should include registered debt collector in the welcome message (DONE — first welcome chat bubble updated to include DRE identity)
@@ -0,0 +1,45 @@
# DRE Portal Session — July 8, 2026
## Fixed Issues
### 1. Client Dashboard link → dead end
**Root cause:** Nav link pointed to `/dre-client-dashboard.html` which is in the internal directory (`/var/www/internal/`), not the public web root (`/var/www/capabilities/`).
**Fix:** Changed both nav link and "Log in" footer link to `/login.html`.
### 2. No portal login page existed
**Root cause:** No login page had ever been built. The "Log in" link on the intake form was the only auth entry point and it went nowhere.
**Fix:** Built `/var/www/capabilities/login.html` — a SSO-only gateway with Cloudflare Access redirect button, "or" separator, and new-customer link back to the intake form.
### 3. Log in link broken
**Root cause:** Same as #1`href="/dre-client-dashboard.html"` resolved to the same intake form because Caddy's `try_files` fallback served `debt-recovery.html` for any missing path.
**Fix:** Pointed to the new `/login.html`.
### 4. Document upload didn't work
**Root cause:** The upload area was a styled `<div>` with no `<input type="file">`, no drag/drop JS handlers, and no file list rendering. Decorative only.
**Fix:** Added:
- Hidden `<input id="file-input" type="file" multiple>`
- Click handler on drop zone → triggers file input
- Drag/drop event listeners with visual feedback (amber border, amber-50 background)
- `handleFiles()` with 20MB size check
- `renderFileList()` showing file name, size, type icon, remove button
- `window.removeFile()` for individual file removal
### 5. Agent DRE too verbose
**Root cause:** All chatbot responses used numbered lists, tier breakdowns with percentages, and multi-step explanations instead of conversational elevator pitches.
**Fix:** Rewrote all response strings to the "one sentence + follow-up question" pattern:
- "How it works": eliminated numbered steps, replaced with "We handle recovery from start to finish..."
- "Fees": removed percentage breakdown, replaced with "We only get paid when you do. Fees start at 20%..."
- "Documents": removed numbered list, replaced with "The basics: contract, invoices, and any correspondence..."
- "Catch-all": changed from hard-sell "submit a claim" to "I can tell you about fees, the process, what documents... What sounds most helpful?"
## Files Modified
| File | Changes |
|------|---------|
| `/var/www/capabilities/debt-recovery.html` | Nav link → `/login.html`, Log in link → `/login.html`, document upload with real file input + JS, Agent DRE responses rewritten |
| `/var/www/capabilities/login.html` | **New** — SSO-only portal login page |
@@ -0,0 +1,60 @@
# Texas Debt Law Research Summary (Jul 7, 2026)
Prepared for Debt Recovery Experts (DRE) internal policy manual. This is a research summary — NOT legal advice. Requires Texas attorney review.
## Texas Debt Collection Act (TDCA) — Finance Code Ch. 392
- DRE must register as a debt collector in Texas (bond/registration likely required)
- Prohibited practices: threats, harassment, false representations, unfair/unconscionable means
- Penalties up to $4,000 per violation
- Must provide written notice within 5 days of first communication (validation notice)
## Limited Power of Attorney
- Must be in writing, signed by principal
- Must be notarized (Texas Estates Code 751.0021)
- Must specifically enumerate debt collection powers
- Recording with county clerk NOT required
- Remote Online Notarization (RON) is valid under Texas HB 3496
## Statute of Limitations (Texas)
| Debt Type | SOL |
|-----------|-----|
| Written contract | 4 years |
| Promissory note | 4 years |
| Open account | 4 years |
| Oral contract | 4 years |
| Tort claims | 2 years |
Policy: Do not pursue claims past SOL. Running SOL from claim date is standard.
## Service of Process
- Certified mail (restricted delivery) is valid service under TRCP 106(a)(2)
- If mail fails: personal service by sheriff/constable required
- Electronic service NOT valid for initial service in Texas
## FDCPA Compliance
- Validation notice within 5 days of first communication
- Mini-Miranda: "This is an attempt to collect a debt..."
- Cease communication upon written request
- No communication at inconvenient times/places
- No false representations (amount, legal status, identity)
- Debtor validation rights: dispute within 30 days
## TCPSA / DTPA
- Prior express consent required for autodialed calls to cell phones
- Manual dialing only for debt collection
- 3 calls per 7-day period per debtor (consumer debts)
- No calls before 8 AM or after 9 PM local time
- Must identify caller name and purpose
## Data Privacy
- Texas Bus. & Commerce Code 521: breach notification within 60 days
- AG notice required if 250+ affected individuals
- GLBA Safeguards Rule best practices for financial data
- Retention: 7 years financial data, 5 years claims data, indefinite notary records
@@ -0,0 +1,249 @@
# TwentyCRM DRE Custom Data Model
Created 2026-07-08 via `https://crm.debtrecoveryexperts.com/rest/metadata/` REST API.
Auth: Bearer token from `TWENTY_CRM_API_KEY` in `~/.hermes/.env`.
## Objects
### 1. Debtors (`debtor`/`debtors`)
- **Icon:** IconUsers
- **Label Identifier:** Name (auto-created TEXT field)
- **Custom fields:**
| Field | Type | Icon | Description |
|-------|------|------|-------------|
| contactInfo | TEXT | IconPhone | Primary contact phone number |
| email | TEXT | IconMail | Primary email address |
| physicalAddress | TEXT | IconMapPin | Physical address |
| businessType | SELECT | IconBuildingStore | INDIVIDUAL, SOLE_PROPRIETORSHIP, LLC, CORPORATION, PARTNERSHIP, OTHER |
### 2. Claims (`claim`/`claims`)
- **Icon:** IconFiles
- **Label Identifier:** Name (auto-created TEXT field)
- **Custom fields:**
| Field | Type | Icon | Description |
|-------|------|------|-------------|
| claimNumber | TEXT (unique) | IconHash | DRE-YYYY-NNNN format |
| amount | CURRENCY | IconCurrencyDollar | Claim amount in USD |
| status | SELECT | IconStatusChange | NEW, ACTIVE, NEGOTIATION, LEGAL, SETTLED, CLOSED, WRITE_OFF |
| tier | SELECT | IconLayersSelected | TIER_1, TIER_2, TIER_3 |
| clientReference | TEXT | IconFileDescription | Client reference number |
| dateAssigned | DATE_TIME | IconCalendarPlus | Date claim was assigned |
| dateResolved | DATE_TIME | IconCalendarCheck | Date claim was resolved |
### 3. Case Notes (`caseNote`/`caseNotes`)
- **Icon:** IconNotes
- **Label Identifier:** Name (auto-created TEXT field)
- **Custom fields:**
| Field | Type | Icon | Description |
|-------|------|------|-------------|
| content | RICH_TEXT | IconFileText | Note content |
| author | TEXT | IconUser | Note author name |
### 4. Payments (`payment`/`payments`)
- **Icon:** IconReceipt
- **Label Identifier:** Name (auto-created TEXT field)
- **Custom fields:**
| Field | Type | Icon | Description |
|-------|------|------|-------------|
| paymentAmount | CURRENCY | IconCurrencyDollar | Amount received |
| payer | TEXT | IconUser | Name of payer |
| paymentDate | DATE_TIME | IconCalendar | Date payment received |
| paymentMethod | SELECT | IconCreditCard | CHECK, WIRE_TRANSFER, CREDIT_CARD, CASH, ACH, OTHER |
## REST API Field Creation Pattern
```bash
API_KEY=$(grep TWENTY_CRM_API_KEY ~/.hermes/.env | cut -d= -f2)
# Create object
curl -s "https://crm.debtrecoveryexperts.com/rest/metadata/objects" \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"nameSingular": "myObject",
"namePlural": "myObjects",
"labelSingular": "My Object",
"labelPlural": "My Objects",
"description": "...",
"icon": "IconFiles",
"isSearchable": true,
"isActive": true,
"isLabelSyncedWithName": true
}'
```
**Create a regular field:**
```bash
curl -s "https://crm.debtrecoveryexperts.com/rest/metadata/fields" \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"name": "fieldName",
"label": "Field Name",
"description": "...",
"type": "TEXT",
"icon": "IconMail",
"isNullable": true,
"isUnique": false,
"objectMetadataId": "'"$OBJECT_ID"'"
}'
```
**Create a SELECT field with options:**
```bash
curl -s "https://crm.debtrecoveryexperts.com/rest/metadata/fields" \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"name": "status",
"label": "Status",
"description": "...",
"type": "SELECT",
"icon": "IconStatusChange",
"isNullable": true,
"isUnique": false,
"objectMetadataId": "'"$OBJECT_ID"'",
"options": [
{"label": "New", "value": "NEW", "color": "blue", "position": 0},
{"label": "Active", "value": "ACTIVE", "color": "turquoise", "position": 1}
]
}'
```
**Available Colors for SELECT options:** blue, turquoise, green, yellow, orange, red, purple, pink, grey, sky
## Relations (MANY_TO_ONE → ONE_TO_MANY)
**IMPORTANT:** The REST API endpoint `POST /rest/metadata/fields` does NOT accept `relationCreationPayload` — it returns `"Relation creation payload is required"`. Relations MUST be created via the **GraphQL mutation endpoint** at `POST https://crm.debtrecoveryexperts.com/metadata`.
### GraphQL Mutation for RELATION Fields
```graphql
mutation CreateOneField($input: CreateOneFieldMetadataInput!) {
createOneField(input: $input) {
id
name
label
type
settings
relation {
type
sourceObjectMetadata { id nameSingular namePlural }
targetObjectMetadata { id nameSingular namePlural }
sourceFieldMetadata { id name }
targetFieldMetadata { id name }
}
object { id nameSingular }
}
}
```
### Variables (JSON)
```json
{
"input": {
"field": {
"name": "debtor",
"label": "Debtor",
"type": "RELATION",
"objectMetadataId": "<SOURCE_OBJECT_UUID>",
"relationCreationPayload": {
"type": "MANY_TO_ONE",
"targetObjectMetadataId": "<TARGET_OBJECT_UUID>",
"targetFieldLabel": "Claims",
"targetFieldIcon": "IconFileDescription"
}
}
}
}
```
### `relationCreationPayload` Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | `"MANY_TO_ONE"` \| `"ONE_TO_MANY"` | ✅ | Direction of the relation |
| `targetObjectMetadataId` | UUID string | ✅ | The object this relation points to |
| `targetFieldLabel` | string (max 63 chars) | ✅ | Label for the auto-generated reverse field on the target object |
| `targetFieldIcon` | string | ✅ | Icon name for the reverse field (e.g. `"IconCurrencyDollar"`) |
### How It Works
**MANY_TO_ONE** field on SourceObject → TargetObject:
- A foreign-key column (e.g. `debtorId`) is **automatically created** on the SourceObject table
- A reverse **ONE_TO_MANY** relation field is **automatically created** on the TargetObject
- `targetFieldLabel` and `targetFieldIcon` control the reverse field's label/icon
- The source-side `settings` will include `{"joinColumnName": "debtorId"}`
**ONE_TO_MANY** field on SourceObject → TargetObject:
- **No** join column on SourceObject (the FK lives on the other side)
- A reverse **MANY_TO_ONE** relation field (with join column) is created on TargetObject
### curl Example
```bash
API_KEY=$(grep TWENTY_CRM_API_KEY ~/.hermes/.env | cut -d= -f2)
# Create a MANY_TO_ONE relation: Payments → Claim
curl -s "https://crm.debtrecoveryexperts.com/metadata" \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"query": "mutation CreateOneField($input: CreateOneFieldMetadataInput!) { createOneField(input: $input) { id name type relation { type targetFieldMetadata { id name } targetObjectMetadata { id nameSingular } } } }",
"variables": {
"input": {
"field": {
"name": "claim",
"label": "Claim",
"type": "RELATION",
"objectMetadataId": "PAYMENTS_OBJECT_UUID",
"relationCreationPayload": {
"type": "MANY_TO_ONE",
"targetObjectMetadataId": "CLAIMS_OBJECT_UUID",
"targetFieldLabel": "Payments",
"targetFieldIcon": "IconCurrencyDollar"
}
}
}
}
}'
```
### DRE Data Model Relations Table
| Source Object | Field | Relation Type | Target Object | Reverse Field |
|---------------|-------|---------------|---------------|---------------|
| Claims | `debtor` (MANY_TO_ONE) | MANY_TO_ONE | Debtors | `claims` (ONE_TO_MANY) |
| CaseNotes | `claim` (MANY_TO_ONE) | MANY_TO_ONE | Claims | `caseNotes` (ONE_TO_MANY) |
| Payments | `claim` (MANY_TO_ONE) | MANY_TO_ONE | Claims | `payments` (ONE_TO_MANY) |
## Reserved Field Names
These names trigger `INVALID_FIELD_INPUT: This name is reserved`:
- `address` (and likely other system-level names)
Use alternatives like `physicalAddress`, `mailingAddress`, etc.
## Verification Command
```bash
API_KEY=$(grep TWENTY_CRM_API_KEY ~/.hermes/.env | cut -d= -f2)
curl -s "https://crm.debtrecoveryexperts.com/rest/metadata/objects" \
-H "Authorization: Bearer $API_KEY" > /tmp/all_objects.json
python3 -c "
import json, sys
data = json.load(open('/tmp/all_objects.json'))
for obj in data.get('data', []):
if not obj['isSystem']:
print(f'\\n## {obj[\"labelSingular\"]} ({obj[\"nameSingular\"]})')
print(f' ID: {obj[\"id\"]}')
for f in obj.get('fields', []):
if not f['isSystem']:
print(f' - {f[\"label\"]} ({f[\"name\"]}) type={f[\"type\"]}')
"
```
@@ -0,0 +1,42 @@
# Web Scraping & Search Stack
## Current Services (July 2026)
| Service | Credits/mo | JS Rendering | Cost | Best For |
|---------|-----------|-------------|------|----------|
| **Firecrawl** | 1,000 | Limited | Free | Quick web lookups, markdown extraction |
| **ScrapingAnt** | 10,000 free / 100K paid | ✅ Headless Chrome | $0 (free) / $19/mo (paid) | JS-heavy sites, gov pages, LinkedIn, Indeed |
| **SearXNG** | Unlimited | ❌ No | Free (self-hosted) | Metadata search, query discovery |
## API Keys
- Firecrawl: `fc-4f9...63c1` — saved in ~/.hermes/.env as `FIRECRAWL_API_KEY`
- ScrapingAnt: `8ab7...af6` — saved in ~/.hermes/.env as `SCRAPINGANT_API_KEY`
- SearXNG runs at `http://127.0.0.1:8888` on Core (Docker, auto-start)
## When to Use Which
| Target | Tool | Why |
|--------|------|-----|
| General web page / article | Firecrawl (free) | Fast, clean markdown |
| JS-rendered gov site (TX Legislature) | ScrapingAnt + browser=true | Headless Chrome renders JS SPAs |
| LinkedIn public profiles | ScrapingAnt | Handles JS auth walls |
| Indeed / CBDriver / job sites | ScrapingAnt | Blocks raw HTTP scrapers |
| People search / skip tracing | ScrapingAnt + Sherlock | Combined: OSINT + JS rendering |
| Quick URL lookup (curl-friendly) | SearXNG | Unlimited, no API key needed |
## Credit Tracking
Daily cron at 8 AM: `model-usage-tracker.sh` also checks Firecrawl credits via header response.
## Self-Hosted Search (SearXNG)
- Docker container at `/root/docker/searxng/`
- JSON API at `http://127.0.0.1:8888/search?q=<query>&format=json`
- Limited to 120 req/hr (configurable in settings.yml)
- Only accessible from localhost (not exposed externally)
## Future Additions (Research Complete)
- **Apify LinkedIn actor** (~$30-50/mo) — structured LinkedIn people search for skip tracing
- **Browserbase** — interactive gov portal automation (form submission, login-gated searches)