Skip to content

In-file cleanup: media, events, certificates, chat (backend campaign 8) - #97

Closed
theobong wants to merge 4 commits into
chore/backend-campaign-07-inplace-b01-b03from
chore/backend-campaign-08-inplace-b04-b06
Closed

theobong wants to merge 4 commits into
chore/backend-campaign-07-inplace-b01-b03from
chore/backend-campaign-08-inplace-b04-b06

Conversation

@theobong

Copy link
Copy Markdown
Member

What changed

A behavior-neutral cleanup inside the files of three areas: the media worker, media intake and reports; events, certificates, guest RSVPs and volunteer hours; chat, direct messages and the websocket gateway. Large functions are split into named helpers, repeated code is shared, magic numbers and strings are named, and dead code and needless exports are removed. Nothing a user sees should change.

Before you start

  • Where: staging (civfix.dev, the staging mobile build) after this merges to main
  • Sign in as: two of your own accounts, A (host) and B (attendee), with emailed codes; a second browser profile for the chat steps
  • Data: an event A hosts that has ended with B checked in, for the hours steps
  • Stacked on In-file cleanup: settings, adapters, auth, db scripts (backend campaign 7) #96 (in-file cleanup 7), which is stacked on Comment, em dash and emoji sweep (backend campaign 6) #95. Read only this PR's diff against that branch.
  • Size: 10696 counted lines. Campaign PR; the author approved PRs over the 400-line cap for this cleanup.
  • Reading order: one commit per area (media; events and certificates; chat).

Verify

Nothing new to verify: every step below is a regression check.

Regression

Filing a photo report — [Web] [Mobile]

  1. As A click "Report", add a photo ("Choose from library", or the camera on mobile), place the pin, pick a category, type a title and click "Drop pin" — Expect: "Pin dropped. We're on it."
  2. Click "View my report" — Expect: "Photos are still processing..." at first
  3. Wait about 30 seconds and reopen the report — Expect: the photo shows; it does not stay on processing or "Under review"

Creating, editing, duplicating and cancelling an event — [Web] [Mobile]

  1. As A open your profile, "Event dashboard", then "Create"; fill the title, a future date and time, the meeting point and one slot with "Next"; optionally "Add a cover"; click "Publish event" — Expect: the event page shows "You're hosting"
  2. Open "Host dashboard", edit the title and click "Save changes" — Expect: the new title shows
  3. On "Event dashboard" open the event's actions, choose duplicate, pick a future time and click "Create copy" — Expect: "Copy created" and a second event
  4. On the copy click "Cancel event", give a reason and confirm with "Cancel event" — Expect: "Cancelled by the host"

Joining an event and claiming a slot — [Web] [Mobile]

  1. As B open A's event and click "Sign up" on a slot — Expect: the slot shows "Signed up"
  2. Click "Message crew" — Expect: the crew chat opens
  3. Go back and click "Leave event" — Expect: "You left the event" and the slot is free again

Guest RSVP — [Web]

  1. Signed out, open an upcoming slot event and click "Sign up", then "Continue as guest"
  2. Fill your name and email (text message is likely not offered on staging) and click "Send code" — Expect: a 6-digit code arrives
  3. Enter it and click "Confirm RSVP" — Expect: "You're on the list" and a confirmation with a cancel link

Volunteer hours and the transcript PDF — [Web] [Mobile]

  1. As A open the ended event, "Host dashboard", then "Log volunteer hours"; type 2 in "Hours for everyone", apply it to all and click "Log hours" — Expect: "Logged hours for attendee" (or "attendees")
  2. As B open your profile, the "Hours" tab, then "Prepare transcript" — Expect: "Transcript ready" with a verification code
  3. Click "Open PDF" — Expect: the PDF opens with the hours total
  4. Open civfix.dev/service-record, paste the code and click "Verify" — Expect: "Verified"

Direct messages and crew chat — [Web] [Mobile]

  1. A: open B's profile, click "Message", send a message — Expect: B sees it live
  2. A: open the message's actions, choose "Edit", change it and send — Expect: both see "(edited)"
  3. A: open the actions again, choose delete and confirm "Delete message" — Expect: both see "Message removed"
  4. B: react to one of A's messages with a like — Expect: a like chip appears for both
  5. B: open the event, "Message crew", send a message — Expect: A sees it live in the event's group chat

Findings addressed

Campaign PRs 7 to 10: the LOCAL DUP, READ and DEAD ledger findings for chunks B04 to B06, plus local magic values, large-function splits and un-exports.

  • B04: BE-DEAD-062, 063 (partly), 064, 068; BE-DUP-101, 102, 103; BE-READ-070, 071, 072, 073, 075.
  • B05: BE-DEAD-025, 028; BE-DUP-027, 029; BE-READ-022, 023, 024, 025, 026, 027, 029.
  • B06: BE-DEAD-071, 072, 073 (partly), 074, 076 (call sites), 077 (partly), 079; BE-DUP-111 (partly), 112, 113, 114, 116; BE-READ-076, 077, 078, 079, 080, 081, 083.

Largest splits: the media job core (processAsset) into phases that each build their retryable infrastructure error at the same point, so only that error can leave the job; the event service (updateCleanup, createEvent, requestResources) and its notifications, slots and address helpers into three new modules; the certificate PDF renderer (about 490 lines) into draw helpers with byte-identical output for eight sample inputs; the chat gateway wiring (388 lines), the websocket send handler and the socket lifecycle into named builders with the same order of side effects.

Decisions for the reviewer

  • Behavior-neutral. An adversarial review compared every changed file before and after; the only differences it found are listed here.
  • Duplicating an event now builds the copy after reading the slots. Only an unparseable start time could notice (one extra read before the same error), and the request schema rejects that first.
  • Chat client ids: the handler's own 64-character check is removed because the shared contract already enforces it before any frame is handled. The contract is now the only bound on the send-dedupe key length.
  • SQL whitespace: two merged statements in the anon hold release and report repositories send different whitespace; the text is identical once whitespace is normalized.
  • Kept and not fixed here (pre-existing): an event requested by an uppercase id gets empty linked reports and slots after edit, cancel, complete or slot claim, because the loader is keyed by the lowercase id. It is logged as a correctness follow-up with its own test.
  • Kept although only tests use them: the chat partition helpers, the H3 cap exemption, the no-GPS check, the media job runner export, the chat thread and unread helpers, the presigner parameter and the memory hides repository. Removing them needs test changes.
  • Types that appear in an exported function or type stay exported (DECISIONS-PENDING D-151).

User-visible copy changes

None.

Tests changed

None. No test file was edited.

Verification

  • Every commit typechecks on its own (api and media worker).
  • At this branch: pnpm lint, prettier check, check:sql clean; api unit suite by explicit path 428 files, 7116 passed, 3 skipped; media-worker unit 300 passed, 2 failed (the known arm64 ffprobe helper issue fixed in Backend test safety net: SQL transcripts, CSRF pairing, authz and characterization tests #92).
  • The offline SQL transcripts of all repository cases are identical to the parent branch.
  • The certificate PDF hashes match before and after for eight inputs (three locales, 0 to 1005 rows, truncation and CJK).
  • CI runs only on PRs based on main, so it starts here when the PRs below merge and GitHub retargets this one to main.

Staging checks

  • https://api.civfix.dev/readyz answers ready after the deploy (no migration in this PR).
  • A photo report publishes (the media worker runs the split job core).

Not covered

  • Guest RSVP by text message: SMS is off on staging, so only the email path is testable.
  • Video uploads are not in the steps; the video path is covered by the media-worker unit tests.

🤖 Generated with Claude Code

@byteful
byteful added this pull request to stack #122 September 24, 2026 17:53
@byteful byteful closed this Sep 24, 2026
@byteful
byteful deleted the chore/backend-campaign-08-inplace-b04-b06 branch September 24, 2026 20:13
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.

2 participants