# Журнал авторского надзора — AR-1

Инструмент для дизайнеров студии AR-1 (architecture & design), заменяющий
ручное заполнение Word-отчётов об авторском надзоре на стройке. Дизайнер
заполняет веб-форму (в т.ч. голосом), данные синхронизируются в Google
Таблицу, менеджер видит сводную панель по всем объектам и может скачать
готовый брендированный PDF-отчёт для заказчика.

## Файлы проекта

- **`forma-zhurnala.html`** — форма для дизайнеров. Полностью самодостаточный
  HTML-файл (без зависимостей, без npm/build-шага) — открывается двойным
  кликом или хостится как есть.
- **`panel-menedzhera.html`** — панель для владельца/менеджера: сводные данные
  по всем дизайнерам/объектам, фильтры, скачивание сводного PDF-отчёта.
- **`index.html`** — лендинг со ссылками на обе страницы (для хостинга/превью).
- **`AppsScript_Code.gs`** — бэкенд. Вставляется в Google Apps Script,
  привязанный к Google Таблице (она же база данных). Разворачивается как Web
  App (`Deploy → Web app → Execute as: Me, Access: Anyone`), выданный URL
  вставляется в `CONFIG.API_URL` в обоих HTML-файлах.

## Архитектура

```
forma-zhurnala.html   ─┐
                        ├──► Google Apps Script (Web App) ──► Google Sheets
panel-menedzhera.html ─┘         (AppsScript_Code.gs)         (Entries, Positions)
```

Никакого отдельного сервера/хостинга под бэкенд не нужно — Apps Script уже
исполняется на серверах Google. Хостинг нужен только для двух статичных HTML.

### Данные (два листа в одной Google Таблице)
- **Entries** — записи журнала: дата, тип мероприятия, место, участники,
  что обсуждали, результат + метаданные (studio, designer, project, client).
- **Positions** — живой трекер позиций/закупок (не пересоздаётся каждый
  отчёт, статус меняется по ходу проекта): категория, позиция, статус
  (Согласовано / Требует согласования / К обязательному заказу), стоимость,
  примечания.

### API (`AppsScript_Code.gs`)
- `GET ?resource=entries` — записи (можно фильтровать по `project`,
  `designer`, `dateFrom`, `dateTo`)
- `GET ?resource=positions&project=...` — позиции по объекту
- `GET ?resource=suggestions` — уникальные ранее введённые значения
  (`projects`, `places`, `participants`, `studios`, `designers`, `clients`)
  для автодополнения полей в форме
- `POST` с `{action: 'create'|'update'|'delete', recordType: 'entry'|'position', ...}`
  — запись/обновление/удаление в соответствующий лист

Все POST-запросы уходят с `Content-Type: text/plain` (не `application/json`)
намеренно — это обходит CORS preflight, который Apps Script не умеет
обрабатывать.

## Как формируется отчёт (PDF)

**Важно: раньше генерировался `.docx` через встроенную библиотеку docx.js —
отказались от этого подхода.** Причина: один и тот же файл по-разному (и
криво) рендерился в Word/LibreOffice/Google Docs — то ячейки таблиц
сжимались до одной буквы в строке, то поле подписи разрывалось между
страницами. Все эти баги — следствие того, что разные программы
по-разному интерпретируют DOCX.

Сейчас вместо этого: кнопка «Скачать отчёт (PDF)» открывает новую вкладку с
HTML-версией отчёта, настроенной под печать (`@page`, `break-inside: avoid`
на все таблицы/блоки), и сразу вызывает `window.print()` — пользователь
жмёт «Сохранить как PDF» в системном диалоге печати браузера. Это даёт
пиксель-в-пиксель одинаковый результат везде, без зависимости от
сторонних библиотек и без сетевых запросов.

Функции генерации: `buildPrintHtml()` в `forma-zhurnala.html` (из
`state.entries`/`state.positions`), `buildPrintHtml()` в
`panel-menedzhera.html` (из отфильтрованных `filtered`/`filteredPositions`,
с доп. колонкой «Объект» в таблицах позиций, если выбрано «Все объекты»).

## Брендинг

Цвета — точные значения из логотипа AR-1 (пиксель-сэмплинг через PIL):
- Красный акцент: `#DD0031`
- Серый (вторичный текст): `#8E9090`

Логотип встроен как `data:image/png;base64,...` (константа `LOGO_DATA_URI`
в `<script>`) — используется и в шапке веб-интерфейса, и в печатном PDF.
Если логотип поменяется, нужно перегенерировать base64 и заменить строку
в обоих файлах (искать `const LOGO_DATA_URI`).

## Голосовой ввод и автогенерация (текущее состояние)

- Поле **«Что обсуждали / выбирали»** — кнопка 🎤, использует браузерный
  Web Speech API (`webkitSpeechRecognition`, `lang: 'ru-RU'`). Бесплатно,
  без сервера, но **работает только в Chrome** (не работает в Safari/iOS).
- Поле **«Результат / решение»** — кнопка ✨, сейчас это **заглушка**
  (функция `generateResult()`): имитирует задержку запроса и подставляет
  первое предложение из «Обсуждали». Нужно заменить на реальный вызов ИИ.

### Следующий шаг (согласовано с пользователем, но не сделано)
Пользователь планирует завести бесплатный ключ **Groq** (console.groq.com,
без карты, 2000 запросов/день) и попросил заменить на:
1. **Транскрибацию** — вместо Web Speech API使用 Groq Whisper Large v3
   (работает во всех браузерах, включая Safari/iPhone — в отличие от
   текущего решения). Потребуется: запись аудио через `MediaRecorder` на
   клиенте → отправка blob на Apps Script → Apps Script проксирует запрос
   в Groq (ключ хранится в Script Properties, не светится в браузере) →
   текст возвращается в поле.
2. **Автогенерацию результата** — тем же ключом Groq, LLM-модель (Llama)
   читает текст «Обсуждали» и формулирует краткий «Результат». Тоже через
   Apps Script как прокси.

Ключ пользователь заводит сам (я не могу создать аккаунт за него).

## Автодополнение полей (сделано)

Поля «Название студии», «Дизайнер», «Объект / проект», «Заказчик», «Место /
адрес», «Участники» — обычные `<input list="...">` + `<datalist>`,
заполняются из `GET ?resource=suggestions`. Это НЕ жёсткий select — можно
вписать новое значение, оно само станет подсказкой в следующий раз.

**⚠️ Требует передеплоя Apps Script** — пользователь ещё не обновил
развёрнутую версию скрипта (только вставил новый код в код черновика).
Без передеплоя `resource=suggestions` вернёт 404/пусто, но это не ломает
форму — просто подсказки не появятся. Порядок передеплоя: открыть проект
в script.google.com → вставить актуальный `AppsScript_Code.gs` → **Deploy
→ Manage deployments → карандаш → Version: New version → Deploy**. URL
веб-приложения при этом не меняется.

## Открытые задачи / пожелания пользователя

1. **Groq-интеграция** (см. выше) — ждём, пока пользователь заведёт ключ.
2. **Пароль на панель менеджера** — отложено пользователем ("пока с
   доступом повременим"), но панель сейчас полностью открыта по ссылке.
   Когда вернёмся к этому — например, HTTP Basic Auth через `.htaccess`
   на хостинге (пользователь на Apache-хостинге с FTP/панелью управления).
3. **Деплой на прод** — у пользователя уже есть хостинг с FTP/панелью
   управления для сайта AR-1. План: `ar-1.ru/report/` (форма, файл
   переименовать в `index.html`) и `ar-1.ru/report/admin/` (панель,
   тоже `index.html`). Ещё не сделано.
4. Apps Script нужно передеплоить (см. выше) при тестировании
   автодополнения.

## Тестирование без сервера

Оба HTML открываются просто двойным кликом (`file://`) — все фичи, кроме
синхронизации с Google Таблицей (нужен задеплоенный `CONFIG.API_URL`),
работают локально. Для проверки мобильной вёрстки — DevTools → Toggle
device toolbar (`Ctrl+Shift+M` / `Cmd+Shift+M`).

## Известные технические детали / грабли, на которые уже наступали

- **Ширина колонок в таблицах** — раньше (в эпоху docx) был баг: Google
  Docs сжимал колонки без явного указания `columnWidths` на уровне
  таблицы. Больше не актуально (перешли на print-HTML/CSS), но если
  когда-нибудь возвращаться к docx-экспорту — помнить про это.
- **`cantSplit` / `break-inside: avoid`** — обязательно на все
  таблицы/блоки-карточки в печатной версии, иначе строки разрываются
  между страницами (особенно поле «Замечания заказчика» — высокая пустая
  ячейка, легко попадает на границу страницы).
- **iOS Safari не поддерживает Web Speech API** — если дизайнеры
  когда-нибудь начнут использовать iPhone, текущий 🎤 просто не будет
  работать (кнопка задизейблена с тултипом, но это не полноценная
  деградация функциональности).
