Cache isProduction() result at module load to avoid repeated property
lookups. Add isSerializedError() check in format functions to skip
re-serialization when error objects have already been processed by
logError/formatErrorForLogging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move logger close from before-quit to will-quit to keep the logger available
for uncaughtException handlers that may fire during shutdown. Remove 4
redundant console.error calls that duplicate Winston logger output.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Extract shared module: consolidate getLogDir() and isProduction()
into shared.ts, eliminate duplication across logger modules
2. Make retention config effective: delay file transport creation
until config is loaded, apply appRetention/auditRetention from config.yaml
3. Add before-quit log flush: close logger and audit logger on
app exit to prevent log loss
4. Unify logError entry point: remove duplicate logError from index.ts,
re-export from error-utils.ts with richer error context
5. Renderer log level filtering: add client-side level check in preload
to skip IPC for filtered-out messages
6. Child logger cache + audit cleanup: cache child loggers in IPC
handler for performance, remove redundant timestamp format in audit logger
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Admin-only delete button in operation history modal
- Replace dropdown with multi-select chip filters for Admin users
- Support filtering by multiple usernames using IN clause
- Fix user state propagation by passing currentUser via props
- Change GetBatchesOptions.username to usernames (array)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The database stores time in UTC format, and the UI should display UTC
time without timezone conversion. Use getUTCXxx() methods instead of
getHours() to avoid adding 8-hour timezone offset.
Also extract common datetime formatting logic to reduce code duplication.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously updateBatchStatus wrote the batch-level total recordCount to
every row, causing the detail view to show misleading identical counts.
Now mergeFiles collects per-order material counts, the handler writes
each order's count individually via updateRecordStatus, and batch
aggregation uses SUM instead of MAX for accurate totals.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MySQL binary protocol prepared statements (connection.execute()) do not
support ? placeholders in LIMIT/OFFSET clauses, causing "Incorrect
arguments to mysqld_stmt_execute". Embed validated integer values directly
for MySQL while keeping parameterized queries for SQL Server.
Also apply React best practices to ExtractorOperationHistoryModal:
- Hoist formatDateTime to module level
- Wrap async handlers with useCallback for stable effect dependencies
- Import shared types instead of duplicating definitions
- Use ternary for conditional rendering
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a new operation history feature for the extractor module that tracks
all extraction operations with persistent database storage.
Features:
- Records extraction operations with batch tracking (UUID-based)
- Preserves production ID to order number mapping
- Shows batch statistics (orders, records, success/failure counts)
- Expandable details for each batch showing individual order records
- User-based permission: Admin sees all records, User sees own records only
- Delete functionality with permission validation
Database:
- New ExtractorOperationHistory table schema
- Supports both SQL Server and MySQL
- Indexed on BatchId, UserId, and OperationTime
Files:
- Add DAO class for history operations
- Add IPC handler with permission checks
- Add preload API wrapper
- Add React modal component with expandable batch details
- Integrate history recording into extractor handler
- Add operation history button to ExtractorPage
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove all references to 'Guest' user type from the codebase, simplifying the role system to only support 'Admin' and 'User' roles.
Changes:
- Update type definitions to exclude 'Guest' from UserType
- Remove isGuest() method from SessionManager
- Remove Guest-specific logic from update services
- Update all type assertions from 'Admin | User | Guest' to 'Admin | User'
- Remove Guest UI styling from UserSelectionDialog
- Replace Guest fallback with ValidationError in settings handler
Error handling:
- Zod schema now rejects 'Guest' as invalid user type
- TypeScript will fail compilation if 'Guest' is referenced
- Runtime errors occur if database contains Guest users
No database migration needed (confirmed: no Guest users exist)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Change update check and download to async execution, allowing immediate app entry for User users
- Updates run in background, showing update prompt when download completes
- Optimize login flow experience, eliminating blocking time caused by update downloads
- Add release notes for version 1.5.1
Co-Authored-By: Claude Sonnet 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>
Added a new "View Reports" button to the CleanerPage which opens a new ReportViewerDialog. This dialog lists all available execution reports stored in S3 for the current user, or for all users if the current user is an admin.
The reports are downloaded as Markdown and rendered using react-markdown.
Added three new IPC channels to fetch and download reports using the existing RustfsService and S3Client.
Co-authored-by: luwamgere15-crypto <255338376+luwamgere15-crypto@users.noreply.github.com>
- Add QueryResultRow interface to represent query results with order numbers
- Add collectQueryResultRows() method to extract order numbers upfront before processing
- Add extractOrderNumberFromQueryRow() helper to parse order numbers from query result cells
- Process rows with order number context instead of just row indexes
- Use actual order numbers in error details instead of BATCH_ROW_X placeholders
- Pass expected order number to detail processing for better validation
- Fix retry success handling to properly update statistics when retries succeed
This change provides better error context by associating each processed row with its actual order number from the query results, improving traceability and debugging.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add case-insensitive comparison for production ID database queries:
- SQL Server: use COLLATE SQL_Latin1_General_CP1_CI_AS
- MySQL: use UPPER() function for both field and input
- Map lookup: store keys in lowercase for consistent matching
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- CleanerPage now uses updateProcessConcurrency instead of setProcessConcurrency
- This ensures slider changes are persisted to config.yaml via IPC
- Remove unused queryBatchSize and setProcessConcurrency from destructuring
- 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>
- Add retry logic with max 2 attempts per failed order
- Track retry statistics (retriedOrders, successfulRetries)
- Generate detailed retry report section in execution reports
- Display retry metrics in ExecutionReportDialog UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix getTableName to properly split schema_tablename format
- Convert productionContractData_26年压力表合同数据 to [productionContractData].[26年压力表合同数据]
- Extend productionId pattern to support 1-6 digit serial numbers
Co-Authored-By: Claude (glm-5) <noreply@anthropic.com>
Fixes a bug where clearing the order number input in the extraction page
did not clear the shared Production IDs in the main process. This caused
the data cleanup page to continue using stale data when filtering by
Production ID.
Changes:
- Add VALIDATION_CLEAR_SHARED_PRODUCTION_IDS IPC channel
- Register handler to clear shared Production IDs by sender ID
- Expose clearSharedProductionIds API in preload script
- Update ExtractorPage to call clear when order numbers are empty
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add validation to detect and report when no order numbers are found from Production IDs (either from shared inputs or file). Provides clear Chinese error messages to guide users when their inputs don't match any database records.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Core improvements:
- Fix focus restoration timing by using queueMicrotask only (removed double-layer async)
- Add comprehensive error handling with dev-mode logging for all failure scenarios
- Validate element visibility (display: none, visibility: hidden) before restoring focus
- Check disabled state and implement fallback to nearest focusable ancestor
- Add findNearestFocusableElement() helper for robust fallback strategy
- Add tabindex="-1" to focusable selectors for better focus management
- Use preventScroll option when calling focus() to prevent scroll jumps
Additional fixes:
- Remove unnecessary type conversion in Modal.tsx
- Fix TypeScript unused variable errors in main process
- Clean up unused imports in bip-users-dao.ts
- Add ARIA attributes and focus management to LoginDialog
- Add triggerRef support to UserSelectionDialog and ExecutionReportDialog
- Refactor ExecutionReportDialog to use Modal component
- Improve MaterialTypeManagementDialog with focus management
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add error-utils module with serializeError and sanitizeError utilities
- Enhance IPC error handling to capture full error context including stack traces
- Add logError helper function for consistent error logging across the application
- Update console and file log formats to properly serialize error objects
- Replace all basic error logging in BIPUsersDAO with structured logError calls
- Add ErrorLike and SerializedError type interfaces for type safety
This improves debugging capability by preserving full error details in development
while sanitizing sensitive information in production logs.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fix all TS6133 errors (unused variables) across service layer:
- Remove unused imports (path, ExtractionProgress type)
- Prefix unused parameters with underscore (_session, _totalBatches, etc.)
- Remove unused _verbose field and constructor from ExcelParser
- Remove unused _importToDatabase method from ExtractorService
- Remove unused _importProgress variable
This ensures clean type checking and eliminates dead code.
Co-Authored-By: Claude Sonnet 4.5 <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>