Skip to content

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.

Terminal window
git clone <the repository> smooth2 && cd smooth2
cp .env.example .env
ddev start
ddev composer install
ddev artisan key:generate
ddev npm install
ddev npm run build # admin (Filament) theme
ddev npm run build:default # storefront: default theme
ddev npm run build:gopromo # storefront: gopromo theme

ddev 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.

Terminal window
ddev artisan migrate:fresh --seed

The 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.

Terminal window
ddev import-db --database=smooth --file=<legacy dump>
ddev import-db --database=wordpress --file=<blog export>
ddev artisan migrate:fresh --seed --seeder=LegacySeeder

It reads:

  • the smooth connection, whose database name is LEGACY_DB_DATABASE (same host and login as the main database), and the wordpress connection, whose database name is fixed
  • under smooth-images/ (not in the repo): the legacy images, the upscaled set named by LEGACY_UPSCALED_SET, wp-uploads, wp-media and blog-stock. The directories can be moved with the LEGACY_*_DIRECTORY variables in config/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:

Terminal window
# 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-legacy

See Commands for what each import can do and resume.

Nothing except Reverb and the assistant’s worker starts by itself. In a terminal of its own:

Terminal window
ddev artisan horizon # every queue lane; dashboard at /horizon, super admins only
ddev artisan schedule:work # only if you are working on something scheduled

Without Horizon the site still renders, but photo conversions, supplier work, search syncs and cascading reindexes wait in Redis. See Queues and scheduling.

Meilisearch runs in its own container at http://meilisearch:7700. Fill the index with:

Terminal window
ddev artisan catalog:search-rebuild

Horizon must be running for later edits to reach search, since those syncs are queued jobs.

  1. ddev start, and ddev artisan horizon in another terminal.
  2. Theme assets built (above), or ddev npm run dev:gopromo for the theme you are editing.
  3. Data seeded, and a site whose domain is a host DDEV answers.
  4. Admin at https://smooth2.ddev.site/admin, storefront at that site’s domain, customer account at /account on the same domain.
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
  • app-modules/: one in-repo Composer package per module. See Modules. Each has its own ARCHITECTURE.md working notes, which go into more depth than this site. Most module README.md files 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, and gopromo as a child). Each has its own Vite config and a theme.php manifest. See Themes.
  • config/roles.php: the staff roles. See Authorization.
  • docs/: this site (Astro Starlight), with its pages in docs/src/content/docs/.
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
  • Add site pages as Markdown under docs/src/content/docs/: user guide pages in guide/, developer pages in developers/. Each group in the sidebar is one folder, listed in docs/astro.config.mjs.
  • ddev docs serves the site with live reload at https://smooth-docs.ddev.site; ddev docs build writes the static site to docs/dist/, which the same address serves when the dev server is not running.