8000 refactor: codebase cleanup (indexes, helper extraction, misc) by mwoods79 · Pull Request #112 · huddlz-hq/huddlz · GitHub
[go: up one dir, main page]

Skip to content

refactor: codebase cleanup (indexes, helper extraction, misc) - #112

Merged
mwoods79 merged 7 commits into
mainfrom
refactor/codebase-cleanup
Apr 21, 2026
Merged

mwoods79 merged 7 commits into
mainfrom
refactor/codebase-cleanup

Conversation

@mwoods79
Copy link
Copy Markdown
Contributor

Summary

Seven atomic commits addressing findings from a codebase audit. Each commit keeps mix precommit green (616 tests, credo --strict clean) and was spot-verified against the live dev DB via tidewave.

Commits

  1. perf(db): add indexes on user_id / owner_id foreign keys — three missing btree indexes on group_members(user_id), huddl_attendees(user_id), groups(owner_id). Existing composite unique indexes couldn't serve user-only lookups (wrong leading column) and groups.owner_id had none. Declared via custom_indexes on the Ash resources.
  2. refactor(geocoding): flatten nested if in geocode_if_changed — nested if/else → single cond.
  3. refactor(geocoding): consolidate duplicate GeocodeLocation changes — two near-identical modules replaced by one parameterized {Huddlz.Geocoding.GeocodeChange, field: :x}.
  4. refactor(components): extract humanize/1 helper — five copies of value |> to_string |> String.replace("_", " ") |> String.capitalize collapsed into a shared helper. huddl_live.humanize_filter/1 left alone (title-cases each word, different semantics).
  5. refactor(group_live): rename authorize?: false helpers to _unchecked — member?/organizer?/get_member_count → member_unchecked?/organizer_unchecked?/member_count_unchecked so policy bypass is visible at every call site.
  6. refactor(live): extract shared modal location state helpers — ~66 lines removed across 5 LiveViews (huddl new/edit, group new/edit/locations). New HuddlzWeb.Live.Helpers.ModalLocationHelpers with init/1, clear/1, apply_selected/2.
  7. refactor(live): extract image upload pipeline — ~57 lines removed across 4 LiveViews. New HuddlzWeb.Live.Helpers.ImageUploadPipeline takes a config map + create-pending / soft-delete lambdas.

Net: 468 deletions, 876 insertions (most of which are the migration + three Ash snapshot JSON files and new helper modules).

Deferred — needs design input

Three audit findings were intentionally not shipped in this PR:

  • Image preview component — false positive. Huddl edit has 4 divergent branches (pending / current / inherited-group / placeholder, thin-card style); group edit has 2 branches (max-w-md style). Forcing one component would require many config props for very little shared markup.
  • Async image processing — real, but needs start_async/handle_async across 4 LiveViews and render_async in ~26 test sites, and is a UX contract change. Worth its own PR + product input.
  • Async geocoding via Oban — real, but changes lat/lng from "populated on create" to "eventually consistent." Downstream map / distance / policy consumers need audit before shipping.

Test plan

  • mix precommit — 616 tests, 0 failures, credo --strict clean
  • Migration applies cleanly (mix ecto.migrate)
  • Indexes verified present in live DB via pg_indexes
  • Both geocode change wirings present via Ash.Resource.Info.actions/1
  • humanize/1 produces identical output to the old pipeline for every enum value in use
  • ModalLocationHelpers.{init,clear,apply_selected} produce expected socket assigns
  • Smoke-test image upload + modal location picker in the browser before merge

Add standalone btree indexes on group_members(user_id),
huddl_attendees(user_id), and groups(owner_id). Existing composite
unique indexes can't serve user-only lookups since user_id is the
trailing column, and there was no index at all on groups.owner_id.

Declared via custom_indexes on the Ash resources so the migration
generator and snapshots stay in sync.
Replace nested if/else with a single cond for readability. Behavior
preserved: provided coordinates short-circuit, unchanged attribute is
a passthrough, otherwise geocode and apply.
Replace Group.Changes.GeocodeLocation and Huddl.Changes.GeocodeLocation
with a single parameterized Huddlz.Geocoding.GeocodeChange that takes
the attribute via a `field:` option. Move the associated test alongside
the new module.
Replace five copies of `value |> to_string |> String.replace("_", " ")
|> String.capitalize()` with a shared `humanize/1` in CoreComponents.
Left huddl_live.humanize_filter/1 untouched — it title-cases each word
and has different semantics.
Rename member?/organizer?/get_member_count on group_live/show.ex to
member_unchecked?/organizer_unchecked?/member_count_unchecked so the
policy bypass is visible at every call site. Also drop stale "removed
unused functions" comment.
Five LiveViews (huddl new/edit, group new/edit/locations) each rolled
their own init/clear/apply logic for the "Select a location" modal
assigns. Extract into HuddlzWeb.Live.Helpers.ModalLocationHelpers with
init/1, clear/1, and apply_selected/2. Drops ~66 lines of near-identical
code and makes future tweaks to the modal's state a single-file change.
Four LiveViews each defined their own process_eager_upload /
store_and_create_pending_image / apply_upload_result /
cleanup_pending_image, differing only in storage module, resource, and
whether a group_id was required. Extract into
HuddlzWeb.Live.Helpers.ImageUploadPipeline that takes a config map and
two callback lambdas for create-pending and soft-delete, then wire the
four LiveViews to the shared pipeline.
@mwoods79
mwoods79 merged commit 25c9917 into main Apr 21, 2026
1 check passed
@mwoods79
mwoods79 deleted the refactor/codebase-cleanup branch April 21, 2026 19:05
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

0