← back to Lawyer Directory Builder

legal/PLATFORM_DECISION_2026-05-03.md

85 lines

# Platform Decision — Lawyers + Doctors (and the rest)
**2026-05-03 · Long-overdue from `apply-templates.js` (~58h stale)**

## TL;DR
**Keep the projects as separate git repos. Extract a shared "vertical-directory" core into `~/Projects/vertical-directory-core` as published modules. Don't merge them into one monorepo — the compliance copy diverges too sharply by vertical.**

---

## What the projects share TODAY (verified 2026-05-03)

| Capability | lawyer-directory-builder | professional-directory (doctors) | animals | restaurant-prof-dir (LA County Eats) |
|---|---|---|---|---|
| Stack | Express + tsx + PG | Express + tsx + PG | Express + tsx + PG | Express + tsx + PG |
| Schema pattern | `professionals`/`organizations`/`practice_areas` | same | analog (`businesses`/`categories`) | analog (`restaurants`/`permits`) |
| Mockup engine | yes (4-variant per firm) | yes | yes (3-variant per record) | planned |
| Audit pipeline | yes (`/audit.html`) | yes (`/audit.html`) | no | planned |
| Lead form | yes (`/find-a-lawyer`) | yes | yes | planned |
| Brand/copy | "Counsel & Bar" §6155 strict | "—" no equivalent compliance load | community-positive ("PawCircles") | civic-record positive |

## What's specific TO each (non-shareable)

- **Lawyers**: Cal B&P §6155, Rule 5.4/7.x, "not a referral service" copy, State Bar disclaimers on every page. **Operator must remain a non-attorney.** This is binding regulatory context — cannot leak into other verticals.
- **Doctors**: would need parallel HIPAA-aware language if any patient PII enters; current state doesn't, but Steve has flagged this as a regulatory landmine to avoid.
- **Animals**: community/UGC tone, no per-record liability concerns
- **Restaurants**: civic public-records vibe, no advertising-rule load

The compliance copy is **not template-able**. A shared "directory.html" template with pluggable copy would invite cross-vertical bleed (e.g., a Rule-5.4 disclaimer ending up on the doctors site, or a HIPAA risk creeping onto lawyers).

## Decision: SEPARATE repos · SHARED core · VERTICAL copy

```
~/Projects/vertical-directory-core/        # NEW, published as @vd-core/* npm scope
  ├─ schema/                                # canonical PG schema (professionals/orgs/practice_areas)
  ├─ ingest/                                # base scrapers, autocomplete, dedup
  ├─ mockup-engine/                         # 4-variant mockup pipeline (vendor-agnostic)
  ├─ audit-pipeline/                        # site-audit (lighthouse + signals)
  ├─ ui-tokens/                             # noir/champagne palette, Cormorant+Inter, monogram SVG factory
  └─ ui-components/                         # configurator, Volume strip, brand-mono, public-trust block

~/Projects/lawyer-directory-builder/         # CURRENT, repo on GitHub
  imports @vd-core/* · adds Cal §6155 copy + State Bar audits + EZ Upgrade product

~/Projects/professional-directory/           # CURRENT, NEEDS REMOTE
  imports @vd-core/* · adds doctor-specific intake + medical-board verification

~/Projects/animals/                          # CURRENT, NEEDS REMOTE
  imports @vd-core/{ui-tokens,mockup-engine} · skips audit-pipeline · adds PawCircles community

~/Projects/lacountyeats/                     # PLANNED (registered 2026-05-02)
  imports @vd-core/* · adds civic-permit ingest
```

## Why not a monorepo

1. **Compliance copy must NOT be DRY.** A monorepo invites accidental sharing of regulatory disclaimers across verticals. Lawyer Rule 7.x ≠ doctor HIPAA ≠ animal community policy. Each vertical's `legal/` and visible disclaimers stay 100% in-vertical.
2. **Independent deploy cadence.** Lawyers ships a hero proof strip on Sunday; restaurants ships next Tuesday. Branch protection / CI lockup of a monorepo would block the loop iteration cadence Steve runs.
3. **Independent secrets.** Each vertical may end up with its own Stripe account, GA4 property, Sendgrid sender. A leaked `.env` in one vertical shouldn't blast-radius to the others.
4. **Independent compliance reviews.** When Steve hires the CA business attorney for §6155 sign-off (per `legal/attorney-engagement-letter.md`), the review scope is *just* lawyer-directory-builder — not 4 verticals at once.

## Why a published core (not just copy/paste)

- Bug fix in mockup engine flows to all verticals on `pnpm update @vd-core/mockup-engine`
- UI token changes (palette, type) propagate uniformly — the brand audit Steve has been running this session would have one canonical source instead of 4 drifted forks
- Schema migrations versioned — `@vd-core/schema` v0.4 → v0.5 forces every vertical to migrate or pin

## Migration plan (proposed, not committed)

| Phase | Work | Time |
|---|---|---|
| 0 | This decision doc reviewed/signed by Steve | 1 day |
| 1 | Create `~/Projects/vertical-directory-core/` repo + initial extract from lawyer-directory-builder (cleanest pattern) | 1 week |
| 2 | Migrate professional-directory (doctors) to consume `@vd-core/*` — proves portability | 1 week |
| 3 | Add GitHub remotes to professional-directory + animals + visual-factory (pre-existing P0 from MEETING_FOLLOWUP) | 30 min |
| 4 | Migrate animals subset, then plan lacountyeats build on `@vd-core` from day 1 | 2 weeks |

## What `apply-templates.js` (Steve's stale 58h-old script) was probably trying

Best guess from filename: copy a tested HTML template from one vertical to others. **That's the wrong layer to share.** Templates with embedded copy are the part that MUST diverge. Share *components* (Volume strip, monogram, configurator chrome), not *templates* (full pages with disclaimer text).

**Recommend: archive `apply-templates.js`. Replace with the `@vd-core/ui-components` migration in Phase 1.**

---

**Decision required from Steve:** approve the shape above, or counter. If approve, Phase 1 starts on next loop iteration after the lawyer landing surfaces converge.