# raclette Framework CLI Documentation

## ⚠️ Development Note

**When working on this core project**: If you modify anything in the `src/` directory, you must run `yarn build` (one-time) or `yarn dev` (continuous watching) within this core project before testing changes. Otherwise, your modifications won't be reflected in the generated CLI.

## Overview

This repository contains the CLI tooling for **raclette** - a framework for platform and portal development. Built for innovators who want to focus on their unique value proposition, not infrastructure.

The CLI provides a smooth development experience inspired by Nuxt.js. When you run `yarn dev`, it automatically:

- Creates a `.raclette/` folder with generated assets
- Sets up Docker Compose configurations
- Manages service dependencies via a virtual file system
- Starts your development environment with hot reloading

### The `.raclette` Directory

The `.raclette` folder is your project's runtime workspace, containing:

```
.raclette/
├── frontend/                 # Frontend service files & dependencies
├── backend/                 # Server service files & dependencies
├── virtual/                # Virtual file system mappings
│   ├── frontend/src/         # Merged frontend source files
│   └── backend/src/         # Merged backend source files
├── docker-compose.yml      # Generated Docker Compose config
├── frontend.Dockerfile       # Generated frontend Dockerfile
├── backend.Dockerfile       # Generated backend Dockerfile
├── tsconfig.json          # Generated TypeScript config
└── eslint.config.js       # Generated ESLint config
```

**Never commit the `.raclette/` directory** - it's entirely generated and will be recreated on each `yarn dev`.

## CLI Commands

### `raclette dev`

The primary development command that orchestrates your entire environment:

```bash
raclette dev                    # Start with logs
raclette dev --quiet           # Start in background (detached)
raclette dev --verbose         # Show all Docker logs during startup
raclette dev --filter frontend   # Show logs only for specific services
raclette dev --force-rebuild   # Force rebuild all Docker images
raclette dev --no-cache        # Rebuild without Docker cache
```

**What happens during `yarn dev`:**

1. **Configuration Loading**: Loads `raclette.config.js` and merges with defaults
2. **Environment Setup**: Creates `.raclette/` directory structure
3. **Virtual File System**: Merges your app files with framework core files
4. **Package Management**: Generates `package.json` for each service from `packages.json`
5. **Docker Generation**: Creates Docker Compose files and Dockerfiles
6. **Service Orchestration**: Starts MongoDB, Cache, and your app services
7. **Hot Reloading**: Watches for file changes and updates services

### `raclette add-package`

Adds packages to specific services (essential for multi-container development):

```bash
raclette add-package frontend lodash        # Add to frontend service
raclette add-package backend express       # Add to backend service
raclette add-package frontend vue --dev     # Add as dev dependency
raclette add-package frontend lodash --no-update  # Skip auto-update
```

This updates your `packages.json` and automatically installs the package in the running container.

### `raclette down`

Stops all running services:

```bash
raclette down                   # Stop all services
raclette down --keep-shared     # Keep MongoDB/Cache running
```

Use this when `Ctrl+C` doesn't properly stop all containers.

### Other Commands

```bash
raclette restart frontend backend  # Restart specific services
raclette update frontend          # Update dependencies in running container
raclette rebuild               # Rebuild changed services
raclette build                 # Build for production
```

## Core File Architecture

### Entry Point and Orchestration

**`cli.ts`** - Main CLI entry point using Commander.js

- Registers all CLI commands (`dev`, `add-package`, `down`, etc.)
- Handles command-line argument parsing and validation
- Orchestrates the bootstrapping sequence for each command
- Provides error handling and user-friendly messages
- Manages the overall flow from command input to execution

**`dev-environment.ts`** - Development environment orchestration

- Coordinates the entire `raclette dev` process
- Manages Docker service startup and health checking
- Sets up process cleanup handlers for graceful shutdown
- Handles both containerized and direct service execution modes
- Manages service dependencies and startup order
- Provides real-time log streaming from Docker services

### Configuration System

**`config-loader.ts`** - Configuration loading and merging

- Loads `raclette.config.js` from the project root
- Merges user configuration with framework defaults
- Handles environment variable loading from `.env` files
- Processes environment-specific configurations
- Validates configuration structure and provides helpful error messages
- Supports dynamic configuration reloading during development

**`types.ts`** - TypeScript type definitions

- Defines `racletteConfig` interface with all configuration options
- Provides type safety for the entire framework
- Documents expected configuration structure through types
- Includes service configuration interfaces, volume definitions, and plugin types
- Supports extensible configuration via custom properties

### File System Management

**`virtual-file-system.ts`** - Priority-based file override system

- Implements the core file merging logic with priority-based resolution
- Creates a virtual file system in `.raclette/virtual/`
- Watches for file changes and updates the virtual mapping in real-time
- Handles source directory priorities (app files override framework files)
- Manages file copying and symlink creation for Docker volume mounts
- Provides hot reloading by updating containers when files change

**`package-manager.ts`** - Multi-service package management

- Processes `packages.json` and generates service-specific `package.json` files
- Merges framework dependencies with user-defined packages
- Handles service-specific lock file management (`app.frontend.yarn.lock`, `app.backend.yarn.lock`)
- Implements the `add-package` command functionality with automatic container updates
- Manages Docker volume mounting for `node_modules` directories
- Ensures reproducible builds across team members and environments

### Docker Infrastructure

**`docker-generator.ts`** - Docker configuration generation

- Generates `docker-compose.yml` from raclette configuration
- Creates service-specific Dockerfiles (`frontend.Dockerfile`, `backend.Dockerfile`)
- Handles database service configuration (MongoDB, Cache)
- Manages Docker volumes, networks, and environment variables
- Supports both development and production Docker configurations
- Processes custom volume definitions and bind mounts

**`docker-utils.ts`** - Docker operation utilities

- Provides Docker installation detection and validation
- Handles Docker Compose command execution with proper error handling
- Manages container lifecycle operations (start, stop, restart, health checks)
- Supports both modern Docker Compose and legacy docker-compose
- Includes utilities for container existence checking and network management

### Code Quality and Tooling

**`ts-generator.ts`** - TypeScript configuration generation

- Generates `tsconfig.json` optimized for the raclette framework
- Sets up path mappings for framework modules and user code
- Configures compiler options for both development and production
- Handles Vue.js specific TypeScript configuration when needed
- Ensures proper type resolution across the virtual file system

**`eslint-generator.ts`** - ESLint flat configuration generation

- Generates modern ESLint flat config (`eslint.config.js`)
- Applies framework-recommended linting rules
- Supports both Vue.js and React project configurations
- Integrates TypeScript and Prettier configurations
- Allows user customization via `raclette.config.js` eslint settings

### Service Configuration

**`config-generator.ts`** - Service-specific configuration generation

- Creates service-specific configuration files in `.raclette/frontend/` and `.raclette/backend/`
- Generates JavaScript configuration modules that services can import
- Splits the main configuration into frontend and backend specific parts
- Creates TypeScript declaration files for IDE support
- Ensures configuration is available to running services

**`package-updater.ts`** - Runtime package management

- Handles live dependency updates in running containers
- Executes dependency installation scripts inside Docker containers
- Manages the `update` command functionality
- Provides container name resolution and service detection
- Handles dependency update error reporting and recovery

### Development Tooling

**`docker-tracker.ts`** - Change detection and rebuilding

- Tracks changes in service files that require Docker image rebuilds
- Compares current file state with previous builds
- Triggers selective service rebuilds when necessary
- Manages the `rebuild` command and `--force-rebuild` option
- Optimizes development workflow by avoiding unnecessary rebuilds

Each file follows functional programming principles with clear separation of concerns, making the codebase maintainable and extensible for future framework development.

## Configuration API (`raclette.config.js`)

Your `raclette.config.js` file configures the entire framework. Use the `defineracletteConfig` helper for TypeScript support:

```javascript
import { defineracletteConfig } from "@raclettejs/core"

export default defineracletteConfig({
  // Required
  name: "my-app",

  // Services configuration
  services: {
    frontend: {
      enabled: true,
      port: 8081,
    },
    backend: {
      enabled: true,
      port: 8082,
      enableDebug: false, // Set to true for Node.js debugging
    },
    mongodb: {
      enabled: true,
      port: 27017,
      databaseName: "my-app", // Optional, defaults to app name
    },
    cache: {
      enabled: true,
      port: 6379,
    },
  },

  // Frontend configuration
  frontend: {
    framework: "vue", // or 'react'
    vue: {
      plugins: ["@vitejs/plugin-vue"],
    },
    // Any custom properties here get passed to frontend container
    customApiUrl: "https://api.example.com",
  },

  // Backend configuration
  backend: {
    sockets: {
      autoSend: {
        compositions: true,
        interactionLinks: true,
        projectConfig: true,
      },
    },
    // Any custom properties here get passed to backend container
    customDatabaseTimeout: 5000,
  },

  // Environment variables by environment
  env: {
    development: {
      DEBUG: true,
      API_URL: "http://localhost:8082",
    },
    production: {
      NODE_ENV: "production",
    },
  },

  // Plugin system
  plugins: ["@raclettejs/plugin-auth"],

  // Global settings
  global: {
    requireAuthentication: true,
  },
})
```

### Required Fields

- `name` - Your application name (used for Docker container names)
- `services` - At minimum, enable the services you need

### Key Optional Fields

- `frontend.framework` - Choose 'vue' or 'react'
- `backend.sockets` - WebSocket configuration
- `env` - Environment-specific variables
- `plugins` - raclette plugins to load
- `global.requireAuthentication` - Framework-level auth requirement

**Custom Properties**: Any custom properties you add to `frontend` or `backend` are automatically passed as environment variables to the respective containers.

## Virtual File System

raclette uses a priority-based file system that allows you to override or extend framework files:

### Priority Order (highest to lowest):

1. **Your App Files** (`/services/frontend/`, `/services/backend/`) - Highest priority
2. **Framework Core Files** - Lowest priority

### How It Works

Create an `app/` folder in your project root:

```
my-project/
├── app/
│   ├── frontend/
│   │   └── src/
│   │       ├── components/     # Your custom Vue/React components
│   │       ├── pages/          # Your application pages
│   │       └── styles/         # Your custom styles
│   └── backend/
│       └── src/
│           ├── routes/         # Your API routes
│           ├── plugins/        # Your backend plugins
│           └── middleware/     # Your custom middleware
├── raclette.config.js
└── packages.json
```

**File Merging Rules:**

- Your files never get overwritten
- Framework files are used as fallbacks when you don't provide them
- The virtual file system merges everything into `.raclette/virtual/`
- Changes to your files trigger hot reloading

## Package Management

### `packages.json`

Instead of managing `package.json` files for each service, use a single `packages.json`:

```json
{
  "frontend": {
    "dependencies": {
      "lodash": "^4.17.21",
      "vue-router": "^4.0.0"
    },
    "devDependencies": {
      "@vitejs/plugin-vue": "^4.0.0"
    }
  },
  "backend": {
    "dependencies": {
      "express": "^4.18.0",
      "mongoose": "^7.0.0"
    },
    "devDependencies": {
      "nodemon": "^2.0.0"
    }
  }
}
```

### Adding Packages

Use the CLI instead of npm/yarn directly:

```bash
# This updates packages.json AND installs in the running container
raclette add-package frontend axios
raclette add-package backend joi --dev
```

### Lock Files

raclette maintains service-specific lock files in your project root:

- `frontend.yarn.lock` - Frontend dependencies
- `backend.yarn.lock` - Backend dependencies

**Always commit these lock files** for reproducible builds across your team.

The system automatically:

- Creates initial lock files from framework defaults
- Syncs changes between containers and your local files via Docker volumes
- Handles dependency installation efficiently (only when actually needed)
