Initial parlo-styring skill - dev/deploy/ops for Mikkel's app
This commit is contained in:
commit
00971656e3
4 changed files with 337 additions and 0 deletions
127
SKILL.md
Normal file
127
SKILL.md
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
---
|
||||
name: parlo-styring
|
||||
description: Parlo Styring app for Parlobyg - Next.js job management system. Use for development, deployment, and working with Mikkel's scheduling app. Triggers on parlo-styring, scheduling app, or Coolify deployment tasks.
|
||||
---
|
||||
|
||||
# Parlo Styring Skill
|
||||
|
||||
Next.js job management and scheduling application for Parlobyg construction company.
|
||||
|
||||
## Live App
|
||||
|
||||
- **URL:** https://parlo.machinemachine.ai
|
||||
- **Status:** ✅ Running healthy
|
||||
|
||||
## Repository
|
||||
|
||||
- **Git:** http://git.machinemachine.ai/machine.machine/parlo-styring.git
|
||||
- **Forgejo UI:** http://git.machinemachine.ai/machine.machine/parlo-styring
|
||||
|
||||
## Deployment (Coolify)
|
||||
|
||||
- **App UUID:** xht4hfyngaimnf0mjmrc93vx
|
||||
- **Stack:** Next.js 14.2.5 (standalone)
|
||||
- **Port:** 3000 (internal)
|
||||
- **Domain:** parlo.machinemachine.ai (via Traefik)
|
||||
|
||||
### Environment Variables
|
||||
```
|
||||
ORDRESTYRING_API_KEY=q3mjVDR6wAdPCvZT
|
||||
ENABLE_WRITES=false
|
||||
OPENROUTER_API_KEY=sk-or-v1-...
|
||||
NEXTAUTH_URL=https://parlo.machinemachine.ai
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Clone & Run Locally
|
||||
```bash
|
||||
# Clone
|
||||
git clone http://git.machinemachine.ai/machine.machine/parlo-styring.git
|
||||
cd parlo-styring
|
||||
|
||||
# Install & run
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Push Changes
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "feat: description"
|
||||
git push origin main
|
||||
# Coolify auto-deploys on push
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
src/
|
||||
├── app/ # Next.js App Router pages
|
||||
│ ├── api/ # API routes
|
||||
│ │ ├── cases/ # Ordrestyring cases
|
||||
│ │ ├── customers/
|
||||
│ │ ├── workers/
|
||||
│ │ └── ai/ # AI chat endpoint
|
||||
│ ├── dashboard/ # Main dashboard
|
||||
│ ├── sager/ # Cases (Sager) pages
|
||||
│ ├── kunder/ # Customers pages
|
||||
│ └── medarbejdere/ # Workers pages
|
||||
├── components/ # React components
|
||||
│ ├── GanttChart/ # Scheduling Gantt view
|
||||
│ ├── CaseDetail/ # Case detail panel
|
||||
│ └── Chat/ # AI chat interface
|
||||
└── lib/
|
||||
└── ordrestyring.ts # GraphQL client
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- 📋 **Dashboard** — Overview of cases, workers, schedule
|
||||
- 📅 **Gantt Chart** — Visual scheduling with AI suggestions
|
||||
- 👥 **Customers** — Customer list with detail views
|
||||
- 👷 **Workers** — Worker management and daily views
|
||||
- 💬 **AI Chat** — OpenRouter-powered assistant
|
||||
- 📱 **PWA** — Mobile-friendly, installable
|
||||
|
||||
## API Integration
|
||||
|
||||
### Ordrestyring
|
||||
The app fetches live data from Ordrestyring GraphQL:
|
||||
- Cases, customers, workers, hours
|
||||
- Read-only by default (`ENABLE_WRITES=false`)
|
||||
|
||||
### AI Chat
|
||||
Uses OpenRouter API with context from:
|
||||
- Qdrant vector memory (memory-qdrant:6333)
|
||||
- BGE-M3 embeddings (memory-embeddings:8000)
|
||||
|
||||
## Work Packages
|
||||
|
||||
The repo contains WORKPACKAGE-*.md files documenting features to build.
|
||||
Current count: ~39 work packages
|
||||
|
||||
## Quick Commands
|
||||
|
||||
```bash
|
||||
# Check deployment status
|
||||
curl -s https://parlo.machinemachine.ai/api/health
|
||||
|
||||
# View recent commits
|
||||
curl -s -H "Authorization: token $FORGEJO_TOKEN" \
|
||||
"http://git.machinemachine.ai/api/v1/repos/machine.machine/parlo-styring/commits?limit=5"
|
||||
|
||||
# Trigger rebuild (via Forgejo webhook)
|
||||
# Push any change → Coolify auto-deploys
|
||||
```
|
||||
|
||||
## Related Skills
|
||||
|
||||
- **ordrestyring** — GraphQL API for job data
|
||||
- **parlobyg-email** — Email integration
|
||||
- **microsoft-graph** — Mikkel's Outlook/OneDrive
|
||||
|
||||
## References
|
||||
|
||||
- [App Architecture](references/architecture.md)
|
||||
- [Deployment Guide](references/deployment.md)
|
||||
94
references/architecture.md
Normal file
94
references/architecture.md
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
# Parlo Styring Architecture
|
||||
|
||||
## Stack
|
||||
|
||||
- **Framework:** Next.js 14.2.5 (App Router)
|
||||
- **Styling:** Tailwind CSS
|
||||
- **Language:** TypeScript
|
||||
- **Deployment:** Docker → Coolify → Traefik
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌──────────────────┐
|
||||
│ Browser/PWA │────▶│ Next.js Server │
|
||||
└─────────────────┘ └────────┬─────────┘
|
||||
│
|
||||
┌───────────────────────┼───────────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌─────────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
||||
│ Ordrestyring │ │ OpenRouter AI │ │ Vector Memory │
|
||||
│ GraphQL API │ │ (claude-haiku) │ │ (Qdrant+BGE-M3) │
|
||||
└─────────────────┘ └──────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
### Pages (App Router)
|
||||
- `/` — Redirect to dashboard
|
||||
- `/dashboard` — Main overview
|
||||
- `/sager` — Cases list
|
||||
- `/sager/[id]` — Case detail
|
||||
- `/kunder` — Customers list
|
||||
- `/medarbejdere` — Workers list
|
||||
- `/tidsplan` — Gantt schedule
|
||||
|
||||
### API Routes
|
||||
- `/api/cases` — Proxy to Ordrestyring cases
|
||||
- `/api/customers` — Proxy to Ordrestyring customers
|
||||
- `/api/workers` — Proxy to Ordrestyring workers
|
||||
- `/api/hours` — Time entries
|
||||
- `/api/ai/chat` — AI chat with RAG
|
||||
|
||||
### Ordrestyring Client
|
||||
`src/lib/ordrestyring.ts` — TypeScript GraphQL client
|
||||
|
||||
```typescript
|
||||
// Read operations (always enabled)
|
||||
getCases(limit, page)
|
||||
getCase(id)
|
||||
getCustomers(limit, page)
|
||||
getWorkers(limit, page)
|
||||
getHours(limit, page)
|
||||
|
||||
// Write operations (gated by ENABLE_WRITES)
|
||||
createCase(data)
|
||||
updateCase(id, data)
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `ORDRESTYRING_API_KEY` | Yes | Ordrestyring GraphQL API key |
|
||||
| `ENABLE_WRITES` | No | Enable write mutations (default: false) |
|
||||
| `OPENROUTER_API_KEY` | No | AI chat functionality |
|
||||
| `NEXTAUTH_URL` | Yes | Auth callback URL |
|
||||
| `NEXTAUTH_SECRET` | Yes | Session encryption |
|
||||
|
||||
## Docker
|
||||
|
||||
```dockerfile
|
||||
FROM node:20-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM node:20-alpine AS runner
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/.next/standalone ./
|
||||
COPY --from=builder /app/.next/static ./.next/static
|
||||
COPY --from=builder /app/public ./public
|
||||
EXPOSE 3000
|
||||
CMD ["node", "server.js"]
|
||||
```
|
||||
|
||||
## Coolify Config
|
||||
|
||||
- **Build:** Dockerfile
|
||||
- **Port:** 3000
|
||||
- **Health:** `/api/health`
|
||||
- **Volume:** `parlo-styring-data:/app/data` (for uploads)
|
||||
76
references/deployment.md
Normal file
76
references/deployment.md
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# Parlo Styring Deployment Guide
|
||||
|
||||
## Coolify Dashboard
|
||||
|
||||
The app is deployed via Coolify at the machinemachine.ai infrastructure.
|
||||
|
||||
## Auto-Deploy
|
||||
|
||||
Pushes to `main` branch trigger automatic deployment via Forgejo webhook.
|
||||
|
||||
```bash
|
||||
# Make changes
|
||||
git add -A
|
||||
git commit -m "feat: new feature"
|
||||
git push origin main
|
||||
# → Coolify builds and deploys automatically
|
||||
```
|
||||
|
||||
## Manual Deploy
|
||||
|
||||
If webhook fails, deploy manually via Coolify UI:
|
||||
1. Go to Coolify dashboard
|
||||
2. Find `parlo-styring` app
|
||||
3. Click "Redeploy"
|
||||
|
||||
## Environment Updates
|
||||
|
||||
To update environment variables:
|
||||
1. Coolify dashboard → parlo-styring → Environment
|
||||
2. Edit variables
|
||||
3. Save & Redeploy
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Health Check
|
||||
```bash
|
||||
curl https://parlo.machinemachine.ai/api/health
|
||||
```
|
||||
|
||||
### Logs
|
||||
View in Coolify dashboard → parlo-styring → Logs
|
||||
|
||||
### Container Status
|
||||
```bash
|
||||
# Via Coolify API or dashboard
|
||||
# Status should show: running:healthy
|
||||
```
|
||||
|
||||
## Rollback
|
||||
|
||||
1. Coolify dashboard → parlo-styring → Deployments
|
||||
2. Find previous successful deployment
|
||||
3. Click "Rollback"
|
||||
|
||||
## DNS / SSL
|
||||
|
||||
- Domain: parlo.machinemachine.ai
|
||||
- SSL: Auto-managed by Traefik (Let's Encrypt)
|
||||
- Proxy: Traefik routes traffic to container port 3000
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### 502 Bad Gateway
|
||||
- Container crashed or not started
|
||||
- Check Coolify logs
|
||||
- Verify health check passes
|
||||
|
||||
### Build Failures
|
||||
- Check build logs in Coolify
|
||||
- Common: dependency issues, TypeScript errors
|
||||
- Fix locally, push again
|
||||
|
||||
### Auth Issues
|
||||
- Verify `NEXTAUTH_URL` matches domain
|
||||
- Check `NEXTAUTH_SECRET` is set
|
||||
- Clear cookies and retry
|
||||
40
scripts/deploy.sh
Executable file
40
scripts/deploy.sh
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
# Parlo Styring deployment helper
|
||||
|
||||
REPO_URL="http://git.machinemachine.ai/machine.machine/parlo-styring.git"
|
||||
APP_URL="https://parlo.machinemachine.ai"
|
||||
FORGEJO_TOKEN="${FORGEJO_TOKEN:-853477e0b57dea951c8c46c6c24b0ddffa5393dc}"
|
||||
|
||||
case "$1" in
|
||||
status)
|
||||
echo "Checking app health..."
|
||||
curl -s "$APP_URL/api/health" 2>/dev/null || echo "App not responding"
|
||||
;;
|
||||
|
||||
commits)
|
||||
echo "Recent commits:"
|
||||
curl -s -H "Authorization: token $FORGEJO_TOKEN" \
|
||||
"http://git.machinemachine.ai/api/v1/repos/machine.machine/parlo-styring/commits?limit=${2:-5}" \
|
||||
| jq -r '.[] | "\(.sha[0:7]) \(.commit.message | split("\n")[0]) - \(.commit.author.name)"'
|
||||
;;
|
||||
|
||||
clone)
|
||||
echo "Cloning parlo-styring..."
|
||||
git clone "$REPO_URL" "${2:-parlo-styring}"
|
||||
;;
|
||||
|
||||
push)
|
||||
echo "Pushing changes (triggers Coolify deploy)..."
|
||||
git push origin main
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $0 {status|commits|clone|push}"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " status Check app health"
|
||||
echo " commits [n] Show recent n commits (default 5)"
|
||||
echo " clone [dir] Clone repo to directory"
|
||||
echo " push Push changes to trigger deploy"
|
||||
;;
|
||||
esac
|
||||
Loading…
Reference in a new issue