101 lines
3.5 KiB
Markdown
101 lines
3.5 KiB
Markdown
# PieCed Portal
|
|
|
|
Customer self-service portal for the PieCed IT multi-tenant OpenClaw platform.
|
|
|
|
## Stack
|
|
|
|
| Layer | Choice |
|
|
|-------|--------|
|
|
| Framework | Next.js 15 LTS (App Router, standalone output, Turbopack) |
|
|
| Auth | NextAuth v5 + ZITADEL OIDC (CODE flow) |
|
|
| Tenant mgmt | Direct K8s API → `PiecedTenant` CRs (Option A) |
|
|
| Usage data | LiteLLM `/team/info` + `/global/spend/logs` |
|
|
| i18n | next-intl 4.x (en/de) |
|
|
| Styling | Tailwind CSS 4 |
|
|
| Deployment | Container in `pieced-system`, exposed at `app.pieced.ch` |
|
|
|
|
## Setup
|
|
|
|
### 1. ZITADEL Application
|
|
|
|
In ZITADEL console (`auth.pieced.ch`), project "OpenClaw Platform":
|
|
|
|
1. Create Application → **PieCed Portal** → Web → Authentication Method: **CODE**
|
|
2. Redirect URI: `https://app.pieced.ch/api/auth/callback/zitadel`
|
|
3. Post-logout URI: `https://app.pieced.ch/login`
|
|
4. Note Client ID and Client Secret
|
|
|
|
### 2. OpenBao Secrets
|
|
|
|
```bash
|
|
bao kv put pieced/portal/oidc \
|
|
client_id="<from step 1>" \
|
|
client_secret="<from step 1>" \
|
|
nextauth_secret="$(openssl rand -base64 32)"
|
|
```
|
|
|
|
### 3. Build & Push
|
|
|
|
```bash
|
|
docker build -t registry.c5ai.ch/pieced/pieced-portal:0.1.0 .
|
|
docker push registry.c5ai.ch/pieced/pieced-portal:0.1.0
|
|
```
|
|
|
|
Update image tag in `pieced-gitops/apps/portal/deployment.yaml`, push, ArgoCD syncs.
|
|
|
|
### 4. DNS
|
|
|
|
Ensure `app.pieced.ch` A record → MetalLB ingress IP (or ExternalDNS handles it).
|
|
|
|
## Local Development
|
|
|
|
```bash
|
|
cp .env.example .env.local
|
|
# Fill in values — K8s client uses ~/.kube/config locally
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
src/
|
|
├── app/
|
|
│ ├── api/
|
|
│ │ ├── auth/[...nextauth]/route.ts # NextAuth handler
|
|
│ │ ├── tenants/route.ts # Tenant CRUD (K8s API)
|
|
│ │ └── usage/route.ts # Usage stub
|
|
│ ├── [locale]/
|
|
│ │ ├── layout.tsx # Locale layout + NavShell
|
|
│ │ ├── page.tsx # Redirect → /dashboard
|
|
│ │ ├── login/page.tsx # ZITADEL sign-in
|
|
│ │ ├── dashboard/page.tsx # Customer dashboard
|
|
│ │ └── admin/page.tsx # Platform admin tenant list
|
|
│ ├── layout.tsx # Root layout
|
|
│ └── globals.css # Tailwind 4 theme
|
|
├── components/
|
|
│ ├── layout/nav-shell.tsx # Header + navigation
|
|
│ └── ui/ # Reusable UI components
|
|
├── i18n/
|
|
│ ├── routing.ts # next-intl 4.x routing config
|
|
│ ├── navigation.ts # Localized Link, redirect, etc.
|
|
│ └── request.ts # Server-side i18n config
|
|
├── lib/
|
|
│ ├── auth.ts # NextAuth v5 + ZITADEL config
|
|
│ ├── k8s.ts # K8s client for PiecedTenant CRs
|
|
│ ├── litellm.ts # LiteLLM API client
|
|
│ └── session.ts # Session helpers
|
|
├── messages/
|
|
│ ├── en.json
|
|
│ └── de.json
|
|
└── types/index.ts # Shared TypeScript types
|
|
```
|
|
|
|
## Session Roadmap
|
|
|
|
- **6.1** ← This session: scaffold, auth, basic pages
|
|
- **6.2**: Instance management, package config, usage display
|
|
- **6.3**: Onboarding flow (create ZITADEL org → PiecedTenant CR)
|
|
- **6.4**: Workspace editor (SOUL.md, AGENTS.md, TOOLS.md)
|
|
- **6.5**: Admin panel (tenant lifecycle, billing overview)
|