- Token-protected mutation endpoints (POST/PATCH/DELETE), audit-logged to
activity_log. Token injected into the basic-auth-gated dashboard.
- Add auto-generates IDs (next C-#### / L-<epoch>), sets created/received/status
defaults, and computes client renewal_date from start + billing cycle
(parity with the onboarding workflow).
- Dashboard: per-row edit (✎) and delete (🗑), "+ Neu" modal form per entity.
Verified end-to-end: add lead/client, edit, delete, renewal compute, token
gating (403), 404s. DB-only for now; DB->Sheets mirror is the next step.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stand up the DB-first CRM backbone (architecture pivot: Postgres is the
source of truth, Google Sheets becomes a one-way downstream mirror).
- backoffice/ stack: smb-db (Postgres 16) + smb-crm (Flask/waitress service).
- Schema mirrors the six Sheet tabs (clients, leads, projects, activity_log,
bookings, invoices) with typed columns + updated_at triggers.
- Service-account Sheets client (PyJWT) for the one-time import + future mirror.
- import_from_sheets.py: idempotent seed of Postgres from the live Sheets.
- Read dashboard (Leads & Clients tables) at onboard.mivanchenko.de/crm,
behind the existing Caddy basic-auth; JSON API reads straight from Postgres.
Deployed + verified: import seeded DB, dashboard/API live, no-auth blocked,
onboarding form unaffected. Add/edit/delete + DB->Sheets sync + n8n ingest
swap are the next steps.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>