overlook / foundation
The conventions Overlook Innovations applies to every application it builds
Requires
- php: ^8.3
- illuminate/support: ^11.0|^12.0|^13.0
- league/flysystem-aws-s3-v3: ^3.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
README
The conventions Overlook Innovations applies to every application it builds.
Installed by the scaffolder into each new project, and kept current on projects
already built by Renovate. Public on purpose: a client handed one of these
repositories must be able to run composer install without a credential from
the studio.
What belongs here, and what does not
Sorted by who owns the file. Getting this wrong is how the template this replaced went stale.
| Tier | Contents | Mechanism |
|---|---|---|
| A | Runtime behaviour — object storage disks, queue and session defaults, the review widget | FoundationServiceProvider. Configuration set at boot, never a published file. |
| B | Repo furniture with no upstream — renovate.json, editor config, CI |
Published stubs. Safe to copy wholesale, because nothing in Laravel owns them. |
| C | Edits to framework-owned files — .env additions |
overlook:install, idempotently. Every entry is a debt; move it to Tier A when you can. |
Never publish a file Laravel ships. A published config/filesystems.php
freezes that file at whatever the framework shipped the day it was copied — the
same drift the template had, on a smaller surface and harder to notice, because
the repository still looks freshly generated.
The storage contract
The studio's provisioner attaches Cloudflare R2 buckets to two disks by name,
private and media. Cloud replaces each entry wholesale at runtime from the
LARAVEL_CLOUD_DISK_CONFIG blob it hands the container, so the application only
has to declare the names — which FoundationServiceProvider does.
Rename either and buckets attach to a disk nothing writes to. The nightly
Upstream workflow checks both still resolve.
Declaring an s3 disk is only half of it, which is why this package requires
league/flysystem-aws-s3-v3 rather than leaving it to the application. Without
the adapter Cloud refuses the very first deploy — "your application has an
attached bucket but is missing the package" — and a build that got that far has
already created the repository, the application and the buckets.
The client review widget
The studio's provisioner connects an environment, mints a key, and writes two
variables into the application's environment: OVERLOOK_REVIEW_KEY, which names
the environment a report is filed against, and OVERLOOK_REVIEW_URL, the address
the widget is served from. This package turns them into the script tag that loads
it, appended to the closing body tag of every HTML response.
Two variables rather than one because there is no address to hardcode. The widget is served by whichever installation of the studio's application provisioned this site, which a deployed site has no other way to learn.
Injected by middleware rather than offered as a Blade component, because there is no layout to put a component in. Applications are generated by the Laravel installer across five starter kits and the studio never edits the result, so a tag placed by hand would reach the next project and none already built — the drift this package exists to avoid, in a new place.
A production site never carries it. The provisioner withholds both variables
from a production environment and refuses the switch that would connect one, and
this package refuses to inject when APP_ENV is production regardless of what
it was given. Three locks, because the widget is a launcher in the corner of
every page and the people looking at a live site are the client's own visitors.
FOUNDATION_REVIEW_ENABLED=false switches it off on a staging site that does
have a key.
Both variable names are a contract with the provisioner, which builds them from
its own OVERLOOK_REVIEW_INJECTION_ENV_VAR and OVERLOOK_REVIEW_INJECTION_URL_ENV_VAR.
Rename one on either side without the other and the widget silently stops
appearing. The studio's feedback:verify-widget command fetches a deployed site
and reports whether the tag is really there, which is the only check that the two
halves still agree — it looks for both the address and the key, since one address
serves every site the studio hosts.
Upstream drift
Applications are generated from whatever the Laravel installer ships that day,
deliberately unpinned. The cost of that is an upstream release breaking
provisioning without anything here changing, so .github/workflows/upstream.yml
runs nightly against every starter kit the studio offers.
A red build there on a Tuesday morning is the whole point. Without it the first report comes from a client watching a provision fail.
Handing a project to a client
Nothing to do. The package is public and carries no credentials, so a client who takes over a repository keeps installing it like any other dependency.