Skip to content

WiP: Add persons as own entity - #922

Open
saerdnaer wants to merge 7 commits into
mainfrom
feat/persons
Open

WiP: Add persons as own entity#922
saerdnaer wants to merge 7 commits into
mainfrom
feat/persons

Conversation

@saerdnaer

Copy link
Copy Markdown
Member

No description provided.

Introduces a first-class Person entity to replace ad-hoc speaker name strings:

- Person model with name, public_name, email, avatar_url; find_or_create_by_name / from_names helpers for import
- Participation join model (event ↔ person) with role enum (speaker/moderator/author/contributor/producer) and ordered scope
- PersonIdentifier model for external GUIDs with source-scoped uniqueness (supports schedule2 / hub import)
- Person#merge_into! moves identifiers and participations to target, skipping duplicates, then destroys self
- ActiveAdmin UI for Person and PersonIdentifier with merge action
- REST API endpoint (GET/POST/PATCH/DELETE /api/people.json)
- Three migrations: create_people, create_participations, create_person_identifiers

Assisted-by: Claude Sonnet 4.6
Link is a polymorphic association (linkable) covering Person and Event targets.
Type subsets mirror hub model (core/models/links.py) and schedule2 Reference schema.
Three-phase enrichment: sync pattern match, async WebFinger, async OpenGraph.

Person API now accepts nested links_attributes and renders links in JSON response.
Admin registration added (menu: hidden, used as nested resource only).

Assisted-by: Claude Sonnet 4.6 <https://claude.ai>
Phase 1 (sync, before_validation): URL pattern matching fills link_type and
service for known hosts (GitHub, GitLab, Codeberg/Forgejo, Bluesky, Instagram,
Threads, Twitter, media.ccc.de).

Phase 2 (async, LinkEnrichWorker): WebFinger lookup via the `webfinger` gem for
Fediverse profile URLs (/@user, /users/user, /accounts/user). Distinguishes
Mastodon from PeerTube by inspecting the ActivityPub self-link href. Approach
follows Podlove Publisher #1195 multi-stage pattern.

Phase 3 (async, LinkMetadataWorker): OpenGraph fetch via `metainspector` with
download_limit: 262_144 — aborts after 256KB, covering <head> without relying
on server-side Range support. Maps og:type prefix to link_type (video.* →
MEDIA, article/book → ARTICLE, etc.), fills name from og:title / <title>.

Gems added: webfinger (~> 2.0), metainspector (~> 5.17)

Assisted-by: Claude Sonnet 4.6 <https://claude.ai>
Add a multi-format schedule download flow: ScheduleProbe detects available
schedule1/schedule2 JSON and XML endpoints; a dialog lets the operator pick
the format before triggering the download worker.

ScheduleImportPreview diffs current DB state against the fetched schedule so
admins can review new/changed events before committing. PersonImportWorker
imports speaker records and participations from the schedule on demand.

Introduce Schedule1JsonParser and Schedule2JsonParser to normalise both JSON
schema variants into a common event_info_by_guid interface. FahrplanUpdater
delegates to conference.schedule_parser instead of hard-wiring FahrplanParser.

New admin actions: schedule_probe, schedule_status (polling badge), schedule_import_preview,
schedule_import_apply. schedule_status badge auto-reloads on transition to
"downloaded".

Assisted-by: Claude Sonnet 4.6 <https://claude.ai>
old frab inline schedule.xml/json only carries id + public_name per speaker, unlike modern pretalx/hub version, which embeds full bio/avatar/url. Probe for a sibling speakers.json next to schedule1 URLs, offer it in the import dialog, and merge it into parsed persons (full name, image, description, profile url) keyed by speaker id.
Add reorderable Participation model with admin, wire nested participations
form into Event admin, and switch Person/Link/PersonIdentifier ordering to
acts_as_list instead of manual :order inputs. Person admin now supports
inline identifier/link creation, uuid display, and guid-based lookup via
Person.find_by_param!. Add ransackable_attributes/associations to
PersonIdentifier for the guid filter, fix Sidekiq::Workers API usage in the
dashboard, add Conference#schedule_importing? to check job state live via
Sidekiq, and add the events.schedule jsonb column migration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant