Skip to content

Audit and clean up unnecessary orgs #1266

@aaronskiba

Description

@aaronskiba

Description

Largely due to users being able to create new orgs via the plan.funder field, there is an excess of "junk" orgs in the database. To maintain a clean and safe dataset, we need a structured, auditable cleanup process that handles data reassignment and destruction.

Org Associations

Orgs have several associations to consider before deletion:

  • tracker
  • guidance_groups
  • plans (both org_id and funder_id columns)
  • templates
  • users
  • contributors
  • annotations
  • departments
  • identifiers

For safe cleanup, we consider orgs with minimal associations as candidates for reassignment or deletion.

Candidate Orgs for Cleanup

Some orgs in the database are already orphaned, while others can be made orphaned through safe data modifications. The following categories describe the current state and potential actions:

  • Existing orphan orgs – orgs with no associations in any has_one, has_many. or HABTM relationships. These are the ideal deletion candidates.

  • Orgs with only junk tracker data – orgs whose only association is an empty or invalid tracker (Tracker.where(code: "")). Removing these junk trackers would make these orgs orphaned, allowing safe deletion.

  • Unmanaged orgs with users – orgs that are unmanaged but have associated users; reassigning users and their plans to the default org converts these orgs into orphans for deletion.

  • "Junk" funders – orgs with flagged names, whose only association is funded plans (plan.funder_id)

  • Because plan.funder has been a simple textbox for quite a while, many "junk" names exist (e.g. '-', '123', 'Anonymous foundation'). A list of these "junk funders" names needs to be constructed.

  • Wherever plan.funder_id is currently a junk funder, we can

  • orgs whose only association is one or a few funded plans (plan.funder_id). Optionally reassigning or nullifying the funder_id converts these orgs into orphaned orgs. A team decision may be required to define the maximum number of funded plans eligible for deletion (e.g., 1–2 funded plans).

Cleanup Plan

Audit

  • Obtain a recent production database dump to record all orgs, users, and funded plans.
  • Ensures a complete record of affected data before any operations.

Reassignment

These steps modify or reassign data so that more orgs become safe to delete:

1. Delete junk trackers

  • Remove empty or invalid tracker records:
    • bundle exec rake orgs:delete_junk_trackers

2. Reassign unmanaged orgs with users

  • Reassign associated users and plans from unmanaged orgs to the default org.
  • Org deletion is not performed here:
    • bundle exec rake orgs:cleanup_unmanaged_orgs_with_users

3. Cleanup junk funders

  • Find orgs with "junk" names (e.g. '-', '123', 'Anonymous foundation') and whose only assocation is plan.funder_id
  • Set plan.funder_id to NULL for these orgs
  • Org deletion is not performed here; only reassignment.
    • bundle exec rake orgs:cleanup_junk_funders

Deletion

  • Remove all true orphan orgs (including those exposed or created by steps in Reassignment / Prep Work).
    • bundle exec rake orgs:delete_orphaned_orgs

Remaining Decisions / Next Steps

Maximum number of funded plans for junk funders

  • Define the threshold of funded plans an org can have and still be considered a “junk funder” eligible for reassignment or deletion.
  • Example: orgs with 1–2 funded plans and no other associations.

Handling of plan.funder_id for junk funders

Decide whether to:

  1. Reassign to the default org,
  2. Nullify the value, or
  3. Apply another policy that preserves historical context.

Audit verification

Ensure all changes are captured in the production DB dump before running tasks.
Optionally verify with CSV outputs or dry-run flags to confirm which orgs and plans will be affected.

Execution order and dependency

Confirm that the cleanup steps (Delete junk trackers → Reassign unmanaged orgs → Cleanup junk funders → Delete orphaned orgs) are performed sequentially.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions