Maintenance: Deleting Products with Missing Data
When products are synced into the excise tax system, some may arrive with incomplete information and get flagged with missingData=true in their details JSON. There may be some cases where we may need to remove these manually (as was the case when BigDVapor.net re-SKU'd all of their products - making these notifications obsolete).
The hq-delete-missing-data-products maintenance script finds these products and optionally removes them.
How it works
The script queries excise_tax_product_by_app_domain for a given app domain, parses the details JSON for each row, and identifies products where missingData is truthy. It uses Cassandra WRITETIME to determine when each product was created, which enables date-based filtering.
Products can be filtered by age (--older-than), a start date (--startDate), an end date (--endDate), or any combination of these.
Usage
node scripts/maintenance/hq-delete-missing-data-products [options] <appDomain ...>
Multiple app domains can be provided and will be processed sequentially.
Options
| Flag | Description |
|---|---|
-x, --execute |
Actually delete the products (default is dry-run) |
-o, --older-than <days> |
Only include products older than this many days |
-s, --startDate <date> |
Only include products created on or after this date (YYYY-MM-DD) |
-e, --endDate <date> |
Only include products created on or before this date (YYYY-MM-DD) |
Modes
| Flags | Behavior |
|---|---|
| (none) | Dry-run. Lists all matching products but does not delete anything. |
--execute |
Deletes all matching products (concurrency of 5). |
Recommended workflow
Step 1: Dry-run scan
Start with a dry-run to see what would be deleted:
node scripts/maintenance/hq-delete-missing-data-products acme.example.com
Example output:
[acme.example.com] Found 42 products with missingData.
[DRY RUN] sku=WIDGET-001 created=2024-06-15 Widget Deluxe
[DRY RUN] sku=GIZMO-002 created=2024-08-22 Gizmo Pro
[DRY RUN] sku=GADGET-003 created=2025-01-10 Gadget Mini
...
[acme.example.com] Total: 42 missing-data products.
[acme.example.com] Dry run complete. Use --execute to actually delete these products.
Step 2: Narrow with date filters (optional)
If you only want to clean up older products, use the date filters:
# Only products older than 90 days
node scripts/maintenance/hq-delete-missing-data-products --older-than 90 acme.example.com
# Only products created in a specific date range
node scripts/maintenance/hq-delete-missing-data-products --startDate 2024-01-01 --endDate 2024-06-30 acme.example.com
# Combine: older than 30 days AND within a date range
node scripts/maintenance/hq-delete-missing-data-products --older-than 30 --startDate 2024-01-01 acme.example.com
Date filters are cumulative — a product must satisfy all specified filters to be included.
Step 3: Execute
Once you've confirmed the dry-run output looks correct:
node scripts/maintenance/hq-delete-missing-data-products --execute acme.example.com
Example output:
[acme.example.com] Found 42 products with missingData.
[DELETE] sku=WIDGET-001 created=2024-06-15 Widget Deluxe
[DELETE] sku=GIZMO-002 created=2024-08-22 Gizmo Pro
...
[acme.example.com] Total: 42 missing-data products.
[acme.example.com] Deleting 42 products...
[acme.example.com] Successfully deleted 42 missing-data products.
Processing multiple domains
You can pass multiple app domains in a single invocation. They are processed one at a time:
node scripts/maintenance/hq-delete-missing-data-products --execute acme.example.com bigco.example.com
How deletion works
Deletions are performed via the exciseTaxProductService.deleteProduct() method with a concurrency of 5. This script does not back up rows before deletion. Make sure you are confident in the dry-run output before using --execute.
Troubleshooting
No output / immediate exit — Running without any arguments prints the help text and exits. Make sure you provide at least one app domain.
"ERROR deleting ..." — Individual product deletion failures are logged but cause the script to stop processing that domain. Check the error message for Cassandra connectivity or consistency issues.
Unexpected products in the list — The script matches any product where details.missingData is truthy. Use date filters to narrow the scope, or inspect the details JSON for specific products to understand why they are flagged.
Debug logging
The script uses the debug module. To see detailed logging:
DEBUG=delete-missing-data-products* node scripts/maintenance/hq-delete-missing-data-products acme.example.com