page.route() перехватывает /api/clients и возвращает тестового клиента.
Карточка клиента теперь открывается и проверяется без реальных данных.
17 чеков, 0 пропущено.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1. Дублирование: init() теперь вызывает routeByHash() вместо копии логики.
#/master, #/me, #/c/cabinet теперь работают при прямом переходе по ссылке.
2. Множественные hashchange listeners: guard _hashListenerAdded.
3. #/picker → #/c/proposal в cabinet.js и me.js (неверный роут).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Тригер: Deploy MiniApp to GitHub Pages → completed + success.
Скриншот сохраняется как артефакт при провале.
workflow_dispatch с опциональным SMOKE_URL для ручного запуска.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
InboxScreen.mount() — список замеров без решения по подбору.
Три действия: начать подбор / отложить / не нужен.
Роутинг #/inbox добавлен в routeByHash() и init().
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- measurement_detail: любой мастер (measurer+assembler) видит фото замера
- assembly_list: клиент видит все свои сборки (по client_tg_id)
- assembly_detail: клиент видит детальную карточку сборки
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4 роли: manager / measurer / assembler / client
Цикл сделки, доступ по экранам, правило совместного подбора техники.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Каждый агент обязан начинать ответ с бейджа роли:
🤖 КООРДИНАТОР / 🔧 DEV / ⚙️ DEVOPS / 🎨 DESIGN / 🧩 FEATURE / 🧪 TEST / 🔍 REVIEW
Правило прописано в CLAUDE.md и в каждом агент-файле.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Блокирует push при JS-ошибках в интерфейсе или CSS-нарушениях.
API-тесты в хук не включены — зависят от VPS/Drive, запускать вручную.
Активируется через: git config core.hooksPath .githooks
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Кнопки больше не зависают бесконечно при медленном или недоступном бэкенде.
AbortController + дружелюбное сообщение «Сервер не отвечает — попробуйте ещё раз».
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- _fetchWithTimeout() — единый fetch с AbortController
- saveClientNote, fetchClientNote, fetchClients, fetchMeasurements
теперь через таймаут вместо бесконечного ожидания
- При таймауте показывает 'Сервер не отвечает — попробуйте ещё раз'
- Версия clients.js: 20260518e
escAttr использовалась в 11 местах (карта, форма редактирования)
но не была объявлена в clients.js — отсюда пустая карточка.
Версия clients.js: 20260518d
- Обернуть renderClientHistory в try/catch — показывает текст ошибки
- Добавить .catch() в mount() для перехвата unhandled promise rejection
- Версия clients.js: 20260518c
- Добавить проверку data.error после fetchClients() в renderClientHistory
- Сравнивать client_tg_id как строки (String(c.client_tg_id) === String(clientKey))
чтобы избежать 5937498515 !== '5937498515'
- Показывать явное сообщение если клиент не найден вместо пустой страницы
- Версия clients.js: 20260518b
- Заголовок 'История подборов' → 'Карточка клиента'
- Убрать инлайн-монтирование Proposals.mountManager в карточке клиента
- Оставить только кнопку 'Открыть →' для перехода к подборам
- Версия clients.js: 20260518a
- lint_css.py: проверка контраста по WCAG 4.5:1 для HEX-цветов,
разделение ошибок/предупреждений, проверка против всех тем
- config.py: SHIPMENTS_FILE_ID обновлён на актуальный из AI АНАЛИТИКА
ARRIVALS_FILE_ID сброшен в пустой (ID пока не найден)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
.client-name и .client-phone → color: var(--card), текст сливается
с фоном карточки во всех темах. Аватар и счётчики подборов остаются видимыми.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- quickActions: «Новый клиент» → «Заказы» (clipboard → #/assembly),
убрали дублирующую кнопку «Сборки» из быстрых действий
- «Свободный день»: текст теперь использует var(--ink)/var(--muted) вместо
rgba белых значений, которые были невидимы на светлом фоне --card;
заголовок — шрифт карточки ×1.3 (17.5px 600), описание — моно uppercase 9.5px
- styles.css: добавлены явные стили .client-card/.client-name/.client-phone/
.client-avatar и др. — исправлен невидимый текст в карточках клиентов
во всех темах (Foundry, Boardroom, Atelier)
- splash: minShow 1200 → 840 мс (−30%)
- index.html: версия ресурсов → 20260517c
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Every "Назад" / "На главную" button was calling location.reload() which
triggered a full page reload → splash screen appeared again. Fix: replace
reload() with routeByHash() call (global router function from app.js) which
re-renders the role-appropriate home screen from cached window.__zovMe
without any network round-trips.
Affected files: app.js, clients.js, measurements.js, request.js,
assembly.js, podbor.js. Bump asset versions to 20260517b to bust cache.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Every /api/me call was reading the entire Users sheet via get_all_values(),
exhausting the 60 reads/minute quota under any load. Added a 90-second
TTL cache keyed by sheet name:
- _cached_get_all_values(): returns cached data or refreshes on miss/expiry
- _invalidate_cache(): called after every write (append_row, append_named_row,
update_cell_by_key) so stale data is never served after mutations
- Patched: find_row, update_cell_by_key, list_users_with_role
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>