Changelog
High-level milestones in the HUPH project, reverse chronological.
This is not a per-commit log — for that, use git log. For design
decisions, see specs in docs/superpowers/specs/.
2026-04-25 — Auth audit + docs site refresh
fix(auth)Zitadelaudclaim mismatch causing/api/v1/*invalid_token. Three-part fix: admin requests theurn:zitadel:iam:org:project:id:<PROJECT_ID>:audscope so the access token'saudincludesproject_id; the API verifier defensively accepts EITHERproject_idORclient_id(keeps pre-fix tokens valid through rollout);requireZitadelJwtmiddleware now writesaudit_logrows onheader_missingandjwt_invalid(failures were previously invisible).fix(admin)PageHelp docs links across 9 admin pages dropped the.idsuffix —mkdocs-static-i18ndoes NOT serve<page>.id/URLs.- Docs site refresh — RAG references replaced with Dify, Zitadel SSO baked into auth flow + glossary + integrations matrix, changelog + onboarding + ops runbooks all bumped to current reality (this entry).
2026-04-24 — Phase 1 visibility + Phase 4 audit + Operator alerts (76-commit bundle)
- Phase 1 Visibility-First (gating Phase 2 contextual tunability)
- Judge Decisions widget on Bot Health (Langfuse-backed,
monitoring.judge.readaudit) - Feature Coverage widget on SystemDashboard (super_admin only,
monitoring.coverage.readaudit) - Executive Summary page + handbook (cross-cluster KPIs)
- Phase 4 audit retrofit —
before_state/after_stateJSONB columns + 16 action families instrumented (cluster, persona, guidance/audience rules, config, escalation rules, FAQ CRUD + bulk, intent rules, campaigns, follow-up rules, KB upload/edit/archive, crawl source, follow-up cancel, conversation notes), audit-coverage-report.sh, RecentConfigChanges dashboard widget with auto-refresh, before/after diff in audit log expanded view, "config changes only" filter, partial index, CSV export - Phase 2 knob #1 prep (flag-gated) — Dify
setAnnotationThreshold()wrapper,app_configmigration,/settings/faq-thresholdGET/PUT (gated byFEATURE_FAQ_THRESHOLD), admin slider in/settings/chatbot, smoke test - Operator alerts —
hot_lead_wait+cron_failurein-app alerts withalerts_sweepcron (every 5 min), kill switch viaFEATURE_ALERTS=false fix(api)P0:parseAuthModenow recognizeslegacyandboth(dispatchAuth-era values mapped toenforce); prior gap silently bypassed inner-guard middlewaresfix(auth)auth allow-list now matchesreq.originalUrlinstead of mountedreq.path— eliminated 2k/week audit noise from the admin proxy poll- Reliability — escalation fan-out race-free via
pg_advisory_xact_lock, alerts fall back to cluster counselors when assigned is inactive, leadsV2 atomic transaction + FOR UPDATE snapshot, FAQ deactivate fail-safe (502 if Dify DELETE fails), notifications partial index,faqKbSynctimer unref - Strategic finding — deep research revealed HUPH is in pre-GTM pilot state (5 conv/30d, 3-4 daily operators); engineering velocity ≠ product value; gate-off Feature Coverage + Executive Summary nav until traffic justifies them
2026-04-22–23 — Dify Phase A foundations + bilingual + Quality Gate
- Phase A foundations — chatflow versioning tooling, dual-LLM prompt slots, error_strategy guardrails
- Phase A.6 bilingual chatflow (dormant) — dual LLM-per-path v2 chatflow live; ID stable, EN +13.7pp; awaits BILINGUAL_ENABLED flip
- Phase A.5 Quality Gate observe-mode — judge node + aggregator
- error_strategy live in v3 chatflow; block-flip deferred after 5 research rounds + production replay
- 32 commits across Apr 23 mega-session including PageHelp banners on 10 admin pages, K1/K2/K3 admin onboarding sequence, D1 orientation, D2 screenshot automation infra
2026-04-19–21 — Zitadel SSO migration + bilingual rollout prep
- Zitadel migration Week 1-3 — pre-token Action live in prod
(Stripe-style HMAC over rawBody), Auth.js v5 Zitadel provider,
Credentials provider removed Week 3,
password_hashcolumn dormant for 30-day soak before drop - Bahasa Indonesia UX pass — non-negotiable rules: roleDisplay
only, Bahasa labels, sonner toasts, no
alert/confirm, aria-label on icon buttons, shared helpers in 4 lib modules, error boundaries on all major routes - Bilingual chatbot code + runbook — chatflow + KB re-embed prep + eval gate + staged ramp procedure shipped (live flip pending)
2026-04-15–17 — Campaigns, conversation guard, KB redesign, cluster FAQ
- Campaign tracking links — CRUD + QR generation + click attribution + bot detection + referrer breakdown
- Conversation guard — profanity 3-strike, repetition filter, cooldown, configurable from admin
- WhatsApp channel config — health endpoint + test message endpoint
- KB multi-dataset redesign — 4 datasets, pre-retrieval, Claude chatflow, query normalization
- CASS KB v2 + frontend config + cluster-aware FAQ system
- 40+ commits across Apr 15-17
2026-04-14 — Sidebar nav + ops hardening
- Sidebar nav redesign (6 groups), follow-up env fix, security sweep, performance audit
2026-04-13 — Activity Timeline + Test Hardening
- Activity Timeline — full-stack lifecycle event log for leads
lead_activitytable (BIGSERIAL, JSONB detail, 3 indexes)leadActivity.tsservice:logActivity()(best-effort) +getTimeline()(paginated)- 8 event types: score_change, status_change, cluster_change, counselor_assigned/released, funnel_change, message_milestone, hot_lead_alert
- Instrumented: leadScoring, counselorAssignment, webhook, leadCaptureStep, postDispatchStep, leadsV2 PATCH
- API endpoint:
GET /api/v1/leads/v2/:id/activity - Admin UI: timeline component on lead detail with icons, colors, load more
- RBAC: pre-flight prisma ownership check for sub-resource paths
- Test coverage jump: 280 → 390 tests (40 suites)
- leadScoring (11), faqKbSync (9), leadActivity (8), webhookHelpers (44), ragClient (11)
- Covers scoring, Dify dispatch, dedup, FAQ sync, persona classification, multi-question detection, timeline pagination, escalation keywords, opt-out
- Webhook pipeline decomposition — 594-line webhook.ts → 222 lines + pipeline modules
- Pool consolidation — 30 independent Pool instances → shared
db.ts - Review fixes: RBAC bypass on activity endpoint, cluster change false positives, actor identity forwarding on PATCH proxy
2026-04-10–12 — Lead Scoring v2, Counselor Assignment, Unified Funnel
- Lead Scoring v2 — GPT-4o-mini scoring at message milestones (3,5,7,every 5) with structured conversation context, hot-lead notifications
- Counselor Auto-Assignment — timestamp round-robin within clusters, My Leads widget, Workload widget, lead card badges
- Unified Funnel Status — inquiry→prospect→registered→...→matriculated, auto-transitions via funnelEngine, role-based manual override
- Enterprise Dify Chatflow — 16-node branching with per-path KB + LLM answers
- FAQ Auto-Sync — faqKbSync debounced 5s, auto-regenerates Milvus KB document
- Feedback on Conversations — thumbs + correction directly from conversations page
- Security — auth middleware for all proxy routes, dashboard RBAC cluster filter
- 84 commits across Apr 10-13 sessions
2026-04-09 — Documentation revamp Pass 1
- Full bilingual MkDocs Material site (ID + EN via
mkdocs-static-i18n) - 8 operator pages, 2 stakeholder lifts, 1 content-team stub, 5 dev onboarding + 5 dev architecture + 4 new dev ops pages + 3 lifted runbooks, bilingual glossary + this changelog
- 9 stale root markdown files archived to
docs/archive/root-legacy/ docs/discovery/archived- Spec:
docs/superpowers/specs/2026-04-09-documentation-revamp-design.md - Plan:
docs/superpowers/plans/2026-04-09-documentation-revamp.md
2026-04-09 — API HTTP Auth middleware (Phase 0)
- Defense-in-depth HTTP auth for Express API in
apps/api - Layer 1: HMAC internal secret (constant-time verify)
- Layer 2: NextAuth JWE forwarding via
X-Forwarded-Session - Layer 3 (webhook HMAC): DEFERRED — current 360dialog tier does not expose an App Secret
- 3-mode middleware:
disabled | warn | enforce, env-flip rollback in sub-30 s - 21 admin proxy routes migrated to
serverFetchhelper - PR #3 (merged 2026-04-10)
- Spec:
2026-04-09-api-http-auth-design.md
2026-04-09 — Counselor Dashboard (Phase 1.6)
- Per-counselor queue view with scoped lead + conversation access
- KPIs (conversion rate, response time, contacted count)
- Merged via PR #2
- Spec:
2026-04-08-counselor-dashboard-design.md
2026-04-08 — RBAC Phase 1.5
- Cluster-based access control on admin endpoints
marketing_counselorwithcluster_id=Xsees only cluster Xmarketing_staff+marketing_adminare global- Applied at admin proxy + Prisma route layer
- Spec:
2026-04-08-rbac-phase15-design.md
2026-04-08 — Escalation Routing Phase 1
conversations.cluster_idpropagation via trigger from leads- Notification fan-out with 2 kinds:
escalation+notify - Cluster-scoped Socket.io rooms (
cluster:<id>) receive events - Global recipients bootstrapped:
marketing_admin+marketing_staff - Spec:
2026-04-08-escalation-routing-phase1-design.md
2026-04-08 — Team Ownership
- Hybrid-lite cluster ownership model:
program_match(fluid) →register_intent(locks) →manual(always wins) - Cluster resolver with exact + prefix program match
- Admin reassign UI with ConfirmDialog
- Backfill: 25 of 28 existing leads matched; 3 legacy rows kept NULL
- Spec:
2026-04-08-team-ownership-design.md
2026-04-08 — Realtime Socket.io + channel cleanup
- Replaced deprecated SSE with Socket.io substrate in API server
- Single
pg_notifyLISTEN bridge → Socket.io rooms - 5 DB trigger functions (message, conversation, lead, notification, followup)
- Enterprise shell fix (
h-screen overflow-hidden, notmin-h-screen) - Telegram + Web channels deleted — WhatsApp only going forward
- Apr 8 ClickHouse OOM fix (memory cap + log disable)
- Timezone WIB trigger bug fix (
AT TIME ZONE 'UTC'in all triggers) - 148 commits over Apr 7-8 sessions
- Spec:
2026-04-07-realtime-socketio-design.md
2026-04-07 — Lead Capture Phase 2A + Analytics Phase 2B.1
- 4-tier hybrid contact extractor (regex Layer 1 + Claude Haiku Layer 2)
- State machine for multi-turn slot filling (6h TTL)
leadStore.upsertatomic with inline status recompute/admin/leads-v2with filter chips + 30s polling- 11 backend analytics endpoints +
/admin/analytics-v2with 13 chart components - Spec:
2026-04-07-intent-routing-phase2a-design.md
2026-04-07 — Intent Router Phase 1
- 4-tier classifier: deterministic regex → keyword heuristic → Claude Haiku → default
- 10 seeded intent handlers (wantRegister, sharePersonalInfo, wantVisitCampus, etc.)
- Escalation rules engine with 3 seeded rules
- Spec:
2026-04-07-intent-routing-design.md
2026-03-27 — KB Phase 1-3 complete
- Full KB system: Milvus + Langfuse + Dify integration
- 308+ pages crawled from
uph.edu - Eval jump: 26% → 74% → 95.2% via dataset fix + faculty content + prompt tuning
- Hybrid search (dense + sparse) with reranking
- Memory:
project_kb_phase3_complete,project_eval_baseline
2026-03-21 — Enterprise Admin Redesign (Phases 0-9)
- Full redesign of
apps/adminusing shadcn/ui (new-york style) - Recharts for analytics
- Inter font, primary UPH blue scale design tokens
- Split-pane Conversations, tabbed Leads/Analytics
- SSE-based realtime (later replaced by Socket.io in Apr 8)
- Spec:
2026-03-21-enterprise-admin-redesign-design.md
2026-03-18 — Phase 1 Foundation complete
- Initial repo + DNS setup
- Infrastructure services (Postgres, Redis, Qdrant, Phoenix)
- API skeleton (Node.js + Express)
- RAG skeleton (Python + FastAPI)
- SSL certificates + auto-renewal
- Docker + docker-compose infrastructure
See also:
- Per-commit history: git log --oneline
- Design specs: docs/superpowers/specs/
- Implementation plans: docs/superpowers/plans/
- Memory records: /home/valid/.claude/projects/-opt-huph/memory/