diff --git a/fleetbase-source/AGENTS.md b/fleetbase-source/AGENTS.md new file mode 100644 index 0000000..672dd7c --- /dev/null +++ b/fleetbase-source/AGENTS.md @@ -0,0 +1,385 @@ +# AGENTS.md — Fleetbase + +## Architecture + +- **Dual-stack monorepo:** Laravel 10 (PHP) backend + Ember.js 5.4 frontend + 12 Git submodules +- **Docker services:** `application` (FrankenPHP/Caddy :8000), `httpd` (:80→8000), `console` (Nginx :4200), `socket` (SocketCluster :38000), `database` (MySQL 8.0 :3306), `cache` (Redis), `queue`, `scheduler` +- **Console port 4200**, **API port 8000** — both must be free or mapped differently +- **Packages:** Each `packages//` is a Git submodule; contains PHP (`composer.json` + `server/`) and/or Ember code (`addon/`, `app/`, `extension.json`) +- **Core packages:** `core-api`, `ember-core`, `ember-ui`, `dev-engine` — framework layers all extensions depend on + +## Prerequisites & Constraints + +- **PHP >= 8.0, <= 8.2.30** (strict upper bound — 8.3+ will break) +- **Node.js >= 22** +- **pnpm** is the JS package manager (not npm/yarn) — `pnpm@11.0.9` +- **Composer** uses private registry at `https://registry.fleetbase.io` — authentication may be required for private packages +- Git submodules must be initialized: `git submodule update --init --recursive` + +## Commands + +### Docker (most common) +```bash +docker compose up -d # Start all services +docker compose exec application bash # Shell into API container +docker compose exec application php artisan … # Run artisan commands +docker compose exec application bash -c "./deploy.sh" # Run deployment script +``` + +### Backend (api/) +```bash +cd api && composer install # Install PHP deps (uses fleetbase registry) +cd api && php artisan … # Laravel artisan (run inside container or locally with DB access) +cd api && php artisan test # Run PHPUnit tests +cd api && ./vendor/bin/php-cs-fixer fix # Fix PHP style +cd api && vendor/bin/phpstan analyse # Static analysis (in packages with phpstan.neon.dist) +``` + +### Frontend (console/) +```bash +cd console && pnpm install # Install JS deps +cd console && pnpm start # Ember dev server (requires API + socket running) +cd console && pnpm lint # ESLint + stylelint + template-lint +cd console && pnpm test # Lint + ember test (QUnit via Testem) +cd console && pnpm build # Production build → dist/ +``` + +### Single test runs +```bash +cd api && php artisan test --filter=MyTest # PHP: single test class +cd api && php artisan test --filter=MyTest::testFoo # PHP: single test method +cd console && pnpm test --filter='My test name' # Ember: filter by test name +cd console && pnpm test --server # Ember: watch mode +``` + +## Extensions (Custom Packages) + +Each extension is a Git submodule under `packages//` with this structure: +``` +extension.json # Metadata (name, version, engine, api) +composer.json # PHP dependencies (if has API) +package.json # JS dependencies (if has Ember engine) +server/ # PHP API code (PSR-4) +addon/ # Ember engine files +app/ # Ember app files +``` + +### Scaffold a new extension +```bash +flb scaffold # CLI wizard +# Or manually: create packages// with extension.json, composer.json, package.json +# Register it as submodule: git submodule add packages/ +``` + +### Link local extensions for development +```bash +node scripts/package-linker.mjs # Symlink all packages/ into api/ and console/ +``` + +### Package registry flow +```bash +flb register # One-time: create registry account +flb verify -e -c # Verify email +flb generate-token -e # Get auth token +flb set-auth # Save token for installs +flb install fleetbase/ # Install extension from registry +``` + +## Production Deployment (VPS: 37.27.183.102) + +``` +SSH key: Config/fleet_key (chmod 600, OpenSSH RSA private key) +SSH command: ssh -i Config/fleet_key root@37.27.183.102 +``` + +### Key env vars for production (docker-compose.override.yml) +- `ENVIRONMENT=production`, `APP_DEBUG=false` +- `APP_KEY` — generate with `docker compose exec application bash -c "php artisan key:generate --show"` +- `APP_URL`, `CONSOLE_HOST` — set to actual domain/IP +- `SESSION_DOMAIN` — domain for session cookies +- `SOCKETCLUSTER_OPTIONS` — restrict origins to production domains +- `MAIL_*` — configure real mailer (not log driver) +- `FILESYSTEM_DRIVER=s3` — S3 for file storage (not local disk) +- `GOOGLE_MAPS_API_KEY`, `IPINFO_API_KEY`, `TWILIO_*` — for full feature set +- `REGISTRY_HOST`, `REGISTRY_PREINSTALLED_EXTENSIONS` — extension registry config +- `OSRM_HOST` — routing engine URL + +### Production checklist +1. Copy repo to server, run `docker compose up -d` (with correct override) +2. Ensure ports 80/443/8000/4200/38000 are open in firewall +3. Set up SSL/reverse proxy (Caddyfile for API, Nginx for console) +4. Use external/managed MySQL in production (not bundled container) +5. S3 for file storage (not local disk) +6. Restrict `SOCKETCLUSTER_OPTIONS` origins + +## Environment File Locations + +| Env | Notes | +|-----|-------| +| `docker-compose.override.yml` | **Primary** — env vars injected into all Docker services | +| `api/.env` | Only needed for local PHP runs outside Docker | +| `api/.env.example` | Template reference | +| `console/environments/.env.development` | Ember dev env | +| `console/environments/.env.production` | Ember prod env | + +## Git Submodule Gotchas + +- Always `git submodule update --init --recursive` after clone +- Submodules track specific commits — working on a package means committing inside `packages//` first, then updating the parent repo's submodule pointer +- After `git pull` in parent, run `git submodule update --recursive` to sync submodules +- Package linker script (`scripts/package-linker.mjs`) symlinks submodules into api/console/ for local dev — run it after changing module structure + +## Linting (all layers) + +| Layer | Tool | Command | +|-------|------|---------| +| PHP | php-cs-fixer | `./vendor/bin/php-cs-fixer fix` (in api/ or package) | +| PHP | PHPStan | `vendor/bin/phpstan analyse` (in packages with neon config) | +| JS | ESLint + Prettier | `pnpm lint` (in console/) | +| CSS | Stylelint | `pnpm lint:css` | +| Templates | ember-template-lint | `pnpm lint:hbs` | +| i18n | fleetbase-intl-lint | `pnpm lint:intl` | + +## Conventions + +- Ember Octane edition — use Glimmer components (`@glimmer/component`), `