Commit Graph

33 Commits

Author SHA1 Message Date
Matt bcc1e17934 Fix login page build error - force dynamic rendering
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m42s Details
Build and Push Docker Image / build (push) Successful in 4m34s Details
The login page checks database for setup status, which fails during
static page generation at build time. Force dynamic rendering to
defer the check to runtime.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 16:21:12 +01:00
Matt a68e1084ad Add initial setup screen for first admin account
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m48s Details
Build and Push Docker Image / build (push) Failing after 3m54s Details
- Add /setup page that appears when no staff exist
- Create first OWNER account with name, email, password
- Login page redirects to /setup if setup required
- Setup page redirects to /login after completion
- API guards prevent setup after first account exists

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 16:10:24 +01:00
Matt a71ef8f9fc Fix: Allow prisma generate without DATABASE_URL
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m46s Details
Build and Push Docker Image / build (push) Successful in 4m43s Details
Use placeholder URL during build - only real URL needed for migrations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 15:33:49 +01:00
Matt 8157531fba Move Prisma config to project root as .mjs for Prisma 7
Build and Push Docker Image / lint-and-typecheck (push) Failing after 1m9s Details
Build and Push Docker Image / build (push) Has been skipped Details
- Move prisma.config.ts to prisma.config.mjs at project root
- Use dynamic dotenv import (works in Docker without dotenv)
- Add dotenv to devDependencies for local development
- Install dotenv globally in Docker for migration support

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 15:31:23 +01:00
Matt 053463b7e1 Install Prisma CLI globally for migrations
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m42s Details
Build and Push Docker Image / build (push) Successful in 4m32s Details
Instead of copying partial node_modules which misses WASM files,
install prisma@7 globally in the production image.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 15:02:13 +01:00
Matt d05b612c11 Include Prisma CLI in production image for migrations
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m44s Details
Build and Push Docker Image / build (push) Successful in 4m9s Details
Copy prisma CLI and its node_modules folder to allow running
migrations in the container with ./node_modules/.bin/prisma

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 14:54:50 +01:00
Matt d378fd7439 Fix CI: use npm install instead of npm ci
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m37s Details
Build and Push Docker Image / build (push) Successful in 3m54s Details
The lint-and-typecheck job was using npm ci which requires
package-lock.json to be in sync. Changed to npm install for
Prisma 7 upgrade compatibility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 14:47:05 +01:00
Matt ccde726123 Use npm install instead of npm ci for Prisma 7 upgrade
Build and Push Docker Image / lint-and-typecheck (push) Failing after 22s Details
Build and Push Docker Image / build (push) Has been skipped Details
package-lock.json is out of sync with package.json after Prisma 7
upgrade. Using npm install allows build to succeed and regenerate
the lock file.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 14:44:13 +01:00
Matt 67bb4138f3 Upgrade to Prisma 7 with adapter pattern
Build and Push Docker Image / lint-and-typecheck (push) Failing after 26s Details
Build and Push Docker Image / build (push) Has been skipped Details
- Update prisma and @prisma/client to ^7.0.0
- Add @prisma/adapter-pg for PostgreSQL connections
- Create prisma.config.ts for datasource configuration
- Remove url from schema.prisma datasource block
- Update prisma.ts to use PrismaPg adapter pattern

Breaking change in Prisma 7: datasource url now configured
via prisma.config.ts instead of schema.prisma

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 14:42:50 +01:00
Matt 49e5f4c43f Change Hub port from 3000 to 3847
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m36s Details
Build and Push Docker Image / build (push) Successful in 3m36s Details
- Add HUB_PORT variable to .env.example
- Update docker-compose.yml to use configurable port
- Update nginx config to proxy to port 3847

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 14:30:45 +01:00
Matt 71ddeacac2 Fix nginx config for certbot workflow
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m35s Details
Build and Push Docker Image / build (push) Has been cancelled Details
- Remove SSL block that referenced non-existent certificates
- HTTP-only config passes nginx -t before certbot
- Certbot --nginx will add SSL configuration automatically

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 14:28:37 +01:00
Matt e876a4c967 chore: Remove Traefik from deploy stack (using Nginx)
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m35s Details
Build and Push Docker Image / build (push) Successful in 3m50s Details
- Remove Traefik network and labels from docker-compose
- Remove redundant docker-compose.simple.yml
- Remove HUB_DOMAIN from .env.example
- Remove traefik network creation from setup.sh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 13:51:07 +01:00
Matt 18721c9487 chore: Add .dockerignore to speed up builds
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m29s Details
Build and Push Docker Image / build (push) Successful in 3m51s Details
Excludes node_modules, .next, .git, env files, and other
unnecessary files from Docker build context.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 13:37:29 +01:00
Matt 622d9f4d2e feat: Add Nginx config for Hub reverse proxy
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m29s Details
Build and Push Docker Image / build (push) Successful in 3m42s Details
- nginx/hub.conf with SSL, headers, and SSE support
- Bind port 3000 to localhost only (Nginx proxies)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 13:24:18 +01:00
Matt 411f7d4604 feat: Add production deployment stack
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m28s Details
Build and Push Docker Image / build (push) Has been cancelled Details
- docker-compose.yml with Traefik integration
- docker-compose.simple.yml for direct port exposure
- .env.example with all configuration options
- setup.sh script for initial deployment

Usage:
  cd deploy/
  cp .env.example .env
  # Edit .env with your values
  ./setup.sh
  docker compose up -d

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 13:17:09 +01:00
Matt 25a67ffea0 feat: Pass Gitea registry credentials to provisioning runner
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m30s Details
Build and Push Docker Image / build (push) Has been cancelled Details
- Add GiteaCredentials interface to config-generator
- Update JobConfig to include gitea registry credentials
- Fetch Gitea credentials from settings in provision route
- Pass gitea credentials through to job config

This enables the runner to login to the Gitea registry on target
servers, allowing deployment of private LetsBe images.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 13:14:01 +01:00
Matt b870c58695 Fix let/const for newTools - let where reassigned, const where mutated
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m26s Details
Build and Push Docker Image / build (push) Successful in 4m3s Details
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 12:45:54 +01:00
Matt d0a5a4ab02 Fix prefer-const lint errors
Build and Push Docker Image / lint-and-typecheck (push) Failing after 1m18s Details
Build and Push Docker Image / build (push) Has been skipped Details
- Change let to const for newTools variables in ToolsEditor and create-order-dialog

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 12:42:29 +01:00
Matt 86fe36b544 Fix ESLint config - bypass FlatCompat circular reference bug
Build and Push Docker Image / lint-and-typecheck (push) Failing after 1m26s Details
Build and Push Docker Image / build (push) Has been skipped Details
- Remove FlatCompat wrapper that caused circular structure error
- Use typescript-eslint directly with react-hooks plugin
- Add eslint-plugin-react-hooks dependency

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 12:39:59 +01:00
Matt 92092760a7 Complete Hub Admin Dashboard with analytics, settings, and enterprise features
Build and Push Docker Image / lint-and-typecheck (push) Failing after 2m10s Details
Build and Push Docker Image / build (push) Has been skipped Details
Major additions:
- Analytics dashboard with charts (line, bar, donut)
- Enterprise client monitoring with container management
- Staff management with 2FA support
- Profile management and settings pages
- Netcup server integration
- DNS verification panel
- Portainer integration
- Container logs and health monitoring
- Automation controls for orders

New API endpoints:
- /api/v1/admin/analytics
- /api/v1/admin/enterprise-clients
- /api/v1/admin/netcup
- /api/v1/admin/settings
- /api/v1/admin/staff
- /api/v1/profile

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 12:33:11 +01:00
Matt 60493cfbdd fix: Fix Docker build for public directory
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m3s Details
Build and Push Docker Image / build (push) Successful in 2m38s Details
- Update Dockerfile to ensure public directory exists in builder stage
- Use 'COPY /app/public/. ./public/' pattern for robust copying
- Add manifest.json to public folder (non-empty directory)
- Remove .gitkeep placeholder

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:55:36 +01:00
Matt 7dc7100fb8 fix: Add public directory for Docker build
Build and Push Docker Image / lint-and-typecheck (push) Successful in 58s Details
Build and Push Docker Image / build (push) Successful in 2m40s Details
Docker build requires public folder to exist even if empty.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:02:12 +01:00
Matt d21dc88812 fix: Wrap useSearchParams in Suspense boundary
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m1s Details
Build and Push Docker Image / build (push) Failing after 2m31s Details
Next.js 15 requires useSearchParams() to be wrapped in a
Suspense boundary for static page generation.

- Split LoginForm into separate component
- Add Suspense wrapper with loading skeleton
- Fixes build error on /login page

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 12:52:41 +01:00
Matt 56b919fe4a chore: Add ESLint configuration
Build and Push Docker Image / lint-and-typecheck (push) Successful in 1m1s Details
Build and Push Docker Image / build (push) Failing after 2m19s Details
- Add eslint.config.mjs with Next.js core-web-vitals preset
- Install @eslint/eslintrc for flat config compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 12:47:13 +01:00
Matt 41cb49eeda fix: Remove npm cache from CI workflow
Build and Push Docker Image / lint-and-typecheck (push) Failing after 57s Details
Build and Push Docker Image / build (push) Has been skipped Details
Gitea Actions runner hangs on npm cache config. Removing
cache option to fix CI pipeline.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 12:44:34 +01:00
Matt 3594bcf297 chore: Remove old Python files and update CI for Next.js
Build and Push Docker Image / build (push) Blocked by required conditions Details
Build and Push Docker Image / lint-and-typecheck (push) Has been cancelled Details
- Remove Python tests, alembic migrations, and requirements.txt
- Update CI workflow to use Node.js instead of Python
- CI now runs TypeScript check and lint before Docker build

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 12:40:26 +01:00
Matt a79b79efd2 feat: Complete rewrite as Next.js admin dashboard
Build and Push Docker Image / test (push) Failing after 34s Details
Build and Push Docker Image / build (push) Has been skipped Details
Major transformation from FastAPI telemetry service to Next.js admin dashboard:

- Next.js 15 App Router with TypeScript
- Prisma ORM with PostgreSQL (same schema, new client)
- TanStack Query for data fetching
- Tailwind CSS + shadcn/ui components
- Admin dashboard with:
  - Dashboard stats overview
  - Customer management (list, detail, edit)
  - Order management (list, create, detail, logs)
  - Server monitoring (grid view)
  - Subscription management

Pages implemented:
- /admin (dashboard)
- /admin/customers (list + [id] detail)
- /admin/orders (list + [id] detail with SSE logs)
- /admin/servers (grid view)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 12:35:01 +01:00
Matt 02fc18f009 fix: Accept string instance_id in telemetry endpoint
The orchestrator sends instance_id as a string (e.g., "letsbe-orchestrator")
but the endpoint was expecting a UUID path parameter. This caused 422
validation errors when orchestrators tried to send telemetry.

- Changed path parameter from UUID to str
- Lookup instance by Instance.instance_id (string) instead of Instance.id (UUID)
- Store telemetry with instance.id (UUID) for correct FK relationship
- Updated TelemetryPayload schema to use str instead of UUID

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 15:11:30 +01:00
Matt 2a1270bfbd Use pre-built image from Gitea registry
Switch from local build to code.letsbe.solutions/letsbe/hub:latest
Remove development volume mount (not needed with pre-built image)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 16:13:26 +01:00
Matt 06ed320136 Add nginx configuration for Hub deployment
Includes:
- HTTP to HTTPS redirect
- Placeholder SSL certs for initial nginx -t pass
- Proxy to Hub API on port 8200
- ACME challenge location for certbot
- WebSocket support headers
- Usage instructions in comments

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 14:23:24 +01:00
Matt 246e7f142a ci: Add Gitea Actions workflow for Docker build 2025-12-22 14:12:12 +01:00
Matt 38daa25d92 chore: Trigger CI build 2025-12-22 14:10:39 +01:00
Matt adc02e176b feat: Initial Hub implementation
Complete LetsBe Hub service for license management and telemetry:

- Client and Instance CRUD APIs
- License key generation and validation (lb_inst_ format)
- Hub API key generation (hk_ format) for telemetry auth
- Instance activation endpoint
- Telemetry collection with privacy-first redactor
- Key rotation and suspend/reactivate functionality
- Alembic migrations for PostgreSQL
- Docker Compose deployment ready
- Comprehensive test suite

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 14:09:32 +01:00