Znymkari · Лабораторія
←

Документация

Архитектура Статус Контекст История Продакшн Ноут Олега VPS COM Oleg COM Pavel Коммиты VPS Коммиты Цеха

STATE.md — статус проекта

Обновляется после каждой рабочей сессии. ТЗ — ARCHITECTURE.md. История — CHANGES.md. Чек-лист прода — PRODUCTION.md. Название проекта — Znymkari (Студія / Медиа группа — на логотипе).

Формат сессий: только даты в CHANGES.md. В остальных докax — без номеров. Если в один день несколько сессий — 2026-10-14, 2026-10-14-б, 2026-10-14-в.


Что делаем сейчас

Проект znymkari-data — цех импорта на ноуте Олега.

2026-10-15-б — реструктуризация завершена. D:\content_shop\web\ стал отдельным git-репо (43 коммита, история через git-filter-repo). Корень D:\content_shop\ — без git, как в ARCHITECTURE.md §7.1. Бэкап: G:\My Drive\backups\content_shop_2026-10-15\.

Два независимых проекта:

Проект Где живёт Роль
web/ VPS (znymkari.com) Сайт-витрина: клиент, корзина, оплата, выдача
znymkari-data/ Ноут Олега (oleg-home) Цех: импорт, sanitize, превью, push

Связь между ними: management-команды pack_event → push_event (ноут) → receive_event (VPS). Транспорт — JSON (django.core.serializers) + ORM-merge. Единая схема БД на обоих.

Текущий план работ:

  1. ✅ Создать каркас znymkari-data — Django-проект, отдельный репо.
  2. ✅ import_service.py, media_metadata.py, generate_video_posters.py, management/commands/ — в znymkari-data.
  3. ✅ sanitize.py — транслит и чистка имён.
  4. ✅ Копирование оригинала из zyn-festivals/<название>/ в STORAGE с sanitize.
  5. ✅ Новые поля моделей: Event.slug, Event.external_id. (storage_root удалён 2026-10-16.)
  6. ✅ Мини-админка для Олега: /, /import/, /import/<id>/, /storage/, /settings/.
  7. ✅ Транспорт: pack_event / push_event (ноут) + receive_event (VPS). Проверено на живом цикле.
  8. ✅ Первый реальный импорт фестиваля (Dance Vocal Class).
  9. ✅ gunicorn-oleg.service — Django на 0.0.0.0:8000 (развёрнут).
  10. ✅ Интерфейс отправки (pack_event / push_event) с логами и прогрессом.
  11. ✅ Страница «Чистка» (удаление мусора и хвостов).
  12. ⏳ Обратный канал VPS → ноут: pull_protected + файл чистки.
  13. ⏳ Кнопка «Удалить из storage» на /storage/ — после pull_protected.

Детали — в ARCHITECTURE.md §5.1 (обновляется вместе с кодом).


Что в очереди

Ближайшее (znymkari-data)

  1. ✅ Каркас проекта + git init.
  2. ✅ Модели каталога — перенос из web/.
  3. ✅ sanitize.py — транслит + правила.
  4. ✅ import_service.py — переписать без services.media_metadata, добавить копирование.
  5. ✅ Новые поля моделей + миграции.
  6. ✅ Мини-админка для Олега.
  7. ✅ pack_event / push_event / receive_event — проверено на живом цикле.
  8. ⏳ systemd-юнит gunicorn-oleg.service + деплой znymkari-data на ноут Олега.
  9. ⏳ Первый реальный импорт.
  10. ⏳ Обратный канал VPS → ноут: pull_protected + файл чистки.
  11. ⏳ Кнопка «Удалить из storage» на /storage/ — после pull_protected.

Дальше (после стабильного импорта)

  1. WireGuard VPS ↔ ноут.
  2. nginx на ноуте + auth_request.
  3. files.znymkari.com + Let's Encrypt.
  4. Модели DownloadToken, Order, OrderItem — Этап 3.
  5. Платёжный провайдер (LiqPay / Fondy / Monobank).
  6. Internal API /internal/large-preview/ — 60% оригинала с QR.
  7. Кнопка «Проверить качество» в лайтбоксе.
  8. home.html → канонический app-shell.
  9. event.html → общий lightbox.js.
  10. Восстановление пароля через email.
  11. Реальный SMTP.
  12. SiteSettings — контакты, соцсети, лого.
  13. Мобильная версия.

Что не начато совсем

Компонент Статус
znymkari-data — каркас ✅
sanitize.py ✅
Копирование оригинала из zyn-festivals в STORAGE ✅
Event.slug, Event.external_id ✅
Event.storage_root (удалено 2026-10-16) ✅
Media.width/height ❌
Мини-админка Олега (/, /import/, /storage/, /settings/) ✅
pack_event / push_event / receive_event ✅
gunicorn-oleg.service ✅
Модель ImportJob ✅
Кнопка «Проверить связь с VPS» в /settings/ ✅
Команда assign_media_authors на VPS ✅
Обратный канал VPS → ноут (pull_protected) ❌
DownloadToken + auth_request ❌
/internal/large-preview/ ❌
Заказы, оплата, выдача ❌
Восстановление пароля ❌
Реальный SMTP ❌
Мобильная версия ❌
SiteSettings — контакты, соцсети, лого ❌
Страница «Услуги» ❌
Кнопка чистки «Удалить без лайков и покупок» ❌
Публичная форма замечаний ❌
Вложения к Issue ❌
Экспорт ивентов (JSON / PDF / Excel) 🚧
Кэшбек, рефералка ❌
Удаление старого мира ✅ (2026-10-16)
Grid-view для разметки ⏳
.timeline-* → .markup-* ⏳

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

Сайт (web/)

Ноут Олега

VPS


Открытые вопросы


VPS — параметры (для новой сессии)

Параметр Значение
IP 128.140.81.213
IPv6 2a01:4f8:c010:9558::/64
Домен znymkari.com (Hetzner, аккаунт Олега konsolch)
Имя сервера znymkari
Провайдер Hetzner
Location Falkenstein (fsn1)
Type CPX22 (2 vCPU / 4 ГБ / 80 ГБ SSD)
OS Ubuntu 24.04.5 LTS
Kernel 6.8.0-146-generic
Swap 2 ГБ (/swapfile)
SSH root root@128.140.81.213, ключ znymkari-my
SSH deploy deploy@128.140.81.213, ключ znymkari-my, sudo NOPASSWD
Backups включены
Цена €23.89/мес
Owner Олег (zhurbenko1985@gmail.com)
Команда Олег — Owner, я — Member
WorkingDirectory /home/deploy/content_shop/web
Структура content_shop/ содержит web/ + venv/ + gunicorn.sock
settings_local /home/deploy/content_shop/web/config/settings_local.py
settings_local_prod /home/deploy/content_shop/web/config/settings_local_prod.py (шаблон)
IPv6 фикс /etc/gai.conf → precedence ::ffff:0:0/96 100
Cockpit https://128.140.81.213:9090, юзер cockpit_admin
Telegram Webhook (/telegram/webhook/<secret>/). Long polling отключён.
Бот @Znymkari_dev_bot (id 8807489402). Токен и TELEGRAM_WEBHOOK_SECRET — в settings_local.py.
Логи journalctl -u gunicorn-znymkari -f. Файл /var/log/znymkari/django.log.

Стек: - Пользователь deploy (uid 1000). - Директория проекта: /home/deploy/content_shop. - venv: /home/deploy/content_shop/venv. - gunicorn: /etc/systemd/system/gunicorn-znymkari.service. - nginx: /etc/nginx/sites-available/znymkari. - Сокет: /home/deploy/content_shop/gunicorn.sock. - www-data в группе deploy. - Postgres: база znymkari_db, юзер znymkari_user, схема public (владелец юзер). - settings_local.py — прод (НЕ в git). - Static: /home/deploy/content_shop/staticfiles.


Ноут Олега — параметры

Параметр Значение
Пользователь olegarh (uid 1000), deploy (uid 1001, sudo NOPASSWD)
Имя хоста oleg-home
ОС Ubuntu Server 24.04 LTS, без GUI, ядро 7.0.0-38
Сеть Wi-Fi wlp8s0, LAN 192.168.31.87 (резерв в роутере). Ethernet сломан.
Внешний SSH 193.176.249.24:22022 → 192.168.31.87:22
SSH-ключ id_ed25519 (разработчик), в authorized_keys для olegarh и deploy
Крышка HandleLidSwitch=ignore. Sleep/suspend/hibernate замаскированы.
Роль Мини-UPS (2–4 ч), склад оригиналов, цех импорта
Python 3.14
PostgreSQL 18, кластер 18/main, локаль uk_UA.UTF-8
nginx 1.28
ffmpeg 8.0.1
HDD WD My Passport 2 ТБ, NTFS, /mnt/hdd, SMART здоровый
STORAGE /mnt/hdd/znymkari-storage/ — рабочая копия
FESTIVALS /mnt/hdd/zny-festivals/ — оригиналы, источник импорта
HEAP /mnt/hdd/zny-heap/ — свалка
SSD ОС + PostgreSQL + venv + превью
Симлинки /home/olegarh/HDD → /mnt/hdd, /home/olegarh/STORE → /mnt/hdd/znymkari-storage
Samba Юзер olegarh, порт 445, LAN 192.168.31.0/24. Шары zny-festivals, zny-heap.
БД znymkari_local, юзер znymkari_local_user, порт 5432
Django /home/deploy/znymkari-data/ (планируется), venv рядом
systemd gunicorn-oleg.service, 0.0.0.0:8000
Доступ к сайту Браузер по LAN: http://192.168.31.87:8000/
WinSCP Локально 192.168.31.87:22 (не 22022, NAT loopback не работает)
deploy не видит /home/olegarh/ — норма
ufw Не включён. Правило для 445 добавлено.

Что работает на сегодня

Сайт (web/)

Компонент Статус
Django 6.1.1, Europe/Kyiv, USE_TZ ✅
Все модели каталога + прайс ✅
Админка Django, разметка, камеры ✅
Просмотр превью, генерация — на ноуте ✅
Импорт медиа — только в znymkari-data (web-копия удалена) ✅
Постеры видео + 10-сек превью со звуком ✅
Главная, список ивентов, прайс ✅
Клиентская страница ивента — галерея, лайтбокс ✅
Избранное (LS + БД) + серверная корзина + merge-prompt ✅
Общий lightbox.js / lightbox.css ✅
header_actions.html, ?auth=, BuyModal ✅
UserEventDiscount + cart/smart/ (правила 1–6) ✅
Три типа офферов с applied ✅
Привязка награды к выступлению ✅
App-shell на 7 шаблонах ✅
Регистрация / логин / активация / профиль ✅
Telegram-флоу (вход, привязка, бот, 5 языков) ✅
apps.issues — трекер + админка ✅
Читалка доков — 8 табов ✅
Django-тесты (77) ✅
deploy.bat + стоп-краны ✅
VPS Hetzner — развёрнут, HTTPS работает ✅
Telegram webhook + set_telegram_webhook ✅
Security hardening (HSTS, secure cookies) ✅
LOGGING с RotatingFileHandler ✅
Отдельный git-репо (web/.git, 43 коммита) ✅
Три поля Event (external_id, storage_root, slug) ✅
manage.py migrate в deploy.bat (шаг 5) ✅

Ноут Олега

Компонент Статус
Ubuntu Server 24.04 ✅
Пользователи olegarh / deploy ✅
Внешний SSH 193.176.249.24:22022 ✅
Wi-Fi Broadcom DKMS ✅
Сон отключён ✅
HDD NTFS /mnt/hdd ✅
Папки STORAGE / FESTIVALS / HEAP ✅
Симлинки в /home/olegarh ✅
Стек Python 3.14 / PG 18 / nginx 1.28 / ffmpeg 8.0.1 ✅
Samba с шарами zyn-festivals, zyn-heap ✅
10 фестивалей в zyn-festivals ✅
Свалка zyn-heap заполнена ✅
Django + settings_local.py в znymkari-data ✅
Модели каталога в znymkari-data ✅ (10 моделей, миграции 0001–0010)
sanitize.py в znymkari-data ✅
import_service.py в znymkari-data ✅
Мини-админка для Олега (/, /import/, /import/<id>/, /storage/, /settings/) ✅
Модель ImportJob ✅
Транспорт pack_event / push_event ✅
Кнопка «Проверить связь с VPS» ✅
systemd gunicorn-oleg.service ✅
Деплой znymkari-data на ноут ✅
Первый реальный импорт фестиваля ✅
Транспорт pack_event / push_event в UI ✅
Страница «Чистка» ✅
Обратный канал pull_protected 🔜
Кнопка «Удалить из storage» 🔜
WireGuard VPS ↔ ноут 🔜
nginx на ноуте + auth_request 🔜