Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Feature: Person activity timeline (/people/:id/timeline)

Aperta
#2,189 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
3-5 giorni
Idoneità per principianti
35/100
Tipo di issue
Funzionalità
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
ruby

Direzione di ricerca

Inizia con il PersonCommentAggregator esistente, app/presenters/activity_presenter.rb, admin/ahoy_activities_controller.rb:292 e i percorsi delle viste della timeline delle persone descritti nell’issue. Esegui o aggiungi le spec di service, presenter, request e system che coprano l’unione degli stream, la paginazione tramite cursore, l’attribuzione, i filtri e il rendering del sentinel. Il lavoro è completo quando la timeline intercalata viene paginata senza duplicati e applica l’ambito e il comportamento di accesso indicati.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

enhancement

Context

Build a per-person activity timeline at /people/:id/timeline — one chronological
feed of everything that happened to/around a person: profile updates, scholarship
awarded, registration created, payment applied, membership renewed, account logins,
tagging changes, plus the person's internal comments and communications.

This evolves an in-progress /people/:id/communications page (which interleaves a
person's comments + communications/notifications) — that work is renamed to
timeline
and broadened into a full activity feed.

Feasible because change history already exists: AhoyTrackable is mixed into
ApplicationRecord, so every model auto-writes create.*/update.*/destroy.* rows
to ahoy_events with before/after diffs in properties["changes"], plus auth.*
account events on User. PaperTrail additionally covers financial models. So the work
is mostly assembly of existing data + presentation.

Scope decisions (confirmed)

  1. Sources: everything — all lifecycle events (incl. profile edits, tagging,
    subscriptions) + comments + communications.
  2. Rows: mixed — comments stay editable-in-place, communications stay rich
    cards, and ahoy changes render as lightweight event rows (icon + label + diff).
  3. Filter: category chips (All / Changes / Comments / Communications) + a
    subject/content keyword search.
  4. Authorship rule: credit records by author_id, falling back to created_by_id
    only when the model has no author_id — so an admin isn't credited for records that
    have a real author. (Mirrors the existing PersonCommentAggregator story logic.)
  5. Imports/jobs creates must be included (console edits may be ignored).
  6. Infinite scroll — must not load all of a person's records/events per request.

Event sourcing (two change streams)

  • "Created" rows derive from each record's own created_at, NOT ahoy — ahoy
    create.* only fires for logged-in web actions, so imports/jobs/console creates would
    be missed. Every row has created_at regardless of origin → complete create coverage.
    Ahoy create.* events are therefore excluded to avoid double-counting.
  • "Updated"/"deleted" rows come from ahoy_events (update.*/destroy.* +
    auth.*/taggings.*) — web-only. Console/job/import edits are out of scope
    (accepted).
  • PaperTrail versions intentionally not merged into the feed (avoid double rows /
    second code path); stays available for a future financial drill-down.
  • Limitation: update/delete rows only go back to when ahoy tracking was enabled; create
    rows go back as far as the records themselves.

Technical approach

Service PersonTimeline (evolves person_communication_feed.rb) — exposes
#page(before:, limit: 20) => { items:, next_cursor: }. k-way-merges four streams,
each queried keyset-style (WHERE <ts> < before ORDER BY <ts> DESC LIMIT limit),
merges the ≤limit-per-stream rows in Ruby, emits the top limit, derives next_cursor
from the last row:

  • Comments — PersonCommentAggregator#comments (reuse).
  • Communications — Notification.email(person.communications_email).
  • Creates — resolve the person's directly-associated records across ~20 source
    types (FK: registrations, scholarships, memberships + invoices, licenses,
    affiliations, form submissions, event staff, CE, payments; polymorphic: addresses,
    contact methods, tags, sectors, bookmarks, the person; authored/created content via
    the authorship rule) → one TimelineChange(action: :created, occurred_at: created_at, actor: author-or-created_by) each.
  • Updates/deletes — Ahoy::Event per {resource_type => ids} map (promoted
    columns), name REGEXP '^(update|destroy|auth|taggings)\.' → TimelineChange.
  • subject/content filters + before/limit pushed into each stream's SQL so the
    per-stream LIMIT stays honest. Category chip selects which streams run.

Presenter — reuse/extend app/presenters/activity_presenter.rb ("The ONE true
timeline") for ahoy rows; add label ("<Subject> <verb>", auth.* special-cased),
icon+theme (new per-model FA-glyph map keyed to DomainTheme colors), detail_lines
(from properties["changes"]), actor_name ("System / import" when nil), link.

Pagination — cursor/keyset infinite scroll (net-new; no existing pattern):
composite (occurred_at, key) cursor, mirroring the comparator at
admin/ahoy_activities_controller.rb:292. UI = a bottom sentinel turbo_frame_tag "timeline_after_<cursor>", loading: :lazy that fetches the next page (same frame id →
replaces itself with next rows + next sentinel, appending visually). Reuse
prefetch_lazy_controller.js (IntersectionObserver) to load ~500px early. Filter
change re-navigates the outer person_timeline_results frame → fresh first page.
will_paginate/tailwind_paginate are NOT used here (can't express a cursor).

Views: people/timeline.html.erb (shell: header, chips + keyword form, lazy
frame), people/person_timeline_results.html.erb (rows + sentinel), _timeline_feed
(branch on class: Comment → editable comment; Notification → comm card; TimelineChange
→ new _timeline_event_row).

Reuse: PersonCommentAggregator (id-resolution), users_controller#account_events_for

  • users/sections/_account_activity (ahoy diff rendering), ActivityPresenter,
    lib/domain_theme.rb, application_helper#section_icon_class, config/initializers/ahoy.rb.

Testing

  • Service spec: interleave order; keyset paging (before/next_cursor, no
    overlap, nil at end); no create.* ahoy dup; import create (nil actor) appears;
    authorship rule (story authored by someone else but created_by this user → excluded;
    author-nil + created_by-this-user → included); category/subject/content filters;
    unrelated person excluded.
  • Presenter spec: label/icon/detail_lines/actor_name for created/updated/destroyed
    • auth.* rows.
  • Request spec: shell renders chips + frame; first page returns interleaved rows +
    sentinel; sentinel before= URL returns next page w/ no dup; last page omits
    sentinel; filters; non-admin → root; ahoy view-tracking on full page only.
  • Light system spec: scroll appends later rows.

Rough effort

~4–5 focused days. Widest surface: create-derivation across ~20 source types with the
authorship scoping. Main correctness risks: the authorship rule, cursor tie/de-dup at
page boundaries, and per-stream filter-in-SQL keeping LIMIT honest.


🤖 From Claude: drafted from a planning session; scope decisions above were confirmed with the requester.

Lingua principale
Ruby
Stelle
15
Fork
28
Merge medio
1g 12m
PR unite (30g)
262

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di rubyforgood/awbw

Tutte le issue di rubyforgood/awbw

Issue simili

Altre issue su Ruby

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.