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
This commit is contained in:
224
.kiro/specs/shopify-price-updater/design.md
Normal file
224
.kiro/specs/shopify-price-updater/design.md
Normal file
@@ -0,0 +1,224 @@
|
||||
# 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
|
||||
|
||||
```graphql
|
||||
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
|
||||
|
||||
```graphql
|
||||
mutation productVariantUpdate($input: ProductVariantInput!) {
|
||||
productVariantUpdate(input: $input) {
|
||||
productVariant {
|
||||
id
|
||||
price
|
||||
compareAtPrice
|
||||
}
|
||||
userErrors {
|
||||
field
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Configuration Object
|
||||
|
||||
```javascript
|
||||
{
|
||||
shopDomain: string,
|
||||
accessToken: string,
|
||||
targetTag: string,
|
||||
priceAdjustmentPercentage: number
|
||||
}
|
||||
```
|
||||
|
||||
### Progress Entry
|
||||
|
||||
```javascript
|
||||
{
|
||||
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
|
||||
94
.kiro/specs/shopify-price-updater/requirements.md
Normal file
94
.kiro/specs/shopify-price-updater/requirements.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Requirements Document
|
||||
|
||||
## Introduction
|
||||
|
||||
This feature involves creating a Node.js script that connects to Shopify's GraphQL API to update product prices based on specific criteria. The script will filter products by a preset tag and adjust their prices by a configurable percentage (either increase or decrease). The solution will use Shopify's official Node.js API package and store configuration in environment variables for security and flexibility.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement 1
|
||||
|
||||
**User Story:** As a store administrator, I want to bulk update product prices for products with specific tags, so that I can efficiently manage pricing across my inventory.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN the script is executed THEN the system SHALL connect to Shopify using GraphQL API
|
||||
2. WHEN connecting to Shopify THEN the system SHALL authenticate using API credentials from environment variables
|
||||
3. WHEN querying products THEN the system SHALL filter products by a configurable tag
|
||||
4. WHEN a matching product is found THEN the system SHALL update its price by the specified percentage
|
||||
5. WHEN updating prices THEN the system SHALL support both price increases and decreases based on percentage value
|
||||
6. WHEN updating a product price THEN the system SHALL set the original price as the "Compare At" price
|
||||
7. WHEN the original price exists THEN the system SHALL preserve it as the Compare At price before applying the adjustment
|
||||
|
||||
### Requirement 2
|
||||
|
||||
**User Story:** As a store administrator, I want to configure the script through environment variables, so that I can easily change settings without modifying code.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN the script starts THEN the system SHALL load Shopify API credentials from .env file
|
||||
2. WHEN loading configuration THEN the system SHALL read the target product tag from environment variables
|
||||
3. WHEN loading configuration THEN the system SHALL read the price adjustment percentage from environment variables
|
||||
4. IF required environment variables are missing THEN the system SHALL display an error message and exit gracefully
|
||||
5. WHEN percentage is positive THEN the system SHALL increase prices
|
||||
6. WHEN percentage is negative THEN the system SHALL decrease prices
|
||||
|
||||
### Requirement 3
|
||||
|
||||
**User Story:** As a store administrator, I want to see detailed feedback about the price update process, so that I can verify the changes were applied correctly.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN the script starts THEN the system SHALL display the configuration being used
|
||||
2. WHEN products are found THEN the system SHALL display the count of matching products
|
||||
3. WHEN updating each product THEN the system SHALL log the product name, old price, new price, and Compare At price
|
||||
4. WHEN all updates are complete THEN the system SHALL display a summary of total products updated
|
||||
5. IF errors occur during updates THEN the system SHALL log error details and continue processing other products
|
||||
|
||||
### Requirement 4
|
||||
|
||||
**User Story:** As a store administrator, I want the script to handle errors gracefully, so that partial failures don't prevent other products from being updated.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN API rate limits are encountered THEN the system SHALL implement appropriate retry logic
|
||||
2. WHEN a product update fails THEN the system SHALL log the error and continue with remaining products
|
||||
3. WHEN network errors occur THEN the system SHALL retry the operation with exponential backoff
|
||||
4. WHEN invalid product data is encountered THEN the system SHALL skip the product and log a warning
|
||||
5. WHEN the script completes THEN the system SHALL exit with appropriate status codes
|
||||
|
||||
### Requirement 5
|
||||
|
||||
**User Story:** As a developer, I want the script to use Shopify's official Node.js package and GraphQL API, so that I can leverage well-maintained and efficient tools.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN implementing the solution THEN the system SHALL use Shopify's official Node.js API package
|
||||
2. WHEN querying products THEN the system SHALL use GraphQL queries for efficient data retrieval
|
||||
3. WHEN updating products THEN the system SHALL use GraphQL mutations for price updates
|
||||
4. WHEN handling API responses THEN the system SHALL properly parse GraphQL response structures
|
||||
5. WHEN managing API connections THEN the system SHALL follow Shopify's best practices for authentication and session management
|
||||
|
||||
### Requirement 6
|
||||
|
||||
**User Story:** As a store administrator, I want the script to set Compare At prices to show customers the original price before adjustment, so that I can create effective promotional pricing displays.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN a product price is being updated THEN the system SHALL capture the current price as the Compare At price
|
||||
2. WHEN the Compare At price is set THEN the system SHALL use the original price value before any percentage adjustment
|
||||
3. WHEN updating product variants THEN the system SHALL set both the new price and Compare At price in the same operation
|
||||
4. WHEN a product already has a Compare At price THEN the system SHALL replace it with the current price before adjustment
|
||||
5. WHEN logging price updates THEN the system SHALL include the Compare At price in the progress tracking
|
||||
|
||||
### Requirement 7
|
||||
|
||||
**User Story:** As a developer, I want the script to maintain a progress log, so that I can track what operations have been completed and reference them later.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN the script starts THEN the system SHALL create or append to a Progress.md file
|
||||
2. WHEN each product is processed THEN the system SHALL log the operation details to Progress.md
|
||||
3. WHEN the script completes THEN the system SHALL write a summary to Progress.md with timestamp
|
||||
4. WHEN errors occur THEN the system SHALL log error details to Progress.md for debugging
|
||||
5. WHEN the script runs multiple times THEN the system SHALL append new progress entries without overwriting previous runs
|
||||
112
.kiro/specs/shopify-price-updater/tasks.md
Normal file
112
.kiro/specs/shopify-price-updater/tasks.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Implementation Plan
|
||||
|
||||
- [x] 1. Set up project structure and dependencies
|
||||
|
||||
- Create package.json with required dependencies (@shopify/shopify-api, dotenv)
|
||||
- Create directory structure (src/, config/, services/, utils/)
|
||||
- Create .env.example file with required environment variables
|
||||
- _Requirements: 2.1, 2.2, 2.3, 5.1_
|
||||
|
||||
- [x] 2. Implement environment configuration module
|
||||
|
||||
- Create config/environment.js to load and validate .env variables
|
||||
- Implement validation for required Shopify credentials and configuration
|
||||
- Add error handling for missing or invalid environment variables
|
||||
- _Requirements: 2.1, 2.2, 2.3, 2.4_
|
||||
|
||||
- [x] 3. Create Shopify API service
|
||||
|
||||
- Implement services/shopify.js with GraphQL client initialization
|
||||
- Add authentication using Shopify access token
|
||||
- Implement retry logic for rate limiting and network errors
|
||||
- _Requirements: 1.1, 1.2, 4.1, 4.3, 5.1, 5.5_
|
||||
|
||||
- [x] 4. Implement price calculation utilities
|
||||
|
||||
- Create utils/price.js with percentage-based price calculation functions
|
||||
- Add validation for price ranges and edge cases
|
||||
- Implement proper rounding for currency values
|
||||
- Add function to prepare price update objects with Compare At price values
|
||||
- _Requirements: 1.5, 2.5, 2.6, 6.1, 6.2_
|
||||
|
||||
- [x] 5. Create progress logging service
|
||||
|
||||
- Implement services/progress.js for Progress.md file management
|
||||
- Add functions to log operation start, product updates, and completion summary
|
||||
- Implement timestamp formatting and markdown structure
|
||||
- _Requirements: 6.1, 6.2, 6.3, 6.4, 6.5_
|
||||
|
||||
- [x] 6. Implement console logging utilities
|
||||
|
||||
- Create utils/logger.js for consistent console and progress file logging
|
||||
- Add different log levels (info, warning, error) with appropriate formatting
|
||||
- Integrate with progress service for dual logging
|
||||
- _Requirements: 3.1, 3.2, 3.3, 3.4, 3.5_
|
||||
|
||||
- [x] 7. Create product querying functionality
|
||||
|
||||
- Implement GraphQL query in services/product.js to fetch products by tag
|
||||
- Add cursor-based pagination handling for large product sets
|
||||
- Include product variants in query response
|
||||
- _Requirements: 1.3, 5.2, 5.4_
|
||||
|
||||
- [x] 8. Implement product price update functionality
|
||||
|
||||
- Add GraphQL mutation for updating product variant prices and Compare At prices
|
||||
- Implement batch processing of product variants with Compare At price setting
|
||||
- Add logic to capture original price before adjustment and set as Compare At price
|
||||
- Add error handling for individual product update failures
|
||||
- _Requirements: 1.4, 1.5, 1.6, 1.7, 4.2, 4.4, 5.3, 5.4, 6.1, 6.2, 6.3_
|
||||
|
||||
- [x] 9. Create main application entry point
|
||||
|
||||
- Implement src/index.js with complete workflow orchestration
|
||||
- Add configuration loading, product fetching, and price updating sequence
|
||||
- Implement error handling and graceful exit with appropriate status codes
|
||||
- _Requirements: 3.1, 3.4, 4.5_
|
||||
|
||||
- [x] 10. Add comprehensive error handling and logging
|
||||
|
||||
- Integrate all error handling scenarios across modules
|
||||
- Ensure progress logging continues even when individual operations fail
|
||||
- Add final summary reporting with success/failure counts
|
||||
- Update logging to include Compare At price information in progress tracking
|
||||
- _Requirements: 3.3, 3.4, 3.5, 4.1, 4.2, 4.3, 4.4, 6.5, 7.4_
|
||||
|
||||
- [x] 11. Create unit tests for core utilities
|
||||
|
||||
- Write tests for price calculation functions with various scenarios
|
||||
- Test environment configuration loading and validation
|
||||
- Test progress logging functionality
|
||||
- _Requirements: 1.5, 2.4, 2.5, 2.6, 6.1, 6.2, 6.3_
|
||||
|
||||
- [x] 12. Update existing implementation to support Compare At price functionality
|
||||
|
||||
- Modify price calculation utilities to handle Compare At price preparation
|
||||
- Update GraphQL mutation to include compareAtPrice field in product variant updates
|
||||
- Modify product update logic to capture original price and set as Compare At price
|
||||
- Update progress logging to include Compare At price information
|
||||
- _Requirements: 1.6, 1.7, 6.1, 6.2, 6.3, 6.4, 6.5_
|
||||
|
||||
- [x] 13. Write integration tests for Shopify API interactions
|
||||
|
||||
- Test GraphQL query execution with mock responses
|
||||
- Test product update mutations with error scenarios
|
||||
- Test rate limiting and retry logic
|
||||
- Add tests for Compare At price functionality
|
||||
- _Requirements: 1.1, 1.2, 1.3, 1.4, 4.1, 4.3, 5.2, 5.3, 6.3_
|
||||
|
||||
## Implementation Status
|
||||
|
||||
✅ **All tasks completed successfully!**
|
||||
|
||||
The Shopify Price Updater implementation is fully complete with:
|
||||
|
||||
- **Core Functionality**: Complete price update workflow with Compare At price support
|
||||
- **Error Handling**: Comprehensive retry logic, rate limiting, and graceful error recovery
|
||||
- **Progress Tracking**: Detailed logging to Progress.md with timestamps and summaries
|
||||
- **Testing**: Full test coverage including unit tests, integration tests, and edge cases
|
||||
- **Configuration**: Robust environment variable validation and configuration management
|
||||
- **Production Ready**: Proper exit codes, signal handling, and production-grade error handling
|
||||
|
||||
The application is ready for production use and meets all requirements specified in the design document.
|
||||
Reference in New Issue
Block a user