Commit Graph

79 Commits

Author SHA1 Message Date
Joseph Doherty 7b3592df96 feat(datasync): register EtlPipelineFactory in DI 2026-01-06 14:03:31 -05:00
Joseph Doherty e75cd70d94 fix(datasync): correct MisData postScript and query filtering
- Replace placeholder postScript with actual MIS data post-processing:
  1. Sets ObsoleteDate based on BackLevel records
  2. Sets ObsoleteDate for remaining NULL cases
  3. Rebuilds PK_MisData index

- Add massQuery support to SourceConfig for mode-specific queries
- MisData mass sync now uses query without date filter (like legacy)
- EtlPipelineFactory selects massQuery when in mass mode if available
- Remove unnecessary minDtOffset from MisData mass mode config
2026-01-06 14:01:26 -05:00
Joseph Doherty 4298fb8147 feat(datasync): add pipelines.json config for all sync tables
Configure ETL pipelines for all 9 sync tables:
- WorkOrder_Curr, Lot, LotUsage_Curr (JDE)
- Item, WorkCenter, ProfitCenter (JDE)
- JdeUser, Branch (JDE)
- MisData (CMS) with postScript for ProcessedFlag update

Each pipeline includes:
- Source query with JDE Julian date/time parameters
- Sync modes for mass (365 day lookback, prePurge, reIndex)
  and incremental (7 day lookback) operations
- Destination table with match columns and updateWhen conditions
2026-01-06 13:53:30 -05:00
Joseph Doherty 795c15df56 feat(datasync): add EtlPipelineFactory with JSON config support
- Implement IEtlPipelineFactory with ForTable() method returning a builder
- Load pipeline config from JSON file path (from PipelineOptions)
- Parse config using System.Text.Json with PropertyNameCaseInsensitive
- Builder supports WithMode() and WithMinimumDate() fluent methods
- Create DbQuerySource for source with ParameterFormatConverter for JDE dates
- Create DbBulkMergeDestination or DbBulkImportDestination based on sync mode
- Mass mode defaults to bulkImport, incremental defaults to bulkMerge
- Support destination override in sync mode config
- Execute pre/post scripts from config (prePurge, reIndex, custom scripts)
- Validate config: require mass and incremental modes, reject runtime params
- Add comprehensive tests for factory, builder, and config validation
2026-01-06 13:45:36 -05:00
Joseph Doherty 0d9e6db7f2 feat(datasync): add IEtlPipelineFactory and SyncMode contracts 2026-01-06 13:38:51 -05:00
Joseph Doherty 8af4f9915f feat(datasync): extend DbBulkMergeDestination with excludeFromUpdate and updateCondition 2026-01-06 13:35:25 -05:00
Joseph Doherty eb85ab6f34 feat(datasync): add generic DbQuerySource for JDE/CMS/LotFinder
Extend DbQuerySource to support multiple connection types:
- Add connectionType parameter ("jde", "cms", "lotfinder")
- Use appropriate IDbConnectionFactory method for each type
- Support Dictionary<string, object> parameters
- Use DbConnection/DbCommand for cross-database compatibility
2026-01-06 13:30:00 -05:00
Joseph Doherty 1f7fd9f0f2 feat(datasync): add ParameterFormatConverter with JDE date/time support 2026-01-06 13:25:15 -05:00
Joseph Doherty 5f8b4422b3 chore: remove obsolete Table Type scripts (033-039) 2026-01-06 13:24:38 -05:00
Joseph Doherty 2fd1cb1fe7 feat(db): add validation stored procedure with THROW errors 2026-01-06 13:20:42 -05:00
Joseph Doherty e875244c8f feat(datasync): add pipeline configuration models 2026-01-06 13:20:35 -05:00
Joseph Doherty 28d2fd30c9 feat(db): add inline TVFs for complex object extraction from SearchCriteria 2026-01-06 13:17:23 -05:00
Joseph Doherty 250323f8b0 feat(db): add inline TVFs for simple array extraction from SearchCriteria 2026-01-06 13:14:18 -05:00
Joseph Doherty 5ee348dc98 feat(db): add scalar extraction functions for SearchCriteria JSON 2026-01-06 13:11:11 -05:00
Joseph Doherty c626ffbd69 test: add edge case tests to ApiClientBaseTests
Add 7 edge case tests for ApiClientBase:
- GetAsync_Returns200_EmptyBody_MapsToApiError
- GetAsync_Returns200_InvalidJson_MapsToApiError
- GetAsync_Returns204_ForUnitType_MapsToSuccess
- GetAsync_Returns204_ForNonUnitType_MapsToApiError
- GetAsync_NetworkException_MapsToApiError
- GetAsync_Timeout_MapsToApiError
- GetAsync_Returns400_WithoutValidationFormat_MapsToApiError

Also fix bug in ApiClientBase where 204 NoContent for Unit type
failed due to incorrect type casting. The implicit conversion from
Unit to ApiResult<Unit> must be applied before the runtime cast.
2026-01-06 11:23:54 -05:00
Joseph Doherty 6bd6138b2a chore(client): add Extensions namespace to global imports
Add @using JdeScoping.Client.Extensions to _Imports.razor so that
extension methods (like ViewModelMappingExtensions) are available
globally in Razor components without explicit using statements.
2026-01-06 10:39:44 -05:00
Joseph Doherty 4e1cd2c221 chore(client): delete old service files replaced by API clients
Delete old service interfaces and implementations that have been
replaced by the new typed API clients:
- ISearchService/SearchService -> ISearchApiClient/SearchApiClient
- ILookupService/LookupService -> ILookupApiClient/LookupApiClient
- IFileService/FileService -> IFileApiClient/FileApiClient

Also remove unused IFileService injection from SearchEdit.razor
(download functionality now uses SearchApi.GetResultsAsync).
2026-01-06 10:38:41 -05:00
Joseph Doherty 6701da137d chore(client): remove old service registrations
Remove ISearchService, ILookupService, and IFileService registrations
from Program.cs as these are now replaced by the typed API clients
(ISearchApiClient, ILookupApiClient, IFileApiClient).
2026-01-06 10:37:15 -05:00
Joseph Doherty 828034d0e2 feat(client): migrate PartOperationFilterPanel to API clients 2026-01-06 10:35:33 -05:00
Joseph Doherty 251e2f910f feat(client): migrate ComponentLotFilterPanel to API clients 2026-01-06 10:34:33 -05:00
Joseph Doherty ead947bf57 feat(client): migrate WorkOrderFilterPanel to API clients 2026-01-06 10:33:36 -05:00
Joseph Doherty 8e05afb34f feat(client): migrate OperatorFilterPanel to API clients 2026-01-06 10:32:54 -05:00
Joseph Doherty ee6afc9e4e feat(client): migrate ProfitCenterFilterPanel to API clients 2026-01-06 10:32:25 -05:00
Joseph Doherty f49390ad01 feat(client): migrate WorkCenterFilterPanel to API clients 2026-01-06 10:31:58 -05:00
Joseph Doherty a6348c4268 feat(client): migrate ItemNumberFilterPanel to API clients
Update ItemNumberFilterPanel.razor to use ILookupApiClient and IFileApiClient
instead of legacy ILookupService and IFileService interfaces. All methods now
use the result.Switch() pattern for proper ApiResult error handling.
2026-01-06 10:30:20 -05:00
Joseph Doherty 20f9a1c683 feat(client): migrate MainLayout.razor to IAuthApiClient
- Replace IAuthService with IAuthApiClient for logout functionality
- Add @using JdeScoping.Core.ApiContracts
- LogoutAsync now calls AuthApi.LogoutAsync() and navigates to login
  regardless of API result
2026-01-06 10:27:24 -05:00
Joseph Doherty b555f57b72 feat(client): migrate Login.razor to IAuthApiClient
- Replace IAuthService injection with IAuthApiClient
- Keep ICryptoService for credential encryption
- Add AuthStateProvider injection to notify authentication state
- Use result.Switch() pattern for ApiResult<LoginResultModel> handling
- Properly handle ValidationError with FieldErrors dictionary
2026-01-06 10:25:54 -05:00
Joseph Doherty 6054412a77 refactor: move JSON ETL classes to DataSync.Dev
Move dev-only JSON reading infrastructure from DataSync to DataSync.Dev:
- JsonColumnSchema (Models/)
- JsonZstdFileSource (Sources/)
- JsonStreamingDataReader (Sources/)
- Utf8JsonStreamingDataReader (Sources/)

Update namespaces and using statements in all DevEtl files.
2026-01-06 10:25:45 -05:00
Joseph Doherty a77b71e53d feat(client): migrate SearchEdit.razor to ISearchApiClient
- Replace ISearchService with ISearchApiClient
- Add @using for JdeScoping.Core.ApiContracts and JdeScoping.Client.Extensions
- Update LoadSearchAsync to use result.Switch() pattern with ApiResult<T>
- Handle CopySearchId, Id, and new search cases with proper error handling
- Use ToClient() extension method to convert Core to Client SearchViewModel
- Add _errorMessage field and display error alert in UI
- Update SubmitSearchInternalAsync and DownloadResultsAsync for consistency
- Add FormatValidationErrors helper for ValidationError.FieldErrors
2026-01-06 10:23:36 -05:00
Joseph Doherty b86d48657e feat(client): migrate SearchQueue.razor to ISearchApiClient
- Replace ISearchService injection with ISearchApiClient
- Add @using for JdeScoping.Core.ApiContracts and JdeScoping.Client.Extensions
- Update LoadQueueAsync to use result.Switch() pattern with ApiResult<T>
- Add _errorMessage field for error display
- Add RadzenAlert for error message display in UI
2026-01-06 10:19:53 -05:00
Joseph Doherty b08f5418ec feat(client): migrate Searches.razor to ISearchApiClient
- Replace ISearchService injection with ISearchApiClient
- Add @using for JdeScoping.Core.ApiContracts and JdeScoping.Client.Extensions
- Update LoadSearchesAsync to use ApiResult<T>.Switch() pattern
- Add _errorMessage field for error state
- Display RadzenAlert for error conditions
- Use ToClientList() extension method to convert Core->Client view models
2026-01-06 10:18:11 -05:00
Joseph Doherty 81b07ce027 feat: extract DevEtl to JdeScoping.DataSync.Dev project
- Create JdeScoping.DataSync.Dev for sandbox testing ETL code
- Create JdeScoping.DataSync.Dev.Tests for associated tests
- Move 22 source files and 8 test files
- Update namespaces from DevEtl to Dev
- Add both projects to solution
2026-01-06 10:18:09 -05:00
Joseph Doherty 7ad4e3ec1c feat(client): configure HttpClient with AuthRedirectHandler
- Add using statement for JdeScoping.Client.Http namespace
- Register AuthRedirectHandler as a scoped service
- Replace simple HttpClient registration with handler pipeline
- AuthRedirectHandler intercepts 401 responses and redirects to login
- Keep all existing service registrations for backward compatibility
2026-01-06 10:15:48 -05:00
Joseph Doherty ba88450feb feat(client): add ViewModelMappingExtensions for Core<->Client mapping
Add extension methods to convert between Core and Client view models:
- SearchViewModel: Core (enum Status) <-> Client (string Status)
- SearchCriteria: Core (primitive lists) <-> Client (full ViewModels)
- JdeUserViewModel -> OperatorViewModel

Handles structural differences in criteria where Core uses primitive
lists (List<long>, List<string>) and Client uses full objects.
2026-01-06 10:14:09 -05:00
Joseph Doherty 0b50c03e44 feat(client): add AuthRedirectHandler for global 401 redirect
Add HTTP message handler that intercepts 401 Unauthorized responses
and redirects to the login page with return URL preserved.
2026-01-06 10:11:43 -05:00
Joseph Doherty badc6a43f3 fix(datasync): throw on cancellation in DevEtlRegistry.RunAllAsync 2026-01-03 16:32:29 -05:00
Joseph Doherty 6bd2b3c285 feat(datasync): add DevEtlRegistry for managing development ETL pipelines 2026-01-03 16:28:35 -05:00
Joseph Doherty fd1e5454da feat(datasync): add BranchDevEtl pipeline for Branch table dev loading 2026-01-03 16:24:34 -05:00
Joseph Doherty 2629cb26e0 fix(datasync): add guards and exception safety to JsonZstdFileSource 2026-01-03 16:21:59 -05:00
Joseph Doherty 57a44e0f3a feat(datasync): add JsonZstdFileSource for reading zstd-compressed JSON files 2026-01-03 16:19:28 -05:00
Joseph Doherty 6d2d8134cb fix(datasync): dispose JsonDocument in JsonStreamingDataReader.Read() 2026-01-03 16:17:38 -05:00
Joseph Doherty bd1c2fd656 feat(datasync): add JsonStreamingDataReader for streaming JSON array parsing 2026-01-03 16:14:31 -05:00
Joseph Doherty bf7cfe9bf1 feat(datasync): add JsonColumnSchema record for ETL column metadata 2026-01-03 16:11:00 -05:00
Joseph Doherty 9ff21958bb feat(datasync): add ZstdSharp.Port package for zstd decompression 2026-01-03 16:08:13 -05:00
Joseph Doherty 7dcbacd5ca fix(etl): address Codex MCP review findings for Phase 2
- Filter MERGE SQL columns to only include columns that exist in destination
  (allColumns and updateColumns were using unfiltered source columns)
- Fix schema-qualified table names to use proper [schema].[table] format
  instead of wrapping entire name in single brackets
- Add empty column mapping validation to throw early if no columns intersect
- Add JdeDateTransformer output column collision detection in OnInitialize
- Add TODO comment for WithCommandTimeout (stored but not yet passed to
  destinations)
- Add tests for FormatQualifiedTableName and output column collision
2026-01-03 11:27:07 -05:00
Joseph Doherty fcd8b660fa feat(etl): add WithCommandTimeout to EtlPipelineBuilder with validation 2026-01-03 11:09:28 -05:00
Joseph Doherty 3145fca371 feat(etl): add column mapping to destinations (intersect with dest schema) 2026-01-03 11:06:38 -05:00
Joseph Doherty 0b317c1ffc feat(etl): add commandTimeoutSeconds to destinations 2026-01-03 11:01:12 -05:00
Joseph Doherty 0e07a76438 feat(etl): add ParseTableName and QUOTENAME to CommonScripts
- Add ParseTableName method to parse table names with optional schema
  - Supports: "Table", "dbo.Table", "[dbo].[Table]"
  - Returns (schema, table) tuple, defaults to "dbo" schema
- Update DisableIndexes, RebuildIndexes, UpdateStatistics to:
  - Use QUOTENAME() for SQL injection protection
  - Pass schema and table as parameters via SqlScriptRunner
  - Support non-dbo schemas
- Update CustomSql to accept optional parameters and timeout
- Add comprehensive tests for ParseTableName with various formats
2026-01-03 10:56:05 -05:00
Joseph Doherty 40e458148d feat(etl): add parameters support to SqlScriptRunner 2026-01-03 10:52:33 -05:00