TenantAtlas/specs/183-website-workspace-foundation/plan.md
ahmido 03b1beb616 feat: implement workspace foundation website app (#214)
## Summary
- add the first multi-app workspace foundation with a new standalone Astro website under `apps/website`
- introduce repo-root pnpm workspace orchestration and migrate the platform Node workflow from npm assumptions to pnpm
- update root docs, editor or agent guidance, and workspace-focused smoke tests for the new platform plus website command model
- add Spec 183 artifacts for spec, plan, research, contracts, quickstart, checklist, and tasks

## Verification
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/WorkspaceFoundation`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `corepack pnpm build:website`
- integrated-browser smoke: verified `http://localhost/up`, `http://localhost/admin/login`, and `http://localhost:4321/` including website anchor navigation and combined root dev flow

## Notes
- branch: `183-website-workspace-foundation`
- commit: `6d41618d`
- root command model now covers `dev:platform`, `dev:website`, `dev`, `build:platform`, and `build:website`
- website port override documentation is included in the command contract, quickstart, and README

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #214
2026-04-08 12:20:31 +00:00

20 KiB

Implementation Plan: Website / Workspace Foundation

Branch: 183-website-workspace-foundation | Date: 2026-04-08 | Spec: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/183-website-workspace-foundation/spec.md Input: Feature specification from /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/183-website-workspace-foundation/spec.md and repo-context planning for the first real multi-app workspace slice.

Summary

Introduce the first true multi-app foundation by adding a public website application under apps/website while keeping the existing Laravel platform stable under apps/platform. The implementation uses a minimal root orchestration model: one official Node workspace standard at repo root, one static-first website runtime, thin root scripts that orchestrate instead of re-implementing app logic, and a clear split between repo-level metadata, website runtime concerns, and platform runtime concerns.

Key approach: adopt pnpm workspaces as the official root package-manager standard, initialize the public website as an Astro app under apps/website, migrate the platform's Node command surface from npm to pnpm so the repo has one official JavaScript package-manager model, keep the platform Sail-first and Docker-backed, keep the website outside Sail in this first slice, and update only the root docs, tooling, and tasks that need multi-app awareness. The plan explicitly avoids shared packages, Turbo or Nx, a docs app, a customer app, a generalized app-runner framework, or any new TenantPilot product behavior.

The feature leaves Filament v5 on Livewire v4 unchanged, keeps panel providers registered in apps/platform/bootstrap/providers.php, does not add or alter globally searchable resources, introduces no destructive operator actions, and preserves the existing deploy-time cd apps/platform && php artisan filament:assets responsibility for platform assets.

Technical Context

Language/Version: PHP 8.4.15 and Laravel 12 for apps/platform; Node.js 20+ with pnpm 10 workspace tooling; Astro v6 for apps/website; Bash and Docker Compose for root orchestration
Primary Dependencies: laravel/framework, filament/filament, livewire/livewire, laravel/sail, vite, tailwindcss, pnpm workspaces, Astro, existing ./scripts/platform-sail wrapper, repo-root Docker Compose
Storage: Existing PostgreSQL, Redis, and filesystem storage for apps/platform; static build artifacts for apps/website; repository-managed workspace manifests and docs; no new database persistence
Testing: Existing Pest v4 platform tests through Sail; website boot/build smoke; root command smoke; parallel-run and build-isolation validation; targeted task and MCP smoke where tooling changes
Target Platform: macOS and Linux developer machines, Dockerized Laravel platform runtime, Node-based static public website runtime, Dokploy-style container deployment for the platform and static-site deployment for the website Project Type: Multi-app repo with repo-root orchestration, one Laravel platform app, and one static-first public website app
Performance Goals: Preserve current platform boot/build behavior; keep website dev/build lightweight; allow platform and website to run in parallel on distinct ports with no cross-app artifact pollution
Constraints: One official workspace standard only; no shared packages; no docs/customer/API surfaces; no website embedding into Blade or Filament; no root-level monorepo framework; keep platform Sail-first; root orchestrates while apps execute
Scale/Scope: Two first-class applications under apps/, root orchestration manifests and scripts, documentation and task updates, and smoke validation across local boot, coexistence, and build separation

Constitution Check

GATE: Passed before Phase 0 research. Re-checked after Phase 1 design and still passing.

Principle Status Notes
Inventory-first Pass No inventory, snapshot, or backup truth changes; this is repo topology and runtime orchestration only
Read/write separation Pass No new product mutation flow, operator write surface, or external write behavior is introduced
Graph contract path Pass No Microsoft Graph calls or contract-registry changes are in scope
Deterministic capabilities Pass Capability derivation and registries remain unchanged
RBAC-UX planes and 404 vs 403 Pass /admin, /admin/t/{tenant}/..., and /system authorization semantics remain unchanged
Workspace isolation Pass No new workspace-scoped data access or workspace routing behavior is introduced
Tenant isolation Pass No tenant-owned routes, queries, or UI semantics are broadened
Global search safety Pass No resource or global-search behavior changes are planned
Dangerous and destructive confirmations Pass No new destructive operator actions are introduced
Run observability Pass No new long-running product operations or OperationRun flows are introduced
Ops-UX 3-surface feedback Pass Not applicable because no operation UX is added or changed
Data minimization Pass No new secrets, logs, payload mirrors, or persisted product truth are added
Proportionality (PROP-001) Pass The design adds only one website app and the minimum root orchestration needed to support it
No premature abstraction (ABSTR-001) Pass The plan explicitly rejects Turbo, Nx, packages, a generic app-runner wrapper, and a generalized Sail abstraction
Persisted truth (PERSIST-001) Pass Only repository artifacts are added; no new application tables or persisted domain entities
Behavioral state (STATE-001) Pass No new domain status or reason-code family is introduced
UI semantics (UI-SEM-001) Pass No new operator semantic layer is introduced; the website is a separate public app
Filament-native UI (UI-FIL-001) Pass Platform Filament surfaces stay unchanged
Filament v5 / Livewire v4 compliance Pass Platform remains on Filament v5 with Livewire v4; the website app does not affect that stack
Provider registration location Pass Provider registration remains in apps/platform/bootstrap/providers.php
Global search hard rule Pass No globally searchable resource gains or losses are introduced
Asset strategy Pass Platform assets remain app-local and keep the filament:assets deploy step; website assets build independently from apps/website
Testing plan Pass The plan includes platform regression smoke, website boot/build smoke, root command smoke, and coexistence validation

Phase 0 Research

Research outcomes are captured in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/183-website-workspace-foundation/research.md.

Key decisions:

  • Adopt pnpm workspaces as the official JavaScript package-manager standard for the multi-app repo. The root receives package.json plus pnpm-workspace.yaml, and the platform's Node command surface migrates from npm to pnpm so the repo has one official package-manager story.
  • Use Astro v6 as the website stack because the spec explicitly wants a public-surface, static-first foundation with minimal runtime coupling.
  • Keep the platform Sail-first and Docker-backed, but do not Dockerize the website in this first slice. The website should run as a plain Node app to keep the first multi-app step proportional.
  • Keep ./scripts/platform-sail as a platform-only compatibility helper. Do not introduce a generic scripts/sail <app> abstraction because only one app uses Sail today.
  • Keep Boost MCP and Laravel-specific editor integration platform-only. The website app is not a second Laravel runtime in this slice, so .vscode/mcp.json and opencode.json only need clearer scoping, not a second Boost server.
  • Limit root task updates to the official entry tasks and any affected labels or notes. This slice does not justify a wholesale task-system rewrite.

Phase 1 Design

Design artifacts are created under /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/183-website-workspace-foundation/:

  • data-model.md: repository-artifact and runtime-boundary model for root orchestration, platform app, website app, and tooling surfaces
  • contracts/workspace-command-model.md: canonical root and app-local command contract for platform, website, and parallel local development
  • contracts/coexistence-smoke.openapi.yaml: HTTP and orchestration smoke contract for website/platform coexistence
  • quickstart.md: implementation, validation, and rollout checklist for the workspace foundation

Design decisions:

  • The root owns JavaScript workspace orchestration, but PHP and Laravel runtime ownership stays inside apps/platform.
  • The official root command model is intentionally small: install workspace dependencies, start the platform, start the website, start both, build the website, and build platform frontend assets.
  • The platform retains its current Docker Compose topology and ./scripts/platform-sail wrapper. The website does not join Docker Compose in this slice.
  • The root does not introduce packages/, shared tokens, shared components, or cross-app runtime modules.
  • Root documentation and tooling are updated only where multi-app awareness is now necessary: README, Agents/GEMINI/Copilot guidance, entry tasks, and root-level config that references the platform as the only app.

Project Structure

Documentation (this feature)

specs/183-website-workspace-foundation/
├── spec.md
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│   ├── workspace-command-model.md
│   └── coexistence-smoke.openapi.yaml
├── checklists/
│   └── requirements.md
└── tasks.md

Source Code (repository root)

repo-root/
├── apps/
│   ├── platform/
│   │   ├── app/
│   │   ├── bootstrap/
│   │   ├── config/
│   │   ├── database/
│   │   ├── public/
│   │   ├── resources/
│   │   ├── routes/
│   │   ├── storage/
│   │   ├── tests/
│   │   ├── artisan
│   │   ├── composer.json
│   │   ├── package.json
│   │   └── vite.config.js
│   └── website/
│       ├── package.json
│       ├── astro.config.mjs
│       ├── public/
│       └── src/
├── docs/
├── specs/
├── scripts/
├── .specify/
├── .github/
├── .vscode/
├── docker-compose.yml
├── package.json
├── pnpm-workspace.yaml
├── README.md
├── Agents.md
├── GEMINI.md
├── boost.json
└── opencode.json

Structure Decision: Repo-root workspace orchestration plus two app roots under apps/: the existing Laravel platform and a new Astro website. No packages/ layer, no docs app, and no generalized monorepo framework are introduced.

Implementation Strategy

Phase A — Establish The Official Root Workspace Standard

Goal: Make the repo root the canonical JavaScript workspace entry point without turning it into an application runtime.

Step Area Change
A.1 Workspace manifests Add a minimal root package.json and pnpm-workspace.yaml for apps/*
A.2 Package-manager contract Declare pnpm as the official JS package-manager standard and remove the implicit npm-only assumption from root docs and tooling
A.3 Lockfile model Replace per-app package-lock.json usage for maintained app packages with one root pnpm-lock.yaml
A.4 Root scripts Define thin root scripts for platform start, website start, parallel dev, website build, and platform frontend build

Phase B — Align The Platform App With The Workspace Standard

Goal: Keep apps/platform stable while letting it participate in the official pnpm-based workspace model.

Step Area Change
B.1 Platform package manifest Update apps/platform/package.json scripts to work under pnpm instead of npm-only assumptions
B.2 Composer scripts Adjust apps/platform/composer.json Node-invoking scripts from npm to pnpm where they are part of the supported workflow
B.3 Sail runtime path Keep ./scripts/platform-sail and existing Compose wiring; rely on Corepack/pnpm availability inside Sail instead of building a new orchestration wrapper
B.4 Asset isolation Preserve platform asset outputs under apps/platform/public/build and keep deploy-time php artisan filament:assets unchanged

Phase C — Create The Website App As A Separate Public Runtime

Goal: Introduce apps/website as a real standalone app with its own dev and build lifecycle.

Step Area Change
C.1 Website scaffold Create apps/website with Astro config, package manifest, src/, and public/
C.2 Public pages Add the narrow initial public site structure needed for the foundation slice, without CMS/blog/docs/customer scope
C.3 Dev/build scripts Ensure website dev and build commands run from root orchestration and app-local commands alike
C.4 Runtime separation Keep website ports, environment assumptions, and build output isolated from the platform app

Phase D — Update Root Orchestration, Tooling, And Docs

Goal: Make the repo entry path obvious and keep automation aligned with the new topology.

Step Area Change
D.1 README and architecture notes Document the multi-app topology, official command model, and app-local ownership clearly
D.2 Agent and editor guidance Update Agents.md, GEMINI.md, .github/copilot-instructions.md, and related guidance where root multi-app knowledge now matters
D.3 VS Code and root tooling Add or adjust official entry tasks for platform, website, and parallel dev; keep Boost MCP platform-only but document that scope explicitly
D.4 Ignore and repo hygiene Update ignore files and related repo metadata for apps/website, root lockfiles, and website build artifacts

Phase E — Validate Coexistence And Build Separation

Goal: Prove the multi-app repo behaves coherently before implementation is considered complete.

Step Area Change
E.1 Platform stability Verify existing platform boot paths and focused regression tests still pass
E.2 Website boot Verify the website starts independently and is reachable on its own dev port
E.3 Parallel dev Verify the platform and website can run together without port or artifact collisions
E.4 Build separation Verify website build outputs remain isolated and platform frontend build still works independently
E.5 Documentation usability Verify a contributor can follow the updated root entry docs without hidden steps

Key Design Decisions

D-001 — pnpm Becomes The One Official JavaScript Workspace Standard

The repo currently has only apps/platform/package.json plus a tracked package-lock.json, but Spec 183 requires one clear workspace/package-manager standard. pnpm workspaces give the minimal root construct needed for multi-app orchestration without requiring a heavier monorepo framework.

D-002 — The Website Is A Static-First Astro App, Not A Second Laravel Runtime

The spec calls for a public website foundation, not another back-office application. Astro fits the static-first, public-surface constraint and avoids accidental coupling to platform sessions, Blade, Filament, or Laravel-specific runtime assumptions.

D-003 — The Platform Stays Sail-First; The Website Does Not Join Docker In V1

The current Compose file and wrapper are already platform-specific and stable. Dockerizing the website now would add extra service orchestration, port strategy, and deployment assumptions that the spec explicitly tries to avoid in the first slice.

D-004 — Root Scripts Orchestrate; App Logic Stays In The Apps

The root will provide the official entry scripts, but the platform keeps its app-local Sail and Composer logic, and the website keeps its app-local Astro logic. Root scripts are thin delegators, not a new orchestration framework.

D-005 — No Shared Packages Or Generic App Wrappers In This Slice

This slice deliberately rejects packages/, shared token libraries, a generalized scripts/sail <app> abstraction, Turbo, Nx, and any cross-app build framework. Those additions would solve hypothetical future variance rather than the current concrete need.

Risk Assessment

Risk Impact Likelihood Mitigation
pnpm migration breaks existing platform frontend commands or Composer scripts High Medium Update platform package.json and composer.json together, and verify pnpm inside Sail before relying on it
Contributors confuse root commands, app-local commands, and compatibility helpers High Medium Publish one root command contract and keep app-local commands documented as secondary but valid
Website dev port collides with current platform or Vite usage Medium Medium Reserve a distinct website port and document override rules in quickstart and root scripts
Root tooling remains platform-only in ways that confuse contributors after website arrives Medium High Update README, task entry points, and agent guidance in the same slice as the website introduction
The slice drifts into packages, shared tokens, or a docs app High Medium Treat all extra surfaces and packages as explicit non-goals and block them in review
Deployment assumptions for the website are overbuilt too early Medium Medium Keep website deployment guidance minimal and static-site oriented, separate from the platform's Dokploy flow

Test Strategy

  • Keep platform regression coverage focused: run the minimum representative Sail-driven Pest tests that prove the platform remains stable after the workspace changes.
  • Validate platform boot via existing local health and login surfaces such as /up and /admin/login after root/workspace changes land.
  • Validate website boot independently on its own dev server and verify it remains reachable without the platform app running.
  • Validate root entry commands for website-only, platform-only, and combined local development flows.
  • Validate platform frontend build and website build independently, ensuring outputs remain in their app-local directories.
  • Validate at least one affected VS Code task or root tooling entry path so editor automation does not drift behind the repo topology.
  • Reconfirm Filament v5 and Livewire v4 compliance by leaving the platform stack untouched and ensuring provider registration remains in apps/platform/bootstrap/providers.php.
  • Preserve the platform asset deployment contract by keeping cd apps/platform && php artisan filament:assets in deployment guidance.

Complexity Tracking

No constitution violation or exemption is planned. The feature intentionally limits complexity to one new app plus the minimum workspace contract needed to support it.

Proportionality Review

  • Current operator problem: The repo needs a public website surface now, but still behaves operationally like a single-app workspace. That makes local setup, docs, and tooling inconsistent the moment a second app is added.
  • Existing structure is insufficient because: apps/platform is correctly isolated, but the repo root still lacks a real workspace standard, root command model, and second-app boundary.
  • Narrowest correct implementation: Add one website app, one official root workspace standard, a thin root orchestration layer, and only the documentation and tooling updates required to make that structure usable.
  • Ownership cost created: One additional app lifecycle, one shared JS workspace lockfile, root script maintenance, and multi-app smoke validation.
  • Alternative intentionally rejected: Embedding the website into Laravel, keeping npm for the platform while adding pnpm only for the website, or introducing shared packages and monorepo frameworks immediately. Each alternative either violates the one-standard rule or adds speculative complexity.
  • Release truth: Current-release infrastructure truth for the first public website surface, not future-only preparation.