Skip to content

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) Zitadel aud claim mismatch causing /api/v1/* invalid_token. Three-part fix: admin requests the urn:zitadel:iam:org:project:id:<PROJECT_ID>:aud scope so the access token's aud includes project_id; the API verifier defensively accepts EITHER project_id OR client_id (keeps pre-fix tokens valid through rollout); requireZitadelJwt middleware now writes audit_log rows on header_missing and jwt_invalid (failures were previously invisible).
  • fix(admin) PageHelp docs links across 9 admin pages dropped the .id suffix — mkdocs-static-i18n does 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.read audit)
  • Feature Coverage widget on SystemDashboard (super_admin only, monitoring.coverage.read audit)
  • Executive Summary page + handbook (cross-cluster KPIs)
  • Phase 4 audit retrofitbefore_state / after_state JSONB 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_config migration, /settings/faq-threshold GET/PUT (gated by FEATURE_FAQ_THRESHOLD), admin slider in /settings/chatbot, smoke test
  • Operator alertshot_lead_wait + cron_failure in-app alerts with alerts_sweep cron (every 5 min), kill switch via FEATURE_ALERTS=false
  • fix(api) P0: parseAuthMode now recognizes legacy and both (dispatchAuth-era values mapped to enforce); prior gap silently bypassed inner-guard middlewares
  • fix(auth) auth allow-list now matches req.originalUrl instead of mounted req.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, faqKbSync timer 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_hash column 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_activity table (BIGSERIAL, JSONB detail, 3 indexes)
  • leadActivity.ts service: 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 serverFetch helper
  • 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_counselor with cluster_id=X sees only cluster X
  • marketing_staff + marketing_admin are 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_id propagation 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_notify LISTEN bridge → Socket.io rooms
  • 5 DB trigger functions (message, conversation, lead, notification, followup)
  • Enterprise shell fix (h-screen overflow-hidden, not min-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.upsert atomic with inline status recompute
  • /admin/leads-v2 with filter chips + 30s polling
  • 11 backend analytics endpoints + /admin/analytics-v2 with 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/admin using 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/