- Backend: новый GET /api/daily_reminders (внутренний, Bearer-токен)
сканирует Measurements, находит клиентов у которых сегодня годовщина
contract_date (по МСК), дедуплицирует по manager+client_key
- Backend config: поле internal_secret (INTERNAL_SECRET)
- Bot: фоновая задача _anniversary_scheduler — каждый день в 09:00 МСК
вызывает эндпоинт и рассылает менеджерам HTML-сообщение с годовщиной
- Bot config: поля internal_secret + backend_url (BACKEND_URL)
- deploy/.env.example: добавлены INTERNAL_SECRET
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wizard: new 'photos' step (6 total) — camera/gallery input, client-side
canvas compression to 1600px @ ~78% JPEG, max 12 photos. Thumbnails
with delete in step; preview in summary.
Backend: POST /api/measurement now decodes data-URL photos and saves
to /app/photos/<id>/N.jpg (volume-mounted). New GET /api/photo/{id}/{n}
serves files with path-traversal protection. New POST /api/measurement_detail
returns full measurement record (walls/openings/photos/notes/...).
Clients page: measurement rows now clickable → renderMeasurement detail
view with key-value grid + photo gallery + 'Скачать PDF / Печать'.
Print stylesheet (@media print) hides navigation/buttons/uploaders and
prints clean A4-friendly layout.
Podbor report: existing 'Печать → PDF' now falls back to inline
window.print() inside Telegram WebApp (popups are blocked there).
Cache bust v=20260513a.