From 1eb4f1642f9c49562969ec64bb604e352385ce8f Mon Sep 17 00:00:00 2001 From: Thorsten Bus Date: Mon, 30 Mar 2026 16:00:02 +0200 Subject: [PATCH] rename cts-work to pp-planer, move Dockerfile to build/, optimize dev scripts - Rename all cts-work references to pp-planer (valet, sanctum, playwright, e2e, docs) - Fix docker-compose build context to use project root with build/Dockerfile - Add .dockerignore to exclude unnecessary files from Docker build - start_dev.sh: stale PID cleanup, dependency checks, APP_KEY check, process health verification - stop_dev.sh: fix set -e crash on arithmetic, report already-dead processes, idempotent exit --- .dockerignore | 10 +++++ AGENTS.md | 10 ++--- Dockerfile => build/Dockerfile | 0 config/sanctum.php | 2 +- docker-compose.yml | 19 +++++----- package-lock.json | 2 +- playwright.config.ts | 2 +- start_dev.sh | 68 +++++++++++++++++++++++++++++----- stop_dev.sh | 16 ++++++-- tests/e2e/auth.setup.ts | 8 ++-- 10 files changed, 101 insertions(+), 36 deletions(-) create mode 100644 .dockerignore rename Dockerfile => build/Dockerfile (100%) diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a101d51 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +node_modules +vendor +.git +.env +storage/logs/* +storage/framework/cache/* +storage/framework/views/* +test-results +tests/e2e/.auth +.dev.pid diff --git a/AGENTS.md b/AGENTS.md index bc3b0c3..be8b237 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -104,14 +104,14 @@ ## Repository Structure | Repo | Path | Branch | Purpose | |------|------|--------|---------| -| **cts-work** | `/Users/thorsten/AI/cts-work` | `cts-presenter-app` | Laravel app (main codebase) | +| **pp-planer** | `/Users/thorsten/AI/pp-planer` | `cts-presenter-app` | Laravel app (main codebase) | | **propresenter-work** | `/Users/thorsten/AI/propresenter-work/php` | `propresenter-parser` | ProPresenter .pro/.proplaylist parser (composer path dependency) | The parser is linked via `composer.json` path repository: `"url": "../propresenter-work/php"`. ## Build, Test, Lint Commands -### cts-work (Laravel App) +### pp-planer (Laravel App) ```bash # First-time setup @@ -141,7 +141,7 @@ # PHP formatting (Laravel Pint, default preset — no pint.json) ./vendor/bin/pint ./vendor/bin/pint --test # check only -# E2E tests (requires dev server at http://cts-work.test) +# E2E tests (requires dev server at http://pp-planer.test) npx playwright test npx playwright test tests/e2e/service-list.spec.ts @@ -164,7 +164,7 @@ # Single test file ## Architecture ``` -cts-work/ +pp-planer/ app/Http/Controllers/ # Inertia controllers (Inertia::render or JSON) app/Models/ # Eloquent models (factories in database/factories/) app/Services/ # Business logic (ChurchToolsService, ProExportService, etc.) @@ -241,7 +241,7 @@ ### ProPresenter Parser Tests (PHPUnit 11) ### E2E Tests (Playwright) -- TypeScript in `tests/e2e/`, baseURL `http://cts-work.test` +- TypeScript in `tests/e2e/`, baseURL `http://pp-planer.test` - Auth via `auth.setup.ts` (XSRF token + `/dev-login` endpoint, saves state to `.auth/user.json`) - Selectors: `page.getByTestId('...')`, `page.getByText('...')`, `page.getByRole('...')` - German text assertions: `await expect(page.getByText('Mit ChurchTools anmelden')).toBeVisible()` diff --git a/Dockerfile b/build/Dockerfile similarity index 100% rename from Dockerfile rename to build/Dockerfile diff --git a/config/sanctum.php b/config/sanctum.php index ce71635..dee6f1e 100644 --- a/config/sanctum.php +++ b/config/sanctum.php @@ -1,5 +1,5 @@ explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,localhost:8000,127.0.0.1,127.0.0.1:8000,::1,cts-work.test')), + 'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,localhost:8000,127.0.0.1,127.0.0.1:8000,::1,pp-planer.test')), ]; diff --git a/docker-compose.yml b/docker-compose.yml index 6453afc..e262d75 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,11 +1,11 @@ -version: '3.8' +version: "3.8" services: app: build: context: . - dockerfile: Dockerfile - container_name: cts-presenter-app + dockerfile: build/Dockerfile + container_name: pp-planer-app restart: unless-stopped working_dir: /app environment: @@ -27,13 +27,13 @@ services: ports: - "8000:8000" networks: - - cts-network + - pp-planer-network depends_on: - node node: image: node:20-alpine - container_name: cts-presenter-node + container_name: pp-planer-node restart: unless-stopped working_dir: /app environment: @@ -44,14 +44,14 @@ services: ports: - "5173:5173" networks: - - cts-network + - pp-planer-network command: npm run dev # Optional: SQLite database service (for reference, SQLite runs in-process) # For MySQL, uncomment and configure: # mysql: # image: mysql:8.0 - # container_name: cts-presenter-mysql + # container_name: pp-planer-mysql # restart: unless-stopped # environment: # MYSQL_DATABASE: ${DB_DATABASE} @@ -63,12 +63,11 @@ services: # ports: # - "3306:3306" # networks: - # - cts-network + # - pp-planer-network networks: - cts-network: + pp-planer-network: driver: bridge - # volumes: # mysql_data: # driver: local diff --git a/package-lock.json b/package-lock.json index 8727491..3aa942b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "cts-work", + "name": "pp-planer", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/playwright.config.ts b/playwright.config.ts index 4aea73e..e64c5b0 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -9,7 +9,7 @@ export default defineConfig({ timeout: 5000, }, use: { - baseURL: 'http://cts-work.test', + baseURL: 'http://pp-planer.test', trace: 'on-first-retry', }, projects: [ diff --git a/start_dev.sh b/start_dev.sh index 0b2bd61..2263384 100755 --- a/start_dev.sh +++ b/start_dev.sh @@ -3,6 +3,7 @@ set -euo pipefail PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" PID_FILE="$PROJECT_DIR/.dev.pid" +SITE_NAME="pp-planer" cd "$PROJECT_DIR" GREEN='\033[0;32m' @@ -11,21 +12,55 @@ RED='\033[0;31m' CYAN='\033[0;36m' NC='\033[0m' +# ── Stale PID cleanup ────────────────────────────────────── if [ -f "$PID_FILE" ]; then - echo -e "${RED}Dev-Umgebung läuft bereits.${NC}" - echo -e "Stoppe zuerst mit: ${CYAN}./stop_dev.sh${NC}" - exit 1 + ALL_DEAD=true + while read -r PID; do + if kill -0 "$PID" 2>/dev/null; then + ALL_DEAD=false + break + fi + done < <(tr ' ' '\n' < "$PID_FILE") + + if [ "$ALL_DEAD" = true ]; then + echo -e "${YELLOW}▸ Verwaiste PID-Datei entfernt${NC}" + rm -f "$PID_FILE" + else + echo -e "${RED}Dev-Umgebung läuft bereits.${NC}" + echo -e "Stoppe zuerst mit: ${CYAN}./stop_dev.sh${NC}" + exit 1 + fi fi # ── Valet link ────────────────────────────────────────────── echo -e "${YELLOW}▸ Valet-Link prüfen …${NC}" -if [ ! -L "$HOME/.config/valet/Sites/cts-work" ]; then - valet link cts-work 2>/dev/null - echo -e " ${GREEN}✓${NC} Valet-Link erstellt: cts-work.test" +if [ ! -L "$HOME/.config/valet/Sites/$SITE_NAME" ]; then + valet link "$SITE_NAME" 2>/dev/null + echo -e " ${GREEN}✓${NC} Valet-Link erstellt: ${SITE_NAME}.test" else echo -e " ${GREEN}✓${NC} Valet-Link vorhanden" fi +# ── Dependencies check ────────────────────────────────────── +if [ ! -d "node_modules" ]; then + echo -e "${YELLOW}▸ npm install …${NC}" + npm install --silent + echo -e " ${GREEN}✓${NC} Node-Module installiert" +fi + +if [ ! -d "vendor" ]; then + echo -e "${YELLOW}▸ composer install …${NC}" + composer install --quiet + echo -e " ${GREEN}✓${NC} Composer-Pakete installiert" +fi + +# ── APP_KEY check ─────────────────────────────────────────── +if ! grep -q '^APP_KEY=base64:' .env 2>/dev/null; then + echo -e "${YELLOW}▸ APP_KEY generieren …${NC}" + php artisan key:generate --quiet + echo -e " ${GREEN}✓${NC} APP_KEY generiert" +fi + # ── Migrate ───────────────────────────────────────────────── echo -e "${YELLOW}▸ Migrations ausführen …${NC}" php artisan migrate --force --quiet @@ -35,13 +70,26 @@ echo -e " ${GREEN}✓${NC} Datenbank aktuell" echo -e "${YELLOW}▸ Queue-Worker starten …${NC}" php artisan queue:listen --tries=1 --timeout=0 > /dev/null 2>&1 & QUEUE_PID=$! -echo -e " ${GREEN}✓${NC} Queue-Worker (PID $QUEUE_PID)" +sleep 0.3 +if kill -0 "$QUEUE_PID" 2>/dev/null; then + echo -e " ${GREEN}✓${NC} Queue-Worker (PID $QUEUE_PID)" +else + echo -e " ${RED}✗${NC} Queue-Worker konnte nicht gestartet werden" + exit 1 +fi # ── Vite dev server ───────────────────────────────────────── echo -e "${YELLOW}▸ Vite starten …${NC}" -npm run dev > /dev/null 2>&1 & +npx --yes vite --port 5173 > /dev/null 2>&1 & VITE_PID=$! -echo -e " ${GREEN}✓${NC} Vite (PID $VITE_PID)" +sleep 0.5 +if kill -0 "$VITE_PID" 2>/dev/null; then + echo -e " ${GREEN}✓${NC} Vite (PID $VITE_PID)" +else + echo -e " ${RED}✗${NC} Vite konnte nicht gestartet werden" + kill "$QUEUE_PID" 2>/dev/null || true + exit 1 +fi # ── Save PIDs ─────────────────────────────────────────────── echo "$QUEUE_PID $VITE_PID" > "$PID_FILE" @@ -51,7 +99,7 @@ echo -e "${GREEN}═════════════════════ echo -e "${GREEN} Dev-Umgebung läuft!${NC}" echo -e "${GREEN}═══════════════════════════════════════════════${NC}" echo "" -echo -e " App: ${CYAN}http://cts-work.test${NC}" +echo -e " App: ${CYAN}http://${SITE_NAME}.test${NC}" echo -e " Vite: ${CYAN}http://localhost:5173${NC}" echo "" echo -e " Stop: ${YELLOW}./stop_dev.sh${NC}" diff --git a/stop_dev.sh b/stop_dev.sh index ac5d428..4f6d05b 100755 --- a/stop_dev.sh +++ b/stop_dev.sh @@ -3,7 +3,6 @@ set -euo pipefail PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" PID_FILE="$PROJECT_DIR/.dev.pid" -cd "$PROJECT_DIR" GREEN='\033[0;32m' RED='\033[0;31m' @@ -11,18 +10,27 @@ YELLOW='\033[1;33m' NC='\033[0m' if [ ! -f "$PID_FILE" ]; then - echo -e "${RED}Dev-Umgebung läuft nicht.${NC}" - exit 1 + echo -e "${RED}Dev-Umgebung läuft nicht (keine PID-Datei).${NC}" + exit 0 fi +STOPPED=0 +ALREADY_DEAD=0 + while read -r PID; do if kill "$PID" 2>/dev/null; then + STOPPED=$((STOPPED + 1)) echo -e " ${YELLOW}▸${NC} Prozess $PID gestoppt" + else + ALREADY_DEAD=$((ALREADY_DEAD + 1)) fi done < <(tr ' ' '\n' < "$PID_FILE") rm -f "$PID_FILE" echo "" -echo -e "${GREEN}Dev-Umgebung gestoppt.${NC}" +if [ "$ALREADY_DEAD" -gt 0 ]; then + echo -e "${YELLOW} $ALREADY_DEAD Prozess(e) waren bereits beendet.${NC}" +fi +echo -e "${GREEN}Dev-Umgebung gestoppt. ($STOPPED Prozess(e) beendet)${NC}" echo "" diff --git a/tests/e2e/auth.setup.ts b/tests/e2e/auth.setup.ts index 7b31957..a528c3e 100644 --- a/tests/e2e/auth.setup.ts +++ b/tests/e2e/auth.setup.ts @@ -4,22 +4,22 @@ const authFile = 'tests/e2e/.auth/user.json'; setup('authenticate', async ({ page }) => { // Navigate to login page to establish session cookies (incl. XSRF-TOKEN) - await page.goto('http://cts-work.test/login'); + await page.goto('http://pp-planer.test/login'); // Get XSRF token from cookies for CSRF protection - const cookies = await page.context().cookies('http://cts-work.test'); + const cookies = await page.context().cookies('http://pp-planer.test'); const xsrfCookie = cookies.find((c) => c.name === 'XSRF-TOKEN'); const xsrfToken = decodeURIComponent(xsrfCookie?.value || ''); // POST to dev-login route directly (bypasses Vue rendering dependency) - await page.request.post('http://cts-work.test/dev-login', { + await page.request.post('http://pp-planer.test/dev-login', { headers: { 'X-XSRF-TOKEN': xsrfToken, }, }); // Navigate to dashboard to confirm login and load session - await page.goto('http://cts-work.test/dashboard'); + await page.goto('http://pp-planer.test/dashboard'); await page.waitForURL('**/dashboard'); // Save signed-in state