3 Commits

Author SHA1 Message Date
Head of Product & Engineering
671577245a fix: use sentinel ErrLocationNotFound to satisfy errorlint
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Replace errors.New("location not found") string with a package-level
sentinel var so callers can use errors.Is() instead of string comparison,
which errorlint flags as unsafe.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-06 14:12:36 +02:00
Head of Product & Engineering
9995027093 feat: per-location Cast API key and unified admin config API
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Each GHL location can now have its own Cast API key and sender ID stored
in MongoDB. Falls back to global CAST_API_KEY / CAST_SENDER_ID env vars
when not set per-location.

Admin endpoints (all require Authorization: Bearer <INBOUND_API_KEY>):
  GET  /api/admin/locations                        — list all locations
  GET  /api/admin/locations/{locationId}/config    — get location config
  PUT  /api/admin/locations/{locationId}/config    — set sender_id + cast_api_key

Cast API key is masked in GET responses (first 12 chars + "...").
Replaces the /sender-id endpoint deployed in the previous commit.

Also adds FUTURE_DEV.md documenting the migration path to Infisical
for secret management, plus MongoDB security hardening checklist.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-06 14:08:29 +02:00
Head of Product & Engineering
5312eb0ca2 feat: per-location sender ID with admin API
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Allows each GHL sub-account to use a different Cast sender ID instead of
the global CAST_SENDER_ID default.

- store.TokenRecord gains a sender_id field (MongoDB)
- store.UpdateSenderID method to set it per location
- cast.Client.SendSMS accepts a senderID override param (empty = use
  client-level default)
- webhook.processOutbound reads the location's sender_id from the token
  record and passes it to Cast
- new admin handler: PUT /api/admin/locations/{locationId}/sender-id
  protected by Authorization: Bearer <INBOUND_API_KEY>

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-06 12:47:00 +02:00