ghostguild-org/scripts
Jennie Robinson Faber aa6a176fb9 feat(migration): convert annual contributionAmount to cadence-unit
One-time script to convert existing annual Member records from the legacy
monthly-equivalent interpretation to cadence-unit. Multiplies
contributionAmount by 12 for billingCadence='annual' members.

Companion to commit 5023fb1 which dropped the server's ×12 on annual
recurringAmount. Must run after deploy, before annual members renew.

Idempotent via a transient `contributionAmountConverted: true` marker
field on each migrated doc — re-runs are safe. Dry-run by default;
`--apply` to write. Skips null/undefined contributionAmount, logs $0
amounts as no-ops.
2026-05-23 15:54:51 +01:00
..
add-coop-values-series.js Add landing page 2025-11-03 11:17:51 +00:00
add-cooperative-values-events.js Many an update! 2025-12-01 15:26:42 +00:00
add-module-events-to-atlas.js Many an update! 2025-12-01 15:26:42 +00:00
add-to-remote-db.js Add landing page 2025-11-03 11:17:51 +00:00
check-events.js Add landing page 2025-11-03 11:17:51 +00:00
check-old-event.js Add landing page 2025-11-03 11:17:51 +00:00
check-series.js Add landing page 2025-11-03 11:17:51 +00:00
cleanup-old-event.js Add landing page 2025-11-03 11:17:51 +00:00
create-admin-and-invite.cjs Update project config and documentation, add admin invite script, 2026-05-19 13:26:05 +01:00
create-correct-series.js Add landing page 2025-11-03 11:17:51 +00:00
debug-series.js Add landing page 2025-11-03 11:17:51 +00:00
diagnose-query.js Add landing page 2025-11-03 11:17:51 +00:00
fix-avatars.js Adding features 2025-10-05 16:15:09 +01:00
fix-series-id.js Add landing page 2025-11-03 11:17:51 +00:00
helcim-plan-consolidation.js chore(scripts): rename contributionTier → contributionAmount in seed + legacy migration 2026-04-19 19:10:37 +01:00
list-all-series-events.js Add landing page 2025-11-03 11:17:51 +00:00
merge-series.js Add landing page 2025-11-03 11:17:51 +00:00
migrate-annual-contribution-to-cadence-unit.cjs feat(migration): convert annual contributionAmount to cadence-unit 2026-05-23 15:54:51 +01:00
migrate-contribution-amount.cjs feat(scripts): add migrate-contribution-amount 2026-04-19 18:31:49 +01:00
migrate-ecology-to-board.cjs feat: update tests + seed script, add ecology→board migration 2026-04-14 12:20:46 +01:00
migrate-event-slugs.js UX/UI improvements. 2026-04-05 13:26:51 +01:00
mint-invite-link.cjs feat(signup): unify cadence UX across accept-invite, join, and account 2026-04-20 12:34:59 +01:00
README.md feat(scripts): add migrate-contribution-amount 2026-04-19 18:31:49 +01:00
reconcile-helcim-payments.mjs feat(payments): add reconcile-helcim-payments script for backfill + ongoing sync 2026-04-20 13:21:56 +01:00
reset-invite.cjs feat(signup): unify cadence UX across accept-invite, join, and account 2026-04-20 12:34:59 +01:00
seed-all.js Huge bunch of UI/UX improvements and tweaks! 2026-04-06 16:17:12 +01:00
seed-events.js refactor(events): expand eventType taxonomy with central config 2026-05-21 17:50:40 +01:00
seed-members.js test(seed): add pending_payment persona for wave-slack §7.3 2026-05-01 10:13:18 +01:00
seed-pre-registrants.js fix(ci): force-add seed-pre-registrants.js 2026-05-01 11:12:14 +01:00
seed-series-events.js refactor(events): expand eventType taxonomy with central config 2026-05-21 17:50:40 +01:00
seed-tags.js Accessibility fixes. 2026-04-05 19:27:25 +01:00
seed-welcome-tester.cjs chore(scripts): rename contributionTier → contributionAmount in seed + legacy migration 2026-04-19 19:10:37 +01:00
setup-helcim-plans.js Adding features 2025-10-05 16:15:09 +01:00

scripts/

One-off admin and migration scripts. None of these run in CI.


helcim-plan-consolidation.js

Consolidates Helcim payment plans from the legacy per-tier model (multiple plans at $15/$30/$50) to two unified plans (Monthly Membership at $15, Annual Membership at $150), and backfills Mongo members.

Required env

HELCIM_API_TOKEN=<token>
MONGODB_URI=<mongodb connection string>

Copy .env.example.env if you haven't already.

Usage

# Dry-run (default) — no mutations, writes backup file
node scripts/helcim-plan-consolidation.js

# Execute all steps: delete subs, delete legacy plans, create new plans, update Mongo
node scripts/helcim-plan-consolidation.js --confirm

# Mongo cleanup only — skips all Helcim steps (use if Helcim steps already ran)
node scripts/helcim-plan-consolidation.js --mongo-only

What it does

  1. Backup — always written to .migration-backup-<timestamp>.json, even in dry-run. Contains all Helcim subscriptions, payment plans, and Mongo members with helcimSubscriptionId.
  2. Delete subscriptions — deletes all Helcim subscriptions (--confirm only).
  3. Delete legacy plans — deletes plan IDs 20162, 21596, 21597, 21598, plus any plan whose name matches the legacy pattern (e.g. "Ghost Guild - Member ($15)").
  4. Create Monthly Membership — $15/month. Idempotent: skipped if a plan named "Monthly Membership" already exists.
  5. Create Annual Membership — $150/year. Same idempotency. Uses billingPeriod: "yearly" (Helcim v2 convention); if Helcim returns 4xx, the script aborts and prints the full error so you can correct the field name.
  6. Mongo cleanupupdateMany with runValidators: false on all members with helcimSubscriptionId: sets contributionTier: '0' and billingCadence: 'monthly', unsets helcimSubscriptionId. Does not change status.

At the end, prints new plan IDs formatted for copy-paste into .env.

Recovery

If something goes wrong mid-run, the backup JSON contains the pre-migration state. You can use the backup to:

  • Identify which subscriptions existed before deletion.
  • Identify which plan IDs to recreate manually in Helcim.
  • Identify which members had helcimSubscriptionId before it was unset.

Backup files are gitignored (.migration-backup-*.json).


migrate-contribution-amount.cjs

One-time migration: converts Member.contributionTier (String enum) to Member.contributionAmount (Number). Idempotent — only touches documents that still have the legacy field.

Usage

node scripts/migrate-contribution-amount.cjs           # dry-run
node scripts/migrate-contribution-amount.cjs --apply   # write

What it does

Iterates members with contributionTier still set, parses each value as an integer (valid: "0", "5", "15", "30", "50"), and writes the converted value to contributionAmount. Unsets the old field. Skips any record that cannot be parsed.

Safe to re-run: only matches members where contributionTier still exists.