Files
gogo-telefon/gogo/sms/templates.py
Senad Uka e855650f09 M1: backend core + proposal engine
- FastAPI skeleton, SQLAlchemy models (§13), Alembic initial migration
- SchedulingProvider interface with google_calendar (free/busy read-only),
  partner_api (Appendix B client) and mock implementations
- Proposal engine: create → provider-routed delivery → owner actions
  (resolve/confirm+SMS/reject) → expiry + reminders (§9)
- Signed single-use action links, .ics METHOD:REQUEST attachment
- Partner outcome webhook with HMAC verification + polling fallback
- SmsProvider (console) with Bosnian templates (§5.5), EmailProvider (console/SMTP)
- Fake partner API server in tests/ — Appendix B reference implementation
- 43 tests: slot math, proposal lifecycle, action links, partner contract

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 09:45:06 +02:00

38 lines
1.3 KiB
Python

"""Per-tenant SMS templates with safe Bosnian defaults (§5.5).
Tenant overrides live in tenants.sms_templates (only overridden keys stored).
Placeholders are .format()-style; unknown placeholders are left intact.
"""
from __future__ import annotations
from gogo.models import Tenant
DEFAULT_TEMPLATES: dict[str, str] = {
"missed_call": (
"Poštovani, dobili ste {salon}. Možete zakazati i putem poruke ili chata: {link}. "
"Nazvaćemo vas ili nas pozovite ponovo."
),
"request_received": (
"Primili smo vaš zahtjev za termin. Javićemo vam potvrdu u najkraćem roku. — {salon}"
),
"confirmation": "Potvrđen termin: {usluga}, {dan} {datum} u {vrijeme}h — {salon}.",
"rejection": "{salon}: nažalost traženi termin nije moguć. Molimo pozovite nas da dogovorimo drugi.",
"expiry": (
"{salon}: nismo uspjeli potvrditi vaš zahtjev za termin. "
"Molimo pozovite nas ponovo da dogovorimo termin."
),
}
class _SafeDict(dict):
def __missing__(self, key: str) -> str:
return "{" + key + "}"
def render_sms(tenant: Tenant, kind: str, **params: str) -> str:
templates = {**DEFAULT_TEMPLATES, **(tenant.sms_templates or {})}
template = templates[kind]
params.setdefault("salon", tenant.name)
return template.format_map(_SafeDict(params))