⛔ АРХИВ (2026-08-22). Этот документ описывает завершённые фазы 0–6 и sprints A–G. Актуальный план: ROADMAP_V2.md (цели лидогенерации, зоны Z1–Z6, фазы M0–M6). История статусов ниже сохранена без изменений.
Historical source-of-truth claim (superseded). This file preserves the old phases/checkpoints exactly as evidence. Current sequencing is in
ROADMAP_V2.md; feature/task status is indocs/planning/FEATURES.mdandBACKLOG.md.Status updated: 2026-07-16 Project version: 0.5.1 Compliance score (audit): 48/100 → 92/100 (after audit fixes + test fixes + doc sync)
| Label | Meaning |
|---|---|
[x] |
Done, verified |
[~] |
In progress |
[ ] |
Not started |
GATE |
Gate — cannot move to the next phase without passing |
P0 |
Critical bug — blocks work |
P1 |
Important — must be fixed before release |
P2 |
Nice to have — can be deferred |
Phase 0: Foundation [████████████████████] 100% ✅
Phase 1: Core Backend [████████████████████] 100% ✅ (LangGraph wired + tested)
Phase 2: Infrastructure [████████████████████] 100% ✅ (rate limiter, SSE, checkpoint — all wired)
Phase 3: UI [████████████████████] 100% ✅ (PostEditor, Toast, Warm-up UI, Rate limit UI — all done)
Phase 4: Quality & Docs [███████████████████░] 95% ✅ (ADRs, Swagger, CorrelationId, RedactInterceptor done)
Phase 5: Testing [████████████████████] 100% ✅ (458 tests pass (all))
Phase 6: Release Readiness [███████████████████░] 95% 🔧 (rollback plan done; manual E2E test with real credentials TBD)
What works right now:
- ✅ Backend compiles and starts (NestJS 11) —
nest buildpasses - ✅ UI builds —
vite buildpasses (442 modules, 15s) - ✅ 375 tests pass (208 unit + 35 integration + 46 system + 82 acceptance + 4 e2e)
- ✅ Prisma schema + 2 migrations applied (init + warmup/banned status)
- ✅ BullMQ queue factory + workers (per-network, concurrency=1)
- ✅ Rate limiter (Redis sliding window, daily + weekly, env-configurable) — wired into PostingService
- ✅ SSE endpoint (
/events/sse) + UI wiring (B6 — real-time updates in Pinia stores) - ✅ Port interfaces (IBrowserPort, ILlmPort, IContentPort) + Symbol-token DI
- ✅ Auto-login flow (X, Threads, Facebook)
- ✅ Thread reply logic (X + Threads posters)
- ✅ UI builds (Vue 3 + Vite, 5 views, 4 Pinia stores, 7 components, SSE live indicator)
- ✅ Shared package (Zod schemas, domain types, content schemas)
- ✅ §10.3 LangGraph parallel graph (7-step, per-network angle, OQ-16) — wired with checkpoint saver
- ✅ LangGraph checkpoint resume (graph.compile({checkpointer: redisSaver}) — tested ITC-033)
- ✅ F20 Session Warm-up Mode (warmup.service.ts, Prisma fields, canPost() check)
- ✅ F21 Account Health Monitor (hourly cron, ban detection, DLQ alerting, SSE alerts)
- ✅ B3 Reconciliation cron (find orphaned APPROVED posts, re-enqueue)
- ✅ B4 Cron schedule env-configurable (CRON_GENERATION_SCHEDULE)
- ✅ B5 SimHash dedup (near-duplicate detection, Hamming distance ≤3) + category diversity (prioritizeTopics)
- ✅ B10 Graceful shutdown (OnModuleDestroy — Redis, browser, SSE, queues)
- ✅ D1 Batch posting rate-limit fix (skip instead of fail)
- ✅ D2 approve() accepts editedContent (backend done, UI PostEditor TBD)
- ✅ D5 brand-voice.md path fix (process.cwd())
- ✅ D6 FB char limit 500 for marketing
- ✅ 5 ADRs (Camoufox, BullMQ, LangGraph, Ports, SSE)
- ✅ 4 Runbooks (login, banned, failed-posts, session-expired)
- ✅ Dockerfiles + docker-compose.prod.yml + nginx.conf (SSE proxy)
- ✅ Swagger/OpenAPI — 65 decorators on controllers,
/docsserves Swagger UI - ✅ CorrelationId (nestjs-cls + CorrelationIdInterceptor, X-Correlation-Id header)
- ✅ RedactInterceptor (passwords, tokens, storageState, credentialsRef)
- ✅ Health check (DB SELECT 1 + Redis PING, /health endpoint)
- ✅ Multi-provider LLM fallback (Groq, OpenRouter, DeepSeek, Cerebras, OpenAI, Ollama)
- ✅ Custom error hierarchy (SpaError → 9 specialized classes + classifyPlaywrightError)
- ✅ Multi-fallback selector strategy (data-testid → role → label → CSS → text)
- ✅ Sentry integration (SentryInterceptor, env-gated)
What does NOT work / is not done:
- ✅ E2E tests (Vitest supertest) — 33 tests (full-flow, HITL, health-check, SSE, smoke)
- ❌ Manual end-to-end posting test with real credentials
⚠️ Engagement module (F1 partial) — implemented without tests/UI/LLM integration (TODO in browsing-session.service.ts:300)
Goal: Monorepo structure, base schema, infrastructure, constitution.
- pnpm workspace (3 packages: backend, ui, shared)
- tsconfig.base.json (shared TS strict config)
- nest-cli.json
- vite.config.ts (Vue + path aliases + proxy)
- tailwind.config.ts
- .env.example (all env vars documented)
- Env var validation (Joi schema in
infrastructure/config/env.validation.ts, called fromAppModule.onModuleInit) - .gitignore
- infra/docker-compose.yml (PostgreSQL :5433 + Redis :6381)
- CONSTITUTION.md (919 lines — full constitution)
- README.md (quickstart)
- brand-voice.md (tone of voice)
- FEATURE_WISHLIST.md (F1-F22)
- Zod schemas (Post, Generation, Session, Posting, Common)
- Domain types (Post, Account, Session, SourceRef, LlmMetadata)
- Shared enums (SocialNetwork, PostStatus, SessionStatus)
- Content schemas (Brief, ArticleFrontmatter, ContentTopic) — moved from infrastructure
- Prisma schema (Post, PostThread, SocialAccount, Session, GenerationRun)
-
retryCountfield added to Post -
ContentSourceTypeenum aligned (lowercase) between Prisma and Zod - Migration
20260626110230_initcreated and applied
- Docker compose (Postgres + Redis) — running
- PrismaService
- BrowserFactory (Camoufox integration)
- LlmService (LangChain ChatOpenAI)
- ContentReader (reads CAP briefs + blog articles)
GATE 0: Foundation Ready ✅
- Monorepo structure exists
- Shared package builds (
pnpm --filter @spa/shared build) - Docker infra runs
- Prisma migration applied
Goal: All REST endpoints work, business logic implemented, DI via port interfaces.
- DTOs (CreatePostDto, UpdatePostStatusDto, PostQueryDto — Zod-validated)
- Enums re-exported from @spa/shared
- Port interfaces:
-
IBrowserPort(createContext, saveStorageState, randomDelay) -
ILlmPort(generate, generateChat) -
IContentPort(getTopics, readBriefs, readArticles)
-
- Port index barrel export
- PostsModule — CRUD + status transitions +
/approve+/rejectendpoints - GenerationModule — generation run + cron triggers + LangGraph 7-step parallel graph
- PostingModule — orchestration + 3 posters (X, Threads, Facebook)
- SessionsModule — session manager + auto-login + health check + warm-up (F20)
- AccountsModule — env-driven account config
- ContentSourceModule — adapter to CAP
- HealthModule — DB + Redis healthcheck
- QueueModule — BullMQ workers per network (concurrency=1)
- RateLimitModule — Redis sliding window rate limiter (daily + weekly + interval)
- EventsModule — SSE endpoint for real-time updates
- HealthMonitorModule — F21: hourly cron, ban detection, DLQ alerting, reconciliation
- EngagementModule — F1 partial: like/comment/follow/reply + browsing sessions (experimental)
- XPoster — compose + post + thread reply (fixed URL concatenation)
- ThreadsPoster — compose + post + thread reply
- FacebookPoster — business page posting
- Symbol-token DI wired (IBrowserPort, ILlmPort, IContentPort)
-
as nevercasts replaced withPrisma.InputJsonValue/Prisma.PostUpdateInput - Content schemas moved from
infrastructure/content/topackages/shared/ - Services depend on port interfaces, not concrete classes
- GenerationService uses
@Inject(ILlmPort)instead ofLlmService - PostingService uses
@Inject(IBrowserPort)instead ofBrowserFactory - SessionsService uses
@Inject(IBrowserPort)+ ConfigService for auto-login
-
generation.graph.ts— StateGraph with 7 nodes (§10.3 parallel graph):- research_extract → hook_generation → angle_per_network → draft_{X,THREADS,FACEBOOK} → critique_{X,THREADS,FACEBOOK} → refine_{X,THREADS,FACEBOOK} → save_to_db
-
RedisCheckpointSaver— custom BaseCheckpointSaver implementation -
CheckpointModule— NestJS wrapper - Wire LangGraph into GenerationService — graph.compile({checkpointer}) + graph.invoke()
- Test graph execution — ITC-026 (3 topics × 3 networks = 9 posts), ITC-001 (LLM called 4× per post)
- Checkpoint resume — ITC-033 (resumes from checkpoint, skipping completed nodes)
- Dashboard.vue:
data.length→data.total(response shape) - Queue.vue:
res.data→res.data.posts(paginated response) - History.vue:
res.data→res.data.posts - PostsController: added
POST /posts/:id/approveandPOST /posts/:id/reject - X poster: URL concatenation
https://x.com${url}→url(page.url() returns full URL) - Threads poster: thread reply navigates to root post instead of compose page
GATE 1: Core Backend Ready ✅ (100%)
- All modules compile
- All P0 bugs fixed
- Port interfaces wired
- LangGraph workflow integrated and tested (ITC-026, ITC-033)
- Build passes:
pnpm --filter @spa/backend build
Goal: BullMQ, rate limiter, SSE, checkpointing — all work and are tested.
-
QueueFactory— queue + worker factory per network -
QueueModule(modules) — wires workers to PostingService -
QueueService— enqueue + job stats + failed jobs -
QueueController—GET /queue/:network/stats+GET /queue/:network/failed - Idempotent jobs (jobId = postId)
- Auto-retry: 3 attempts, exponential backoff (60s base)
- Dead-letter: BullMQ
failedqueue retained (500 jobs max) - Integration test: ITC-016 (enqueue adds job with postId), ITC-032 (job data contains postId + network)
- Verify retry: STC-023 (BullMQ retries failed post 3x with exponential backoff)
-
RateLimitService— Redis sliding window (daily + weekly + interval) -
RateLimitModule - Per-network limits (env-configurable: RATE_LIMIT_{NET}_MAX_PER_DAY/WEEK)
-
recordPost()— updates interval timestamp -
getStatus()— current rate limit state - Wire into PostingService — checkRateLimit() before posting, recordPost() after (posting.service.ts:63, 160)
- Integration tests: STC-020 (rate limit blocks), STC-021 (recordPost updates Redis), STC-031 (enforcement)
- UI display — show rate limit status in Sessions view (Sessions.vue displays daily/weekly counts)
-
SseService— Redis Pub/Sub → SSE client broadcast -
SseModule— NestJS wrapper, OnModuleInit on bootstrap -
EventsController—GET /events/sse(text/event-stream) - Heartbeat every 30s
- Publish events from PostingService — POSTING, POSTED, FAILED (5 sseService.publish calls)
- Publish events from HealthMonitorService — health_alert events (ban detection, DLQ)
- Publish events from GenerationService — generation_progress (TBD — low priority)
- UI SSE composable — App.vue EventSource + Pinia stores (posts.ts handles post_status, health_alert)
-
RedisCheckpointSaver— custom BaseCheckpointSaver -
CheckpointModule - Wire checkpoint into graph compilation —
graph.compile({ checkpointer: redisSaver })(generation.service.ts:59) - Thread ID = generation run ID — for resume after crash
- TTL configurable — CHECKPOINT_TTL_SECONDS env var
- Tested: ITC-004 (put called during invoke), ITC-033 (resume skips completed nodes)
- Auto-login flow (X, Threads, Facebook)
- Login selectors per network
- Captcha/2FA detection (graceful fail)
- storageState persistence (DB + browser context restore)
- Health check (open browser, verify not redirected to login)
- Session refresh — if health check fails, trigger auto-login (ITC-034)
- Test auto-login with real credentials (env vars set) — TBD Sprint G
GATE 2: Infrastructure Ready ✅ (100%)
- BullMQ queues + workers registered
- Rate limiter implemented + wired into PostingService
- SSE endpoint live + events published from PostingService/HealthMonitor
- Checkpoint saver implemented + wired into graph.compile()
- All wired into business logic
- Integration tests pass (ITC-006..009, ITC-016, STC-020..023, STC-031..033)
Goal: Functional Vue 3 SPA with 5 views, Pinia stores, shared components, SSE.
- Dashboard.vue — stats + recent posts (5 stat cards, PostCard, LoadingSpinner, ErrorState)
- Queue.vue — draft posts for HITL review (approve/reject actions, EmptyState)
- History.vue — posted/failed history (filter tabs, up to 50 posts)
- Generate.vue — manual generation trigger (count 1-10, source type, network checkboxes, run history)
- Sessions.vue — session status (ACTIVE/EXPIRED/ERROR, health check button)
- SSE integration — App.vue EventSource + Pinia stores handle post_status + health_alert events
- Loading states — LoadingSpinner component used in Dashboard
- Error states — ErrorState component used in Dashboard
- Empty states — EmptyState component used in Queue, History
-
stores/posts.ts— post state (SSE-fed, CRUD actions, handles post_status + health_alert events) -
stores/queue.ts— queue state (BullMQ job stats, failed jobs) -
stores/sessions.ts— session state (health check, refresh) -
stores/stats.ts— dashboard stats + generation run history - Wire stores into views — all 5 views use Pinia stores
-
components/PostCard.vue— post card (network, status, content, actions, approve/reject) -
components/StatusBadge.vue— colored status badge (DRAFT/APPROVED/POSTING/POSTED/FAILED/REJECTED) -
components/NetworkIcon.vue— X/Threads/Facebook icon + label -
components/LoadingSpinner.vue— animated SVG spinner -
components/ErrorState.vue— error display with message -
components/EmptyState.vue— empty state with message -
components/StatCard.vue— stat display card (label, value, color) -
components/PostEditor.vue— inline edit post content before approve (modal, char-limit validation) -
components/ToastContainer.vue— toast notifications (success/error/info)
-
useApi.ts— axios client (typed, base URL /api/v1) -
useSSE.ts— SSE subscription composable (connect, data, error, isConnected) -
useToast.ts— toast notifications composable (success/error/info) -
usePosts.ts— posts CRUD composable (optional — stores sufficient) -
useQueue.ts— queue actions composable (optional — stores sufficient) -
useSessions.ts— session actions composable (optional — stores sufficient)
- Path aliases (
@/→src/,@shared→../shared/src) in vite.config.ts + tsconfig.json - Responsive layout (mobile-friendly) — P2
- Dark mode (optional — Tailwind dark: prefix) — P2
- Navigation active state — router-link active class
- SSE connection indicator (green/red dot in nav)
- Toast notifications (approve/reject/generate feedback) — useToast + ToastContainer
GATE 3: UI Ready ✅ (100%)
- All 5 views functional with Pinia stores
- SSE real-time updates working (App.vue → Pinia stores)
- Shared components created and used (8 of 8)
- Loading/error/empty states implemented
-
pnpm --filter @spa/ui buildpasses (449 modules) - PostEditor.vue for inline draft editing
- Warm-up status display in Sessions.vue
- Rate limit status in Sessions.vue
- Toast notifications (useToast + ToastContainer)
Goal: ADRs, Swagger, logging, Constitution update — production-ready docs.
-
docs/adr/ADR-001-camoufox-browser-automation.md— why Camoufox (stealth, footprint) -
docs/adr/ADR-002-bullmq-queue.md— why BullMQ (retry, rate limit, dead-letter) -
docs/adr/ADR-003-langgraph-generation.md— why LangGraph (checkpoint, multi-step) -
docs/adr/ADR-004-hexagonal-ports.md— why Symbol-token DI (testability, DDD) -
docs/adr/ADR-005-sse-realtime.md— why SSE (simplicity, one-directional)
-
main.ts— SwaggerModule setup (DocumentBuilder, SwaggerModule.setup) -
@ApiTagson all controllers (Posts, Generation, Posting, Sessions, Accounts, Queue, Events, ContentSource, Engagement, HealthMonitor) -
@ApiOperationon all endpoints — 65 Swagger decorators total -
@ApiResponsefor error codes (400, 404, 500) - Verify
/docsserves Swagger UI — STC-046 (Swagger/OpenAPI accessible at /docs)
- Correlation ID —
nestjs-cls(Continuation Local Storage)- ClsModule.forRoot() in AppModule (AppClsModule)
- CorrelationIdInterceptor — generates
spa-{timestamp}-{random}per request - Response header:
X-Correlation-Id— STC-047 (correlationId present in headers)
- Redact Interceptor — strip secrets from logs
-
RedactInterceptor(NestJS interceptor) — redacts passwords, tokens, apiKey, storageState, credentialsRef - Registered globally in AppModule
- Tested: UTC-120..125 (redacts nested, arrays, null), STC-034 (credentials not in logs)
-
- Health check — DB + Redis
-
HealthController— checks DB (SELECT 1) + Redis (PING) -
GET /healthreturns{ status, database, redis, timestamp } - Tested: UTC-115..119 (ok/degraded scenarios), STC-042
-
- Update version to 0.5.0 (post-implementation)
- Update §6 structure diagram (match actual file layout) — Sprint A (v0.5.3)
- Add cron env vars to §8 (CRON_GENERATION_SCHEDULE)
- Add health check endpoint to §4.1
- Mark Phase 0/1 checkboxes as
[x]— Sprint A
- No
as nevercasts (replaced with Prisma.InputJsonValue / Prisma.PostUpdateInput) - No
anytypes in domain layer (port interfaces use generics) - Build passes clean:
nest build+vite build
GATE 4: Quality Ready ✅ (95%)
- 5 ADRs written
- Swagger UI live on
/docs(65 decorators, STC-046) - Correlation ID in all logs (STC-047)
- Redact interceptor active (UTC-120..125, STC-034)
- Health check covers DB + Redis (UTC-115..119, STC-042)
- Build passes clean
- Constitution §6 structure update (Sprint A)
Goal: Unit tests for critical paths, integration tests for API, E2E for browser flow. Status: 458 tests pass (208 unit + 35 integration + 46 system + 82 acceptance + 33 e2e + 54 other), 26 files.
-
vitest.config.tsin packages/backend -
vitest.config.tsin packages/ui - Test scripts in package.json (
test,test:watch,test:coverage) - Test utilities: mock factories for ILlmPort, IBrowserPort, IContentPort
- ioredis mock with sharedPubSub for cross-instance Redis Pub/Sub (SSE tests)
-
posts.service.spec.ts— 16 tests (UTC-026..041: CRUD + status transitions) -
posts.controller.spec.ts— 16 tests (UTC-C-026..reject-404) -
posting.service.spec.ts— 18 tests (UTC-042..059: orchestration, idempotency, SSE) -
posters.spec.ts— 16 tests (UTC-057..059: X/Threads/FB posters) -
selector-strategy.spec.ts— 8 tests (multi-fallback selector resolution) -
errors.spec.ts— 18 tests (SpaError hierarchy + classifyPlaywrightError) -
sessions.service.spec.ts— 15 tests (UTC-060..074: session management + auto-login) -
rate-limit.service.spec.ts— 21 tests (UTC-075..088: check + record + status) -
queue.factory.spec.ts— 17 tests (BullMQ queue + worker management) -
sse.service.spec.ts— 10 tests (UTC-089..098: addClient, publish, broadcast) -
redis-checkpoint.spec.ts— 22 tests (checkpoint storage + retrieval + resume) -
llm.service.spec.ts— 12 tests (multi-provider fallback chain) -
health.controller.spec.ts— 5 tests (UTC-115..119: ok/degraded) -
events.controller.spec.ts— 4 tests (SSE endpoint behavior) -
redact.interceptor.spec.ts— 6 tests (UTC-120..125: redaction) -
smoke.spec.ts— 5 tests (mock infrastructure validation)
-
bottom-up.integration.spec.ts— 10 tests (ITC-006..009, ITC-021..022, ITC-028..031) -
sandwich.integration.spec.ts— 9 tests (ITC-010..014, ITC-023..025, ITC-034) -
top-down.integration.spec.ts— 11 tests (ITC-001..005, ITC-015..016, ITC-026..027, ITC-032..033) -
big-bang.integration.spec.ts— 4 tests (ITC-017..020: full AppModule, CLS, redact, posting flow) - Posts API, Generation API, Posting API, Sessions API, Queue API, Health API, SSE — all covered
-
generation-infrastructure.system.spec.ts— 16 tests (STC-001..009, STC-042..048) -
posts-posting.system.spec.ts— 16 tests (STC-010..025) -
sessions-crosscutting.system.spec.ts— 14 tests (STC-026..035, STC-049..052)
-
acceptance-test-cases.spec.ts— 53 tests (ATP-001..020: all 48 ATPs, US-001..020) -
bdd-scenarios.spec.ts— 29 tests (BDD-S1..S5, BDD-HITL, BDD-CRED, BDD-REDACT, BDD-ZOD, BDD-HEALTH, BDD-IDEMP, BDD-TONE, BDD-SHARED, BDD-SSE-CLEANUP)
-
vitest.config.tsconfigured - Store tests: posts.spec.ts, queue.spec.ts, sessions.spec.ts, stats.spec.ts (exist)
- Component tests (PostCard, StatusBadge, etc.) — P2
- View tests (Dashboard, Queue, History) — P2
-
playwright.config.tsconfigured - Full flow: generate → approve → post (mocked browser) — 8 tests (
full-flow.e2e.spec.ts) - HITL flow: generate → review → approve → verify queue — 10 tests (
hitl-flow.e2e.spec.ts) - Session health check flow — 6 tests (
health-check.e2e.spec.ts) - SSE real-time update flow — 5 tests (
sse-flow.e2e.spec.ts) - Smoke test (app boots + basic endpoints) — 4 tests (
smoke.e2e.spec.ts)
GATE 5: Testing Ready ✅ (100%)
- Vitest configured (backend + ui)
- Critical path unit tests pass (205 tests)
- API integration tests pass (35 tests)
- System tests pass (46 tests)
- Acceptance tests pass (82 tests)
- All 458 tests pass:
npx vitest run - E2E smoke test passes (Vitest supertest) — 33 E2E tests
Goal: Production deploy ready — env vars, runbooks, monitoring, rollback plan.
-
.env.examplecomplete and documented (131 lines, all env vars) -
.envcreated locally with real credentials (NEVER commit) — TBD Sprint G - All env vars validated at startup (ConfigModule validation)
- Social credentials set (X, Threads, Facebook) — TBD Sprint G
- LLM API key set (OPENAI_API_KEY) — TBD Sprint G
- Content paths correct (CONTENT_AGENT_PLATFORM_PATH, SITE_BLOG_PATH)
- Dockerfile.backend (multi-stage: node:22-slim, Chromium deps for Camoufox)
- Dockerfile.ui (multi-stage: node:22-slim → nginx:alpine)
- docker-compose.prod.yml (backend + ui + postgres + redis + volumes)
- nginx.conf (SPA fallback, /api/ proxy, /events/ SSE proxy with no buffering)
- Health check endpoint for container orchestration (GET /health)
- Graceful shutdown (OnModuleDestroy — BullMQ, Redis, browser, SSE)
- Structured logging (NestJS Logger + correlationId via nestjs-cls)
- Error tracking (Sentry — SentryInterceptor, env-gated SENTRY_DSN)
- Health check (DB + Redis, GET /health)
- F21 Health Monitor (hourly cron, ban detection, DLQ alerting, SSE alerts)
- BullMQ dashboard (bull-board or custom) — P2
-
docs/runbook-login.md— manual login if auto-login fails (captcha/2FA) -
docs/runbook-banned.md— what to do if account gets banned -
docs/runbook-failed-posts.md— retry/reject failed posts -
docs/runbook-session-expired.md— session refresh procedure
- All P0/P1 bugs fixed
- GATEs 0-4 passed
- GATE 5 passed (100% — 458 tests pass)
- Build passes:
nest build+vite build - Tests pass:
npx vitest run(375/375) - Swagger docs accessible on
/docs(STC-046) - Health check returns green (STC-042)
- Constitution updated to v0.5.0
- Auto-login tested with real credentials — TBD Sprint G
- First end-to-end posting test (manual approve → verify posted) — TBD Sprint G
GATE 6: Release Ready 🔧 (85%)
- Dockerfiles + docker-compose.prod.yml + nginx.conf
- 4 Runbooks written
- Sentry monitoring wired
- Graceful shutdown implemented
- Manual end-to-end test passed (generate → approve → post → verify URL) — Sprint G
- Rollback plan documented — Sprint G
What to do right now, in priority order. Sprints 1-5 (core backend, UI, quality, testing, release infra) — COMPLETED. New sprints are based on the v0.5.1 gap analysis.
- Update ROADMAP.md — mark completed items, recalculate percentages ✅
- ✅ Update CONSTITUTION.md §6 — structure tree synced with actual codebase (v0.5.3): added events/, analytics/, recycling/, quote-cards/, replies/, engagement/engagers/, warmup.module.ts, trending-scraper, infrastructure/{redis,captcha,proxy,selector-health}, UI additions, new migrations
- Mark Phase 0/1 checkboxes in CONSTITUTION.md §16 as
[x] - Update Feature Wishlist Mapping in ROADMAP (F20/F21 = done, engagement = WIP)
- ✅ PostEditor.vue — modal for editing draft before approve (backend D2 ready)
- ✅ Warm-up status in Sessions.vue — warmupEnabled, warmupStartedAt, days remaining
- ✅ Rate limit status in Sessions.vue — GET /rate-limit/:network/status + display
- ✅ Toast notifications — useToast composable + ToastContainer.vue, feedback on approve/reject/generate
- Decision: FREEZE behind a feature flag (ENGAGEMENT_ENABLED=false by default)
- ✅
ENGAGEMENT_ENABLED=falsefeature flag in app.module.ts — routes not registered - ✅ Env var added to .env.example with documentation
- Code preserved (1,300 lines) — can be activated when there is time to finish it
- Known gaps if activated: LLM integration (TODO in generateComment), no tests, no UI, no Swagger decorators
- Full flow E2E: generate → approve → post (mocked browser) — 8 tests (
full-flow.e2e.spec.ts) - HITL flow E2E: generate → review → approve → verify queue — 10 tests (
hitl-flow.e2e.spec.ts) - Session health check E2E: dashboard, check, reconcile — 6 tests (
health-check.e2e.spec.ts) - SSE real-time updates E2E: event-stream, connected event, headers — 5 tests (
sse-flow.e2e.spec.ts) - Smoke E2E: app boots, health, posts, approve, posting — 4 tests (
smoke.e2e.spec.ts) - Mock browser — mocked IBrowserPort (no real posting)
- SSE indicator green verification — headers + connected event verified
- ✅ Category in ContentTopic — ContentReader extracts category from blog frontmatter (tags[0]), outline (heading), trending ('trending'), topics ('fresh')
- ✅ B5 category diversity — prioritizeTopics() round-robin across categories (already worked)
- ✅ Fact extraction — research_extract node strengthened: LLM call to extract 5-8 facts from topic + keywords + outline (fallback to pre-extracted facts if available)
- ✅ F2: Multi-Stage Posting — Backend done (multiStage param, PostThread, PostingService thread items); TODO: test with real threads
- ✅ F13: Content Recycling — Backend done (recycleTopPosts, POST /recycle endpoint, UI button "F13: Recycle Old Top Posts"); evergreen revival from POSTED posts older than N days
- ✅ F10: Content Repurposing — Backend done (repurposeFromArticles, /repurpose endpoint, UI button); TODO: deeper fact extraction
- ✅ F22: Trending Topic Detection — Backend done (TrendingModule, astro events calendar, UI display); TODO: Google Trends / X trending API
- ❌ Manual E2E test with real credentials — first end-to-end posting test (requires real social credentials)
- ✅ Health check —
/healthreturns green (verified in E2E tests:smoke.e2e.spec.tsD3-6) - ✅ Swagger —
/docsserves Swagger UI (verified in acceptance tests) - ✅ Graceful shutdown —
app.enableShutdownHooks()+OnModuleDestroyon 5 services (Prisma, Redis, Browser, SSE, QueueFactory) - ✅ Rollback plan —
docs/runbooks/rollback.md(pg_dump, prisma migrate rollback, blue-green, decision tree) - ✅ Docker compose — updated env var names to match
.env.example(SOCIAL_X_USERNAME, etc.) - ❌
.envwith real credentials — user must fill in SOCIAL_X_USERNAME/PASSWORD, OPENAI_API_KEY, etc.
| Dimension | Current | Target | Gap |
|---|---|---|---|
| EDA (Event-Driven) | 80/100 | 90/100 | SSE events from GenerationService (TBD) |
| DDD (Domain-Driven) | 90/100 | 95/100 | Port interfaces ✅, repository interfaces optional |
| FSD (Feature-Sliced) | N/A | N/A | UI is flat SPA (acceptable for internal tool) |
| Boundary violations | 0 | 0 | ✅ All cross-module imports via ports |
| Doc-Code drift | 0 gaps | 0 | ✅ ROADMAP/CONSTITUTION synced with code (Sprint A+B); traceability phantom refs removed |
| Code bugs (P0/P1) | 0 P0 / 0 P1 | 0/0 | ✅ F20 warm-up wired (was dead code); all P0/P1 fixed |
| Test coverage | 100% (375 + 33 E2E) | 100% | ✅ Sprint D complete |
| Overall | 95/100 | 95/100 |
From
FEATURE_WISHLIST.md— which feature belongs to which phase.
| Feature | Phase | Status | Notes |
|---|---|---|---|
| F20 (Warm-up) | MVP | [x] | ✅ Done — warmup.service.ts, Prisma fields, canPost() check, WarmupModule, seedFromEnv() wires SOCIAL_*_WARMUP env vars |
| F21 (Health Monitor) | MVP | [x] | ✅ Done — hourly cron, ban detection, DLQ alerting, SSE alerts, reconcile |
| F2 (Multi-Stage Posting) | Phase 1.5 | [~] | Partial — backend done: multiStage param in GeneratePostsDto, GenerationService creates PostThread + continuation (position=1), PostingService loads thread items + passes to X/Threads posters, UI checkbox in Generate.vue. TODO: test with real threads, F13 recycling |
| F3 (On-Demand Launch) | Phase 1.5 | [~] | Partial — Generate.vue has count/network/source; no model picker, no F1/F2 control panel |
| F5 (Pause/Resume) | Phase 1.5 | [~] | Partial — LangGraph checkpoint wired; Queue.vue has pause/resume UI + BullMQ stats per network |
| F10 (Content Repurposing) | Phase 1.5 | [~] | Partial — backend done: repurposeFromArticles() in GenerationService extracts facts from articles + generates posts, /repurpose endpoint, UI button in Generate.vue. TODO: deeper fact extraction, source variety |
| F13 (Content Recycling) | Phase 1.5 | [ ] | Not started — no evergreen revival |
| F22 (Trending Topics) | Phase 1.5 | [~] | Partial — backend done: TrendingModule with TrendingService (astro events calendar), TrendingController (/trending endpoint), UI display in Generate.vue. TODO: Google Trends / X trending API integration |
| F1 (Autonomous Agent) | Phase 2-3 | [~] | |
| F4 (Adaptive Replies) | Phase 2 | [ ] | Not started |
| F6 (Analytics Dashboard) | Phase 2 | [ ] | Not started |
| F7 (Content Calendar) | Phase 2 | [ ] | Not started |
| F8 (A/B Testing) | Phase 2-3 | [ ] | Not started |
| F11 (Best Time to Post) | Phase 2 | [ ] | Not started |
| F19 (Image Quote Cards) | Phase 2 | [ ] | Not started |
| Date | Version | Change |
|---|---|---|
| 2026-07-27 | 0.6.1 | Sprint A partial: CONSTITUTION §6 structure tree synced with actual codebase (v0.5.3). Fixed false v0.5.2 changelog claim that Sprint O modules were removed (they are feature-flagged, not removed). ROADMAP §4.4 task marked done. |
| 2026-07-27 | 0.6.0 | Bug fix sprint + Phase 1.5 features: P0-1 approve()→BullMQ enqueue (ModuleRef lazy resolve), P0-2 thread/multi-post posting (PostingService loads thread items, passes to X/Threads posters, marks continuations POSTED). P1-3 Joi env validation (validateEnv() in AppModule.onModuleInit), P1-4 consecutive ban detection (streak analysis), P1-5 stuckPosting uses approvedAt, P1-6 SSE severity field, P1-7 RedactInterceptor exact key match. Minor-26 UTC getWeekStart, Minor-29 seedFromEnv→AccountsService.onModuleInit, Minor-30 Zod→400. F2/F10/F22 backend done (Sprint F partially complete). 375 tests (208 unit + 35 integration + 46 system + 82 acceptance + 4 e2e). Compliance: 95/100. |
| 2026-07-16 | 0.5.1 | ROADMAP sync with codebase: All phases updated to reflect actual implementation. Phase 1: 100% (LangGraph wired + tested). Phase 2: 100% (rate limiter, SSE, checkpoint — all wired). Phase 3: 90% (stores, SSE, components done; PostEditor TBD). Phase 4: 95% (ADRs, Swagger, CorrelationId, RedactInterceptor done). Phase 5: 95% (375 tests pass; E2E TBD). Phase 6: 85% (docker, runbooks done; manual E2E TBD). Feature Wishlist Mapping updated (F20/F21 = done, F1 = experimental). Compliance score: 92/100. New sprints A-G defined. |
| 2026-07-15 | 0.5.0 | Audit fixes: A1 rate-limit env vars, A2 Redis port 6381, A4 LangGraph 7-step parallel graph, B1 F21 Health Monitor, B2 F20 Warm-up, B3 Reconciliation cron, B4 Cron env-configurable, B5 SimHash dedup, B6 SSE UI wiring, B10 Graceful shutdown, D1 Batch posting rate-limit fix, D2 approve() editedContent, D5 brand-voice path, D6 FB char limit 500. 5 ADRs, 4 runbooks, Dockerfiles + docker-compose.prod.yml. |
| 2026-06-26 | 0.4.2 | Architecture audit completed, 22 doc-code gaps fixed, P0 bugs fixed, DDD ports wired, BullMQ + SSE + rate limiter + checkpoint implemented |
| 2026-06-25 | 0.4.1 | Camoufox integration completed (replaced Playwright) |
| 2026-06-20 | 0.4.0 | Initial scaffold — NestJS + Prisma + Vue 3 + shared package |