Skip to content

zorgoalex/API_with_Auth0_for_GoogleTable

Repository files navigation

Google Table Hub

Внутреннее Next.js-приложение для оперативной работы с производственным регистром в Google Sheets. После авторизации через Auth0 пользователи получают единый рабочий стол: интерактивную таблицу на Handsontable и производственный календарь, синхронизированные с одной и той же гугл-таблицей. Сервис поддерживает редактирование записей, отметку статусов, перемещение заказов между датами и полу-реальное время (Drive push + SSE, fallback polling).

Основные возможности

  • Авторизация через Auth0 с Refresh Token Rotation:
    • Автоматическое обновление токенов (до 30 дней без повторного логина)
    • Токены сохраняются в localStorage для работы между сессиями
    • Idle timeout: 7 дней неактивности
  • Отображение Google Sheet в Handsontable с возможностью редактирования, добавления и удаления строк.
  • Очередь изменений с дебаунсом и безопасной записью в лист через API /api/sheet.
  • Производственный календарь, группирующий заказы по плановым датам; drag&drop обновляет дату прямо в таблице.
  • Отметка статуса заказа чекбоксом внутри производственного календаря (обновляет соответствующий столбец в sheet).
  • Попытка подключения к push-уведомлениям Google Drive и трансляция изменений в браузер через Server-Sent Events; автоматический откат на опрос каждые 5 секунд при отсутствии вебхуков.
  • REST API-обёртка над Google Sheets для front-end и внешних интеграций.
  • Контекстное меню карточек (v2):
    • Desktop: ПКМ для вызова меню, hover для раскрытия подменю, клик для фиксации подменю
    • Mobile: двойной тап для вызова меню, тап для раскрытия подменю с адаптивным позиционированием
    • 11 свойств заказа с динамической загрузкой значений из Google Sheets data validation
    • Оптимистичные обновления с автоматическим откатом при ошибках
    • Визуальная индикация текущих значений
  • Визуальные индикаторы статусов производства на карточках Kanban:
    • 5 статусов технологического процесса: З Р Ш П У (Закуп пленки, Распил, Шлифовка, Пленка, Упаковка)
    • Цветовая индикация: оранжевый (#ff6f00) = "Готов", невидимый (цвет фона) = "-" (не готов)
    • Специальный режим: при всех статусах "Готов" отображается светло-оранжевая полоска внизу карточки
    • Tooltip при hover (desktop) с полным названием статуса и текущим значением
    • Компактное размещение в нижней части карточки с адаптивными размерами для mobile/desktop

Технологический стек

  • Next.js 14 + React 18.
  • Auth0 SPA SDK (@auth0/auth0-react).
  • Handsontable (@handsontable/react) для табличного UI.
  • Google Sheets API (google-spreadsheet) и Google Drive API (googleapis) для чтения/записи и push-уведомлений.
  • JWT верификация (jsonwebtoken, jwks-rsa).
  • Server-Sent Events для доставки уведомлений в браузер.

Архитектура и ключевые модули

  • components/Layout.js — оболочка рабочего стола: управляет навигацией между таблицей, производственным календарем и настройками, хранит общий список заказов, вычисляет набор дат для доски, предоставляет callback-функции для обновления статусов через DataTable ref.
  • components/DataTable.js — Handsontable-обёртка. Подтягивает данные из /api/sheet, ведёт очередь отложенных изменений, создаёт/удаляет строки, выставляет высоту таблицы, управляет push/SSE и fallback polling. Экспортирует метод updateOrderFields через useImperativeHandle для обновления статусов из Kanban.
  • components/KanbanBoard.js — визуализация заказов по дням. Показывает статусы, материалы, подсчитывает суммарную площадь, поддерживает drag&drop и оптимистичные обновления, интегрирует контекстное меню для быстрого изменения статусов, отображает визуальные индикаторы статусов производства.
  • components/OrderContextMenu.js — компонент контекстного меню для карточек заказов. Поддерживает desktop (ПКМ/hover/клик) и mobile (двойной тап/тап) взаимодействие, динамически загружает доступные значения из Google Sheets validation rules, реализует адаптивное позиционирование подменю.
  • lib/google-sheets.js — доступ к Google Sheet через сервисный аккаунт: чтение всех строк, добавление, обновление (по rowNumber) и удаление. Функция getColumnValidationRules() извлекает правила валидации для динамической загрузки списков статусов.
  • lib/auth.js — проверка JWT от Auth0, в том числе через JWKS, и утилита requireAuth для API-роутов.
  • pages/api/sheet.js — REST CRUD для таблицы (GET/POST/PUT/DELETE). Все запросы защищены requireAuth.
  • pages/api/sheet/statuses.js — API эндпоинт для получения списка доступных статусов из Google Sheets data validation с fallback на жестко закодированные значения.
  • pages/api/setup-push.js — настройка drive.files.watch, проверяет окружение, создаёт канал на Google Drive и возвращает информацию о вебхуке.
  • pages/api/webhook/drive-changes.js — точка приёма push-уведомлений от Google и SSE-эндпоинт для клиентов. Рассылает события всем подключённым браузерам.
  • pages/index.js, _app.js, _document.js — корневые страницы и провайдер Auth0.
  • styles/globals.css — единый стиль интерфейса (светлая/тёмная тема, состояния drag&drop и т.д.).

Переменные окружения

Переменная Описание Обязательность
AUTH0_BASE_URL Базовый URL приложения (например, http://localhost:3000 локально или продовый домен). Используется на клиенте и при формировании вебхуков. Да
AUTH0_ISSUER_BASE_URL Домен арендатора Auth0, например https://your-tenant.eu.auth0.com. Да
AUTH0_CLIENT_ID Client ID SPA-приложения в Auth0. Да
AUTH0_SECRET Секрет приложения (используется Next.js на сервере; нужен в production, для разработки можно заменить случайной строкой). Рекомендуется
GOOGLE_SHEET_ID ID таблицы в Google Sheets (часть URL после /d/). Да
GOOGLE_CREDENTIALS JSON сервисного аккаунта (как выдаёт Google; строка одним значением). Предпочтительный способ передачи ключей. Да, если не используете пары ниже
GOOGLE_SERVICE_ACCOUNT_EMAIL Email сервисного аккаунта. Задавайте вместе с GOOGLE_PRIVATE_KEY, когда GOOGLE_CREDENTIALS недоступна. Условно
GOOGLE_PRIVATE_KEY Приватный ключ сервисного аккаунта. Храните в кавычках, переводите строки через \n. Условно

Совет: убедитесь, что сервисный аккаунт имеет доступ на чтение/запись к целевой таблице (поделитесь таблицей на email аккаунта). Если используете push-уведомления, учётке также нужна роль Drive API Service Agent или аналогичный доступ к Drive.

Настройка Auth0

  1. Создайте SPA-приложение в Auth0.
  2. В разделе Application URIs добавьте AUTH0_BASE_URL в поля Allowed Callback URLs, Allowed Logout URLs и Allowed Web Origins.
  3. Разрешите audience https://{tenant}.auth0.com/api/v2/ для выдачи access token (Management API). Добавьте scope openid profile email offline_access.
  4. Включите встроенный Login, убедитесь что silent login работает (для getAccessTokenSilently).
  5. Настройте Refresh Token Rotation (Settings → Advanced Settings → Grant Types):
    • ✅ Включите "Refresh Token Rotation"
    • ✅ Включите "Set Idle Refresh Token Lifetime"
    • ID Token Expiration: 86400 секунд (24 часа)
    • Idle Refresh Token Lifetime: 604800 секунд (7 дней)
    • Maximum Refresh Token Lifetime: 2592000 секунд (30 дней)
    • Rotation Overlap Period: 0 секунд

Настройка Google API

  1. Создайте сервисный аккаунт в Google Cloud Console, включите Google Sheets API и Google Drive API.
  2. Скачайте JSON ключ. Либо положите содержимое в GOOGLE_CREDENTIALS, либо вынесите client_email и private_key в отдельные переменные.
  3. Поделитесь Google Sheet с сервисным аккаунтом (роль «Редактор»).
  4. Для push-уведомлений:
    • Подтвердите домен, на который будет указывать вебхук (AUTH0_BASE_URL/api/webhook/drive-changes) в Google Search Console.
    • Убедитесь, что приложение доступно по HTTPS из интернета.
    • После запуска авторизуйтесь и выполните POST /api/setup-push (DataTable делает это автоматически; статус смотрите в консоли браузера).

Без публичного домена приложение продолжит работать на fallback polling каждые 5 секунд.

Локальный запуск

  1. Установите зависимости: pm install.
  2. Создайте .env.local с переменными из таблицы.
  3. Запустите dev-сервер: pm run dev (по умолчанию http://localhost:3000).
  4. Авторизуйтесь через Auth0. После входа:
    • Вкладка «Таблица» загрузит данные из Google Sheets. Индикатор статус-бара покажет состояние соединения (polling / push / ошибка).
    • Вкладка «Производственный календарь» отобразит заказы по дням. Перетаскивание заказа меняет дату в таблице.
  5. Для теста realtime убедитесь, что Google может достучаться до вебхука или используйте инструмент вроде ngrok, обновите AUTH0_BASE_URL и перезапустите сервер.

API и интеграция

Метод и путь Описание
GET /api/sheet Возвращает все строки листа. Требует Authorization: Bearer от Auth0.
POST /api/sheet Добавляет строку (ожидает JSON с полями, совпадающими с заголовками таблицы).
PUT /api/sheet?rowId={n} Обновляет строку по номеру. Тело — объект со значениями столбцов.
DELETE /api/sheet?rowId={n} Удаляет строку.
GET /api/sheet/statuses Возвращает доступные статусы для всех свойств заказа из Google Sheets data validation (с fallback на hardcoded значения).
POST /api/setup-push Регистрирует канал drive.files.watch для текущего листа. Требует доступного из интернета URL.
GET /api/webhook/drive-changes?token=... SSE-канал для браузера. Токен — тот же access token Auth0.
POST /api/webhook/drive-changes Точка приёма вебхуков Google Drive. Google вызывает её, когда лист меняется.

При разработке следите за логами console (в коде оставлено много диагностических сообщений, помогающих отладить интеграцию).

Структура проекта

components/
  DataTable.js             # Handsontable + realtime логика
  KanbanBoard.js           # Календарное представление заказов
  OrderContextMenu.js      # Контекстное меню для редактирования статусов
  Layout.js                # Общий фрейм приложения
lib/
  auth.js                  # Верификация JWT и guard для API
  google-sheets.js         # Утилиты работы с Google Sheets + парсинг validation rules
pages/
  api/
    sheet/
      statuses.js          # API для получения доступных статусов
    sheet.js               # CRUD над таблицей
    setup-push.js          # Регистрация push-канала
    webhook/
      drive-changes.js     # Вебхук и SSE
  _app.js                  # Auth0Provider с refresh tokens
  _document.js
  index.js
styles/
  globals.css
Google Sheets Api Quota.md
Setting push Google Drive…md

Особенности и советы по эксплуатации

Общие рекомендации

  • Названия столбцов в таблице должны точно совпадать с теми, что используются в коде (см. DataTable и KanbanBoard). Если вы переименуете колонку в Google Sheet, обновите маппинг в PROPERTY_COLUMN_MAP (OrderContextMenu.js).
  • Производственный календарь рассчитывает набор дат динамически: 5 дней назад от текущего дня + все рабочие дни до максимальной плановой даты в таблице (воскресенье пропускается).
  • Очередь изменений в DataTable работает с задержкой 500 мс; не закрывайте вкладку, пока индикатор «Сохранение…» активен.
  • При локальной разработке push-канал, как правило, не поднимется — ориентируйтесь на polling и логи.
  • Если заметите неожиданные изменения в файлах, остановитесь и уточните у команды (репозиторий может использоваться как рабочий).

Авторизация и токены

  • Первый логин после обновления: пользователям нужно залогиниться заново для получения refresh token.
  • Срок действия токенов: Access token обновляется автоматически каждые 24 часа через refresh token.
  • Автоматический выход: через 7 дней неактивности или 30 дней с последнего логина (в зависимости от того, что наступит раньше).
  • Токены в localStorage: при работе на общем компьютере рекомендуется выходить из системы через кнопку Logout.

Контекстное меню и статусы

  • Desktop: ПКМ на карточке → выбор свойства (hover для раскрытия подменю) → клик на значение
  • Mobile: двойной тап на карточке → тап на свойство → тап на значение
  • Изменение статусов выполняется с оптимистичным обновлением (карточка обновляется сразу); при ошибке значения автоматически откатываются.
  • Доступные значения для выбора подтягиваются из Google Sheets data validation rules через /api/sheet/statuses.
  • Если data validation не настроена в Google Sheets, используются hardcoded fallback значения.

Визуальные индикаторы статусов производства

  • З Р Ш П У = Закуп пленки, Распил, Шлифовка, Пленка, Упаковка
  • Оранжевая буква = статус "Готов"
  • Невидимая буква = статус "-" (не готов)
  • Светло-оранжевая полоска внизу карточки = все 5 статусов в "Готов" (заказ полностью готов)
  • Tooltip при hover (desktop) показывает полное название статуса и текущее значение

Технические нюансы

  • DataTable импортируется статически (не через dynamic import), чтобы ref был доступен из Layout для обновления статусов через контекстное меню.
  • При добавлении новых свойств в контекстное меню:
    1. Обновите ORDERED_PROPERTIES в OrderContextMenu.js
    2. Добавьте маппинг в PROPERTY_COLUMN_MAP (если название в UI ≠ название в Google Sheets)
    3. Настройте data validation в Google Sheets для автоматической загрузки списков значений

Скрипты npm

  • npm run dev — запуск Next.js в режиме разработки.
  • npm run build — сборка production.
  • npm start — запуск production-сборки.
  • npm run lint — проверка линтером.

Git Workflow development

branch main - production branch stage - stage

Releases

No releases published

Packages

No packages published