Operations
Idempotency and Automations
Mutation replay safety and post-submission automation execution.
Idempotency
Management mutations support Idempotency-Key.
- same key + same payload => replay previous response
- same key + different payload =>
409 Conflict
Config:
formforge.http.idempotency.ttl_minutes
Submission automations
Automations execute after submission persistence.
Registration APIs:
Form::automation('form-key')->sync()->handler(...)Form::automation('form-key')->queue(...)->handler(...)Form::automationForResolver(ResolverClass::class)->...
Contracts:
SubmissionAutomationSubmissionAutomationResolver
Runs are tracked in formforge_submission_automation_runs and execution is idempotent per submission plus automation key.
Add metadata from an automation
EvanSchleret\FormForge\Models\FormSubmission provides a helper to update submission.meta and persist immediately:
meta(string|array $key, mixed $value = null): self
Supported usages:
$submission->meta('team_request_id', (int) $id);
$submission->meta([
'team_request_id' => (int) $id,
'source' => 'automation',
]);
Complete automation example
<?php
declare(strict_types=1);
namespace App\FormForge\Automations;
use App\Models\TeamRequest;
use EvanSchleret\FormForge\Automations\Contracts\SubmissionAutomation;
use EvanSchleret\FormForge\Models\FormSubmission;
final class CreateTeamRequestFromSubmission implements SubmissionAutomation
{
public function handle(FormSubmission $submission): void
{
$request = TeamRequest::query()->create([
'email' => (string) ($submission->payload['email'] ?? ''),
'team_name' => (string) ($submission->payload['team_name'] ?? ''),
'status' => 'pending',
]);
$submission->meta([
'team_request_id' => (int) $request->getKey(),
'source' => 'automation',
]);
}
}
Expose team_request_id in submit HTTP response
Use a custom submission resource and map the meta value explicitly:
<?php
declare(strict_types=1);
namespace App\Http\Resources\FormForge;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
final class SubmissionResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'uuid' => (string) $this->uuid,
'form_key' => (string) $this->form_key,
'payload' => $this->payload,
'team_request_id' => $this->meta['team_request_id'] ?? null,
'created_at' => $this->created_at?->toISOString(),
];
}
}
'http' => [
'resources' => [
'submission' => \App\Http\Resources\FormForge\SubmissionResource::class,
],
],
Important note on queue vs sync
If the automation runs in queue mode, meta updates may not be available immediately in the submit HTTP response.
Use ->sync() when the value must be present right away.
Best practices
- Use stable meta keys (for example
team_request_id). - Prefer scalar or small array values for predictable serialization.
- Do not store sensitive data in
meta.