After 44395e2 added --pull, pipeline 6032 still fails on docker-app/
projection-writer/read-api with same blob 74e368... missing. --pull pulled
base image fine, but BuildKit reads BUILDKIT_INLINE_CACHE из previously-pushed
:latest (которое references the lost blob). BuildKit thinks "this blob already
in registry, skip push" → manifest references missing blob.
--no-cache форсирует rebuild from scratch без inline cache reading. Все blobs
пересобираются → pushed заново → manifest is consistent.
Stack +2 min per service (3 services = +6 min total pipeline). Acceptable
до восстановления Nexus blob storage health. Когда :latest references stable
blobs снова — оба флага можно убрать одной revert командой.
Sister fix к 44395e2.
Pipeline 6017 (07c5ca0, main) failed on docker-app/projection-writer/read-api
all referencing missing blob sha256:74e368405305a59e71a1fec5de6a75cc307bd663ebb9b47af045c3a5bdf30cec
после Nexus disk-full cleanup. Blob — это shared layer от base image
(eclipse-temurin:21-jre / maven:3.9.9-eclipse-temurin-21), который Nexus
docker-proxy кэш потерял. BuildKit на runner'е держал stale reference в своём
inline cache, не push'ал blob, manifest fail.
`docker build --pull` форсирует Nexus proxy лениво re-fetch base image с
Docker Hub на каждом build'е → blob возвращается в storage. После одного
успешного pipeline'а можно убрать флаг (cache восстановится), но flag
безвреден в healthy state — стоит ~5-10s на проверку pull.
Не меняет behaviour приложения. CI/runtime fix only.
Готовит ground для тага v1.1.0 после окончания Approval Workflow v2 soak'а
на staging (≥7 дней с 2026-05-08 → target ≥2026-05-15).
- docs-internal/releases/v1.1.0.md — полные release notes:
Track A (Approval Workflow v2 P0–P4, 8 commits) + Track B (5 CEO v1
gap closures), migrations 0017-0020, API surface additions, decisions
D1-D4 rationale, 6 lessons learned, cluster ops checklist, out-of-scope
list (deferred к v3 design doc).
- docs-internal/releases/v1.1.0-tag-message.txt — готовый текст для
`git tag -a v1.1.0 -F docs-internal/releases/v1.1.0-tag-message.txt`.
NOT тагаем сейчас — soak ahead. Documentация заранее = меньше work
после soak conclusion. Если в soak найдутся issues, release notes
проще обновить чем писать с нуля.
Phase 4 last optional UX из design doc — bulk operations:
- Multi-select column в reviewer queue (Checkbox per row + select-all
header). Set<draftId> selection state, persisted между refetch'ами.
- "Approve выбранные" — confirm dialog → parallel approveDraft mutations
через Promise.all. Каждая mutation independent: если одна fail
(409 self_approve_forbidden / draft_not_pending race), остальные
продолжают.
- "Reject выбранные" — Modal с TextArea для shared reason (required,
matches backend reject_reason_required validation). Reason одинаковый
для всех — bulk обычно "duplicate registration" / "wrong scope" / etc.
- Bulk result Alert: approved count / rejected count / failed list с
per-draft reason'ами (err code из 409). User видит точно что прошло
и что нет.
- Auto-clear selection после bulk operation. Queue refetch'ит через
refetchInterval=30s, плюс mutation onSuccess invalidate'ит ['drafts'].
i18n RU/EN: 22 keys (selectAll/selectRow/selectedCount/approveSelected/
rejectSelected/clear/confirmApprove/rejectModal*/confirmReject/cancel/
resultTitle/approvedCount/rejectedCount/failedCount). Pluralization
через i18next plurals.
Why ship without soak data:
- Implementation не зависит от queue depth — это просто loop'ит над
выбранными drafts.
- Reviewer на любом dict с queue >5 уже выгадывает время.
- Если queue staying small после soak — feature не bothering нас (UI
toolbar показывается только когда anySelected).
Tests: vitest 89/89, tsc clean, prod build clean.
Approval Workflow v2 Phase 4 — UX:
Backend:
- DraftController.myDrafts: GET /api/v1/drafts/me?page&size — все статусы
(PENDING/APPROVED/REJECTED/WITHDRAWN) текущего authenticated user, sorted
submitted_at DESC. Resolve maker_id из JWT subject (fallback "anonymous"
если auth off).
- Reuses existing DraftService.listByMaker (Phase 1 method, был не exposed).
Frontend:
- routes/my-drafts.tsx: новый маршрут с табличным view.
Колонки: businessKey / operation / status / submittedAt / reviewedAt /
reviewerId / comment / actions. Status badge tinted (warning/success/
error/neutral). PENDING строки имеют Withdraw кнопку (calls existing
useWithdrawDraft с confirm).
- api/queries.ts: useMyDrafts (refetch 30s — maker увидит когда reviewer
decide).
- api/mutations.ts: useWithdrawDraft теперь invalidate'ит ['drafts'] —
/me + by-dict обе видят изменение.
- routes/__root.tsx: nav link "Мои черновики" / "My drafts" (после Reviews).
- i18n RU/EN: 18 keys (nav.myDrafts, myDrafts.* col/action/status).
Pluralization для total через i18next plurals.
Why это нужно:
- До этого maker submit'нул draft и пропадал — единственный feedback был
badge "На review" в records list (только для текущего dict). Здесь — все
его submissions с history + withdraw для PENDING.
- Reviewer pool (D3=A) маленький, /reviews queue только для них. Maker
без role'а не видит queue, но должен tracking своих submissions.
Tests: ordinis-rest-api unit 119/119, ordinis-app e2e 28/28, vitest 89/89.