Initial portal commit: landing + 9 AI-powered apps
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
This commit is contained in:
78
README.md
Normal file
78
README.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user