Files
PriceUpdaterAppv2/.kiro/specs/windows-compatible-tui/design.md
2025-08-10 14:54:47 -05:00

12 KiB

Design Document

Overview

This design document outlines the replacement of the Blessed-based TUI with a Windows-compatible alternative using Ink (React for CLI) as the primary library choice. Ink provides excellent cross-platform support, modern React-based component architecture, and superior Windows compatibility compared to Blessed. The design maintains all existing functionality while improving performance, maintainability, and user experience across all platforms.

Architecture

Library Selection: Ink (React for CLI)

Primary Choice: Ink v4.x

  • Rationale: Ink is built on React principles, providing a modern component-based architecture
  • Windows Compatibility: Excellent support for Windows Terminal, Command Prompt, and PowerShell
  • Performance: Uses React's reconciliation for efficient updates, reducing flicker
  • Ecosystem: Large ecosystem of pre-built components and utilities
  • Maintenance: Actively maintained by Vercel with strong community support

Alternative Considerations:

  • Blessed: Current library with Windows issues (being replaced)
  • Terminal-kit: Good Windows support but more complex API
  • Enquirer: Limited to prompts, not full TUI applications
  • Neo-blessed: Fork of Blessed with some improvements but still has Windows issues

Component Architecture

TuiApplication (Root)
├── AppProvider (Context/State Management)
├── Router (Screen Management)
├── StatusBar (Global Status)
└── Screens/
    ├── MainMenuScreen
    ├── ConfigurationScreen
    ├── OperationScreen
    ├── SchedulingScreen
    ├── LogViewerScreen
    └── TagAnalysisScreen

State Management

Using React Context API with custom hooks for:

  • Application state (current screen, navigation history)
  • Configuration state (environment variables, settings)
  • Operation state (progress, results, errors)
  • UI state (focus, selections, modal states)

Components and Interfaces

Core Components

1. TuiApplication (Root Component)

const TuiApplication = () => {
	return (
		<AppProvider>
			<Box flexDirection="column" height="100%">
				<StatusBar />
				<Router />
			</Box>
		</AppProvider>
	);
};

2. AppProvider (State Management)

const AppProvider = ({ children }) => {
	const [appState, setAppState] = useState({
		currentScreen: "main-menu",
		navigationHistory: [],
		configuration: {},
		operationState: null,
	});

	return (
		<AppContext.Provider value={{ appState, setAppState }}>
			{children}
		</AppContext.Provider>
	);
};

3. Router (Screen Management)

const Router = () => {
	const { appState } = useContext(AppContext);

	const screens = {
		"main-menu": MainMenuScreen,
		configuration: ConfigurationScreen,
		operation: OperationScreen,
		scheduling: SchedulingScreen,
		logs: LogViewerScreen,
		"tag-analysis": TagAnalysisScreen,
	};

	const CurrentScreen = screens[appState.currentScreen];
	return <CurrentScreen />;
};

4. StatusBar (Global Status Display)

const StatusBar = () => {
	const { connectionStatus, operationProgress } = useAppState();

	return (
		<Box borderStyle="single" paddingX={1}>
			<Text color="green"> Connected</Text>
			<Text> | </Text>
			<Text>Progress: {operationProgress}%</Text>
		</Box>
	);
};

Screen Components

MainMenuScreen

  • Navigation menu with keyboard shortcuts
  • Current configuration summary
  • Quick action buttons
  • Help information

ConfigurationScreen

  • Environment variable editor
  • Input validation with real-time feedback
  • API connection testing
  • Save/cancel operations

OperationScreen

  • Operation type selection (update/rollback)
  • Real-time progress display
  • Product processing information
  • Error handling and display

SchedulingScreen

  • Date/time picker interface
  • Schedule management
  • Countdown display
  • Cancellation controls

LogViewerScreen

  • Paginated log display
  • Search and filtering
  • Log entry details
  • Export functionality

TagAnalysisScreen

  • Tag listing and statistics
  • Product count per tag
  • Sample product display
  • Recommendations

Reusable UI Components

ProgressBar

const ProgressBar = ({ progress, label, color = "blue" }) => {
	const width = 40;
	const filled = Math.round((progress / 100) * width);

	return (
		<Box flexDirection="column">
			<Text>{label}</Text>
			<Box>
				<Text color={color}>{"█".repeat(filled)}</Text>
				<Text color="gray">{"░".repeat(width - filled)}</Text>
				<Text> {progress}%</Text>
			</Box>
		</Box>
	);
};

InputField

const InputField = ({ label, value, onChange, validation, placeholder }) => {
	const [isValid, setIsValid] = useState(true);

	return (
		<Box flexDirection="column" marginY={1}>
			<Text>{label}:</Text>
			<TextInput
				value={value}
				onChange={(val) => {
					onChange(val);
					setIsValid(validation ? validation(val) : true);
				}}
				placeholder={placeholder}
			/>
			{!isValid && <Text color="red">Invalid input</Text>}
		</Box>
	);
};

MenuList

const MenuList = ({ items, selectedIndex, onSelect }) => {
	return (
		<Box flexDirection="column">
			{items.map((item, index) => (
				<Box key={index} paddingX={2}>
					<Text color={index === selectedIndex ? "blue" : "white"}>
						{index === selectedIndex ? "► " : "  "}
						{item.label}
					</Text>
				</Box>
			))}
		</Box>
	);
};

Data Models

Application State

interface AppState {
	currentScreen: string;
	navigationHistory: string[];
	configuration: ConfigurationState;
	operationState: OperationState | null;
	uiState: UIState;
}

interface ConfigurationState {
	shopifyDomain: string;
	accessToken: string;
	targetTag: string;
	priceAdjustment: number;
	operationMode: "update" | "rollback";
	isValid: boolean;
	lastTested: Date | null;
}

interface OperationState {
	type: "update" | "rollback" | "scheduled";
	status: "idle" | "running" | "completed" | "error";
	progress: number;
	currentProduct: string | null;
	results: OperationResults | null;
	errors: Error[];
}

interface UIState {
	focusedComponent: string;
	modalOpen: boolean;
	selectedMenuIndex: number;
	scrollPosition: number;
}

Service Integration

interface ServiceIntegration {
	shopifyService: ShopifyService;
	productService: ProductService;
	progressService: ProgressService;
	configService: ConfigurationService;
}

Error Handling

Error Categories

  1. Configuration Errors: Invalid environment variables, API credentials
  2. Network Errors: Connection failures, timeout issues
  3. API Errors: Shopify API rate limits, authentication failures
  4. UI Errors: Component rendering issues, state inconsistencies
  5. System Errors: File system access, permission issues

Error Display Strategy

const ErrorBoundary = ({ children }) => {
	const [error, setError] = useState(null);

	if (error) {
		return (
			<Box
				flexDirection="column"
				padding={2}
				borderStyle="single"
				borderColor="red"
			>
				<Text color="red" bold>
					Error Occurred
				</Text>
				<Text>{error.message}</Text>
				<Text color="gray">Press 'r' to retry or 'q' to quit</Text>
			</Box>
		);
	}

	return children;
};

Graceful Degradation

  • Fallback to basic text display if advanced features fail
  • Automatic retry mechanisms for network operations
  • State persistence to recover from crashes
  • Clear error messages with suggested actions

Testing Strategy

Component Testing

// Example test using Ink's testing utilities
import { render } from "ink-testing-library";
import { MainMenuScreen } from "../screens/MainMenuScreen";

test("renders main menu with correct options", () => {
	const { lastFrame } = render(<MainMenuScreen />);
	expect(lastFrame()).toContain("Price Update Operations");
	expect(lastFrame()).toContain("Configuration");
	expect(lastFrame()).toContain("View Logs");
});

Integration Testing

  • Test service integration with mock services
  • Verify state management across screen transitions
  • Test keyboard navigation and input handling
  • Validate error handling scenarios

Cross-Platform Testing

  • Automated testing on Windows, macOS, and Linux
  • Terminal compatibility testing (Windows Terminal, Command Prompt, PowerShell)
  • Unicode and color support verification
  • Performance testing with large datasets

Migration Strategy

Phase 1: Setup and Core Infrastructure

  1. Install Ink and related dependencies
  2. Create basic application structure
  3. Implement state management system
  4. Set up routing and navigation

Phase 2: Screen Implementation

  1. Implement MainMenuScreen (simplest)
  2. Create ConfigurationScreen with form handling
  3. Build OperationScreen with progress display
  4. Add remaining screens (Scheduling, Logs, TagAnalysis)

Phase 3: Component Migration

  1. Replace Blessed ProgressBar with Ink version
  2. Migrate form components and input handling
  3. Update navigation and keyboard shortcuts
  4. Implement error handling and validation

Phase 4: Testing and Refinement

  1. Comprehensive testing on Windows systems
  2. Performance optimization and bug fixes
  3. Documentation updates
  4. Legacy code cleanup

Dependency Changes

{
	"dependencies": {
		"ink": "^4.4.1",
		"react": "^18.2.0",
		"@ink/text-input": "^5.0.1",
		"@ink/select-input": "^5.0.1",
		"@ink/spinner": "^5.0.1"
	},
	"devDependencies": {
		"ink-testing-library": "^3.0.0"
	}
}

File Structure Changes

src/
├── tui/
│   ├── components/
│   │   ├── common/
│   │   │   ├── ProgressBar.jsx
│   │   │   ├── InputField.jsx
│   │   │   ├── MenuList.jsx
│   │   │   └── ErrorBoundary.jsx
│   │   ├── screens/
│   │   │   ├── MainMenuScreen.jsx
│   │   │   ├── ConfigurationScreen.jsx
│   │   │   ├── OperationScreen.jsx
│   │   │   ├── SchedulingScreen.jsx
│   │   │   ├── LogViewerScreen.jsx
│   │   │   └── TagAnalysisScreen.jsx
│   │   └── providers/
│   │       ├── AppProvider.jsx
│   │       └── ServiceProvider.jsx
│   ├── hooks/
│   │   ├── useAppState.js
│   │   ├── useNavigation.js
│   │   └── useServices.js
│   ├── utils/
│   │   ├── keyboardHandlers.js
│   │   └── validation.js
│   └── TuiApplication.jsx
└── tui-entry.js (new entry point)

Performance Considerations

Rendering Optimization

  • Use React.memo for expensive components
  • Implement virtual scrolling for large lists
  • Debounce rapid state updates
  • Minimize re-renders with proper state structure

Memory Management

  • Clean up event listeners and timers
  • Implement proper component unmounting
  • Use weak references for large data structures
  • Monitor memory usage during long operations

Windows-Specific Optimizations

  • Use Windows-compatible Unicode characters
  • Optimize for Windows Terminal performance
  • Handle Windows-specific keyboard events
  • Ensure proper color rendering in different terminals

Security Considerations

Input Validation

  • Sanitize all user inputs
  • Validate configuration values
  • Prevent injection attacks through input fields
  • Secure handling of API credentials

State Security

  • Encrypt sensitive data in state
  • Clear sensitive information on exit
  • Prevent credential logging
  • Secure temporary file handling

This design provides a robust foundation for replacing Blessed with Ink, ensuring excellent Windows compatibility while maintaining all existing functionality and improving the overall user experience.