Add three SqlDialect implementations with a factory function:
- MySqlDialect: positional ?, ON DUPLICATE KEY UPDATE, LIMIT/OFFSET
- SqlServerDialect: @pN params, MERGE USING, OFFSET/FETCH
- PostgreSqlDialect: $N (1-based), ON CONFLICT DO UPDATE, LIMIT/OFFSET
TDD approach: 43 tests written first, all passing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix logger-performance test mock path to use bare module specifier
- Replace meaningless "should be defined" assertions in repositories test
with behavior-based tests covering upsert, batch operations, queries,
deletes, and error handling for both MaterialsToBeDeletedRepository
and DiscreteMaterialPlanRepository
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The shouldDeleteMaterial tests had a mockCleaner that reimplemented the
production logic inline, meaning bugs in the real code would never be caught.
Now uses an actual CleanerService instance instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Refactor logger.test.ts to mock logger module directly instead of winston
- Move vi.resetModules() to beforeEach to avoid module cache pollution
- Simplify mock structure to avoid conflicts with logger-performance.test.ts
- All 335 tests now pass (44 files)
Replace toBeDefined()/typeof checks with assertions that verify actual
behavior and output content. Key changes:
- locators: assert actual CSS selector values instead of existence
- logger-integration: test run()/getContext()/withRequestContext() behavior
- logger: verify winstonCalls content (level, message, metadata)
- config-manager: test default values, singleton, and getConfig() throws
- erp-auth: remove empty Class Structure block (covered by behavior tests)
- audit-logger: spy on auditLogger.info to verify JSONL entry content
- extractor: remove Math.ceil tests, verify error result structure
Net: -209 lines of hollow/redundant test code.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The vi.mock('fs') factory returned { default: { ... } } causing fs.mkdirSync
to be undefined at runtime. Add top-level exports alongside default for ESM/CJS interop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace 4x expect(true).toBe(true) in audit-logger.test.ts with
applyAuditConfig() + app.getVersion call count assertions
- Replace if(!hasCredentials){return} pattern with it.skipIf() in
3 integration test files (cleaner, erp-auth, extractor) so Vitest
correctly reports 12 tests as "skipped" instead of "passed"
- Remove placeholder assertion from skipped update-service test
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enhance ERP automation error diagnostics by capturing PNG screenshots
on every error and forwarding browser console warnings/errors to the
structured logger. Includes automatic cleanup of old screenshots
aligned with the configured log retention period.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove misleading await from audit-logger tests (functions are sync)
- Add cleanup() to LoggerAPI type definition in index.d.ts
- Fix circular reference fallback to preserve null values
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Make logAudit and closeAuditLogger synchronous (were async for no reason)
- Set audit-logger silent:true initially, enable on applyAuditConfig()
- Add try-catch for circular references in consoleFormat meta JSON
- Update all callers to remove unnecessary await/.catch() on sync functions
- Add comment to shared.ts explaining acceptable sync FS usage
- Fix audit-logger test for sync closeAuditLogger
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change the protected row number range from 7000-7999 to 2000-7999 to prevent deletion of materials in this broader range.
- Updated isMaterialDeletable() method logic
- Updated getSkipReason() error messages
- Updated test cases to reflect new range boundaries
- Updated documentation templates and error collection guide
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add *.yaml text eol=lf rule to .gitattributes for consistent line endings
- Format cleaner.ts with Prettier (parameter and chain formatting)
- Format CleanerPage.tsx (JSX formatting)
- Format cleaner.test.ts (array formatting)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit integrates the logging infrastructure across the entire application:
IPC Layer:
- Add logger-handler.ts with centralized IPC logging channels
- Integrate audit logging into auth, cleaner, extractor handlers
- Add structured logging for IPC operations and data flow
Service Layer:
- Add logger integration to ERP services (extractor, cleaner)
- Integrate logging into excel-parser and user DAO
- Add operation tracking and error logging
Renderer Layer:
- Add useLogger hook for component-level logging
- Update App.tsx with session and user activity logging
- Enable frontend audit trail for critical actions
Testing:
- Add comprehensive IPC logging integration tests
- Enhance unit test coverage for logger and audit-logger
- Add end-to-end logging flow validation
Types:
- Update preload type definitions for logging APIs
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add waitForLoginResult() method using Promise.race to detect:
- Success: .nc-workbench-icon element visible
- Failure: '名称或密码错误' error text visible
- Force login: click confirm button and re-detect
- Extract timeout constants (PAGE_LOAD_TIMEOUT, LOGIN_RESULT_TIMEOUT, FORCE_LOGIN_TIMEOUT)
- Improve error handling with clear error messages
- Add unit tests for class structure verification
- Fix test setup for Electron app mock
Fixes: ERP login success/failure detection was ambiguous
Apply consistent code formatting using Prettier to improve code readability
and maintain style consistency throughout the project.
Co-Authored-By: Claude (glm-5) <noreply@anthropic.com>
- Add DataImportService for reading Excel and importing to database
- Extend DiscreteMaterialPlanDAO with deleteBySourceNumbers and batchInsert
- Auto-trigger database write after successful Excel merge
- Support batch delete by SourceNumber and batch insert (1000/batch)
- Update ExtractorPage UI to show import results
- Fix SQL Server query to handle undefined recordset for DELETE/INSERT
Co-Authored-By: Claude (glm-5) <noreply@anthropic.com>
- Add SqlServerService and MySqlService for database persistence
- Implement IPC handlers for file, extractor, cleaner, and database operations
- Define IPC API types and update preload script
- Create ExtractorPage UI with OrderNumberInput component
- Add unit and integration tests for MySQL and SQL Server
- Update vitest config with path aliases
**Core Implementation (src/main/services/erp/cleaner.ts):**
- CleanerService class with dry-run mode support
- Material deletion logic with safety constraints:
- Row numbers 7000-7999 are protected
- Materials with pending quantity are skipped
- Materials not in delete list are ignored
- Order processing with nested iframe navigation
- Progress callback support for UI integration
**Types (src/main/types/cleaner.types.ts):**
- CleanerInput: order numbers, material codes, dry-run flag
- CleanerResult: processing statistics and details
- OrderCleanDetail: per-order breakdown
**Tests:**
- Unit tests for shouldDeleteMaterial logic
- Integration tests for order processing
- Dry-run mode validation
- Navigation tests
Reference: playwrite/utils/discrete_material_plan_cleaner.py
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implement Excel parsing module for ERP exported files following TDD principles.
Key features:
- Parse Excel files with multiple orders per file
- Extract order header information (production order, product code, etc.)
- Extract material data rows with 13 fields
- Handle empty orders gracefully
- Detect footer rows (制单人/打印人)
- Map Chinese field names to English property names
- Support field name mapping from Python reference
Implementation:
- ExcelParser class with parse() method
- DiscreteMaterialPlan and ExcelParseOptions types
- OrderHeader interface for order metadata
- Test fixtures with realistic Excel structure
- Comprehensive unit tests (3 tests, all passing)
Reference: playwrite/utils/excel_converter.py
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implement Task 3.1: Core Extractor Logic with TDD approach.
Changes:
- Add ExtractorService class with batch processing and download support
- Update ERP_LOCATORS with extractor-specific selectors from Python reference
- Add integration tests for single and multiple order extraction
- Add unit tests for batch creation logic
- Update existing tests to skip gracefully without ERP credentials
Features:
- Navigate to discrete material plan page with nested iframes
- Setup query interface (search icon, order query, limit settings)
- Batch download with configurable batch size (default: 100)
- Progress callback support for real-time updates
- Error handling for individual batch failures
- File download handling with proper wait strategies
Reference: playwrite/utils/discrete_material_plan_extractor.py
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implement ErpAuthService with TDD approach:
- Add login(), close(), getSession(), isActive() methods
- Use Playwright chromium with headless:false for debugging
- Manage browser lifecycle and session state
- Handle authentication flow with ERP_LOCATORS
- Add integration tests for login scenarios
- Add unit tests for session management
- Fix dotenv config path in test setup
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>