Repository Tour
Purpose
A guided tour of the HUPH monorepo so you know where to look for each concern. Complements the setup page — this one focuses on "what lives where" rather than "how do I run things".
Prerequisites
- You have cloned the repo and read setup
- Basic familiarity with npm workspaces
Monorepo layout
huph/
├── apps/
│ ├── api/ # Node.js + Express API (port 3101)
│ │ ├── src/routes/ # webhook + REST routes
│ │ ├── src/services/ # intentRouter, leadCapture, notifications, realtime
│ │ ├── src/auth/ # HMAC + NextAuth JWE verifier (Phase 0 auth)
│ │ ├── src/middleware/ # requireInternalSecret, requireForwardedSession, audit
│ │ ├── src/db/ # Drizzle ORM schema
│ │ └── src/__tests__/ # Jest tests
│ ├── admin/ # Next.js 14 admin dashboard (dev 3103, prod 47293)
│ │ ├── src/app/ # app router pages
│ │ ├── src/components/ # shared + shadcn/ui components
│ │ ├── src/hooks/ # useSocketEvent, useAnalytics, etc.
│ │ └── src/lib/ # utilities (socket, time-format, serverFetch)
│ ├── crawler-worker/ # Background worker for Dify KB ingestion jobs
│ └── landing/ # Public landing page (static)
│
├── docker/
│ ├── nginx/ # nginx vhost configs (in-repo sources)
│ └── clickhouse/ # ClickHouse tuning for Langfuse
│
├── scripts/ # SQL migrations, bootstrap helpers, smoke tests
│ ├── migrate-*.sql # manual migration files (applied via psql)
│ └── bootstrap-*.md / .sh # one-off setup runbooks
│
├── docs/ # This documentation site (MkDocs)
│ ├── guide/ # Non-developer docs (ID source)
│ ├── dev/ # Developer docs (EN source) — you are here
│ ├── reference/ # Glossary + changelog
│ ├── archive/ # Historical legacy docs + discovery
│ └── superpowers/ # Specs + plans archive (not rendered)
│
├── docker-compose.yml # Primary infra (postgres + huph-api + crawler-worker)
├── docker-compose.dify.yml # Dify AI stack (chat + KB + annotation)
├── docker-compose.langfuse.yml # Langfuse observability + ClickHouse
├── docker-compose.milvus.yml # Milvus (vector DB used by Dify KB)
├── docker-compose.mem0.yml # mem0 memory service
├── mkdocs.yml # Docs site config (at repo root)
├── docs-env/ # Python venv for docs (gitignored)
├── site/ # mkdocs build output (gitignored)
├── CLAUDE.md # Project instructions for AI assistants
├── CREDENTIALS.md # Live credentials (gitignored — DO NOT commit)
└── uph-codebase/ # Legacy Laravel reference (DO NOT MODIFY)
Notable absences (compared to older CLAUDE.md / memory records):
apps/rag/, apps/webchat/, apps/webchat-enterprise/, and
packages/ do not currently exist. apps/rag was replaced by
Dify in April 2026, and packages/ is planned but not yet
materialized. Do not be misled by older documentation — always
verify with ls /opt/huph/apps/ and cat docker-compose.yml as
sources of truth.
Per-app purpose (1-sentence each)
| App | Purpose |
|---|---|
apps/api |
Node.js + Express server handling webhooks (360dialog), admin REST API, intent routing, lead capture, escalation, realtime Socket.io substrate, Phase 0 HTTP auth middleware, and outbound dispatch to Dify for AI generation |
apps/admin |
Next.js 14 + React + Tailwind enterprise dashboard — conversation inbox, KB management (via Dify proxy), leads pipeline, analytics, FAQ, follow-up, escalation routing, counselor dashboard |
apps/crawler-worker |
Background worker that picks up KB source changes and dispatches ingestion jobs to the Dify KB API; runs as its own Docker container |
apps/landing |
Public static landing page for the product (separate from the admin app) |
Data flow (single message)
User WA message
↓
360dialog webhook POST /webhook/whatsapp (apps/api)
↓
HTTP auth middleware (Phase 0, disabled by default)
↓
Intent Router (4-tier classifier: regex → heuristic → Claude Haiku → default)
↓
Persist conversation + messages (Postgres)
↓
Lead capture pipeline (regex Layer 1 + Claude Haiku LLM Layer 2)
↓
leadStore.upsert (atomic, cluster resolver for ownership)
↓
Escalation rules engine (frustrated / long conversation / hot lead)
↓
Dispatch to Dify chat-messages API (apps/api → huph-dify-api:5001)
↓
Dify runs:
• Annotation reply match (~300 ms FAQ hit) — bypasses LLM
• OR full retrieval: OpenAI embeddings → Milvus similarity search
→ rerank → persona prompt assembly → Claude (via Dify workflow)
↓
Response back to apps/api
↓
Persist bot message + pg_notify trigger → pgBridge → Socket.io rooms
↓
Admin clients in the lead's cluster room see the message in realtime
↓
Reply sent back to user via 360dialog Business API
Where tests live
- API (Jest):
apps/api/src/**/__tests__/*.test.ts. Run vianpm run test -w apps/api(from repo root) ornpx jest(fromapps/api/). - Admin: NO test infrastructure. Verify via
tsc+ browser smoke curl. See running-tests.en.md.- crawler-worker: tests live alongside the source in
apps/crawler-worker/if present; verify viadocker-compose logs crawler-workerduring local runs. - Integration / smoke:
scripts/smoke-e2e-synthetic.shis the end-to-end auth + lead capture smoke, wired tonpm run smoke:e2e.
Where configs live
.env— root env vars for all services (local).env.example— template committed to repodocker-compose.yml+docker-compose.<service>.yml— container definitionsmkdocs.yml— this docs siteapps/api/tsconfig.json,jest.config.js,package.jsonapps/admin/next.config.mjs,tailwind.config.tsapps/rag/requirements.txt,requirements-optional.txt
Where plans and specs live
docs/superpowers/specs/— design specs for each phase (~35 files)docs/superpowers/plans/— execution plans matching each spec (~41 files)docs/archive/— legacy root docs from the Mar 18 phase-1 snapshot + discovery material
These directories are in exclude_docs — not rendered by MkDocs —
but remain in git for history and AI-assisted work.
Gotchas
apps/rag/is gone — replaced by Dify in April 2026. Any reference to a localapps/rag,npm run dev:rag, or self-hosted BGE-M3 is historical. Current AI pipeline lives in Dify.apps/webchat/andapps/webchat-enterprise/are gone — deleted in the Apr 8 channel cleanup. WhatsApp is the only active channel. Don't expect Telegram or Web references to work.packages/does not exist yet. The rootpackage.jsonhasdb:migrateanddb:generatescripts that referencepackages/database, but that workspace is not materialized. Running those commands today will fail. Use the raw SQL migration flow described in setup.uph-codebase/is a legacy Laravel reference — read-only. Do not modify it, do not run it, do not import from it.CLAUDE.mdhas drifted. It is still the AI-assistant instructions file and should be treated as authoritative for conventions, but its architecture section referencesapps/rag,packages/, Qdrant, and BGE-M3 as current — none of which is true anymore. When in doubt, verify againstdocker-compose.yml,ls apps/, andcat package.json.
See also
- Setup — local env bring-up
- Architecture overview — system diagram and per-component walkthrough
- Running tests