8.1 KiB
8.1 KiB
Docker Migration + Redis + AI Context Cache — Implementation Plan
Goal: Migrate PostgreSQL to Docker · Add Redis · Build AI Steward global context cache
Order: Docker setup → data migration → Redis integration → context cache
Part 1 — Docker Setup
Services to containerize
- PostgreSQL — use
ankane/pgvectorimage (includes pgvector extension, no manual install) - Redis — use
redis:7-alpineimage, lightweight, set max memory 512mb, eviction policyallkeys-lru - Backend — FastAPI app
- Frontend — React/Vite app
Configuration
- All secrets (DB password, Redis password, GLM API key) in
.envfile, never committed to Git - Services communicate via Docker internal network (backend connects to
db:5432, notlocalhost:5432) - All data volumes mounted to named Docker volumes (data persists across container restarts)
- Health checks on DB and Redis — backend only starts after both pass
Part 2 — Database Migration Steps
- Export existing local PostgreSQL data to a
.sqlbackup file - Start Docker DB container
- Wait for health check to pass
- Import backup into Docker container
- Enable pgvector extension inside Docker DB
- Verify row counts match original
- Update backend
DATABASE_URLto point to Docker container - Run backend, confirm everything works
- Stop local PostgreSQL service
Part 3 — Redis Key Design
| Key pattern | Content | TTL |
|---|---|---|
pmflow:context:system |
System-wide snapshot (all projects, team, signals) | 30 min |
pmflow:context:user:{id} |
Per-user snapshot (my tasks, my signals, my workload) | 5 min |
pmflow:qa:session:{id} |
Conversation history for multi-turn chat (last 10 turns) | 1 hour |
pmflow:project:list |
Project list for quick lookup | 10 min |
pmflow:signal:pending_count |
Pending signal count by priority | 5 min |
Cache invalidation rules
- Project created/updated → delete
pmflow:context:system - Signal status changed → delete
pmflow:context:system - Task assigned/completed → delete
pmflow:context:user:{affected_user_id} - Team member added/removed → delete
pmflow:context:system - TTL acts as safety net for any missed invalidations
Part 4 — AI Context Cache
System snapshot (shared by all users)
- All projects: id / name / status / current stage / owner / signal count / task count / completion rate
- All team members: id / name / role / workload ratio / assigned projects
- Pending signals: total / P0 count / P1 count / P2 count
- Snapshot build timestamp
User snapshot (per user)
- Projects I own or am a member of
- Tasks assigned to me (not done, with due dates)
- Signals pending my action
- My current workload ratio
How it works
- User opens AI Steward chat
- Backend checks Redis for system + user snapshots
- Cache hit → use immediately (milliseconds)
- Cache miss → query DB, build snapshot, store in Redis, use result
- Both snapshots injected into GLM-4 System Prompt
- GLM-4 answers based on real data — no more "I couldn't find information"
System Prompt structure
- Role definition: "You are PMFlow's AI Steward..."
- System snapshot injected as structured data
- User personal snapshot injected
- Rules: answer directly from data / never fabricate / handle identity questions without searching / indicate when deeper search is needed
Part 5 — Multi-turn Conversation Cache
- Every user message + AI response appended to Redis session key
- Max 20 messages (10 turns) per session — oldest trimmed automatically
- Session expires after 1 hour of inactivity
- Permanent QA records still written to PostgreSQL asynchronously (not affected by Redis TTL)
- If Redis restarts: session history resets (acceptable), permanent records safe in PostgreSQL
Part 6 — Full Call Flow
User sends question
↓
Load system snapshot from Redis (cache hit: <5ms)
Load user snapshot from Redis (cache hit: <5ms)
Load session history from Redis
↓
Build: [system prompt + snapshots] + [history] + [new question]
↓
Call GLM-4
↓
Append messages to Redis session
Async write QA record to PostgreSQL
↓
Return answer
Implementation Order
| Day | Tasks |
|---|---|
| 1 | docker-compose.yml. Export local DB. Start containers. Import data. Verify. Stop local PostgreSQL. |
| 2 | Redis connection setup. System snapshot builder. |
| 3 | User snapshot builder. Wire both into AI Steward endpoint. |
| 4 | Cache invalidation on all data-changing APIs. Session history cache. |
| 5 | End-to-end test: projects / members / tasks / signals. Verify accurate answers. |
Out of scope
- Redis cluster / sentinel
- Cache monitoring dashboard
- Multi-tenant isolation
- Cache pre-warming
Execution Backfill (2026-03-02)
Part 1 — Docker Setup
- Added
docker-compose.ymlwithdb(redis/pgvector) + backend + frontend. - Added DB/Redis health checks and
depends_onhealth gating. - Added backend container build/runtime file:
backend/Dockerfile. - Added backend dependency lock baseline:
backend/requirements.txt. - Added docker env template:
.env.exampleand updatedbackend/.env.example. - Redis policy configured to
maxmemory 512mb+allkeys-lru.
Part 2 — Database Migration Steps
- Added migration helper script:
scripts/migrate_postgres_to_docker.sh. - Script includes export/import/pgvector-enable/row-count verification steps.
- Updated Alembic driver adaptation (
asyncpg -> psycopg) for container migration runtime. - Runtime execution blocked in current environment: Docker daemon unavailable.
Part 3 — Redis Key Design
- Implemented key-space in
backend/app/services/context_cache.py:pmflow:context:system:{tenant}pmflow:context:user:{tenant}:{user}pmflow:qa:session:{tenant}:{session}pmflow:project:list:{tenant}pmflow:signal:pending_count:{tenant}
- TTL implemented:
- system 30min / user 5min / session 1h / project-list 10min / pending-signal 5min.
Part 4 — AI Context Cache
- Added system snapshot builder (projects/team/pending signals/timestamp).
- Added user snapshot builder (my projects/my tasks/pending signals/workload).
- Wired snapshot cache read into
AdaptiveRAGService.answer_question. - Updated RAG prompt template to inject
System Snapshot + User Snapshot.
Part 5 — Multi-turn Conversation Cache
- Added Redis session message store (append user+assistant).
- Enforced max 20 messages (10 turns) with auto trim.
- Session TTL set to 1 hour.
- DB persistence for QA records retained (existing behavior kept).
Part 6 — Full Call Flow
- Implemented flow in code path:
- load system/user snapshot from Redis (fallback DB build),
- load session history from Redis (fallback DB),
- build prompt with snapshots + history + context,
- call LLM,
- append chat history to Redis,
- persist QA record to PostgreSQL.
Cache Invalidation Backfill
- Added global SQLAlchemy invalidation hooks in
context_cache.py. - Hooked app startup registration in
backend/app/main.py. - Added explicit invalidation at high-impact endpoints:
- project create/update/delete/link/unlink,
- task status/update/delete/batch-create in SSTC,
- user-project replacement helper (bulk delete path).
Verification Backfill
docker compose configpassed.- Modified python modules syntax-checked via
python3 -m py_compile. - Docker stack startup validated after daemon available.
- Backend/Redis/DB health checks passed (
/healthz,redis ping,pgvector extension).
Runtime Deviation (Important)
- Observed historical Alembic chain defect in this repository:
add_users_table_rbac.pycan trigger duplicate ENUM creation (userrole) on PostgreSQL.
- For reliable runtime startup, backend container entrypoint switched to direct
uvicornboot, while schema creation relies on existingAUTO_CREATE_TABLES=truein app lifespan. - Follow-up recommended: fix legacy Alembic migration scripts for fully idempotent PostgreSQL upgrades.