Commit Graph

70 Commits

Author SHA1 Message Date
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 380ffb9a82 fix(test): correct connection string name and cache directory path 2026-01-03 16:42:11 -05:00
Joseph Doherty e04e81b178 test(datasync): add integration tests for BranchDevEtl
Add integration tests for the Branch development ETL pipeline:
- BranchDevEtlTests with tests for pipeline creation and execution
- Tests verify pipeline creates correctly and loads data from cache files
- Added appsettings.json with local connection string and cache directory
- Added necessary packages (Configuration.Json, SqlClient, Dapper)

Tests require local SQL Server and CACHED_DB_FILES directory with
branch.json.zstd to pass; tests silently skip if resources unavailable.
2026-01-03 16:38:11 -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 373ac71e74 docs: add ETL source paths to ComponentMap 2026-01-03 15:42:34 -05:00
Joseph Doherty bafebb2703 docs: add ETL troubleshooting documentation 2026-01-03 15:41:21 -05:00
Joseph Doherty 1f4bd3fe71 docs: add ETL configuration documentation 2026-01-03 15:39:41 -05:00
Joseph Doherty 804f1e82c5 docs: add ETL destinations and scripts documentation 2026-01-03 15:38:01 -05:00
Joseph Doherty 64b9054d87 docs: add ETL transformers documentation 2026-01-03 15:36:22 -05:00
Joseph Doherty b93019bb73 docs: add ETL sources documentation 2026-01-03 15:34:45 -05:00
Joseph Doherty 9a6dfa44b1 docs: add ETL pipeline overview documentation 2026-01-03 15:33:01 -05:00
Joseph Doherty bb21eb9468 docs: add ETL documentation implementation plan
8-task plan to create comprehensive ETL pipeline documentation:
- Overview, Sources, Transformers, Destinations, Configuration, Troubleshooting
- Update ComponentMap with ETL source paths
- Final verification of links and commits
2026-01-03 15:27:59 -05:00
Joseph Doherty 9103626ad4 docs: add ETL pipeline documentation design
Design for 6 documentation files covering the DataSync ETL pipeline:
- Overview, Sources, Transformers, Destinations, Configuration, Troubleshooting

Target audience: developers extending the pipeline + operations/support.
2026-01-03 15:22:57 -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
Joseph Doherty 0820a9b024 feat(etl): add collision detection to ColumnRenameTransformer 2026-01-03 10:50:03 -05:00
Joseph Doherty ae84cb3d75 feat(etl): add MapOrdinal and date validation with sentinel to JdeDateTransformer
- Add DefaultInvalidDateSentinel (1900-01-01) for invalid date handling
- Add optional invalidDateSentinel constructor parameter
- Add MapOrdinal override returning -1 for computed DateTime column
- Add GetDataTypeName override returning "datetime" for computed column
- Update ParseJdeDateTime with comprehensive validation:
  - Validate date is positive
  - Validate century (0 or 1)
  - Validate year (0-99)
  - Validate day of year (1-366 and respects leap year)
  - Validate time components (hours 0-23, minutes/seconds 0-59)
- Add tests for all new functionality
2026-01-03 10:46:19 -05:00
Joseph Doherty 577e67ec64 feat(etl): add MapOrdinal override to ColumnDropTransformer 2026-01-03 10:35:54 -05:00
Joseph Doherty 506ba5c61d feat(etl): add binary method overrides to DataTransformerBase
Add virtual methods to DataTransformerBase for GetBytes, GetChars,
GetData, and GetDataTypeName that properly handle computed columns
by throwing NotSupportedException when MapOrdinal returns -1.

Update TransformingDataReader to delegate these methods to the
transformer instead of directly to the source reader.
2026-01-03 10:33:13 -05:00
Joseph Doherty f5468d019f feat(etl): add MapOrdinal to IDataTransformer interface
Add MapOrdinal method to the IDataTransformer interface and provide
a default implementation in DataTransformerBase. This enables
transformers to report the mapping between transformed ordinals and
source ordinals, supporting use cases like computed columns which
return -1 to indicate no source ordinal.

- Add MapOrdinal(int, IDataReader) to IDataTransformer interface
- Add virtual MapOrdinal implementation in DataTransformerBase
- Add DataTransformerBaseTests with test for default behavior
2026-01-03 10:28:49 -05:00
Joseph Doherty 61d4848955 docs: add ETL Pipeline Phase 2 implementation plan
12-task TDD implementation plan covering:
- MapOrdinal interface and binary method overrides
- ColumnDropTransformer and JdeDateTransformer ordinal mapping
- JDE date validation with 1900-01-01 sentinel
- Column rename collision detection
- SqlScriptRunner parameters support
- CommonScripts with ParseTableName and QUOTENAME
- Destination command timeouts
- Column mapping with destination schema intersection
- EtlPipelineBuilder.WithCommandTimeout validation
- Full test suite verification
- Codex MCP final review
2026-01-03 10:24:28 -05:00
Joseph Doherty 7ae2cd4882 docs: add ETL Pipeline Phase 2 design document
Design addresses 7 issues identified in Phase 1 review:
- Bulk copy column mapping (by name, intersect with destination)
- Schema-qualified table names (parse tableName, QUOTENAME)
- Configurable timeouts (single commandTimeoutSeconds)
- JDE date sentinel (1900-01-01 default for invalid dates)
- TransformingDataReader ordinal mapping (MapOrdinal on interface)
- Transformer lifecycle (document single-use, no auto-dispose)
- Column rename collision validation (fail-fast on duplicates)

Reviewed by Codex MCP with all issues addressed.
2026-01-03 10:21:02 -05:00
Joseph Doherty 27f84fa3c1 feat(etl): add DI registration for ETL pipeline 2026-01-03 09:33:07 -05:00
Joseph Doherty 4c16e62661 feat(etl): implement EtlPipeline and EtlPipelineBuilder
Add pipeline orchestration for ETL operations:
- EtlPipeline: executes source -> transform -> destination flow
- EtlPipelineBuilder: fluent builder for pipeline configuration
- Supports pre/post scripts, multiple transformers
- Returns PipelineResult with step-by-step timing
2026-01-03 09:31:32 -05:00
Joseph Doherty 644e884b21 feat(etl): implement DbBulkMergeDestination for incremental updates 2026-01-03 09:26:43 -05:00
Joseph Doherty 63a0e7cf7e feat(etl): implement DbBulkImportDestination for full table refresh
Add bulk import destination that truncates and loads data using
SqlBulkCopy with configurable batch sizes and streaming support.
2026-01-03 09:22:57 -05:00
Joseph Doherty 8594baf11d feat(etl): implement DbQuerySource for database queries
Adds DbQuerySource, an IImportSource implementation that executes SQL
queries against the LotFinder database. Supports parameterized queries
using anonymous objects and configurable command timeouts.
2026-01-03 09:18:58 -05:00
Joseph Doherty 74c3f37446 feat(etl): implement JdeDateTransformer for Julian date parsing
Add transformer that combines JDE Julian date (CYYDDD) and time (HHMMSS)
columns into a single DateTime column. Includes static ParseJdeDateTime
method for direct date conversion.
2026-01-03 09:16:11 -05:00
Joseph Doherty 81cb0df6bf feat(etl): implement ColumnRenameTransformer
Add transformer for renaming columns in the data stream during ETL.
Supports case-insensitive column name matching and multiple renames.
2026-01-03 09:13:02 -05:00