Commit Graph

111 Commits

Author SHA1 Message Date
vasyansk 4533b0ca25 feat(api): RequireAuth+RequireProjectAccess middleware, IDOR-scope check/apply по projectID 2026-07-03 20:47:40 +07:00
vasyansk 35ffe73ae3 fix(auth): wiring Auth/Sessions, нормализация email, GetUserByID для /me, 409 на дубль, timing-guard логина 2026-07-03 20:29:05 +07:00
vasyansk aa0ef1c6a9 feat(api): auth-хендлеры register/login/logout/me + session cookie 2026-07-03 20:11:00 +07:00
vasyansk a584cf5c37 fix(auth): VerifyPassword валидирует параметры/версию, не паникует на битом хэше 2026-07-03 19:58:54 +07:00
vasyansk 12b7945efc feat(auth): argon2id пароли + session store (sha256 токена) 2026-07-03 19:50:11 +07:00
vasyansk 3bd237d562 feat(store): миграция sessions/password + методы users/sessions/projects
Фаза 2, Task 1: добавлена таблица sessions и nullable password_hash у
users, sqlc-запросы и *Store-обёртки (CreateUser, GetUserByEmail,
CreateProjectForUser, GetProjectOwned, GetUserProject, CreateSession,
GetSessionUser, DeleteSession, RegisterUser в транзакции), интеграционные
тесты на testcontainers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwxdSt4reTm7Dj1oxRvpP3
2026-07-03 19:44:36 +07:00
vasyansk bd82fe5509 docs: план реализации Фазы 2 (авторизация)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 19:37:27 +07:00
vasyansk fc5d3cdbae docs: детализация дизайна Фазы 2 (авторизация)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 19:33:12 +07:00
vasyansk 136708bdf0 merge: Фаза 1C — React SPA
- web/: Vite+React+TS+TanStack Query+shadcn/Tailwind, тёмная technical console
- API-клиент+типы+хуки (зеркало Go DTO), DEFAULT_PROJECT_ID
- DiffView+DomainDiffPage (prune-guard по умолчанию выключен)
- DomainsPage (импорт зон, привязка шаблона), AccountsPage (secret+Selectel), TemplatesPage+RecordEditor
- internal/web: embed SPA + SPA-fallback, cmd/server монтирование (API приоритетно)
Финальный ревью: READY TO MERGE. web 32 теста, Go 74/14 пакетов.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 19:17:45 +07:00
vasyansk 4140847a15 fix(web,server): плейсхолдер dist для воспроизводимой сборки + /api без слэша → API
Коммитим internal/web/dist/index.html как минимальный плейсхолдер, чтобы
//go:embed all:dist находил совпадения на чистом клоне без npm/`make web`
(CRITICAL: go build ./... падал с "pattern all:dist: no matching files
found"). .gitignore теперь игнорирует только реальные build-ассеты
(internal/web/dist/* кроме index.html); `make web` перезаписывает
плейсхолдер настоящей сборкой.

Также чинит MEDIUM: голый /api (без хвостового слэша) уходил в
SPA-fallback вместо API-роутера — вынесен isAPIPath() с явной проверкой
path == "/api", покрыт TestIsAPIPath.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwxdSt4reTm7Dj1oxRvpP3
2026-07-03 18:24:24 +07:00
vasyansk bba72cc70f feat(web,server): embed статики SPA + fallback, монтирование в cmd/server 2026-07-03 18:14:18 +07:00
vasyansk 388bf4aeb6 fix(web): валидация записей шаблона — пустые values не уходят в API, ошибки видимы 2026-07-03 18:10:10 +07:00
vasyansk 99e09d35fb feat(web): TemplatesPage + RecordEditor — CRUD шаблонов с редактором записей 2026-07-03 18:02:08 +07:00
vasyansk 4e91211a89 feat(web): AccountsPage — CRUD учёток, secret-форма, инструкция Selectel 2026-07-03 17:52:59 +07:00
vasyansk ef003230fa fix(web): DomainsPage показывает ошибки привязки шаблона и удаления 2026-07-03 17:49:48 +07:00
vasyansk 0ce15d30a8 feat(web): DomainsPage — список, импорт зон, привязка шаблона 2026-07-03 17:43:49 +07:00
vasyansk 1412da9a31 feat(web): DiffView + DomainDiffPage с prune-guard по умолчанию выключенным
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwxdSt4reTm7Dj1oxRvpP3
2026-07-03 17:32:20 +07:00
vasyansk 267ffc4ed9 fix(web): Domain.templateId опционален (Go omitempty), String() на error
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 17:19:51 +07:00
vasyansk 6f82036e38 feat(web): типизированный API-клиент, типы DTO, TanStack Query хуки 2026-07-03 17:14:11 +07:00
vasyansk 41242973e1 feat(web): scaffold Vite+React+TS, Tailwind v4, shadcn, router, тёмная console-тема 2026-07-03 17:06:23 +07:00
vasyansk 93cbe538e2 docs: план реализации Фазы 1C (React SPA)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 16:44:41 +07:00
vasyansk fe85918407 docs: детализация дизайна Фазы 1C (React SPA)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 16:40:22 +07:00
vasyansk b329855c28 merge: Фаза 1B — persistence + REST API
- internal/config: env-конфиг (DSN, ENC-ключ, listen)
- internal/crypto: AES-256-GCM шифрование секретов
- internal/store: goose-миграции + seed, sqlc (pgx/v5, uuid override), dto JSONB, Repository, Loader/Recorder (testcontainers)
- internal/provider/registry: резолвинг провайдера
- internal/service: Check/Apply с guard на prune
- internal/api: chi REST — check/apply + CRUD accounts/templates/domains + import + PATCH привязки шаблона
- cmd/server: wiring
Финальный ревью: READY TO MERGE. 72 теста / 13 пакетов.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 15:33:36 +07:00
vasyansk ddab6e2162 fix(store,api): идемпотентный import (UNIQUE+ON CONFLICT) + PATCH привязки шаблона к домену 2026-07-03 15:24:08 +07:00
vasyansk 2aca92d070 fix(api): tenant-проверка account/template в CreateDomain (HIGH), атомарный import через транзакцию (MEDIUM) 2026-07-03 15:08:16 +07:00
vasyansk ae6a4d7f4c feat(api): CRUD accounts/templates/domains + import зон (полный цикл), secret не в ответах
Task 9 Фазы 1B: узкий интерфейс TenantStore (внутри store.Account/Template/Domain,
без db.* в api) реализован тонкими обёртками в internal/store/tenant.go; API.Store/
Cipher/Reg добавлены к существующему Svc. Роуты POST/GET/DELETE для accounts/
templates/domains + POST /accounts/{aid}/import (ListZones -> CreateDomain на зону).
accountResponse не содержит секрет ни в каком виде.
2026-07-03 14:53:29 +07:00
vasyansk 763919d23f feat(server): Loader/Recorder на Store, wiring cmd/server (config→migrate→pool→api) 2026-07-03 14:41:09 +07:00
vasyansk 05dc586646 fix(api): 400 на битое тело apply, маскирование internal-ошибок, лимит тела 2026-07-03 14:35:43 +07:00
vasyansk fdf90a7c23 feat(api): chi-роутер, check/apply хендлеры, changeset DTO 2026-07-03 14:28:06 +07:00
vasyansk 8a2d985197 feat(service): Check/Apply оркестрация с guard на prune 2026-07-03 14:22:59 +07:00
vasyansk 635b05361f refactor(store): sqlc override uuid→google/uuid.UUID (убирает pgtype boilerplate) 2026-07-03 14:20:03 +07:00
vasyansk 34bc49ee8c feat(store): sqlc-запросы, dto TemplateDoc, Repository, интеграционные тесты CRUD 2026-07-03 14:08:37 +07:00
vasyansk 9c29d40269 fix(store): postgres.BasicWaitStrategies() — устраняет flaky first-run на macOS
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 14:04:23 +07:00
vasyansk 5588e10e05 merge 1B wave: worktree-agent-a59d2fd8fdbcc99aa 2026-07-03 14:03:05 +07:00
vasyansk a3bb9474a4 merge 1B wave: worktree-agent-af74a8911eb1561ff 2026-07-03 14:03:05 +07:00
vasyansk d8d72aede1 merge 1B wave: worktree-agent-a472bc04034219ff7 2026-07-03 14:03:05 +07:00
vasyansk 788f1db80e feat(store): goose-миграции схемы + seed default tenant, тест на testcontainers 2026-07-03 13:56:21 +07:00
vasyansk 3b7ed8434b feat(registry): резолвинг провайдера по имени 2026-07-03 13:41:56 +07:00
vasyansk 7c82bafaaa feat(crypto): AES-256-GCM шифрование секретов учёток 2026-07-03 13:41:52 +07:00
vasyansk fc10451340 feat(config): загрузка env-конфига (DSN, ENC-ключ, listen) 2026-07-03 13:35:47 +07:00
vasyansk 50aec973ff docs: план реализации Фазы 1B (persistence + REST API)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:31:36 +07:00
vasyansk 3d6e3110b3 docs: детализация дизайна Фазы 1B (persistence + REST API)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:25:49 +07:00
vasyansk c0c8e3188d merge backlog: worktree-agent-aca0d858dec169a39 2026-07-03 13:16:27 +07:00
vasyansk b62f7d58cd merge backlog: worktree-agent-a0d4f6f75e1f8f7cd 2026-07-03 13:16:27 +07:00
vasyansk 6b515622e3 merge backlog: worktree-agent-a2c71dd931a5bf2a0 2026-07-03 13:16:26 +07:00
vasyansk 70f9bc6793 harden(selectel): защита пагинации от неподвижного offset, тест New, документирование disabled 2026-07-03 13:13:24 +07:00
vasyansk c42d242a3b feat(diff): prune-guard Updates()/Prunes() + фиксация семантики dedup 2026-07-03 13:12:10 +07:00
vasyansk 1505997b19 refactor(model): slices.Sort/Equal вместо ручного цикла 2026-07-03 13:11:18 +07:00
vasyansk 9de5d4712c merge: Фаза 1A — доменное ядро + провайдер Selectel
- internal/model: нейтральная модель Record (нормализация MX/SRV/TXT, Key, Equal)
- internal/diff: диф-движок шаблон↔зона, ReadOnly для NS/SOA, Actionable
- internal/provider: интерфейс Provider + Credentials/Zone
- internal/provider/selectel: Selectel DNS API v2 (ListZones/GetRecords/ApplyChanges)
Финальный ревью: READY TO MERGE. 23/23 тестов.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:02:30 +07:00
vasyansk cb2f826dc2 test(diff): пустой шаблон — массовый Delete управляемых, NS остаётся ReadOnly 2026-07-03 12:57:36 +07:00