# Rabbi Gerzi Rabbi Gerzi is the public website and Torah media application for Rabbi Yehoshua Gerzi. The site presents Rabbi Gerzi's work, projects, and Torah media, with an authenticated admin area for managing media sets, nested elements, rich text, YouTube links, icons, and PDF uploads. The application is split into: - `backend/`: Laravel 13, PHP 8.3, PostgreSQL, PHPUnit. - `frontend/rabbi_gerzi/`: Vue 3, Vite, TypeScript, Pinia, Cypress. - `nix/`: Nix packages, checks, upload limits, and the NixOS service module. Production assumptions: - Website: `https://rabbigerzi.com` - API: `https://api.rabbigerzi.com` All local and deployment workflows are Nix-first. Run commands from `nix develop`, or use direnv with the checked-in `.envrc`. ## Required Secrets and Environment Do not commit real secret values. Local examples can live in ignored `.env` files, and production secrets should live outside the Nix store. ### Required Production Secrets The NixOS module requires `services.rabbi-gerzi.backend.environmentFile`. That file must contain: ```dotenv APP_KEY=base64:replace-with-laravel-app-key RABBI_GERZI_INITIAL_ADMIN_EMAIL=admin@example.com RABBI_GERZI_INITIAL_ADMIN_PASSWORD=replace-with-a-long-random-password ``` - `APP_KEY` encrypts and signs Laravel application data. - `RABBI_GERZI_INITIAL_ADMIN_EMAIL` is the first admin login email. - `RABBI_GERZI_INITIAL_ADMIN_PASSWORD` is used only to create that admin if it does not already exist. Generate an app key inside the dev shell: ```sh cd backend php artisan key:generate --show ``` ### Public Frontend Config The frontend build needs the public API origin: ```dotenv VITE_API_BASE_URL=https://api.rabbigerzi.com ``` For NixOS deployment this is handled by `services.rabbi-gerzi.frontend.apiBaseUrl`, which defaults to the backend public URL. ### NixOS Runtime Config The NixOS module supplies these non-secret runtime values: | Setting | Production value | |---|---| | `APP_ENV` | `production` | | `APP_DEBUG` | `false` | | `APP_URL` | `https://api.rabbigerzi.com` | | `CORS_ALLOWED_ORIGINS` | `https://rabbigerzi.com` by default | | `DB_CONNECTION` | `pgsql` | | `DB_HOST` | `/run/postgresql` | | `DB_DATABASE` | `rabbi-gerzi` by default | | `DB_USERNAME` | `rabbi-gerzi` by default | | `FILESYSTEM_DISK` | `public` | | `LARAVEL_STORAGE_PATH` | `/var/lib/rabbi-gerzi/storage` by default | | `SESSION_DRIVER` | `database` | | `SESSION_DOMAIN` | empty by default, meaning host-only cookies | | `SESSION_SAME_SITE` | `none` by default | | `SESSION_SECURE_COOKIE` | `true` by default | | `CACHE_STORE` | `file` | | `QUEUE_CONNECTION` | `sync` | | `MAIL_MAILER` | `log` | The module also manages PostgreSQL, php-fpm, nginx, writable storage/cache directories, and the 6 MB upload limit for nginx and PHP. ### Local Environment Files Backend local configuration starts from: ```sh cd backend cp .env.example .env php artisan key:generate ``` The checked-in example already targets the Nix dev PostgreSQL socket through `PGHOST`, and uses the `postgres` local database/user. Frontend local configuration should point Vite at the local backend: ```sh cd frontend/rabbi_gerzi printf '%s\n' 'VITE_API_BASE_URL=http://127.0.0.1:8000' > .env.local ``` ## Local Development Enter the Nix dev shell before running local development commands: ```sh nix develop ``` If direnv is installed: ```sh direnv allow ``` The dev shell provides PHP, Composer, Node, PostgreSQL, Cypress, process-compose, TypeScript tooling, formatters, linters, and Nix formatters. It also initializes a local PostgreSQL cluster in `.postgres` when needed. Install dependencies: ```sh cd backend composer install cd ../frontend/rabbi_gerzi npm install --legacy-peer-deps ``` Create local environment files: ```sh cd ../../backend cp .env.example .env php artisan key:generate cd ../frontend/rabbi_gerzi printf '%s\n' 'VITE_API_BASE_URL=http://127.0.0.1:8000' > .env.local ``` Start the local services from the repo root: ```sh process-compose up ``` This starts: - PostgreSQL on the local Unix socket under `.postgres`. - Laravel at `http://127.0.0.1:8000`. - Vite at `http://localhost:5173`. In another dev-shell terminal, prepare the database: ```sh cd backend php artisan migrate:fresh --seed ``` The seed admin login is: ```text admin@rabbigerzi.test password123!@# ``` ## Testing Run local tests from `nix develop`. To run the entire local test suite, keep the app stack running in one dev-shell terminal: ```sh nix develop process-compose up ``` Then run backend, frontend, and Cypress checks from another dev-shell terminal. `process-compose` provides the PostgreSQL database, Laravel backend, and Vite frontend needed by the full suite. Backend tests live under `backend/tests`. - Unit tests exercise domain entities, use cases, middleware, controllers, and fake repositories without requiring PostgreSQL. - Feature tests exercise HTTP endpoints, Laravel routing, migrations, seed data, and real framework integration. - PHPUnit is configured to use an in-memory SQLite database for test runs. Run backend tests: ```sh cd backend ./vendor/bin/phpunit tests ``` Run backend style checks: ```sh cd backend phpcs app tests routes database ``` Frontend quality checks live under `frontend/rabbi_gerzi`. - `npm run format` checks and formats Vue and TypeScript source with oxfmt. - `npm run lint` runs oxlint and eslint. - `npm run type-check` runs vue-tsc against the Vite application. Run frontend checks: ```sh cd frontend/rabbi_gerzi npm run format npm run lint npm run type-check ``` Cypress E2E tests live under `frontend/rabbi_gerzi/cypress/e2e`. - Specs drive the UI through the Vite frontend at `http://localhost:5173`. - The Laravel backend must be running at `http://127.0.0.1:8000`. - The Cypress config creates a seeded PostgreSQL template database before the run and resets the app database between specs with the `db:reset` task. - Seeded media assets are copied into `backend/storage/app/public` for each reset. Run E2E tests after `process-compose up` is healthy: ```sh cd frontend/rabbi_gerzi npm run test:e2e ``` Open the Cypress runner: ```sh cd frontend/rabbi_gerzi npm run test:e2e:open ``` ## Verification Run the full local suite from a second dev-shell terminal while `process-compose up` is running: ```sh cd backend phpcs app tests routes database ./vendor/bin/phpunit tests cd ../frontend/rabbi_gerzi npm run format npm run lint npm run type-check npm run test:e2e ``` Run the full Nix package and module checks: ```sh nix flake check ``` ## Deployment Deploy through the flake's NixOS module. The module builds the frontend with `VITE_API_BASE_URL=https://api.rabbigerzi.com`, serves it from nginx, runs the Laravel backend with php-fpm, provisions PostgreSQL, creates writable storage and cache directories, runs migrations, and ensures the initial admin exists. Example host configuration: ```nix { inputs.rabbi-gerzi.url = "git+ssh://git@example.com/rabbi-gerzi.git"; outputs = { nixpkgs, rabbi-gerzi, ... }: { nixosConfigurations.rabbigerzi = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ rabbi-gerzi.nixosModules.default { services.rabbi-gerzi = { enable = true; frontend.hostName = "rabbigerzi.com"; backend = { hostName = "api.rabbigerzi.com"; environmentFile = "/run/secrets/rabbi-gerzi.env"; }; }; } ]; }; }; } ``` If the API origin must be set explicitly, use: ```nix services.rabbi-gerzi.frontend.apiBaseUrl = "https://api.rabbigerzi.com"; ``` Create the production environment file on the server: ```dotenv APP_KEY=base64:replace-with-laravel-app-key RABBI_GERZI_INITIAL_ADMIN_EMAIL=admin@example.com RABBI_GERZI_INITIAL_ADMIN_PASSWORD=replace-with-a-long-random-password ``` Then rebuild the host with the deployment method used by the server, for example: ```sh sudo nixos-rebuild switch --flake .#rabbigerzi ``` During activation, `rabbi-gerzi-setup` runs: ```sh php artisan migrate --force php artisan rabbi-gerzi:ensure-initial-admin ``` The initial admin command is idempotent. If the configured admin email already exists, it leaves the user unchanged. ## Useful Nix Outputs Build the frontend package: ```sh nix build .#frontend ``` Build the backend package: ```sh nix build .#backend ``` Evaluate all checks: ```sh nix flake check ```