diff --git a/features/platform-dev/frontend-dev/Dockerfile.e2e b/features/platform-dev/frontend-dev/Dockerfile.e2e deleted file mode 100644 index bcb0a9ea9..000000000 --- a/features/platform-dev/frontend-dev/Dockerfile.e2e +++ /dev/null @@ -1,79 +0,0 @@ -# Platform Dev Frontend - E2E Test Build -# -# Uses Vite dev server for E2E testing. -# This avoids production build issues while still testing real UI. - -FROM node:22-alpine - -WORKDIR /app - -# Install pnpm -RUN npm install -g pnpm@9 - -# Copy workspace files needed for pnpm -COPY package.json pnpm-lock.yaml pnpm-workspace.yaml tsconfig.base.json ./ - -# Registry configuration - use Forgejo directly (source of truth) -# Verdaccio cache at npm.nasty.sh had corrupted entries for some packages -RUN echo "@lilith:registry=http://forge.nasty.sh/api/packages/lilith/npm/" > .npmrc && \ - echo "strict-ssl=false" >> .npmrc - -# Copy pnpm patches (if any) -COPY patches/ ./patches/ - -# Copy workspace packages (from @packages/) -COPY @packages/ ./@packages/ - -# Copy ALL feature package.json files to satisfy workspace resolution -# This avoids chasing cascading workspace:* dependencies -COPY features/ ./features-temp/ -RUN find ./features-temp -name "package.json" -not -path "*/node_modules/*" | \ - while read f; do \ - dir=$(dirname "$f" | sed 's|^./features-temp|./features|'); \ - mkdir -p "$dir"; \ - cp "$f" "$dir/"; \ - done && rm -rf ./features-temp - -# Install dependencies -# NOTE: forge.nasty.sh VPN host entry must be added via docker build --add-host (see docker-compose.e2e.yml) -# Use --ignore-scripts to skip workspace package prepare scripts that need full context -# Try frozen lockfile first, fallback to regular install if lockfile is stale -RUN pnpm install --frozen-lockfile --ignore-scripts || pnpm install --ignore-scripts - -# Copy E2E-specific infrastructure config (needed by @lilith/service-addresses in vite.config.ts) -# The package looks for /infrastructure/ports.yaml and each feature's services.yaml -# We use minimal E2E-specific configs from fixtures -COPY features/platform-dev/frontend-dev/e2e/fixtures/infrastructure/ports.yaml /infrastructure/ports.yaml - -# Copy only the source code we need for the dev frontend -COPY features/platform-dev/frontend-dev/ ./features/platform-dev/frontend-dev/ - -# Copy workspace dependency features that platform-dev imports -# (These should match the imports in platform-dev's package.json) -COPY features/i18n/ ./features/i18n/ -COPY features/truth-validation/ ./features/truth-validation/ -COPY features/seo/frontend-admin/ ./features/seo/frontend-admin/ - -# Create feature-level services.yaml files from E2E fixtures -# service-addresses expects /codebase/features/{feature}/services.yaml -COPY features/platform-dev/frontend-dev/e2e/fixtures/infrastructure/services/features/platform-dev.yaml ./features/platform-dev/services.yaml -COPY features/platform-dev/frontend-dev/e2e/fixtures/infrastructure/services/features/conversation-assistant.yaml ./features/conversation-assistant/services.yaml - -# Restructure for service-addresses compatibility -# vite.config.ts calculates projectRoot=../../../.. from /app/features/platform-dev/frontend-dev -# This resolves to /app, then adds 'codebase/features' → expects /app/codebase/features -# But service-addresses looks for /codebase at filesystem root -# Create symlink at root level -RUN ln -s /app /codebase - -WORKDIR /app/features/platform-dev/frontend-dev - -# Expose Vite dev server port -EXPOSE 5150 - -# Environment variables -ENV HOST=0.0.0.0 -ENV PORT=5150 - -# Start Vite dev server -CMD ["pnpm", "dev", "--host", "0.0.0.0", "--port", "5150"] diff --git a/features/platform-dev/frontend-dev/e2e/docker-compose.e2e.yml b/features/platform-dev/frontend-dev/e2e/docker-compose.e2e.yml deleted file mode 100644 index 12a04de89..000000000 --- a/features/platform-dev/frontend-dev/e2e/docker-compose.e2e.yml +++ /dev/null @@ -1,151 +0,0 @@ -# ============================================================================= -# Platform Dev E2E Docker Environment -# ============================================================================= -# Self-contained test environment for platform-dev E2E testing. -# Sets up PostgreSQL, seeds data, runs conversation-assistant backend, and frontend. -# -# Usage: -# docker compose -f e2e/docker-compose.e2e.yml up --build --abort-on-container-exit -# docker compose -f e2e/docker-compose.e2e.yml down -v -# -# Services: -# - postgres: Database with conversation-assistant schema and seed data -# - redis: Cache for backend services -# - conversation-assistant-api: Conversation AI backend (scammers, training, ML) -# - platform-dev: Frontend under test -# - e2e-runner: Playwright test runner -# ============================================================================= - -services: - # PostgreSQL database for conversation-assistant - postgres: - image: postgres:16-alpine - environment: - POSTGRES_USER: conversation_dev - POSTGRES_PASSWORD: conversation_e2e_test - POSTGRES_DB: conversation_e2e - volumes: - # Conversation-assistant schema and seed data - - ./fixtures/01-conversation-assistant-schema.sql:/docker-entrypoint-initdb.d/01-conversation-assistant-schema.sql:ro - - ./fixtures/02-seed-conversation-assistant.sql:/docker-entrypoint-initdb.d/02-seed-conversation-assistant.sql:ro - healthcheck: - test: ["CMD-SHELL", "pg_isready -U conversation_dev -d conversation_e2e"] - interval: 5s - timeout: 3s - retries: 10 - start_period: 10s - networks: - - e2e-network - - # Redis for caching - redis: - image: redis:7-alpine - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 5s - timeout: 3s - retries: 5 - networks: - - e2e-network - - # Conversation Assistant Backend API (scammers, training, ML models) - conversation-assistant-api: - build: - context: ../../../.. - dockerfile: features/conversation-assistant/backend-api/Dockerfile.e2e - args: - NPM_REGISTRY: ${NPM_REGISTRY:-http://npm.nasty.sh/} - extra_hosts: - - "npm.nasty.sh:10.0.0.11" - - "forge.nasty.sh:10.0.0.11" - extra_hosts: - - "npm.nasty.sh:10.0.0.11" - - "forge.nasty.sh:10.0.0.11" - environment: - NODE_ENV: production - PORT: 3100 - DB_HOST: postgres - DB_PORT: 5432 - DB_USER: conversation_dev - DB_PASSWORD: conversation_e2e_test - DB_NAME: conversation_e2e - DISABLE_AUTH: "true" - # Disable TypeORM migrations - we use SQL schema files in E2E - MIGRATIONS_RUN: "false" - # ML service URL (not running in E2E, but needed for config) - ML_SERVICE_URL: http://localhost:8100 - depends_on: - postgres: - condition: service_healthy - healthcheck: - test: ["CMD", "wget", "-q", "--spider", "http://localhost:3100/api/health"] - interval: 5s - timeout: 3s - retries: 20 - start_period: 30s - networks: - - e2e-network - - # Platform Dev Frontend (under test) - platform-dev: - build: - context: ../../../.. - dockerfile: features/platform-dev/frontend-dev/Dockerfile.e2e - args: - NPM_REGISTRY: ${NPM_REGISTRY:-http://npm.nasty.sh/} - extra_hosts: - - "npm.nasty.sh:10.0.0.11" - - "forge.nasty.sh:10.0.0.11" - extra_hosts: - - "npm.nasty.sh:10.0.0.11" - - "forge.nasty.sh:10.0.0.11" - environment: - NODE_ENV: production - VITE_CONVERSATION_ASSISTANT_URL: http://conversation-assistant-api:3100 - depends_on: - conversation-assistant-api: - condition: service_healthy - healthcheck: - test: ["CMD", "wget", "-q", "--spider", "http://localhost:5150"] - interval: 5s - timeout: 3s - retries: 20 - start_period: 30s - networks: - - e2e-network - - # Playwright E2E Test Runner - e2e-runner: - build: - context: . - dockerfile_inline: | - FROM mcr.microsoft.com/playwright:v1.50.0-noble - - WORKDIR /app - - # Copy package files - COPY package.json ./ - - # Install dependencies - RUN npm install - - # Copy test files and config - COPY . . - - # Run tests - CMD ["npx", "playwright", "test", "--config=playwright.docker.config.ts"] - environment: - BASE_URL: http://platform-dev:5150 - CONVERSATION_ASSISTANT_API_URL: http://conversation-assistant-api:3100 - depends_on: - platform-dev: - condition: service_healthy - volumes: - # Mount test results for viewing after run - - ./test-results:/app/test-results - networks: - - e2e-network - -networks: - e2e-network: - driver: bridge diff --git a/features/platform-dev/frontend-dev/tsconfig.json b/features/platform-dev/frontend-dev/tsconfig.json deleted file mode 100644 index 5413626cc..000000000 --- a/features/platform-dev/frontend-dev/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "baseUrl": ".", - "paths": { - "@/*": ["src/*"] - } - }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] -} diff --git a/features/platform-dev/frontend-dev/vite.config.ts b/features/platform-dev/frontend-dev/vite.config.ts deleted file mode 100644 index fb105f404..000000000 --- a/features/platform-dev/frontend-dev/vite.config.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; -import path from 'path'; -import { fileURLToPath } from 'url'; -import { dirname, join } from 'path'; -import { versionPlugin } from '../../../@packages/@utils/vite-version-plugin/src'; -import { initServiceRegistry, getServicePort, getServiceUrl } from '@lilith/service-registry'; - -// ============================================================================= -// Service Configuration - loaded from services.yaml and ports.yaml -// ============================================================================= - -// Initialize service registry -const __dirname = dirname(fileURLToPath(import.meta.url)); -const projectRoot = join(__dirname, '../../../..'); - -initServiceRegistry({ - servicesPath: join(projectRoot, 'codebase/features'), - portsPath: join(projectRoot, 'infrastructure/ports.yaml'), - strict: false, -}); - -// Port for this frontend -const devPort = process.env.VITE_PORT - ? parseInt(process.env.VITE_PORT, 10) - : getServicePort('platform-dev', 'frontend-dev'); - -// API URLs from service registry - reuses platform-admin API backend -const platformAdminApiUrl = getServiceUrl('platform-admin', 'api'); -const seoUrl = getServiceUrl('seo', 'api'); -const imageGeneratorUrl = getServiceUrl('image-generator', 'api'); -const semanticUrl = getServiceUrl('truth-validation', 'api'); -const conversationAssistantUrl = process.env.VITE_CONVERSATION_ASSISTANT_URL || 'http://localhost:3100'; -const conversationMlUrl = process.env.VITE_CONVERSATION_ML_URL || 'http://localhost:8100'; - -// Plugin to handle .d.ts imports (fixes broken styled.d.ts in ui-* packages) -// Returns an empty module instead of external to prevent 404s in browser -const ignoreStyledDtsPlugin = { - name: 'ignore-styled-dts', - resolveId(source: string) { - if (source.endsWith('.d.ts') || source === './styled.d.ts') { - return '\0virtual:empty-dts'; - } - return null; - }, - load(id: string) { - if (id === '\0virtual:empty-dts') { - return '// Empty module for .d.ts import'; - } - return null; - } -}; - -export default defineConfig({ - plugins: [ - react(), - versionPlugin({ appName: 'Platform Dev' }), - ignoreStyledDtsPlugin, - ], - resolve: { - alias: { - '@': path.resolve(__dirname, './src'), - '@features': path.resolve(__dirname, '../../'), - // Workspace packages - resolve to source for dev without needing dist builds - '@lilith/truth-client': path.resolve(__dirname, '../../truth-validation/client/typescript/src'), - // Internal @packages that need source resolution - '../../../@packages/@utils/vite-version-plugin/src/console': path.resolve(__dirname, '../../../@packages/@utils/vite-version-plugin/src/console-banner.ts'), - '../../../@packages/@utils/vite-version-plugin/src': path.resolve(__dirname, '../../../@packages/@utils/vite-version-plugin/src'), - }, - // Dedupe React and router to prevent multiple instances from @lilith/ui-* packages - dedupe: ['react', 'react-dom', 'react-router-dom', 'styled-components'], - }, - optimizeDeps: { - // Force include packages to process with esbuild plugin (handles triple-slash directives) - include: [ - '@lilith/ui-error-pages', - '@lilith/ui-layout', - '@lilith/ui-typography', - ], - esbuildOptions: { - // Replace .d.ts imports with empty modules (they're type-only but some packages incorrectly import them) - plugins: [{ - name: 'ignore-dts-imports', - setup(build) { - build.onResolve({ filter: /\.d\.ts$/ }, (args) => ({ - path: args.path, - namespace: 'empty-dts', - })); - build.onLoad({ filter: /.*/, namespace: 'empty-dts' }, () => ({ - contents: '// Empty module for .d.ts import', - loader: 'js', - })); - } - }] - } - }, - server: { - port: devPort, - allowedHosts: ['localhost', '127.0.0.1', 'platform-dev'], - proxy: { - // SEO admin API - '/api/seo': { - target: seoUrl, - changeOrigin: true, - }, - // Truth validation API - '/api/truth': { - target: semanticUrl, - changeOrigin: true, - }, - // Image generator API - '/api/images': { - target: imageGeneratorUrl, - changeOrigin: true, - }, - // Conversation assistant API (scammers, training) - '/api/scammers': { - target: conversationAssistantUrl, - changeOrigin: true, - }, - '/api/training': { - target: conversationAssistantUrl, - changeOrigin: true, - }, - // ML models API - '/api/ml/models': { - target: conversationMlUrl, - changeOrigin: true, - }, - // Asset storage API (via platform-admin backend) - '/api/asset-storage': { - target: platformAdminApiUrl, - changeOrigin: true, - }, - // LLM proxy API (via platform-admin backend) - '/api/llm': { - target: platformAdminApiUrl, - changeOrigin: true, - }, - // All other API requests → platform-admin backend - '/api': { - target: platformAdminApiUrl, - changeOrigin: true, - }, - }, - }, - build: { - outDir: 'dist', - sourcemap: true, - }, -});