Apps: - dwg-rooms: extract room numbers from DWG/DXF - dwg-counting: count symbols in PDF drawings (OpenCV template matching) - contract-check: review PDF contracts against a checklist (Claude vision + Tesseract OCR fallback) - email-drafter: bullet notes → polished Czech/English business emails - invoice-extractor: PDF/image invoice → structured data → Excel - translator: Czech-first translator across 19 languages with tone control - vv-check: find inconsistent unit prices across VV sheets in one workbook - vv-compare: diff original vs new VV files (changes / added / removed) - feature-request: portal users submit ideas + sample files Infrastructure: - LiteLLM gateway with per-app virtual keys + budgets - Langfuse observability - Geist font, shared theme, cross-subdomain back link + theme sync via cookie/URL - Caddy reverse proxy on *.klas.chat
79 lines
2.3 KiB
Markdown
79 lines
2.3 KiB
Markdown
# AI Portal
|
|
|
|
Internal landing page that fronts a stack of AI tools (chat + workflow apps),
|
|
all routed through company API keys with per-user budgets and observability.
|
|
|
|
See `AI_PORTAL_HANDOFF.md` for full architecture and rationale.
|
|
|
|
## Phase 0 — what's running
|
|
|
|
- **Landing page** (Next.js 16 + Auth.js v5) — this repo, `landing/`
|
|
- **Open WebUI** — already running on host (`127.0.0.1:8080`)
|
|
- **Dify stack** — already running (`docker_default` network, nginx on `:443/:8090`)
|
|
- **LiteLLM** — already running on `localai` network (`:4000`)
|
|
- **Langfuse** — not yet (compose stub left in `docker-compose.yml`)
|
|
|
|
## Local dev
|
|
|
|
```bash
|
|
cd landing
|
|
cp ../.env.example ../.env # then edit secrets
|
|
pnpm install
|
|
pnpm dev # http://localhost:3000
|
|
```
|
|
|
|
Set at minimum:
|
|
- `AUTH_SECRET` — `openssl rand -base64 32`
|
|
- `DEV_PORTAL_PASSWORD` — any string; gates the dev login
|
|
|
|
## Production-style run (Docker)
|
|
|
|
From the `portal/` directory:
|
|
|
|
```bash
|
|
docker compose up -d --build
|
|
```
|
|
|
|
The landing service binds to `127.0.0.1:3010`. Caddy on the host fronts it at
|
|
`https://ai.klas.chat`.
|
|
|
|
## Auth
|
|
|
|
Two providers, both wired through Auth.js v5:
|
|
|
|
1. **Microsoft Entra ID** — production. Activated automatically when
|
|
`AUTH_MICROSOFT_ENTRA_ID_ID` and `AUTH_MICROSOFT_ENTRA_ID_SECRET` are set.
|
|
2. **Dev Credentials** — single shared password from `DEV_PORTAL_PASSWORD`.
|
|
Used only while Entra is not provisioned. Both can coexist; the login page
|
|
shows whichever is configured.
|
|
|
|
All routes except `/login` and `/api/auth/*` are gated by `proxy.ts`.
|
|
|
|
## Adding a new tile
|
|
|
|
Edit `landing/src/data/apps.json` and add an entry:
|
|
|
|
```json
|
|
{
|
|
"id": "my-app",
|
|
"title": "My App",
|
|
"description": "What it does in one line.",
|
|
"category": "Documents",
|
|
"icon": "FileText",
|
|
"accent": "blue",
|
|
"href": "https://dify.klas.chat/app/<id>"
|
|
}
|
|
```
|
|
|
|
Icon names come from [lucide-react](https://lucide.dev). Accents:
|
|
`violet`, `blue`, `cyan`, `emerald`, `amber`, `rose`. Use `"href": "#"` to
|
|
mark a tile as "Coming soon".
|
|
|
|
## What's next (post Phase 0)
|
|
|
|
1. Wire Open WebUI to use LiteLLM as its OpenAI-compatible endpoint.
|
|
2. Configure Dify model providers to point at LiteLLM (so spend is attributed).
|
|
3. Stand up Langfuse (uncomment in `docker-compose.yml`).
|
|
4. Map per-user identity → LiteLLM virtual keys.
|
|
5. Provision Microsoft Entra app registration; flip prod auth on.
|