feat(12.2-01): add deferred:purge, its daily framework schedule and relation child hooks

- deferred:purge [--days] in lagoon.RuntimeCommands (purge_days, default 5)
- lagoon.FrameworkSchedule entry at purge_at (default 03:00, empty disables)
- conga prepends framework entries as summercms.lagoon[i]:<command>
- pact.Relation{Before,After}{Create,Update,Delete} optional hooks
- lagoon, conga and pact READMEs, scheduling and setup docs
This commit is contained in:
Jakub Zych
2026-10-02 17:45:41 +02:00
parent f48a886f94
commit 8818d7b023
11 changed files with 378 additions and 8 deletions

View File

@@ -24,6 +24,21 @@ Every application binary carries the framework's runtime commands. The examples
Each plugin keeps its own migration history table, so rolling back one plugin never touches another. The migrations are listed in [lagoon](../../modules/lagoon/README.md).
## Pending uploads and related records
An admin form holds the files uploaded and the related records created for a record that is not saved yet as deferred bindings. Saving the record commits them; abandoned ones are removed by `deferred:purge`:
| Command | Flags | Purpose |
|---------|-------|---------|
| `deferred:purge` | `--days <n>` | Deletes deferred bindings older than `n` days, the unattached uploads they hold and the records created under deferral, and prints the counts. Records that were only linked are kept. Without the flag, `database.deferred_bindings.purge_days` applies, else 5 days. |
```sh
./bin/acme deferred:purge
./bin/acme deferred:purge --days=1
```
The scheduler already runs it every day at 03:00; see [Task scheduling](../plugins/scheduling.md#the-frameworks-own-schedule).
## Application key
| Command | Flags | Purpose |

View File

@@ -66,6 +66,18 @@ Each run is a job on the `scheduled` queue with a single attempt: an interrupted
The worker runs in `serve` by default. When you run workers separately (`queue.work_in_serve` set to `false`), `./bin/acme queue:work` carries the schedule too.
## The framework's own schedule
The framework schedules one command of its own: `deferred:purge`, which deletes the uploads and related records that admin forms left pending more than five days ago. It runs daily at 03:00 in `app.timezone`, with the ID `summercms.lagoon[0]:deferred:purge`, listed before the plugin entries. Set `database.deferred_bindings.purge_at` to another `HH:MM` time to move it, or to an empty string to remove it, for example when system cron runs `deferred:purge` instead:
```yaml
database:
deferred_bindings:
purge_at: "04:30"
```
A value that is not `HH:MM` fails the worker start with an error naming the key.
## Running the scheduler on its own
To run only the scheduler in its own process, use `schedule:run`. It starts a worker on the `scheduled` queue and runs until it receives SIGINT or SIGTERM: