Files
selfpost/docs/progress.md
T
mix fc53ae1314 panel: shared nav, account settings, backup page, connection settings
Phase 12 (UI/UX). The navigation bar now renders once from layout.html
instead of being copied into each content template, so it is present on
every authenticated page — including the domain page and its delete
confirmation, which had no links at all — and the current page is
highlighted via .Active rather than quietly dropping out of the list.

New /account page changes the administrator's username and/or password:
the current password is required and the attempt is throttled on the same
limiter as the login form, so this route cannot be used to brute-force
past that limit. A password change invalidates every other session while
keeping the one performing it; a rename carries that session over.

Backup and domain import move from a card in the middle of the domain
list to their own /backup page, one card each; the handlers themselves
are unchanged, only the page the import form renders its errors on.

The domain page gains a "Sending server settings" card (server, port,
encryption) so a client can be configured without reading the docs; 587
is listed only when SUBMISSION_ENABLE is true for this deployment, which
is a deploy-time flag the panel cannot verify at runtime.

Client-side (static/panel.js, no libraries): Copy buttons on the values
that get carried elsewhere (DKIM record, new application credentials,
server name), and the Addresses field is hidden while the address mode is
wildcard, where the server ignores it.

Verified in a container on the dev server: setup, login, every page's
nav and active item, domain and application creation, all account-form
paths including cross-session invalidation, import errors, full backup
download. gofmt/vet/test/docker build green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 21:34:59 +03:00

45 lines
6.5 KiB
Markdown

# Прогресс реализации SelfPost
Живой трекер состояния. **Переживает `/clear`** — читается первым при возобновлении работы.
План (открытые вопросы + опциональные фазы): [implementation-plan.md](implementation-plan.md).
ТЗ: [specification.md](specification.md). История релизов: [CHANGELOG.md](../CHANGELOG.md).
История сделанного по фазам (0→11, все закрыты) — в `git log` и в CHANGELOG, здесь не дублируется.
## Как возобновить после сброса контекста
1. Прочитать этот файл (текущее состояние, что дальше).
2. Открыть `implementation-plan.md` — там нерешённые вопросы и опциональная линия 2.x.x (Фаза O1+).
3. При необходимости — детали в `specification.md`.
4. Продолжить с пункта «Следующий шаг».
## Модель по типу работы
Правило: безопасность / инфра / риск-критичное → **Opus**; UI / документация / бойлерплейт → **Sonnet**; тривиальная механика → **Haiku**.
## Коммиты
Коммит на **каждом осмысленном шаге** (не каждое сохранение файла, но и не только конец фазы): рабочий под-функционал, зелёная сборка, конец фазы. Минимум — один коммит на закрытую фазу + промежуточные на связные под-шаги. Ветка `main` (если пользователь не попросит отдельную). Push/PR — только по явной команде. Сообщение коммита завершается трейлером `Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>`.
На каждом таком шаге — запись в [CHANGELOG.md](../CHANGELOG.md) под `[Unreleased]` (формат Keep a Changelog). При явном решении зарезать версию — секция `[Unreleased]` переименовывается в `[X.Y.Z] - дата`, заводится новая пустая `[Unreleased]`. Тег/пуш образа — только по явному запросу (см. workflow release.yml).
## Протокол закрытия фазы/крупного шага
Перед `/clear` в конце каждого законченного шага Claude:
1. Обновляет этот файл: «Текущее состояние» → что изменилось, что дальше.
2. Проверяет применимые критерии «Готово, когда…».
3. Дописывает `CHANGELOG.md` под `[Unreleased]`.
4. Делает финальный коммит шага.
---
## Текущее состояние
- **Базовый линейный план 0→11 (v1.0) полностью выполнен и принят** (аудит безопасности ТЗ 7.6 — полное соответствие, деплой в проде подтверждён). Подробности — в git-истории и `CHANGELOG.md`.
- **Фаза 12 (v1.x, UI/UX) выполнена:** общий `nav`-partial в `layout.html` (нав на каждой аутентифицированной странице + подсветка текущей через `Active`), `/account` (смена логина/пароля админа с проверкой текущего пароля и инвалидацией остальных сессий, `store.UpdateAdmin`), `/backup` (полный бэкап и импорт домена — две отдельные карточки, убраны с дашборда), карточка «Sending server settings» на странице домена (сервер/465/587 по `SUBMISSION_ENABLE`), кнопки Copy у DKIM-записи и нового пароля приложения, скрытие поля «Addresses» в режиме wildcard (`static/panel.js`). Проверено в контейнере на dev-сервере (setup→login→домен→приложение→смена пароля→импорт), `gofmt`/`vet`/`test`/`docker build` зелёные.
- **Дальше — то, что перечислено в `implementation-plan.md`:** открытые вопросы (раздел A-D — hardening сверх обязательного 7.6, надёжность, CI/тесты), **Фаза 13 (v1.x, запланирована, не начата)** — страница статуса `/status` (процессы/очередь/TLS/milter-сокеты/PTR) + DNS-статус домена (DKIM/SPF-эвристика/DMARC), `/status` как стартовая страница и перенос кнопки Reload; **Фаза 14** — security-заголовки + документация про `/data/setup-token`; опциональная **Фаза O1+** (входящий релей, линия 2.x.x, требует согласования).
- **Прод:** `selfpost.example.com`, реальный Let's Encrypt сертификат, живой e2e (DKIM/SPF pass).
## Рабочая петля (dev loop) — ВАЖНО
Локально (Windows, `<repo>`) **нет Go и Docker** — только редактирование и git. Вся сборка/тесты идут на dev-сервере `selfpost.example.com` (Debian 12 bookworm, тот же, что базовый образ; провижён под разработку). Цикл: править локально → залить дерево на сервер → `go build`/`go vet`/`docker build`/тесты там. `rsync` в локальном git-bash нет, поэтому дерево едет tar'ом по ssh: `tar -czf - --exclude=.git . | ssh root@selfpost.example.com 'rm -rf /root/selfpost-src && mkdir -p /root/selfpost-src && tar -xzf - -C /root/selfpost-src'`; Go на сервере — в `/usr/local/go/bin` (не в `PATH` по умолчанию); образ — `docker build -f build/Dockerfile -t selfpost:dev --build-arg VERSION=dev .`. Источник истины и git-история — локальный репозиторий; сервер — только исполнитель сборки/тестов. Подключение: `ssh root@selfpost.example.com` (по ключу).