Events are {resource}.created, .updated, .deleted and .restored for content,
the inbox, redirects, repositories and media, taken from the audit log so the
two agree on what happened. Subscriptions take wildcards. Users, tokens,
webhooks and settings are never sent, nor what the application does by
itself; the inbox's own words only with personal data enabled.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Create one and see its secret once, send a test, change the secret, and read
each delivery with what the other end answered.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tags are named in every language and made from the page form; the byline is
the member who signs a post on the site. The public API sends both, filters
posts by tag and lists the tags in use.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each field's original sits beside the field to write, and a translation that
fell behind shows what the original said when it was translated and what it
says now, word by word.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A reply starts from a template filled in the language the person wrote in,
is sent by the application when it has a mailer that delivers or handed to
the replier's mail program otherwise, and is recorded on the submission.
The same is available through the API.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The copy keeps the content, stack and team, but is unpublished, out of any
review, and gets a title marked as a copy and a free slug. It replaces
Filament's replicate action, which left the copy without a slug and still
published. The same copy is available through the API.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Media::referencedPaths() is what `content:prune --media` asks before
deleting a file, and it did not know about two kinds of image a page
shows:
- A technology's logo. Every logo on the radar looked orphaned, and one
prune would have deleted all of them.
- Images inside rich text — a page's body, a project's description,
decisions and postmortem — whether attached in the panel's editor or
uploaded through the API and written in as <img src>. They are now
found in the HTML, in every language, bin included.
The page body's editor also states where attachments go — the media
disk, pages/content, public — instead of relying on Filament's
defaults: the HTML reaches the frontend as it is, and a private file
would be a broken image there.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saving a page with a category failed with "El campo categoría no está
en la lista de valores permitidos" — for every category, not only the
one being tried. Filament builds such a list through a query, which
handles `->relationship('category', 'name->es')`, but validates a choice
by reading the title back off the record as a property,
`$record->{'name->es'}`, which does not exist. No label, so every
option was refused.
The same pattern was in seven more places: a call's, a testimonial's,
a talk's and a repository's project, a testimonial's service, and the
page and application filters. TranslatedOptionLabel gives Filament the
record's own translation instead, in the language of whoever uses the
panel; the JSON path stays for search and ordering.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer
collective, backed by the Pireon OAuth identity server. The public site is a
separate, server-rendered application consuming /api/public/v1.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>