Przeglądaj źródła

[web] rm unnecessary scripts (#31631)

GitOrigin-RevId: c6388685bd9cd43d8d22e38f25db4ee579def808
Kristina 5 miesięcy temu
rodzic
commit
8872d851ec

+ 0 - 255
services/web/scripts/stripe/add_user_id_to_stripe_customer.mjs

@@ -1,255 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * This script iterates through all Stripe subscriptions, checks if they have metadata adminUserId,
- * and sets it to customer metadata "userId" if present.
- *
- * Usage:
- *   node scripts/stripe/add_user_id_to_stripe_customer.mjs --region=us [options]
- *   node scripts/stripe/add_user_id_to_stripe_customer.mjs --region=uk [options]
- *
- * Options:
- *   --region=us|uk     Required. Stripe region to process (us or uk)
- *   --commit           Actually perform the updates (default: dry-run mode)
- *   --verbose          Enable verbose logging
- *   --limit=N          Limit processing to N subscriptions (for testing)
- *
- * Examples:
- *   # Dry run for US region with verbose output
- *   node scripts/stripe/add_user_id_to_stripe_customer.mjs --region=us --verbose
- *
- *   # Commit changes for UK region
- *   node scripts/stripe/add_user_id_to_stripe_customer.mjs --region=uk --commit
- *
- *   # Test with limited subscriptions
- *   node scripts/stripe/add_user_id_to_stripe_customer.mjs --region=us --limit=10 --verbose
- */
-
-import minimist from 'minimist'
-import { z } from '../../app/src/infrastructure/Validation.mjs'
-import { scriptRunner } from '../lib/ScriptRunner.mjs'
-import {
-  getRegionClient,
-  CUSTOMER_SEGMENT_MAPPING,
-} from '../../modules/subscriptions/app/src/StripeClient.mjs'
-
-const paramsSchema = z.object({
-  region: z.enum(['us', 'uk']),
-  commit: z.boolean().default(false),
-  verbose: z.boolean().default(false),
-  limit: z.number().int().min(1).optional(),
-})
-
-let processedCount = 0
-let updatedCount = 0
-let errorCount = 0
-
-/**
- * Sleep function to respect Stripe rate limits (100 requests per second)
- * We'll be conservative and sleep for 50ms between requests to stay well under the limit
- */
-async function rateLimitSleep() {
-  return new Promise(resolve => setTimeout(resolve, 50))
-}
-
-/**
- * Process a single subscription and update customer metadata if needed
- */
-async function processSubscription(
-  subscription,
-  stripeClient,
-  commit,
-  verbose
-) {
-  try {
-    processedCount++
-
-    // Check if subscription has adminUserId metadata
-    const adminUserId = subscription.metadata?.adminUserId
-
-    if (verbose) {
-      console.info(
-        `Processing subscription ${subscription.id} (customer: ${subscription.customer.id}) - adminUserId: ${adminUserId || 'none'}`
-      )
-    }
-
-    if (!adminUserId) {
-      // No adminUserId to migrate
-      return
-    }
-
-    // Get customer details to check current metadata
-    const customer = subscription.customer
-    if (customer.deleted) {
-      if (verbose) {
-        console.info(`Customer ${customer.id} is deleted, skipping`)
-      }
-      return
-    }
-
-    if (customer.metadata?.userId === adminUserId) {
-      if (verbose) {
-        console.info(
-          `Customer ${customer.id} already has userId=${adminUserId}, skipping`
-        )
-      }
-      return
-    }
-
-    if (customer.metadata?.userId && customer.metadata.userId !== adminUserId) {
-      console.warn(
-        `Customer ${customer.id} has existing userId=${customer.metadata.userId} which differs from adminUserId=${adminUserId}, skipping to avoid overwrite`
-      )
-      return
-    }
-
-    if (commit) {
-      // Update customer metadata using the StripeClient method
-      await stripeClient.updateCustomerMetadata(customer.id, {
-        ...customer.metadata,
-        userId: adminUserId,
-        segment: CUSTOMER_SEGMENT_MAPPING.B2C,
-      })
-
-      console.info(
-        `Updated customer ${customer.id} metadata: userId=${adminUserId}`
-      )
-    } else {
-      console.info(
-        `DRY RUN: Would update customer ${customer.id} metadata: userId=${adminUserId}`
-      )
-    }
-
-    updatedCount++
-  } catch (error) {
-    errorCount++
-    console.log(error)
-  }
-
-  // Respect rate limits
-  await rateLimitSleep()
-}
-
-/**
- * Main script function
- */
-async function main(trackProgress) {
-  const parseResult = paramsSchema.safeParse(
-    minimist(process.argv.slice(2), {
-      boolean: ['commit', 'verbose'],
-      string: ['region'],
-      number: ['limit'],
-    })
-  )
-
-  if (!parseResult.success) {
-    throw new Error(`Invalid parameters: ${parseResult.error.message}`)
-  }
-
-  const { region, commit, verbose, limit } = parseResult.data
-
-  const mode = commit ? 'COMMIT MODE' : 'DRY RUN MODE'
-  await trackProgress(
-    `Starting script in ${mode} for Stripe ${region.toUpperCase()} region`
-  )
-
-  if (limit) {
-    await trackProgress(`Processing limited to ${limit} subscriptions`)
-  }
-
-  // Get Stripe client for the specified region
-  const stripeClient = getRegionClient(region)
-
-  // Reset counters
-  processedCount = 0
-  updatedCount = 0
-  errorCount = 0
-
-  await trackProgress('Starting to iterate through Stripe subscriptions...')
-
-  const listParams = {
-    limit: 100, // Stripe's maximum limit per request
-    expand: ['data.customer'], // Expand customer data to reduce additional API calls
-    status: 'all', // Include subscriptions in all statuses (active, past_due, unpaid, canceled, etc.)
-  }
-
-  let hasMore = true
-  let startingAfter = null
-  let totalProcessed = 0
-
-  while (hasMore) {
-    const params = { ...listParams }
-    if (startingAfter) {
-      params.starting_after = startingAfter
-    }
-
-    // Get batch of subscriptions
-    const subscriptions = await stripeClient.stripe.subscriptions.list(params)
-
-    await trackProgress(
-      `Retrieved ${subscriptions.data.length} subscriptions (total processed so far: ${totalProcessed})`
-    )
-
-    // Process each subscription in the batch
-    for (const subscription of subscriptions.data) {
-      await processSubscription(subscription, stripeClient, commit, verbose)
-
-      totalProcessed++
-
-      // Check if we've hit the limit
-      if (limit && totalProcessed >= limit) {
-        await trackProgress(`Reached limit of ${limit} subscriptions, stopping`)
-        hasMore = false
-        break
-      }
-
-      // Progress update every 50 subscriptions
-      if (totalProcessed % 50 === 0) {
-        await trackProgress(
-          `Progress: ${totalProcessed} processed, ${updatedCount} customers updated, ${errorCount} errors`
-        )
-      }
-    }
-
-    // Check if there are more subscriptions to process
-    hasMore = hasMore && subscriptions.has_more
-    if (hasMore && subscriptions.data.length > 0) {
-      startingAfter = subscriptions.data[subscriptions.data.length - 1].id
-    }
-
-    // Rate limit between batch requests
-    await rateLimitSleep()
-  }
-
-  // Final summary
-  await trackProgress('FINAL SUMMARY:')
-  await trackProgress(`   Total subscriptions processed: ${processedCount}`)
-  await trackProgress(
-    `   Customers ${commit ? 'updated' : 'would be updated'}: ${updatedCount}`
-  )
-  await trackProgress(`   Errors encountered: ${errorCount}`)
-
-  if (!commit && updatedCount > 0) {
-    await trackProgress('')
-    await trackProgress(
-      'To actually perform the updates, run the script with --commit flag'
-    )
-  }
-
-  if (errorCount > 0) {
-    await trackProgress(
-      'Some errors were encountered. Check the logs above for details.'
-    )
-  }
-
-  await trackProgress(`Script completed successfully in ${mode}`)
-}
-
-// Execute the script using the runner
-try {
-  await scriptRunner(main)
-  process.exit(0)
-} catch (error) {
-  console.error('Script failed:', error.message)
-  process.exit(1)
-}

+ 0 - 358
services/web/scripts/stripe/bulk-update-migration-status.mjs

@@ -1,358 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * This script validates subscriptions that are canceled or expired and have migration metadata set to "in_progress",
- * then updates the metadata to "cancelled" if validation passes.
- *
- * TODO: This script can be deleted after being run in production.
- *
- * Usage:
- *   node scripts/stripe/bulk-update-migration-status.mjs [OPTS] [INPUT-FILE]
- *
- * Options:
- *   --output PATH                 Output file path (default: /tmp/bulk_update_output_<timestamp>.csv)
- *                                 Use '-' to write to stdout
- *   --commit                      Apply changes (without this flag, runs in dry-run mode)
- *   --concurrency N               Number of subscriptions to process concurrently (default: 10)
- *   --stripe-rate-limit N         Requests per second for Stripe (default: 50)
- *   --stripe-api-retries N        Number of retries on Stripe 429s (default: 5)
- *   --stripe-retry-delay-ms N     Delay between Stripe retries in ms (default: 1000)
- *   --help                        Show a help message
- *
- * CSV Input Format:
- *   The CSV must have the following columns:
- *   - subscription_id: Stripe subscription id
- *   - target_stripe_account: Either 'stripe-uk' or 'stripe-us'
- *
- * Output:
- *   Writes a CSV with columns:
- *   - subscription_id: The subscription id processed
- *   - target_stripe_account: The Stripe account
- *   - status: Result status (validated, updated, invalid-status, invalid-metadata, or error)
- *   - note: Additional information about the status
- */
-
-import fs from 'node:fs'
-import path from 'node:path'
-import * as csv from 'csv'
-import minimist from 'minimist'
-import PQueue from 'p-queue'
-import { z } from '../../app/src/infrastructure/Validation.mjs'
-import { scriptRunner } from '../lib/ScriptRunner.mjs'
-import { getRegionClient } from '../../modules/subscriptions/app/src/StripeClient.mjs'
-import { ReportError } from './helpers.mjs'
-import {
-  createRateLimitedApiWrappers,
-  DEFAULT_STRIPE_RATE_LIMIT,
-  DEFAULT_STRIPE_API_RETRIES,
-  DEFAULT_STRIPE_RETRY_DELAY_MS,
-} from './RateLimiter.mjs'
-
-const DEFAULT_CONCURRENCY = 10
-
-// rate limiters - initialized in main()
-let rateLimiters
-
-function usage() {
-  console.error(`Usage: node scripts/stripe/bulk-update-migration-status.mjs [OPTS] [INPUT-FILE]
-
-Options:
-    --output PATH                 Output file path (default: /tmp/bulk_update_output_<timestamp>.csv)
-                                  Use '-' to write to stdout
-    --commit                      Apply changes (without this, runs in dry-run mode)
-    --concurrency N               Number of subscriptions to process concurrently (default: ${DEFAULT_CONCURRENCY})
-    --stripe-rate-limit N         Requests per second for Stripe (default: ${DEFAULT_STRIPE_RATE_LIMIT})
-    --stripe-api-retries N        Number of retries on Stripe 429s (default: ${DEFAULT_STRIPE_API_RETRIES})
-    --stripe-retry-delay-ms N     Delay between Stripe retries in ms (default: ${DEFAULT_STRIPE_RETRY_DELAY_MS})
-    --help                        Show this help message
-`)
-}
-
-async function main(trackProgress) {
-  const opts = parseArgs()
-  const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
-  const outputFile = opts.output ?? `/tmp/bulk_update_output_${timestamp}.csv`
-
-  // initialize rate limiters
-  rateLimiters = createRateLimitedApiWrappers({
-    stripeRateLimit: opts.stripeRateLimit,
-    stripeApiRetries: opts.stripeApiRetries,
-    stripeRetryDelayMs: opts.stripeRetryDelayMs,
-  })
-
-  await trackProgress(
-    'Starting bulk validation and update of subscription metadata'
-  )
-  await trackProgress(`Run mode: ${opts.commit ? 'COMMIT' : 'DRY RUN'}`)
-  await trackProgress(`Rate limit: Stripe ${opts.stripeRateLimit}/s`)
-  await trackProgress(`Concurrency: ${opts.concurrency}`)
-
-  const inputStream = opts.inputFile
-    ? fs.createReadStream(opts.inputFile)
-    : process.stdin
-  const csvReader = getCsvReader(inputStream)
-  const csvWriter = getCsvWriter(outputFile)
-
-  await trackProgress(`Output: ${outputFile === '-' ? 'stdout' : outputFile}`)
-
-  let processedCount = 0
-  let successCount = 0
-  let errorCount = 0
-
-  const queue = new PQueue({ concurrency: opts.concurrency })
-  const maxQueueSize = opts.concurrency
-
-  try {
-    for await (const input of csvReader) {
-      if (queue.size >= maxQueueSize) {
-        await queue.onSizeLessThan(maxQueueSize)
-      }
-
-      queue.add(async () => {
-        try {
-          const result = await processValidation(input, opts.commit)
-
-          csvWriter.write({
-            subscription_id: input.subscription_id,
-            target_stripe_account: input.target_stripe_account,
-            status: result.status,
-            note:
-              result.note ||
-              (opts.commit ? '' : 'dry run - no changes applied'),
-          })
-
-          if (result.status === 'updated' || result.status === 'validated') {
-            successCount++
-          } else {
-            errorCount++
-          }
-        } catch (err) {
-          errorCount++
-          if (err instanceof ReportError) {
-            csvWriter.write({
-              subscription_id: input.subscription_id,
-              target_stripe_account: input.target_stripe_account,
-              status: err.status,
-              note: err.message,
-            })
-          } else {
-            csvWriter.write({
-              subscription_id: input.subscription_id,
-              target_stripe_account: input.target_stripe_account,
-              status: 'error',
-              note: err.message,
-            })
-            await trackProgress(
-              `Error processing ${input.subscription_id}: ${err.message}`
-            )
-          }
-        }
-
-        processedCount++
-        if (processedCount % 10 === 0) {
-          await trackProgress(
-            `Processed ${processedCount} subscriptions (${successCount} ${opts.commit ? 'updated' : 'validated'}, ${errorCount} errors)`
-          )
-        }
-      })
-    }
-  } finally {
-    await queue.onIdle()
-  }
-
-  await trackProgress(`✅ Total processed: ${processedCount}`)
-  if (opts.commit) {
-    await trackProgress(`✅ Successfully updated: ${successCount}`)
-  } else {
-    await trackProgress(`✅ Successfully validated: ${successCount}`)
-    await trackProgress('ℹ️  DRY RUN: No changes were applied')
-  }
-  await trackProgress(`❌ Errors: ${errorCount}`)
-  await trackProgress('🎉 Script completed!')
-
-  csvWriter.end()
-}
-
-function parseArgs() {
-  const args = minimist(process.argv.slice(2), {
-    string: [
-      'output',
-      'concurrency',
-      'stripe-rate-limit',
-      'stripe-api-retries',
-      'stripe-retry-delay-ms',
-    ],
-    boolean: ['commit', 'help'],
-    default: {
-      commit: false,
-      concurrency: DEFAULT_CONCURRENCY,
-      'stripe-rate-limit': DEFAULT_STRIPE_RATE_LIMIT,
-      'stripe-api-retries': DEFAULT_STRIPE_API_RETRIES,
-      'stripe-retry-delay-ms': DEFAULT_STRIPE_RETRY_DELAY_MS,
-    },
-    unknown: arg => {
-      if (arg.startsWith('-')) {
-        console.error(`Unknown option: ${arg}`)
-        usage()
-        process.exit(1)
-      }
-      return true
-    },
-  })
-
-  if (args.help) {
-    usage()
-    process.exit(0)
-  }
-
-  const inputFile = args._[0]
-  const paramsSchema = z.object({
-    output: z.string().optional(),
-    commit: z.boolean(),
-    concurrency: z.number().int().positive(),
-    stripeRateLimit: z.number().positive(),
-    stripeApiRetries: z.number().int().nonnegative(),
-    stripeRetryDelayMs: z.number().int().nonnegative(),
-    inputFile: z.string().optional(),
-  })
-
-  try {
-    return paramsSchema.parse({
-      output: args.output,
-      commit: args.commit,
-      concurrency: Number(args.concurrency),
-      stripeRateLimit: Number(args['stripe-rate-limit']),
-      stripeApiRetries: Number(args['stripe-api-retries']),
-      stripeRetryDelayMs: Number(args['stripe-retry-delay-ms']),
-      inputFile,
-    })
-  } catch (err) {
-    console.error('Invalid arguments:', err.message)
-    usage()
-    process.exit(1)
-  }
-}
-
-function getCsvReader(inputStream) {
-  const parser = csv.parse({ columns: true })
-  inputStream.pipe(parser)
-  return parser
-}
-
-function getCsvWriter(outputFile) {
-  if (outputFile === '-') {
-    const writer = csv.stringify({
-      columns: ['subscription_id', 'target_stripe_account', 'status', 'note'],
-      header: true,
-    })
-    writer.on('error', err => {
-      console.error(err)
-      process.exit(1)
-    })
-    writer.pipe(process.stdout)
-    return writer
-  }
-
-  fs.mkdirSync(path.dirname(outputFile), { recursive: true })
-  const outputStream = fs.createWriteStream(outputFile)
-
-  const writer = csv.stringify({
-    columns: ['subscription_id', 'target_stripe_account', 'status', 'note'],
-    header: true,
-  })
-
-  writer.on('error', err => {
-    console.error(err)
-    process.exit(1)
-  })
-
-  writer.pipe(outputStream)
-  return writer
-}
-
-async function processValidation(input, commit) {
-  const {
-    subscription_id: subscriptionId,
-    target_stripe_account: targetStripeAccount,
-  } = input
-
-  // get Stripe client for the target account (strip 'stripe-' prefix if present)
-  const region = targetStripeAccount.replace(/^stripe-/, '')
-  const stripeClient = getRegionClient(region)
-
-  // fetch subscription
-  let subscription
-  try {
-    subscription = await rateLimiters.requestWithRetries(
-      stripeClient.serviceName,
-      () => stripeClient.stripe.subscriptions.retrieve(subscriptionId),
-      {
-        operation: 'subscriptions.retrieve',
-        subscriptionId,
-        region: stripeClient.serviceName,
-      }
-    )
-  } catch (err) {
-    throw new ReportError(
-      'subscription-not-found',
-      `Subscription not found: ${err.message}`
-    )
-  }
-
-  const validStatuses = ['canceled']
-  if (!validStatuses.includes(subscription.status)) {
-    throw new ReportError(
-      'invalid-status',
-      `Subscription status is ${subscription.status}, expected canceled`
-    )
-  }
-
-  if (
-    subscription.metadata?.recurly_to_stripe_migration_status !== 'in_progress'
-  ) {
-    throw new ReportError(
-      'invalid-metadata',
-      `Migration status is ${subscription.metadata?.recurly_to_stripe_migration_status}, expected in_progress`
-    )
-  }
-
-  if (!commit) {
-    return {
-      status: 'validated',
-      note: 'Subscription is valid for update',
-    }
-  }
-
-  try {
-    await rateLimiters.requestWithRetries(
-      stripeClient.serviceName,
-      () =>
-        stripeClient.updateSubscriptionMetadata(subscriptionId, {
-          recurly_to_stripe_migration_status: 'cancelled',
-        }),
-      {
-        operation: 'updateSubscriptionMetadata',
-        subscriptionId,
-        region: stripeClient.serviceName,
-      }
-    )
-
-    return {
-      status: 'updated',
-      note: `Updated metadata for subscription ${subscriptionId}`,
-    }
-  } catch (err) {
-    throw new ReportError(
-      'update-failed',
-      `Failed to update metadata: ${err.message}`
-    )
-  }
-}
-
-try {
-  await scriptRunner(main)
-  process.exit(0)
-} catch (error) {
-  console.error(error)
-  process.exit(1)
-}

+ 0 - 244
services/web/scripts/stripe/register-analytics-mapping.mjs

@@ -1,244 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * This script registers analytics account mapping for subscriptions migrated to Stripe.
- *
- * // TODO: delete this when the migration is complete
- *
- * Usage:
- *   node scripts/stripe/register-analytics-mapping.mjs [OPTS] [INPUT-FILE]
- *
- * Options:
- *   --output PATH          Output file path (default: /tmp/register_output_<timestamp>.csv)
- *   --commit               Apply changes (without this, runs in dry-run mode)
- *   --help                 Show help message
- *
- * CSV Input Format:
- *   recurly_account_code,target_stripe_account,stripe_customer_id
- *   507f1f77bcf86cd799439011,stripe-uk,cus_1234567890abcdef
- *
- * CSV Output Format:
- *   recurly_account_code,target_stripe_account,stripe_customer_id,status,note
- */
-
-import fs from 'node:fs'
-import path from 'node:path'
-import * as csv from 'csv'
-import minimist from 'minimist'
-import { z } from '../../app/src/infrastructure/Validation.mjs'
-import { scriptRunner } from '../lib/ScriptRunner.mjs'
-import { Subscription } from '../../app/src/models/Subscription.mjs'
-import AnalyticsManager from '../../app/src/Features/Analytics/AnalyticsManager.mjs'
-import AccountMappingHelper from '../../app/src/Features/Analytics/AccountMappingHelper.mjs'
-import { ReportError } from './helpers.mjs'
-
-function usage() {
-  console.error(`Usage: node scripts/stripe/register-analytics-mapping.mjs [OPTS] [INPUT-FILE]
-
-Options:
-    --output PATH          Output file path (default: /tmp/register_output_<timestamp>.csv)
-    --commit               Apply changes (without this, runs in dry-run mode)
-    --help                 Show this help message
-`)
-}
-
-async function main(trackProgress) {
-  const opts = parseArgs()
-  const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
-  const outputFile = opts.output ?? `/tmp/register_output_${timestamp}.csv`
-
-  await trackProgress('Starting analytics mapping registration')
-  await trackProgress(`Run mode: ${opts.commit ? 'COMMIT' : 'DRY RUN'}`)
-
-  const inputStream = opts.inputFile
-    ? fs.createReadStream(opts.inputFile)
-    : process.stdin
-  const csvReader = getCsvReader(inputStream)
-  const csvWriter = getCsvWriter(outputFile)
-
-  await trackProgress(`Output: ${outputFile}`)
-
-  let processedCount = 0
-  let successCount = 0
-  let errorCount = 0
-
-  for await (const input of csvReader) {
-    processedCount++
-
-    try {
-      const result = await processRow(input, opts.commit)
-
-      csvWriter.write({
-        recurly_account_code: input.recurly_account_code,
-        target_stripe_account: input.target_stripe_account,
-        stripe_customer_id: input.stripe_customer_id,
-        status: result.status,
-        note: result.note,
-      })
-
-      if (result.status === 'registered' || result.status === 'dry-run') {
-        successCount++
-      } else {
-        errorCount++
-      }
-
-      if (processedCount % 25 === 0) {
-        await trackProgress(
-          `Progress: ${processedCount} processed, ${successCount} successful, ${errorCount} errors`
-        )
-      }
-    } catch (err) {
-      errorCount++
-      if (err instanceof ReportError) {
-        csvWriter.write({
-          recurly_account_code: input.recurly_account_code,
-          target_stripe_account: input.target_stripe_account,
-          stripe_customer_id: input.stripe_customer_id,
-          status: err.status,
-          note: err.message,
-        })
-      } else {
-        csvWriter.write({
-          recurly_account_code: input.recurly_account_code,
-          target_stripe_account: input.target_stripe_account,
-          stripe_customer_id: input.stripe_customer_id,
-          status: 'error',
-          note: err.message,
-        })
-      }
-    }
-  }
-
-  await trackProgress(`✅ Total processed: ${processedCount}`)
-  if (opts.commit) {
-    await trackProgress(`✅ Successfully registered: ${successCount}`)
-  } else {
-    await trackProgress(`✅ Successfully validated: ${successCount}`)
-    await trackProgress('ℹ️  DRY RUN: No changes were applied')
-  }
-  await trackProgress(`❌ Errors: ${errorCount}`)
-  await trackProgress('🎉 Script completed!')
-
-  csvWriter.end()
-}
-
-function getCsvReader(inputStream) {
-  const parser = csv.parse({ columns: true })
-  inputStream.pipe(parser)
-  return parser
-}
-
-function getCsvWriter(outputFile) {
-  fs.mkdirSync(path.dirname(outputFile), { recursive: true })
-  const outputStream = fs.createWriteStream(outputFile)
-
-  const writer = csv.stringify({
-    columns: [
-      'recurly_account_code',
-      'target_stripe_account',
-      'stripe_customer_id',
-      'status',
-      'note',
-    ],
-    header: true,
-  })
-
-  writer.on('error', err => {
-    console.error(err)
-    process.exit(1)
-  })
-
-  writer.pipe(outputStream)
-  return writer
-}
-
-async function processRow(input, commit) {
-  const {
-    recurly_account_code: accountCode,
-    target_stripe_account: targetStripeAccount,
-  } = input
-
-  // 1. Fetch Mongo subscription
-  const mongoSubscription = await Subscription.findOne({
-    admin_id: accountCode,
-  }).exec()
-  if (!mongoSubscription) {
-    throw new ReportError(
-      'no-mongo-subscription',
-      'No subscription found in Mongo'
-    )
-  }
-
-  // 2. Check if migrated to Stripe
-  if (!mongoSubscription.paymentProvider?.service?.includes('stripe')) {
-    throw new ReportError('not-stripe', 'Subscription not using Stripe')
-  }
-
-  const subscriptionId = mongoSubscription.paymentProvider.subscriptionId
-  if (!subscriptionId) {
-    throw new ReportError(
-      'no-subscription-id',
-      'No Stripe subscription ID in Mongo'
-    )
-  }
-
-  // 3. Register analytics mapping
-  if (commit) {
-    AnalyticsManager.registerAccountMapping(
-      AccountMappingHelper.generateSubscriptionToStripeMapping(
-        mongoSubscription._id,
-        subscriptionId,
-        targetStripeAccount
-      )
-    )
-    return {
-      status: 'registered',
-      note: 'Analytics mapping registered',
-    }
-  } else {
-    return {
-      status: 'dry-run',
-      note: 'DRY RUN: Would register analytics mapping',
-    }
-  }
-}
-
-function parseArgs() {
-  const args = minimist(process.argv.slice(2), {
-    string: ['output'],
-    boolean: ['commit', 'help'],
-    default: { commit: false },
-  })
-
-  if (args.help) {
-    usage()
-    process.exit(0)
-  }
-
-  const inputFile = args._[0]
-  const paramsSchema = z.object({
-    output: z.string().optional(),
-    commit: z.boolean(),
-    inputFile: z.string().optional(),
-  })
-
-  try {
-    return paramsSchema.parse({
-      output: args.output,
-      commit: args.commit,
-      inputFile,
-    })
-  } catch (err) {
-    console.error('Invalid arguments:', err.message)
-    usage()
-    process.exit(1)
-  }
-}
-
-try {
-  await scriptRunner(main)
-  process.exit(0)
-} catch (error) {
-  console.error(error)
-  process.exit(1)
-}

+ 0 - 227
services/web/scripts/stripe/remove_admin_user_id_from_stripe_subscription.mjs

@@ -1,227 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * This script iterates through all Stripe subscriptions and removes the adminUserId metadata
- * from subscription objects that have it.
- *
- * Usage:
- *   node scripts/stripe/remove_admin_user_id_from_stripe_subscription.mjs --region=us [options]
- *   node scripts/stripe/remove_admin_user_id_from_stripe_subscription.mjs --region=uk [options]
- *
- * Options:
- *   --region=us|uk     Required. Stripe region to process (us or uk)
- *   --commit           Actually perform the updates (default: dry-run mode)
- *   --verbose          Enable verbose logging
- *   --limit=N          Limit processing to N subscriptions (for testing)
- *
- * Examples:
- *   # Dry run for US region with verbose output
- *   node scripts/stripe/remove_admin_user_id_from_stripe_subscription.mjs --region=us --verbose
- *
- *   # Commit changes for UK region
- *   node scripts/stripe/remove_admin_user_id_from_stripe_subscription.mjs --region=uk --commit
- *
- *   # Test with limited subscriptions
- *   node scripts/stripe/remove_admin_user_id_from_stripe_subscription.mjs --region=us --limit=10 --verbose
- */
-
-import minimist from 'minimist'
-import { z } from '../../app/src/infrastructure/Validation.mjs'
-import { scriptRunner } from '../lib/ScriptRunner.mjs'
-import { getRegionClient } from '../../modules/subscriptions/app/src/StripeClient.mjs'
-
-const paramsSchema = z.object({
-  region: z.enum(['us', 'uk']),
-  commit: z.boolean().default(false),
-  verbose: z.boolean().default(false),
-  limit: z.number().int().min(1).optional(),
-})
-
-let processedCount = 0
-let updatedCount = 0
-let errorCount = 0
-
-/**
- * Sleep function to respect Stripe rate limits (100 requests per second)
- * We'll be conservative and sleep for 50ms between requests to stay well under the limit
- */
-async function rateLimitSleep() {
-  return new Promise(resolve => setTimeout(resolve, 50))
-}
-
-/**
- * Process a single subscription and remove adminUserId metadata if present
- */
-async function processSubscription(
-  subscription,
-  stripeClient,
-  commit,
-  verbose
-) {
-  try {
-    processedCount++
-
-    // Check if subscription has adminUserId metadata
-    const adminUserId = subscription.metadata?.adminUserId
-
-    if (verbose) {
-      console.info(
-        `Processing subscription ${subscription.id} - adminUserId: ${adminUserId || 'none'}`
-      )
-    }
-
-    if (!adminUserId) {
-      // No adminUserId to remove
-      return
-    }
-
-    if (commit) {
-      // Create a new metadata object that will remove adminUserId
-      const updatedMetadata = { ...subscription.metadata }
-      updatedMetadata.adminUserId = ''
-
-      // Update subscription metadata using Stripe API directly
-      await stripeClient.stripe.subscriptions.update(subscription.id, {
-        metadata: updatedMetadata,
-      })
-
-      console.info(
-        `Removed adminUserId metadata from subscription ${subscription.id}`
-      )
-    } else {
-      console.info(
-        `DRY RUN: Would remove adminUserId metadata from subscription ${subscription.id}`
-      )
-    }
-
-    updatedCount++
-  } catch (error) {
-    errorCount++
-    console.log(error)
-  }
-
-  // Respect rate limits
-  await rateLimitSleep()
-}
-
-/**
- * Main script function
- */
-async function main(trackProgress) {
-  const parseResult = paramsSchema.safeParse(
-    minimist(process.argv.slice(2), {
-      boolean: ['commit', 'verbose'],
-      string: ['region'],
-      number: ['limit'],
-    })
-  )
-
-  if (!parseResult.success) {
-    throw new Error(`Invalid parameters: ${parseResult.error.message}`)
-  }
-
-  const { region, commit, verbose, limit } = parseResult.data
-
-  const mode = commit ? 'COMMIT MODE' : 'DRY RUN MODE'
-  await trackProgress(
-    `Starting script in ${mode} for Stripe ${region.toUpperCase()} region`
-  )
-
-  if (limit) {
-    await trackProgress(`Processing limited to ${limit} subscriptions`)
-  }
-
-  // Get Stripe client for the specified region
-  const stripeClient = getRegionClient(region)
-
-  // Reset counters
-  processedCount = 0
-  updatedCount = 0
-  errorCount = 0
-
-  await trackProgress('Starting to iterate through Stripe subscriptions...')
-
-  const listParams = {
-    limit: 100, // Stripe's maximum limit per request
-  }
-
-  let hasMore = true
-  let startingAfter = null
-  let totalProcessed = 0
-
-  while (hasMore) {
-    const params = { ...listParams }
-    if (startingAfter) {
-      params.starting_after = startingAfter
-    }
-
-    // Get batch of subscriptions
-    const subscriptions = await stripeClient.stripe.subscriptions.list(params)
-
-    await trackProgress(
-      `Retrieved ${subscriptions.data.length} subscriptions (total processed so far: ${totalProcessed})`
-    )
-
-    // Process each subscription in the batch
-    for (const subscription of subscriptions.data) {
-      await processSubscription(subscription, stripeClient, commit, verbose)
-
-      totalProcessed++
-
-      // Check if we've hit the limit
-      if (limit && totalProcessed >= limit) {
-        await trackProgress(`Reached limit of ${limit} subscriptions, stopping`)
-        hasMore = false
-        break
-      }
-
-      // Progress update every 50 subscriptions
-      if (totalProcessed % 50 === 0) {
-        await trackProgress(
-          `Progress: ${totalProcessed} processed, ${updatedCount} subscriptions updated, ${errorCount} errors`
-        )
-      }
-    }
-
-    // Check if there are more subscriptions to process
-    hasMore = hasMore && subscriptions.has_more
-    if (hasMore && subscriptions.data.length > 0) {
-      startingAfter = subscriptions.data[subscriptions.data.length - 1].id
-    }
-
-    // Rate limit between batch requests
-    await rateLimitSleep()
-  }
-
-  // Final summary
-  await trackProgress('FINAL SUMMARY:')
-  await trackProgress(`   Total subscriptions processed: ${processedCount}`)
-  await trackProgress(
-    `   Subscriptions ${commit ? 'updated' : 'would be updated'}: ${updatedCount}`
-  )
-  await trackProgress(`   Errors encountered: ${errorCount}`)
-
-  if (!commit && updatedCount > 0) {
-    await trackProgress('')
-    await trackProgress(
-      'To actually perform the updates, run the script with --commit flag'
-    )
-  }
-
-  if (errorCount > 0) {
-    await trackProgress(
-      'Some errors were encountered. Check the logs above for details.'
-    )
-  }
-
-  await trackProgress(`Script completed successfully in ${mode}`)
-}
-
-// Execute the script using the runner
-try {
-  await scriptRunner(main)
-  process.exit(0)
-} catch (error) {
-  console.error('Script failed:', error.message)
-  process.exit(1)
-}