Getting started
Smooth Promotion 2.0 is a modular Laravel 13 + Filament 5 application (PHP 8.4, MariaDB 10.11,
Vite + Tailwind 4). DDEV is the supported local environment, and every PHP,
Composer and Node command runs inside it: prefix with ddev (ddev artisan ...,
ddev composer ..., ddev npm ...).
Read the architecture overview next.
First-time setup
Section titled “First-time setup”git clone <the repository> smooth2 && cd smooth2cp .env.example .envddev startddev composer installddev artisan key:generateddev npm installddev npm run build # admin (Filament) themeddev npm run build:default # storefront: default themeddev npm run build:gopromo # storefront: gopromo themeddev start brings up the web container, MariaDB, Redis and Meilisearch (the last two are the
compose files in .ddev/), plus two daemons from .ddev/config.assistant.yaml: Reverb and the
assistant’s queue worker. Chromium is installed in the web image for document PDFs.
.env.example is not set up for DDEV out of the box. Check these in .env before migrating:
| Variable | Value under DDEV | Why |
|---|---|---|
DB_CONNECTION, DB_HOST, DB_DATABASE |
mariadb, db, db |
The example says sqlite. DDEV’s Laravel project type writes its database settings into .env |
REDIS_HOST |
redis |
The example says 127.0.0.1, and the queue is on Redis |
CACHE_STORE, SESSION_DRIVER |
redis |
What development runs with; the example says database |
MEDIA_DISK |
media |
Not in the example. Without it media goes to the public disk rather than public/media |
MEILISEARCH_KEY |
The master key in .ddev/docker-compose.meilisearch.yaml |
A local development value |
REVERB_APP_ID, REVERB_APP_KEY, REVERB_APP_SECRET |
Any values you generate | Needed by the assistant’s chat |
INITIAL_ADMIN_EMAIL, INITIAL_ADMIN_PASSWORD |
Your login | Read by AdminUserSeeder. A blank password prints a random one |
Supplier feed keys, Turnstile, the exchange rate key and the assistant’s model key are only needed when you work on those features. Deploying lists the variables by purpose.
Then create the database content, either from the demo or from real data.
Option 1: the demo data
Section titled “Option 1: the demo data”ddev artisan migrate:fresh --seedThe root DatabaseSeeder runs AdminUserSeeder, the sales reference data and automation rules,
the supplier text rules, colour groups, sizes, and then two generated demos: content-management’s
DemoSeeder (sites, taxonomies, content, per-site configuration, projection) and catalog’s
DemoCatalogSeeder on the same sites. It needs nothing from outside the repo.
The demo sites have the domains shop.example.com, blog.example.com and
lifestyle.example.com, which DDEV does not serve. A site is found by an exact match of the
request host on sites.domain, so to see one, sign in to https://smooth2.ddev.site/admin, open
Sites under Content Management and set its Domain Name to a host DDEV answers:
smooth2.ddev.site, or one of additional_hostnames in .ddev/config.yaml with .ddev.site on
the end.
Option 2: real data from the legacy system
Section titled “Option 2: real data from the legacy system”LegacySeeder builds a fully seeded install from the legacy system’s data: sites, catalog, blog,
the GoPromotional content and every supplier setting seeder, ending with a cms:reindex.
ddev import-db --database=smooth --file=<legacy dump>ddev import-db --database=wordpress --file=<blog export>ddev artisan migrate:fresh --seed --seeder=LegacySeederIt reads:
- the
smoothconnection, whose database name isLEGACY_DB_DATABASE(same host and login as the main database), and thewordpressconnection, whose database name is fixed - under
smooth-images/(not in the repo): the legacyimages, the upscaled set named byLEGACY_UPSCALED_SET,wp-uploads,wp-mediaandblog-stock. The directories can be moved with theLEGACY_*_DIRECTORYvariables inconfig/legacy.php
IMPORT_SKIP_IMAGES=true or --skip-images on the import commands makes a data-only run much
faster. The site records get the local domains gopromo.ddev.site and ie-gopromo.ddev.site
(GoPromoSitesSeeder), so the storefronts work straight away.
Two further steps are opt-in:
# Supplier products, one sync of each configured feed (needs network and credentials).ddev artisan db:seed --class="WebMoves\Catalog\Database\Seeders\SupplierCatalogSeeder"
# Customers, quotes, orders, invoices and attachments.ddev artisan sales:import-legacySee Commands for what each import can do and resume.
Workers and the scheduler
Section titled “Workers and the scheduler”Nothing except Reverb and the assistant’s worker starts by itself. In a terminal of its own:
ddev artisan horizon # every queue lane; dashboard at /horizon, super admins onlyddev artisan schedule:work # only if you are working on something scheduledWithout Horizon the site still renders, but photo conversions, supplier work, search syncs and cascading reindexes wait in Redis. See Queues and scheduling.
Search
Section titled “Search”Meilisearch runs in its own container at http://meilisearch:7700. Fill the index with:
ddev artisan catalog:search-rebuildHorizon must be running for later edits to reach search, since those syncs are queued jobs.
What to run to see a working site
Section titled “What to run to see a working site”ddev start, andddev artisan horizonin another terminal.- Theme assets built (above), or
ddev npm run dev:gopromofor the theme you are editing. - Data seeded, and a site whose domain is a host DDEV answers.
- Admin at
https://smooth2.ddev.site/admin, storefront at that site’s domain, customer account at/accounton the same domain.
Everyday commands
Section titled “Everyday commands”| Task | Command |
|---|---|
| Run all tests | ddev artisan test |
| Run one test file | ddev artisan test path/to/SomeTest.php |
| Format PHP | ddev artisan pint |
| Admin (Filament) assets | ddev npm run dev / ddev npm run build |
| Storefront theme assets | ddev npm run dev:default / build:default (and :gopromo) |
| Rebuild the per-site projection | ddev artisan cms:reindex |
| Rebuild storefront search | ddev artisan catalog:search-rebuild |
| Sync roles and permissions | ddev artisan roles:sync |
| This documentation site | ddev docs (dev server) / ddev docs build |
Where things live
Section titled “Where things live”app-modules/: one in-repo Composer package per module. See Modules. Each has its ownARCHITECTURE.mdworking notes, which go into more depth than this site. Most moduleREADME.mdfiles are stale; the exception is content-management’s.app/: what composes the modules: the admin panel provider, the base layout component, and the legacy and WordPress import commands.themes/: storefront themes (default, andgopromoas a child). Each has its own Vite config and atheme.phpmanifest. See Themes.config/roles.php: the staff roles. See Authorization.docs/: this site (Astro Starlight), with its pages indocs/src/content/docs/.
Common breakages
Section titled “Common breakages”| Symptom | Cause and fix |
|---|---|
| “Unable to locate file in Vite manifest” | That build has not run. The admin builds to public/build, each theme to public/<theme>: run the matching build command |
404 on every storefront URL, including / |
No site has this host as its domain, or the projection is empty. Check Sites, then run cms:reindex |
| A page you just made is a 404 | It has no available site_documents row: check the site’s content rules, its status and publish time |
| Can’t get past the admin login, or a 403 after it | User::canAccessPanel() needs a role. AdminUserSeeder gives the initial admin super_admin |
| A new capability does nothing, or a role can’t see a screen | Run roles:sync |
| Photos missing or stuck on the original size | Horizon is not running: conversions are on the media lane |
| Search returns nothing or errors | Run catalog:search-rebuild; check SCOUT_DRIVER, MEILISEARCH_HOST and MEILISEARCH_KEY |
| Assistant chat never answers | Reverb’s keys are blank, or the assistant-worker daemon died: check ddev logs |
| “Class not found” for a provider at every artisan boot | A module or package was removed without refreshing the package cache. See removing a module |
composer resolves a module as dev-<branch> and fails on a branch switch |
That module’s composer.json is missing "version": "1.0" |
| Tests fail with an unknown database | The testing database is missing. See Testing |
| The dev database was wiped by a command you meant for tests | --env=testing does not switch databases. See Testing |
Working on these docs
Section titled “Working on these docs”- Add site pages as Markdown under
docs/src/content/docs/: user guide pages inguide/, developer pages indevelopers/. Each group in the sidebar is one folder, listed indocs/astro.config.mjs. ddev docsserves the site with live reload at https://smooth-docs.ddev.site;ddev docs buildwrites the static site todocs/dist/, which the same address serves when the dev server is not running.