TenantAtlas/specs/182-platform-relocation/research.md
ahmido ce0615a9c1 Spec 182: relocate Laravel platform to apps/platform (#213)
## Summary
- move the Laravel application into `apps/platform` and keep the repository root for orchestration, docs, and tooling
- update the local command model, Sail/Docker wiring, runtime paths, and ignore rules around the new platform location
- add relocation quickstart/contracts plus focused smoke coverage for bootstrap, command model, routes, and runtime behavior

## Validation
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/PlatformRelocation`
- integrated browser smoke validated `/up`, `/`, `/admin`, `/admin/choose-workspace`, and tenant route semantics for `200`, `403`, and `404`

## Remaining Rollout Checks
- validate Dokploy build context and working-directory assumptions against the new `apps/platform` layout
- confirm web, queue, and scheduler processes all start from the expected working directory in staging/production
- verify no legacy volume mounts or asset-publish paths still point at the old root-level `public/` or `storage/` locations

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #213
2026-04-08 08:40:47 +00:00

4.6 KiB

Research: Platform Relocation to apps/platform

Decision 1

  • Decision: Move the entire Laravel application into apps/platform, including composer.json, package.json, vite.config.js, phpunit*.xml, drizzle.config.ts, public/, bootstrap/, and .env.example.
  • Rationale: Moving the whole project root together preserves existing internal relative-path assumptions in artisan, public/index.php, bootstrap/app.php, PHPUnit bootstrap, Vite inputs, Tailwind @source, Filament theme imports, and Drizzle config. That minimizes risky bootstrap edits.
  • Alternatives considered:
    • Keep Composer or vendor/ at repo root and move only app code: rejected because it forces cross-root bootstrap rewiring and increases long-term ambiguity.
    • Leave public/ or bootstrap/ at root: rejected because it creates a hybrid steady state that violates the structure contract.

Decision 2

  • Decision: Make apps/platform the single official working directory for platform development commands.
  • Rationale: One command model is clearer than a split root-plus-app workflow and matches the long-term goal of turning root into a real orchestration layer.
  • Alternatives considered:
    • Root-wrapper-first workflow: rejected because it preserves root as the mental app root.
    • Dual official workflows: rejected because it guarantees documentation and tooling drift.

Decision 3

  • Decision: Keep docker-compose.yml at repo root and let app-local Sail load it through SAIL_FILES.
  • Rationale: The current Sail script already supports SAIL_FILES. This allows apps/platform/vendor/bin/sail to stay the canonical launcher while root remains the orchestration layer.
  • Alternatives considered:
    • Move docker-compose.yml into apps/platform: rejected because the spec explicitly keeps compose at root.
    • Make root the only supported Sail entrypoint: rejected because it conflicts with the chosen official command model.

Decision 4

  • Decision: Update root compose services to mount ./apps/platform into /var/www/html for both web and queue containers.
  • Rationale: Container runtime, queue commands, vendor binaries, and build outputs should operate against the relocated app only, not the whole repo tree.
  • Alternatives considered:
    • Mount the entire repo and cd into apps/platform inside commands: rejected because it keeps stale root assumptions alive and complicates worker commands.
    • Use symlinks from root back into the app: rejected because it obscures ownership and rollback.

Decision 5

  • Decision: Keep apps/platform/.env and apps/platform/.env.example as the canonical Laravel environment files; any root env file must be compose-only.
  • Rationale: Application config truth should live with the application. Root-level env data should exist only if compose itself needs separate variables.
  • Alternatives considered:
    • Keep the canonical .env at repo root: rejected because it blurs the root/app boundary the spec is trying to establish.
    • Duplicate app env files at root and app level: rejected because it creates split configuration truth.

Decision 6

  • Decision: Move app-specific tooling files with the app and leave repo-wide tooling configs at root.
  • Rationale: composer.json, package.json, Vite, PHPUnit, and Drizzle are app-owned. Editor tasks, MCP config, agent config, docs, and Spec Kit files remain repo-owned.
  • Alternatives considered:
    • Keep Drizzle or test config at root as a convenience: rejected unless a repo-wide consumer is proven, because it breaks the file-placement contract.

Decision 7

  • Decision: Treat repo documentation, MCP config, and agent instructions as first-class relocation work items, not post-move cleanup.
  • Rationale: Current repo guidance is saturated with root-relative vendor/bin/sail, artisan, and npm run instructions. Leaving those untouched would undermine the single command model immediately after the move.
  • Alternatives considered:
    • Update runtime only and defer docs or tooling: rejected because the spec explicitly includes DX and tooling alignment.

Decision 8

  • Decision: Capture Dokploy build context, production working directory, storage-volume assumptions, and unpublished helper scripts as explicit operational unknowns instead of silently designing around them.
  • Rationale: These concerns cannot be proven from the repository alone, so the correct plan is to isolate them as rollout prerequisites rather than smuggling in guesses.
  • Alternatives considered:
    • Assume staging and production behave like local Sail: rejected because the spec forbids hidden deploy assumptions.