正在加载完整 README。 以下为已保存的摘录。
Local-first therapy practice management for solo LMHCs. Clinical data stays on your desktop — always.
Product truth and build order live in PRODUCT_PLAN.md. That file wins if anything here disagrees. Active work is Gate A (fake-client loop). Do not use with real clients until Gate B (encryption + attorney-reviewed consents).
Desktop sync pulls contact info and consent status via GET /api/desktop/sync (X-Desktop-API-Key). It does not upload the chart.
Never leave the desktop / never sync to web:查看完整 README ↗Local-first therapy practice management for solo LMHCs. Clinical data stays on your desktop — always.
Product truth and build order live in PRODUCT_PLAN.md. That file wins if anything here disagrees. Active work is Gate A (fake-client loop). Do not use with real clients until Gate B (encryption + attorney-reviewed consents).
┌─────────────────────────────┐ ┌──────────────────────────────┐
│ Desktop (Windows first) │ │ Web │
│ - Local SQLite (plaintext) │◀───▶│ - Client intake + consents │
│ - Audio recording │sync │ - Schedule + SMS reminders │
│ - whisper.cpp transcription│ │ - Invoices + Stripe (card) │
│ - Ollama SOAP drafts │ │ - Therapist dashboard │
│ - Superbill PDF │ │ │
└─────────────────────────────┘ └──────────────────────────────┘
│ │
│ clinical chart stays on disk │
▼ ▼
Your local disk only Contact info, consent text and
signatures, appointments, invoices
Desktop sync pulls contact info and consent status via GET /api/desktop/sync (X-Desktop-API-Key). It does not upload the chart.
Never leave the desktop / never sync to web:
Local database: a normal SQLite file. The app does not encrypt it. Use BitLocker (or similar) on the machine until Gate B. Do not sync %APPDATA%\com.solopractice.desktop to OneDrive.
Web portal holds:
notes field — not for session contentsolopractice/
├── PRODUCT_PLAN.md # North star, current truth, release gates
├── apps/
│ ├── desktop/ # Tauri 2 + React (Windows first)
│ │ ├── src/ # React frontend
│ │ └── src-tauri/ # Rust backend
│ └── web/ # Next.js web app
│ └── src/
│ ├── app/ # App router pages + API routes
│ ├── db/ # Drizzle schema
│ └── lib/ # Stripe, Resend, Twilio, auth
├── packages/
│ └── shared/ # Web vs desktop types + clinical field blocklist
├── docs/
│ └── WINDOWS_SETUP.md # Windows machine setup
└── .env.example
pnpm install
cp .env.example .env
# Edit .env with your API keys
pnpm db:generate
pnpm db:push
pnpm dev:web
cd apps/desktop
pnpm install
pnpm tauri:dev
# Production: pnpm tauri:build
Installer output: apps/desktop/src-tauri/target/release/bundle/.
More detail: docs/WINDOWS_SETUP.md and apps/desktop/README.md.
See .env.example.
| Variable | Description |
|---|---|
DATABASE_URL | PostgreSQL connection string |
STRIPE_SECRET_KEY | Stripe API secret key |
RESEND_API_KEY | Resend API key for emails |
TWILIO_* | Twilio credentials for SMS |
/api/webhooks/stripePlatform fee: 1% on payments (no monthly subscription). Cards only today.
Consent forms are DRAFT templates. Fake clients only until attorney review (Gate B).
/therapist/loginggml-base.en (Linux/Windows/Mac Apple Silicon); older builds need Setup download or hand transcriptFull Gate A checklist for her Windows PC: docs/GATE_A_WALKTHROUGH.md.
| Job | Tool | Status |
|---|---|---|
| Transcription | whisper.cpp CLI | Bundled in v0.1.9 installers (Linux AppImage, Windows, Mac Apple Silicon); else Setup download / paths; failed jobs can be continued from SOAP status |
| SOAP draft | Ollama on 127.0.0.1 | Uses configured model (phi4-mini if unset) |
| Superbill PDF | Local (printpdf) | Sidebar Superbill screen; generate_superbill writes under superbills/ |
| Backup | — | Not implemented |
Jobs are SQLite rows processed on a background thread. Failed jobs stay failed (not requeued). Jobs left in_progress after a crash are not auto-reset.
Write routes reject payloads with clinical field names (defense in depth; schema also excludes them):
const CLINICAL_FIELD_BLOCKLIST = [
"subjective", "objective", "assessment", "plan",
"diagnosisCodes", "procedureCodes", "transcript",
"recording", "soapNote", ...
];
Response: 400 with code: "CLINICAL_DATA_REJECTED".
Note: free-text keys like appointment notes are not on this list — do not put clinical content there.
Draft pack (not legal advice):
Before real clients: attorney review, state compliance, remove DRAFT warnings.
pnpm typecheck
pnpm test
pnpm dev:web
pnpm dev:desktop # requires Rust
cd packages/shared && pnpm build
Closed-source. All rights reserved.