Update project handoff docs

This commit is contained in:
Your Name
2026-07-29 16:46:04 +05:00
parent b93b785862
commit eb04005e23
2 changed files with 39 additions and 1 deletions
+13
View File
@@ -117,6 +117,15 @@
- Для VK-постера user token нужно получать через VK ID Authorization Code Flow с PKCE: `/vk-oauth/start` -> `id.vk.ru/authorize` -> `/vk-oauth/callback`. Callback обменивает `code` через `id.vk.ru/oauth2/auth` на `access_token` + `refresh_token`, сохраняет `vk_poster_access_token`, `vk_poster_refresh_token`, `vk_poster_token_device_id`, `vk_poster_token_expires_at` и проверяет `wall.get` / `photos.getWallUploadServer`. Воркер обновляет access token через refresh token до истечения. Refresh token живёт 180 дней по документации VK ID; Redirect URI в VK ID-приложении: `https://sw.exostring.xyz/vk-oauth/callback`. - Для VK-постера user token нужно получать через VK ID Authorization Code Flow с PKCE: `/vk-oauth/start` -> `id.vk.ru/authorize` -> `/vk-oauth/callback`. Callback обменивает `code` через `id.vk.ru/oauth2/auth` на `access_token` + `refresh_token`, сохраняет `vk_poster_access_token`, `vk_poster_refresh_token`, `vk_poster_token_device_id`, `vk_poster_token_expires_at` и проверяет `wall.get` / `photos.getWallUploadServer`. Воркер обновляет access token через refresh token до истечения. Refresh token живёт 180 дней по документации VK ID; Redirect URI в VK ID-приложении: `https://sw.exostring.xyz/vk-oauth/callback`.
- По документации VK API метод `photos.getWallUploadServer` требует пользовательское право `photos`, которое VK выдаёт в исключительных случаях через запрос в поддержку `devsupport@corp.vk.com`. Если token без `photos`, VK-постер пропускает upload редакторских/URL-фото, но всё равно публикует текст и существующие VK `photo...`/`video...` attachments. - По документации VK API метод `photos.getWallUploadServer` требует пользовательское право `photos`, которое VK выдаёт в исключительных случаях через запрос в поддержку `devsupport@corp.vk.com`. Если token без `photos`, VK-постер пропускает upload редакторских/URL-фото, но всё равно публикует текст и существующие VK `photo...`/`video...` attachments.
- VK-постер исключает из очереди video-only записи с `raw_post_media.status='link_only'`: VK API не разрешает прикреплять часть чужих видео без предварительной загрузки в целевое сообщество. Медиа `link_only` также не добавляются к смешанным постам, а публикации со статусом `publish_failed` не возвращаются автоматически в каждый следующий часовой слот и требуют явного ручного повтора. - VK-постер исключает из очереди video-only записи с `raw_post_media.status='link_only'`: VK API не разрешает прикреплять часть чужих видео без предварительной загрузки в целевое сообщество. Медиа `link_only` также не добавляются к смешанным постам, а публикации со статусом `publish_failed` не возвращаются автоматически в каждый следующий часовой слот и требуют явного ручного повтора.
- Админка на 2026-07-29: заголовок берётся из `ADMIN_APP_TITLE`, fallback `Редакторская`; старая молния рядом с названием удалена. Боковая навигация сворачиваемая и по умолчанию свёрнута до иконок.
- В редакторской фильтры на ПК сворачиваемые и по умолчанию свёрнуты; лента занимает освободившуюся ширину. На мобильных статусные вкладки скроллятся горизонтально, а `/sources` и `/raw` не должны давать page-level horizontal scroll.
- В карточке редакторской meta-блок поста находится над постом. `Оригинальный текст` расположен спойлером сразу над `Финальный текст`; `AI заметки / Резолюция` отдельным спойлером показывает заметки/резолюцию и ниже preview того, как AI написал пост после рерайта.
- `Финальный текст` должен полностью вмещать текст без внутреннего скролла. Текущая защита от регресса: autosize через Alpine `ResizeObserver`, trimming лишних хвостовых whitespace в браузере/template и `min-h-[150px]`; не заменять на фиксированную большую высоту.
- В редакторской восстановлено скрытие медиа: крестик на фото/видео добавляет `delete_media_ids`, backend помечает media `editor_hidden=TRUE`, и такие media не публикуются.
- Действие `Отклонить` выполняется без confirm/alert. Возврат поста на проверку идёт через `/editor/{post_id}/return`; кнопка должна быть доступна во вкладках `accepted` и `rejected`.
- Редакторские action-кнопки должны обновлять только нужные HTMX partials статуса/действий, чтобы открытые спойлеры и тело поста не схлопывались после `Сохранить`, `Сохранить и Опубликовать` или `Вернуть на проверку`.
- Светлая/тёмная тема реализована CSS-переменными. Tailwind `app.*` цвета заданы как RGB channels и используются через `rgb(var(--app-...)/<alpha-value>)`; не возвращать hex-переменные, иначе `bg-app-bg/50` и похожие opacity utilities ломаются. В светлой теме hover не должен превращать текст в белый на светлом фоне.
- AI Writer на 2026-07-29 проверен с `ai_writer_model = anthropic/claude-sonnet-4-6`. Sonnet 4.6 иногда возвращает поле `rewrites` JSON-строкой, поэтому `validate_rewrites()` парсит stringified `rewrites` перед проверкой.
### 4.1. Секреты в `.env`, операционные настройки в БД ### 4.1. Секреты в `.env`, операционные настройки в БД
@@ -1258,6 +1267,8 @@ local repo
- Не выполнять `/opt/vk-parser`, `git pull` на VPS и `systemctl restart ...` - Не выполнять `/opt/vk-parser`, `git pull` на VPS и `systemctl restart ...`
без явного указания пользователя, что речь именно о старом VPS. без явного указания пользователя, что речь именно о старом VPS.
- Основной deploy remote: `gitea`. - Основной deploy remote: `gitea`.
- Перед push/deploy обязательно делать `git pull --rebase gitea main`.
- Coolify app UUID: `n6cnr60anmruiwkiey0pukye` (`FN-8 admin`). API token хранится только в `D:\DEVELOPMENT\.infra.md`; не переносить секрет в репозиторий.
- URL репозитория в Coolify должен резолвиться из build/helper container на - URL репозитория в Coolify должен резолвиться из build/helper container на
deploy-сервере. Не использовать `http://coolify.lan:3000/...`, если это имя deploy-сервере. Не использовать `http://coolify.lan:3000/...`, если это имя
не настроено внутри LXC/Docker; рабочий локальный URL Gitea: не настроено внутри LXC/Docker; рабочий локальный URL Gitea:
@@ -1287,6 +1298,8 @@ git push gitea main
`origin` остаётся GitHub/upstream/backup. Для deploy использовать `gitea`, `origin` остаётся GitHub/upstream/backup. Для deploy использовать `gitea`,
потому что Gitea webhook запускает Coolify. потому что Gitea webhook запускает Coolify.
Перед каждым push не пропускать `git pull --rebase gitea main`: пользователь отдельно просил не забывать pull, потому что Coolify должен видеть свежий commit из Gitea.
## 18. Контролируемый тест AI-райтера ## 18. Контролируемый тест AI-райтера
Важно: не включать AI writer обычным способом, если нужно проверить один пост. Иначе живой systemd service может начать брать очередь самостоятельно. Важно: не включать AI writer обычным способом, если нужно проверить один пост. Иначе живой systemd service может начать брать очередь самостоятельно.
+26 -1
View File
@@ -1,6 +1,6 @@
# N8 Parser: current state # N8 Parser: current state
Last updated: 2026-07-28 Last updated: 2026-07-29
This file is the short handoff state for future Codex threads. Read this first before touching the project, so the whole chat history does not need to be carried forward. This file is the short handoff state for future Codex threads. Read this first before touching the project, so the whole chat history does not need to be carried forward.
@@ -12,6 +12,7 @@ Current runtime is local infrastructure, not the old VPS.
- Git deploy remote: `gitea` -> `http://192.168.1.135:3000/exostring/new_vk_parser.git`. - Git deploy remote: `gitea` -> `http://192.168.1.135:3000/exostring/new_vk_parser.git`.
- Deploy path: push to `gitea/main` -> Gitea webhook -> Coolify -> Docker build/deploy. - Deploy path: push to `gitea/main` -> Gitea webhook -> Coolify -> Docker build/deploy.
- Coolify + Gitea LXC: `192.168.1.135` (CTID 102). - Coolify + Gitea LXC: `192.168.1.135` (CTID 102).
- Coolify app UUID: `n6cnr60anmruiwkiey0pukye` (`FN-8 admin`). API token is only in `D:\DEVELOPMENT\.infra.md`; do not copy it into repo docs.
- Application LXC: `192.168.1.105` (CTID 105, `new-vk-parser`). - Application LXC: `192.168.1.105` (CTID 105, `new-vk-parser`).
- Public admin URL: `https://panel.f-n8.ru` (also `https://admin.f-n8.ru` when DNS is current). - Public admin URL: `https://panel.f-n8.ru` (also `https://admin.f-n8.ru` when DNS is current).
- Coolify repository URL must be reachable from the deployment container; use `http://192.168.1.135:3000/exostring/new_vk_parser.git` or another resolvable Gitea URL, not `http://coolify.lan:3000/...`. - Coolify repository URL must be reachable from the deployment container; use `http://192.168.1.135:3000/exostring/new_vk_parser.git` or another resolvable Gitea URL, not `http://coolify.lan:3000/...`.
@@ -79,6 +80,29 @@ On 2026-06-17 the hashtag flow was fixed:
- `/users`: admin users. - `/users`: admin users.
- `/logs`: audit/log page if enabled. - `/logs`: audit/log page if enabled.
## Recent Admin UI State
As of 2026-07-29:
- Admin title comes from env `ADMIN_APP_TITLE`; fallback is `Редакторская`. The old hardcoded `Parser Admin` title and lightning SVG are gone.
- Admin sidebar is collapsible and collapsed by default; collapsed state shows icons only.
- Theme toggle supports dark/light themes. Tailwind `app.*` colors use RGB-channel CSS variables (`rgb(var(--app-...)/<alpha-value>)`), so do not revert them to hex variables or opacity utilities will break. Light-theme hover contrast is patched in base CSS.
- `/editor` desktop filter panel is collapsible and collapsed by default; the feed expands into the freed width.
- Mobile editor status tabs scroll horizontally instead of overflowing the viewport. `/sources` and `/raw` have mobile layout fixes to avoid page-level horizontal scroll.
- In editor cards, post meta/status/source info is above the post, not in a side column.
- `Оригинальный текст` is a spoiler directly above `Финальный текст`.
- `AI заметки / Резолюция` is a separate spoiler. It contains AI notes/resolution and an AI rewrite preview below it, so editors can compare their changes with the original AI rewrite.
- `Финальный текст` textarea must autosize to fully fit text without internal scroll. Current implementation uses Alpine `ResizeObserver`, trims trailing whitespace in the browser/template, and keeps `min-h-[150px]`.
- Media hiding is handled by the editor media X button: it adds hidden `delete_media_ids`; backend marks media `editor_hidden=TRUE`, so hidden media is not published.
- Reject action has no confirmation popup.
- Save/accept/return actions use targeted HTMX partial updates for status/actions where possible, so open spoilers and the post body should not collapse after clicking action buttons.
- `/editor/{post_id}/return` returns accepted/rejected posts to review. The return button should exist on both accepted and rejected tabs.
## Recent AI Writer State
- Current live writer model setting checked on 2026-07-29: `ai_writer_model = anthropic/claude-sonnet-4-6`.
- Sonnet 4.6 can return `rewrites` as a JSON string instead of a list. `validate_rewrites()` in `src/vk_parser_app/workers/ai_writer.py` now parses stringified `rewrites` before validation.
## Prompt Architecture ## Prompt Architecture
- Prompts are split into editable human part and technical contract part. - Prompts are split into editable human part and technical contract part.
@@ -97,6 +121,7 @@ On 2026-06-17 the hashtag flow was fixed:
## Working Rules For Future Codex Runs ## Working Rules For Future Codex Runs
- Before any deploy/server operation, read `D:\DEVELOPMENT\.infra.md` first. - Before any deploy/server operation, read `D:\DEVELOPMENT\.infra.md` first.
- Before pushing or deploying, run `git pull --rebase gitea main`.
- For this project, push deployable changes to `gitea/main`; Coolify handles deployment. - For this project, push deployable changes to `gitea/main`; Coolify handles deployment.
- Prefer small targeted file reads with `rg` and narrow ranges. - Prefer small targeted file reads with `rg` and narrow ranges.
- Avoid dumping long post texts from DB unless explicitly needed. - Avoid dumping long post texts from DB unless explicitly needed.