Files
PriceUpdaterAppv2/.kiro/specs/shopify-price-updater/design.md
Spencer Grimes 1e6881ba86 Initial commit: Complete Shopify Price Updater implementation
- Full Node.js application with Shopify GraphQL API integration
- Compare At price support for promotional pricing
- Comprehensive error handling and retry logic
- Progress tracking with markdown logging
- Complete test suite with unit and integration tests
- Production-ready with proper exit codes and signal handling
2025-08-05 10:05:05 -05:00

6.9 KiB

Design Document

Overview

The Shopify Price Updater is a Node.js command-line script that uses Shopify's GraphQL Admin API to bulk update product prices based on tag filtering. The script will be built using the @shopify/shopify-api package and will implement proper error handling, rate limiting, and progress tracking.

Architecture

The application follows a modular architecture with clear separation of concerns:

shopify-price-updater/
├── src/
│   ├── config/
│   │   └── environment.js     # Environment variable loading and validation
│   ├── services/
│   │   ├── shopify.js         # Shopify API client and authentication
│   │   ├── product.js         # Product querying and updating logic
│   │   └── progress.js        # Progress logging functionality
│   ├── utils/
│   │   ├── price.js           # Price calculation utilities
│   │   └── logger.js          # Console and file logging utilities
│   └── index.js               # Main application entry point
├── .env.example               # Environment variable template
├── package.json
└── Progress.md                # Generated progress log file

Compare At Price Workflow

The Compare At price functionality works as follows:

  1. Price Capture: When a product variant is processed, the current price is captured as the "original price"
  2. Price Calculation: The new price is calculated by applying the percentage adjustment to the original price
  3. Compare At Assignment: The original price (before adjustment) is set as the Compare At price
  4. Simultaneous Update: Both the new price and Compare At price are updated in a single GraphQL mutation
  5. Progress Tracking: All three values (original, new, and Compare At) are logged for transparency

This creates a promotional pricing display where customers can see both the current discounted price and the original price for comparison.

Components and Interfaces

Environment Configuration (config/environment.js)

  • Loads and validates environment variables from .env file
  • Required variables: SHOPIFY_SHOP_DOMAIN, SHOPIFY_ACCESS_TOKEN, TARGET_TAG, PRICE_ADJUSTMENT_PERCENTAGE
  • Validates that percentage is a valid number and tag is not empty
  • Exports configuration object with validated values

Shopify Service (services/shopify.js)

  • Initializes Shopify GraphQL client using @shopify/shopify-api
  • Handles authentication and session management
  • Provides methods for executing GraphQL queries and mutations
  • Implements retry logic for rate limiting (HTTP 429 responses)

Product Service (services/product.js)

  • Implements GraphQL queries to fetch products by tag
  • Handles pagination for large product sets using cursor-based pagination
  • Implements GraphQL mutations for price and Compare At price updates
  • Manages product variant price updates (products can have multiple variants)
  • Sets Compare At price to the original price before applying percentage adjustment
  • Automatically formats tag queries with "tag:" prefix if not already present

Progress Service (services/progress.js)

  • Creates and manages Progress.md file
  • Logs operation start, product updates, errors, and completion summary
  • Appends to existing file with timestamps for multiple runs
  • Formats progress entries in markdown for readability

Price Utilities (utils/price.js)

  • Calculates new prices based on percentage adjustment
  • Handles rounding to appropriate decimal places for currency
  • Validates price ranges and handles edge cases (negative prices, zero prices)
  • Provides functions to prepare price update objects with both price and Compare At price values

Logger Utilities (utils/logger.js)

  • Provides consistent logging to console and progress file
  • Implements different log levels (info, warning, error)
  • Formats output for both human readability and progress tracking

Data Models

Product Query Response

query getProductsByTag($query: String!, $first: Int!, $after: String) {
	products(first: $first, after: $after, query: $query) {
		edges {
			node {
				id
				title
				tags
				variants(first: 100) {
					edges {
						node {
							id
							price
							compareAtPrice
						}
					}
				}
			}
			cursor
		}
		pageInfo {
			hasNextPage
			endCursor
		}
	}
}

Product Update Mutation

mutation productVariantUpdate($input: ProductVariantInput!) {
	productVariantUpdate(input: $input) {
		productVariant {
			id
			price
			compareAtPrice
		}
		userErrors {
			field
			message
		}
	}
}

Configuration Object

{
  shopDomain: string,
  accessToken: string,
  targetTag: string,
  priceAdjustmentPercentage: number
}

Progress Entry

{
  timestamp: Date,
  productId: string,
  productTitle: string,
  variantId: string,
  oldPrice: number,
  newPrice: number,
  compareAtPrice: number,
  status: 'success' | 'error',
  errorMessage?: string
}

Error Handling

Rate Limiting

  • Implement exponential backoff for HTTP 429 responses
  • Use Shopify's rate limit headers to determine retry timing
  • Maximum retry attempts: 3 with increasing delays (1s, 2s, 4s)

API Errors

  • Parse GraphQL userErrors from mutation responses
  • Log specific error messages for debugging
  • Continue processing remaining products when individual updates fail

Network Errors

  • Catch and handle network connectivity issues
  • Implement retry logic for transient network failures
  • Graceful degradation when API is temporarily unavailable

Data Validation

  • Validate product data before attempting updates
  • Skip products with invalid price data
  • Handle edge cases like products without variants

Progress Tracking Errors

  • Continue script execution even if progress logging fails
  • Fallback to console-only logging if file writing fails
  • Ensure critical operations aren't blocked by logging issues

Testing Strategy

Unit Tests

  • Test price calculation utilities with various percentage values
  • Test environment configuration loading and validation
  • Test GraphQL query and mutation builders
  • Test error handling scenarios with mocked API responses

Integration Tests

  • Test Shopify API authentication with test credentials
  • Test product querying with known test data
  • Test price update operations in Shopify development store
  • Test progress logging functionality

End-to-End Tests

  • Test complete workflow with development store
  • Verify price updates are applied correctly
  • Test error recovery and continuation scenarios
  • Validate progress logging accuracy

Manual Testing Checklist

  • Test with various percentage values (positive, negative, decimal)
  • Test with products having multiple variants
  • Test with large product sets requiring pagination
  • Test error scenarios (invalid credentials, network issues)
  • Verify Progress.md file generation and formatting