feat(11.1-04): add the Backend section, the remaining Services pages and the concept map links

- docs/backend: admin controllers, forms, lists and filters, relation
  manager, users and permissions, settings, partials and widgets, admin SPA
- docs/services: storage, outbound HTTP, realtime, Web Push, search, parity
  testing and the Frontend and AJAX (not provided) page
- Examples for cabana (with testdata/docs YAML), fetchguard, lighthouse and
  its centrifugo driver, flare, beachcomber and typesense, tide; lighthouse
  and beachcomber TestDocs* regions run on their Postgres harnesses
- concept map rows link their guide pages and the not-provided rows the
  Frontend and AJAX page; index lists Backend, Database and Services
- TestDocsRequiredPages asserts the D-08 section order
This commit is contained in:
Jakub Zych
2026-09-30 23:18:35 +02:00
parent f7dfe68707
commit 44bd1446f5
40 changed files with 2882 additions and 30 deletions

View File

@@ -12,31 +12,31 @@ What changes is everything that depends on PHP at runtime. Plugins are Go packag
## Concept map
Each row names the WinterCMS concept, the SummerCMS identifiers that replace it and the module that documents them.
Each row names the WinterCMS concept, the SummerCMS identifiers that replace it, and where to read more: the guide page first, then the module reference.
| WinterCMS | SummerCMS | Where |
|-----------|-----------|-------|
| `Plugin.php` with `pluginDetails`, `register` and `boot` | A type implementing `party.Plugin` (`party.Plugin.ID`, `party.Plugin.Requires`, `party.Plugin.Register`, `party.Plugin.Boot`), registered from `init` with `party.Register` | [party](../../modules/party/README.md) |
| `$require` plugin dependencies | `party.Plugin.Requires`; `party.Activate` orders plugins so each comes after the ones it requires | [party](../../modules/party/README.md) |
| `registerPermissions`, `registerNavigation` | `pact.HasPermissions` returning `pact.Permission` values, `pact.HasNavigation` returning `pact.NavigationItem` values | [pact](../../modules/pact/README.md) |
| `version.yaml` and the `updates/` directory | `pact.HasMigrations` returning an ordered gormigrate set; `lagoon.Migrate` runs every plugin's set and `lagoon.RollbackLast` undoes the last one | [lagoon](../../modules/lagoon/README.md) |
| Eloquent models | GORM structs with lagoon helpers: `lagoon.Fill` for mass assignment, `lagoon.Validate` for rules, `lagoon.Jsonable` for JSON columns, `lagoon.Page` for pagination | [lagoon](../../modules/lagoon/README.md) |
| `fields.yaml` and `columns.yaml` | The same YAML, embedded in the plugin through `pact.AdminAssets` and compiled at boot into a `cabana.CompiledController` | [cabana](../../modules/cabana/README.md) |
| Backend controllers with the Form, List and Relation behaviours | A `pact.AdminController` returned from `pact.HasAdminControllers`; the generic admin API replaces the behaviours, and hooks such as `pact.FormBeforeCreate` and `pact.ListExtendQuery` replace behaviour overrides | [cabana](../../modules/cabana/README.md) |
| `routes.php` | `pact.HasRoutes`, declaring routes on a `pact.Router` with groups, middleware names and `pact.Router.Where` constraints | [surf](../../modules/surf/README.md) |
| Route middleware | Named middleware of type `pact.Middleware`, registered through `pact.HasMiddleware` | [surf](../../modules/surf/README.md) |
| `config/*.php`, `.env` and `Config::get` | `compass.Config` with per-environment directories and `SUMMER_` overrides; plugin defaults through `pact.HasConfig` | [compass](../../modules/compass/README.md) |
| `lang/` files and `Lang::get` | `pact.HasLang` for plugin catalogs, read through `phrasebook.Translator.Get` and `phrasebook.Translator.Choice` | [phrasebook](../../modules/phrasebook/README.md) |
| `Event::listen` and `Event::fire` | `festival.Bus.Listen` and `festival.Bus.Fire` on `backpack.App.Events`, keyed by the event's Go type | [festival](../../modules/festival/README.md) |
| `App::make` and singleton bindings | `backpack.App.Publish` and `backpack.App.Lookup`, keyed by type | [backpack](../../modules/backpack/README.md) |
| Artisan commands and `registerConsoleCommand` | `bonfire.Command` values returned from `pact.HasCommands` | [bonfire](../../modules/bonfire/README.md) |
| `Plugin.php` with `pluginDetails`, `register` and `boot` | A type implementing `party.Plugin` (`party.Plugin.ID`, `party.Plugin.Requires`, `party.Plugin.Register`, `party.Plugin.Boot`), registered from `init` with `party.Register` | [Plugin registration](../plugins/registration.md), [party](../../modules/party/README.md) |
| `$require` plugin dependencies | `party.Plugin.Requires`; `party.Activate` orders plugins so each comes after the ones it requires | [Plugin registration](../plugins/registration.md), [party](../../modules/party/README.md) |
| `registerPermissions`, `registerNavigation` | `pact.HasPermissions` returning `pact.Permission` values, `pact.HasNavigation` returning `pact.NavigationItem` values | [Users and permissions](../backend/users-and-permissions.md), [pact](../../modules/pact/README.md) |
| `version.yaml` and the `updates/` directory | `pact.HasMigrations` returning an ordered gormigrate set; `lagoon.Migrate` runs every plugin's set and `lagoon.RollbackLast` undoes the last one | [Migrations](../database/migrations.md), [lagoon](../../modules/lagoon/README.md) |
| Eloquent models | GORM structs with lagoon helpers: `lagoon.Fill` for mass assignment, `lagoon.Validate` for rules, `lagoon.Jsonable` for JSON columns, `lagoon.Page` for pagination | [Models](../database/models.md), [Casts and validation](../database/casts-and-validation.md), [lagoon](../../modules/lagoon/README.md) |
| `fields.yaml` and `columns.yaml` | The same YAML, embedded in the plugin through `pact.AdminAssets` and compiled at boot into a `cabana.CompiledController` | [Forms](../backend/forms.md), [Lists and filters](../backend/lists-and-filters.md), [cabana](../../modules/cabana/README.md) |
| Backend controllers with the Form, List and Relation behaviours | A `pact.AdminController` returned from `pact.HasAdminControllers`; the generic admin API replaces the behaviours, and hooks such as `pact.FormBeforeCreate` and `pact.ListExtendQuery` replace behaviour overrides | [Admin controllers](../backend/admin-controllers.md), [cabana](../../modules/cabana/README.md) |
| `routes.php` | `pact.HasRoutes`, declaring routes on a `pact.Router` with groups, middleware names and `pact.Router.Where` constraints | [Routing](../services/routing.md), [surf](../../modules/surf/README.md) |
| Route middleware | Named middleware of type `pact.Middleware`, registered through `pact.HasMiddleware` | [Routing](../services/routing.md), [surf](../../modules/surf/README.md) |
| `config/*.php`, `.env` and `Config::get` | `compass.Config` with per-environment directories and `SUMMER_` overrides; plugin defaults through `pact.HasConfig` | [Configuration](../services/configuration.md), [compass](../../modules/compass/README.md) |
| `lang/` files and `Lang::get` | `pact.HasLang` for plugin catalogs, read through `phrasebook.Translator.Get` and `phrasebook.Translator.Choice` | [Localization](../services/localization.md), [phrasebook](../../modules/phrasebook/README.md) |
| `Event::listen` and `Event::fire` | `festival.Bus.Listen` and `festival.Bus.Fire` on `backpack.App.Events`, keyed by the event's Go type | [Events](../services/events.md), [festival](../../modules/festival/README.md) |
| `App::make` and singleton bindings | `backpack.App.Publish` and `backpack.App.Lookup`, keyed by type | [Extending plugins](../plugins/extending.md), [backpack](../../modules/backpack/README.md) |
| Artisan commands and `registerConsoleCommand` | `bonfire.Command` values returned from `pact.HasCommands` | [Writing commands](../console/writing-commands.md), [bonfire](../../modules/bonfire/README.md) |
| Queued jobs | `pact.HasJobs` with jobs built by `conga.Job`, dispatched with `conga.Manager.Dispatch` inside the caller's transaction | [Queued jobs](../services/jobs.md), [conga](../../modules/conga/README.md) |
| `registerSchedule` and the scheduler | `pact.HasSchedule` returning `pact.ScheduledCommand` entries with a `pact.Cadence` | [pact](../../modules/pact/README.md) |
| Mail templates in `views/mail` | `pact.HasMailTemplates`, sent through `postcard.Mailer` | [postcard](../../modules/postcard/README.md) |
| Settings models and `registerSettings` | `pact.HasSettings` returning `pact.SettingsItem` entries | [cabana](../../modules/cabana/README.md) |
| Laravel broadcasting | `lighthouse.Publisher` drivers and models that implement `lighthouse.Broadcastable` | [lighthouse](../../modules/lighthouse/README.md) |
| Laravel Scout search | Models that implement `beachcomber.Searchable`, synced after commit | [beachcomber](../../modules/beachcomber/README.md) |
| The Laravel HTTP client | `fetchguard.Fetch` with a `fetchguard.Policy` that blocks private addresses and limits size and time | [fetchguard](../../modules/fetchguard/README.md) |
| `registerSchedule` and the scheduler | `pact.HasSchedule` returning `pact.ScheduledCommand` entries with a `pact.Cadence` | [Task scheduling](../plugins/scheduling.md), [pact](../../modules/pact/README.md) |
| Mail templates in `views/mail` | `pact.HasMailTemplates`, sent through `postcard.Mailer` | [Mail](../services/mail.md), [postcard](../../modules/postcard/README.md) |
| Settings models and `registerSettings` | `pact.HasSettings` returning `pact.SettingsItem` entries | [Settings](../backend/settings.md), [cabana](../../modules/cabana/README.md) |
| Laravel broadcasting | `lighthouse.Publisher` drivers and models that implement `lighthouse.Broadcastable` | [Realtime](../services/realtime.md), [lighthouse](../../modules/lighthouse/README.md) |
| Laravel Scout search | Models that implement `beachcomber.Searchable`, synced after commit | [Search](../services/search.md), [beachcomber](../../modules/beachcomber/README.md) |
| The Laravel HTTP client | `fetchguard.Fetch` with a `fetchguard.Policy` that blocks private addresses and limits size and time | [Outbound HTTP](../services/outbound-http.md), [fetchguard](../../modules/fetchguard/README.md) |
## What is not provided
@@ -44,16 +44,16 @@ SummerCMS does not port the WinterCMS frontend or the PHP helpers that Go alread
| WinterCMS | SummerCMS |
|-----------|-----------|
| CMS pages, themes, layouts and partials | Not provided. The frontend is a separate application that calls the JSON API. |
| Components | Not provided. Write an HTTP handler and declare its route through `pact.HasRoutes`. |
| The AJAX framework and Snowboard | Not provided. The frontend calls the JSON API and subscribes to realtime channels. |
| The media manager | Not provided. Store uploads as model attachments. |
| CMS pages, themes, layouts and partials | Not provided. The frontend is a separate application that calls the JSON API; see [Frontend and AJAX](../services/frontend-and-ajax.md). |
| Components | Not provided. Write an HTTP handler and declare its route through `pact.HasRoutes`; see [Frontend and AJAX](../services/frontend-and-ajax.md). |
| The AJAX framework and Snowboard | Not provided. The frontend calls the JSON API and subscribes to realtime channels; see [Frontend and AJAX](../services/frontend-and-ajax.md). |
| The media manager | Not provided. Store uploads as model attachments; see [Attachments](../database/attachments.md). |
| Import and export in backend lists | Not provided. |
| Record sorting (the Reorder behaviour) | Not provided. |
| Collections | Not provided. Use Go slices and the `slices` and `maps` packages. |
| Behaviours and dynamic class extension | Not provided. Use Go interfaces and composition. |
| Cache | Not provided. Use the Go standard library or a service another plugin publishes. |
| Session | Not provided. The API is stateless and authenticates with tokens. |
| Session | Not provided. The API is stateless and authenticates with tokens; see [Frontend and AJAX](../services/frontend-and-ajax.md). |
## Plugin.php in Go