fix: restore full typecheck stability

This commit is contained in:
Misaka
2026-03-21 09:17:58 +08:00
parent 08bd2cb7d5
commit 2fba07fd8f
13 changed files with 114 additions and 130 deletions

1
package-lock.json generated
View File

@@ -16433,7 +16433,6 @@
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
"integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
"license": "MIT", "license": "MIT",
"peer": true,
"peerDependencies": { "peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
} }

View File

@@ -15,6 +15,13 @@ import { SessionManager } from '../services/user/session-manager'
import { createLogger } from '../services/logger' import { createLogger } from '../services/logger'
import { logAudit } from '../services/logger/audit-logger' import { logAudit } from '../services/logger/audit-logger'
import type { UserInfo } from '../types/user.types' import type { UserInfo } from '../types/user.types'
import type {
CurrentUserResponse,
LoginRequest,
LoginResponse,
SilentLoginResponse,
UserSelectionResponse
} from '../types/auth-ipc.types'
import { IPC_CHANNELS } from '../../shared/ipc-channels' import { IPC_CHANNELS } from '../../shared/ipc-channels'
import { ValidationError } from '../types/errors' import { ValidationError } from '../types/errors'
import { withErrorHandling, type IpcResult } from './index' import { withErrorHandling, type IpcResult } from './index'
@@ -22,50 +29,6 @@ import { UpdateService } from '../services/update/update-service'
const log = createLogger('AuthHandler') const log = createLogger('AuthHandler')
/**
* Login request
*/
export interface LoginRequest {
username: string
password: string
}
/**
* Login response
*/
export interface LoginResponse {
success: boolean
userInfo?: UserInfo
error?: string
}
/**
* Silent login response
*/
export interface SilentLoginResponse {
success: boolean
userInfo?: UserInfo
requiresUserSelection?: boolean // True if admin needs to select a user
error?: string
}
/**
* User selection response
*/
export interface UserSelectionResponse {
success: boolean
userInfo?: UserInfo
error?: string
}
/**
* Current user response
*/
export interface CurrentUserResponse {
isAuthenticated: boolean
userInfo?: UserInfo
}
/** /**
* Register IPC handlers for user authentication * Register IPC handlers for user authentication
*/ */

View File

@@ -19,19 +19,12 @@ import { registerUpdateHandlers } from './update-handler'
import { createLogger, logError } from '../services/logger' import { createLogger, logError } from '../services/logger'
import { serializeError, sanitizeError } from '../services/logger/error-utils' import { serializeError, sanitizeError } from '../services/logger/error-utils'
import { getErrorMessage, getErrorCode, isBaseError } from '../types/errors' import { getErrorMessage, getErrorCode, isBaseError } from '../types/errors'
import type { IpcResult } from '../types/ipc.types'
export type { IpcResult } from '../types/ipc.types'
const log = createLogger('IPC') const log = createLogger('IPC')
/**
* Standard result type for all IPC handlers
*/
export interface IpcResult<T = unknown> {
success: boolean
data?: T
error?: string
code?: string
}
export function ok<T>(data: T): IpcResult<T> { export function ok<T>(data: T): IpcResult<T> {
return { success: true, data } return { success: true, data }
} }

View File

@@ -10,38 +10,12 @@ import { ipcMain } from 'electron'
import { create, type IDatabaseService } from '../services/database' import { create, type IDatabaseService } from '../services/database'
import { OrderNumberResolver } from '../services/erp/order-resolver' import { OrderNumberResolver } from '../services/erp/order-resolver'
import { createLogger } from '../services/logger' import { createLogger } from '../services/logger'
import type { OrderMapping, ResolutionStats } from '../services/erp/order-resolver' import type { ResolverInput, ResolverResponse } from '../types/resolver-ipc.types'
import { IPC_CHANNELS } from '../../shared/ipc-channels' import { IPC_CHANNELS } from '../../shared/ipc-channels'
import { withErrorHandling, type IpcResult } from './index' import { withErrorHandling, type IpcResult } from './index'
const log = createLogger('ResolverHandler') const log = createLogger('ResolverHandler')
/**
* Resolver input from renderer
*/
export interface ResolverInput {
/** List of order numbers/productionIDs to resolve */
inputs: string[]
}
/**
* Resolver response to renderer
*/
export interface ResolverResponse {
/** Whether the resolution was successful */
success: boolean
/** Resolved order mappings */
mappings?: OrderMapping[]
/** Valid production order numbers ready for use */
validOrderNumbers?: string[]
/** Warning messages for invalid inputs */
warnings?: string[]
/** Resolution statistics */
stats?: ResolutionStats
/** Error message if failed */
error?: string
}
/** /**
* Register IPC handlers for order number resolver * Register IPC handlers for order number resolver
*/ */

View File

@@ -13,42 +13,14 @@
import type { IDatabaseService } from '../database' import type { IDatabaseService } from '../database'
import { ConfigManager } from '../config/config-manager' import { ConfigManager } from '../config/config-manager'
import { createLogger } from '../logger' import { createLogger } from '../logger'
import type {
OrderMapping,
OrderNumberType,
ResolutionStats
} from '../../types/order-resolver.types'
const log = createLogger('OrderResolver') const log = createLogger('OrderResolver')
/**
* Order mapping result
*/
export interface OrderMapping {
/** Original input from user */
input: string
/** Recognized productionID (if input matches productionID pattern) */
productionId?: string
/** Final production order number to use */
orderNumber?: string
/** Whether the order number was successfully resolved */
resolved: boolean
/** Error message if resolution failed */
error?: string
}
/**
* Order number type recognition result
*/
export type OrderNumberType = 'productionId' | 'orderNumber' | 'unknown'
/**
* Resolution statistics
*/
export interface ResolutionStats {
totalInputs: number
validOrderNumbers: number
validProductionIds: number
resolvedCount: number
failedCount: number
unknownFormat: number
}
/** /**
* ProductionID pattern: 2 digits + 1 letter + 1-6 digits * ProductionID pattern: 2 digits + 1 letter + 1-6 digits
* Examples: 22A1, 22A123, 26B10617 * Examples: 22A1, 22A123, 26B10617

View File

@@ -0,0 +1,30 @@
import type { UserInfo } from './user.types'
export interface LoginRequest {
username: string
password: string
}
export interface LoginResponse {
success: boolean
userInfo?: UserInfo
error?: string
}
export interface SilentLoginResponse {
success: boolean
userInfo?: UserInfo
requiresUserSelection?: boolean
error?: string
}
export interface UserSelectionResponse {
success: boolean
userInfo?: UserInfo
error?: string
}
export interface CurrentUserResponse {
isAuthenticated: boolean
userInfo?: UserInfo
}

View File

@@ -11,7 +11,7 @@ import type {
ExportResultItem, ExportResultItem,
ExportResultResponse ExportResultResponse
} from './cleaner.types' } from './cleaner.types'
import type { IpcResult } from '../ipc' import type { IpcResult } from './ipc.types'
/** /**
* MySQL connection configuration * MySQL connection configuration
@@ -176,13 +176,23 @@ export interface ReportAPI {
/** /**
* List all reports across all users (Admin only typically) * List all reports across all users (Admin only typically)
*/ */
listAll: () => Promise<IpcResult<{ key: string; filename: string; username: string; lastModified?: Date; size?: number }[]>> listAll: () => Promise<
IpcResult<
{ key: string; filename: string; username: string; lastModified?: Date; size?: number }[]
>
>
/** /**
* List reports for a specific user * List reports for a specific user
* @param username - Username to list reports for * @param username - Username to list reports for
*/ */
listByUser: (username: string) => Promise<IpcResult<{ key: string; filename: string; username: string; lastModified?: Date; size?: number }[]>> listByUser: (
username: string
) => Promise<
IpcResult<
{ key: string; filename: string; username: string; lastModified?: Date; size?: number }[]
>
>
/** /**
* Download a specific report by key * Download a specific report by key

View File

@@ -0,0 +1,6 @@
export interface IpcResult<T = unknown> {
success: boolean
data?: T
error?: string
code?: string
}

View File

@@ -0,0 +1,18 @@
export interface OrderMapping {
input: string
productionId?: string
orderNumber?: string
resolved: boolean
error?: string
}
export type OrderNumberType = 'productionId' | 'orderNumber' | 'unknown'
export interface ResolutionStats {
totalInputs: number
validOrderNumbers: number
validProductionIds: number
resolvedCount: number
failedCount: number
unknownFormat: number
}

View File

@@ -0,0 +1,14 @@
import type { OrderMapping, ResolutionStats } from './order-resolver.types'
export interface ResolverInput {
inputs: string[]
}
export interface ResolverResponse {
success: boolean
mappings?: OrderMapping[]
validOrderNumbers?: string[]
warnings?: string[]
stats?: ResolutionStats
error?: string
}

View File

@@ -1,13 +1,19 @@
import type { FileAPI, ExtractorAPI, CleanerAPI, DatabaseAPI, ReportAPI } from '../main/types/ipc-api.types' import type {
import type { ResolverInput, ResolverResponse } from '../main/ipc/resolver-handler' FileAPI,
ExtractorAPI,
CleanerAPI,
DatabaseAPI,
ReportAPI
} from '../main/types/ipc-api.types'
import type { ResolverInput, ResolverResponse } from '../main/types/resolver-ipc.types'
import type { UserInfo } from '../main/types/user.types' import type { UserInfo } from '../main/types/user.types'
import type { import type {
CurrentUserResponse,
LoginRequest, LoginRequest,
LoginResponse, LoginResponse,
SilentLoginResponse, SilentLoginResponse,
UserSelectionResponse, UserSelectionResponse
CurrentUserResponse } from '../main/types/auth-ipc.types'
} from '../main/ipc/auth-handler'
import type { import type {
ValidationRequest, ValidationRequest,
ValidationResponse, ValidationResponse,
@@ -19,7 +25,7 @@ import type {
ConnectionTestResult, ConnectionTestResult,
SaveSettingsResult SaveSettingsResult
} from '../main/types/settings.types' } from '../main/types/settings.types'
import type { IpcResult } from '../main/ipc' import type { IpcResult } from '../main/types/ipc.types'
import type { LogLevel } from '../shared/ipc-channels' import type { LogLevel } from '../shared/ipc-channels'
import type { CleanerConfig } from '../main/types/config.schema' import type { CleanerConfig } from '../main/types/config.schema'
import type { import type {

View File

@@ -2,15 +2,15 @@ import { contextBridge, ipcRenderer } from 'electron'
import type { MySqlConfig, SqlServerConfig } from '../main/types/ipc-api.types' import type { MySqlConfig, SqlServerConfig } from '../main/types/ipc-api.types'
import type { ExtractorInput, ExtractionProgress } from '../main/types/extractor.types' import type { ExtractorInput, ExtractionProgress } from '../main/types/extractor.types'
import type { CleanerInput, CleanerProgress, ExportResultItem } from '../main/types/cleaner.types' import type { CleanerInput, CleanerProgress, ExportResultItem } from '../main/types/cleaner.types'
import type { ResolverInput } from '../main/ipc/resolver-handler' import type { ResolverInput } from '../main/types/resolver-ipc.types'
import type { LoginRequest } from '../main/ipc/auth-handler' import type { LoginRequest } from '../main/types/auth-ipc.types'
import type { UserInfo } from '../main/types/user.types' import type { UserInfo } from '../main/types/user.types'
import type { import type {
ValidationRequest, ValidationRequest,
MaterialTypeRecord, MaterialTypeRecord,
MaterialTypeBatchRequest MaterialTypeBatchRequest
} from '../main/types/validation.types' } from '../main/types/validation.types'
import type { IpcResult } from '../main/ipc' import type { IpcResult } from '../main/types/ipc.types'
import { IPC_CHANNELS, type LogLevel } from '../shared/ipc-channels' import { IPC_CHANNELS, type LogLevel } from '../shared/ipc-channels'
import type { CleanerConfig } from '../main/types/config.schema' import type { CleanerConfig } from '../main/types/config.schema'
import type { DownloadReleaseRequest, UpdateStatus } from '../main/types/update.types' import type { DownloadReleaseRequest, UpdateStatus } from '../main/types/update.types'
@@ -234,8 +234,7 @@ const api = {
installDownloaded: (): Promise<IpcResult<void>> => installDownloaded: (): Promise<IpcResult<void>> =>
invokeIpc(IPC_CHANNELS.UPDATE_INSTALL_DOWNLOADED), invokeIpc(IPC_CHANNELS.UPDATE_INSTALL_DOWNLOADED),
onStatusChanged: (callback: (data: UpdateStatus) => void) => { onStatusChanged: (callback: (data: UpdateStatus) => void) => {
const subscription = (_event: Electron.IpcRendererEvent, data: UpdateStatus) => const subscription = (_event: Electron.IpcRendererEvent, data: UpdateStatus) => callback(data)
callback(data)
ipcRenderer.on(IPC_CHANNELS.UPDATE_STATUS_CHANGED, subscription) ipcRenderer.on(IPC_CHANNELS.UPDATE_STATUS_CHANGED, subscription)
return () => ipcRenderer.removeListener(IPC_CHANNELS.UPDATE_STATUS_CHANGED, subscription) return () => ipcRenderer.removeListener(IPC_CHANNELS.UPDATE_STATUS_CHANGED, subscription)
} }

View File

@@ -5,7 +5,7 @@
"src/renderer/src/**/*", "src/renderer/src/**/*",
"src/renderer/src/**/*.tsx", "src/renderer/src/**/*.tsx",
"src/preload/*.d.ts", "src/preload/*.d.ts",
"src/main/types/*.ts", "src/main/types/**/*.ts",
"src/shared/*.ts" "src/shared/*.ts"
], ],
"compilerOptions": { "compilerOptions": {