New-client onboarding automation update #24

Closed
opened 2026-07-23 14:07:59 +02:00 by mivanchenko · 1 comment
Owner

Parent

#14

What to build

New-client onboarding produces a working booking setup automatically, so a new client's landing
page booking button isn't broken while they get around to configuring it themselves.

  • n8n/onboarding.json is extended to insert, for each new client: a default resources row, a
    starter services row, and a users row with a temp password (delivered the same way other
    onboarding credentials are handled today, e.g. via the existing credentials CRM entity).
  • The existing EA-provisioning step in n8n/onboarding.json is removed as part of this same
    change (no more auto-creating an EA provider account).

Acceptance criteria

  • Running the onboarding workflow for a new client results in a client that has: a slug, a
    default resource, at least one active service, and an owner users row with credentials
    recorded in the CRM's credentials entity.
  • The new client's /book/<slug> page (ticket 3) is immediately functional (shows a bookable
    slot grid) without any manual setup.
  • The onboarding workflow no longer creates an Easy!Appointments provider account.

Blocked by

  • #15 (Booking schema + tenancy-safe data access layer)
  • #19 (Owner accounts: auth, password reset, CRM dashboard visibility)
## Parent #14 ## What to build New-client onboarding produces a working booking setup automatically, so a new client's landing page booking button isn't broken while they get around to configuring it themselves. - `n8n/onboarding.json` is extended to insert, for each new client: a default `resources` row, a starter `services` row, and a `users` row with a temp password (delivered the same way other onboarding credentials are handled today, e.g. via the existing `credentials` CRM entity). - The existing EA-provisioning step in `n8n/onboarding.json` is removed as part of this same change (no more auto-creating an EA provider account). ## Acceptance criteria - [ ] Running the onboarding workflow for a new client results in a client that has: a `slug`, a default resource, at least one active service, and an owner `users` row with credentials recorded in the CRM's `credentials` entity. - [ ] The new client's `/book/<slug>` page (ticket 3) is immediately functional (shows a bookable slot grid) without any manual setup. - [ ] The onboarding workflow no longer creates an Easy!Appointments provider account. ## Blocked by - #15 (Booking schema + tenancy-safe data access layer) - #19 (Owner accounts: auth, password reset, CRM dashboard visibility)
mivanchenko added the ready-for-agentenhancementbooking labels 2026-07-23 14:07:59 +02:00
mivanchenko added a new dependency 2026-07-23 14:09:18 +02:00
mivanchenko added a new dependency 2026-07-23 14:09:19 +02:00
Author
Owner

Implemented in aabd1d5.

  • n8n/onboarding.json: after Save client, a new Build provisioning node fans out to create a default resource (Hauptressource, Mon-Sat 09:00-18:00 hours so slots are bookable immediately), a starter service (Termin, 30 min), and an owner-login user. A new User created? If-gate only fires Save credential when the owner-user creation actually succeeded, so a failed call can't leave a stale/misleading credentials row. The EA-provisioning chain (EA build/create service+provider, EA booking info/update client) is fully removed -- no dangling references remain.
  • Compute now derives and sets clients.slug (slugified business name + random suffix).
  • New backoffice endpoints: POST /api/resources, POST /api/services, POST /api/owner_users, all X-CRM-Token gated, backed by booking_db.py's existing tenancy-scoped create_resource/create_service/create_user helpers.
  • Fixed a latent bug: slug was already a DB column (#17) but missing from db.py's clients column list, so the generic /api/clients POST silently dropped it -- onboarding could never actually set a client's slug until now.

Acceptance criteria:

  • Onboarding results in a client with a slug, a default resource (with hours), an active service, and an owner users row with credentials recorded in credentials.
  • /book/<slug> is immediately functional -- resource has hours configured so _available_slots has something to return.
  • No more EA provider account creation.

149 tests pass (backoffice/app/tests), including a new test_provisioning.py covering all three new routes plus slug persistence through /api/clients.

Implemented in aabd1d5. - `n8n/onboarding.json`: after `Save client`, a new `Build provisioning` node fans out to create a default resource (`Hauptressource`, Mon-Sat 09:00-18:00 hours so slots are bookable immediately), a starter service (`Termin`, 30 min), and an owner-login user. A new `User created?` If-gate only fires `Save credential` when the owner-user creation actually succeeded, so a failed call can't leave a stale/misleading credentials row. The EA-provisioning chain (EA build/create service+provider, EA booking info/update client) is fully removed -- no dangling references remain. - `Compute` now derives and sets `clients.slug` (slugified business name + random suffix). - New backoffice endpoints: `POST /api/resources`, `POST /api/services`, `POST /api/owner_users`, all X-CRM-Token gated, backed by `booking_db.py`'s existing tenancy-scoped `create_resource`/`create_service`/`create_user` helpers. - Fixed a latent bug: `slug` was already a DB column (#17) but missing from `db.py`'s `clients` column list, so the generic `/api/clients` POST silently dropped it -- onboarding could never actually set a client's slug until now. Acceptance criteria: - [x] Onboarding results in a client with a `slug`, a default resource (with hours), an active service, and an owner `users` row with credentials recorded in `credentials`. - [x] `/book/<slug>` is immediately functional -- resource has hours configured so `_available_slots` has something to return. - [x] No more EA provider account creation. 149 tests pass (`backoffice/app/tests`), including a new `test_provisioning.py` covering all three new routes plus slug persistence through `/api/clients`.
Sign in to join this conversation.