refactor: remove unused CMS/JDE repositories and data sources

Remove legacy JDE and CMS direct-access code that is no longer used:
- Delete ICmsDataSource, IJdeDataSource interfaces
- Delete ISearchProcessor, IUpdateProcessor interfaces
- Delete IJdeRepository and ICmsRepository (all partials)
- Delete JdeRepository and CmsRepository implementations
- Delete JdeQueries and CmsQueries
- Delete JdeFileDataSource, JdeOracleDataSource
- Delete CmsFileDataSource, CmsOracleDataSource
- Remove unused methods from LotFinderRepository interfaces
- Delete associated unit tests (CmsRepositoryTests, JdeRepositoryTests)

All data sync now uses ETL pipelines via DataSync project.
This commit is contained in:
Joseph Doherty
2026-01-07 05:04:49 -05:00
parent 6952f686fa
commit 1618b6664d
52 changed files with 1497 additions and 3779 deletions
@@ -1,6 +1,3 @@
using JdeScoping.Core.Models;
using JdeScoping.Core.Models.Enums;
using JdeScoping.Core.Models.Inventory;
using JdeScoping.Core.Models.Search;
using JdeScoping.Core.ViewModels;
using JdeScoping.DataAccess.Options;
@@ -31,8 +28,7 @@ public class LotFinderRepositoryTests
_logger = Substitute.For<ILogger<LotFinderRepository>>();
_options = Microsoft.Extensions.Options.Options.Create(new DataAccessOptions
{
DefaultTimeoutSeconds = 30,
RebuildIndexTimeoutSeconds = 60
DefaultTimeoutSeconds = 30
});
}
@@ -77,160 +73,6 @@ public class LotFinderRepositoryTests
#endregion
#region RebuildIndicesAsync - Table Name Validation Tests
[Theory]
[InlineData("Branch")]
[InlineData("DataUpdate")]
[InlineData("FunctionCode")]
[InlineData("Item")]
[InlineData("JdeUser")]
[InlineData("Lot")]
[InlineData("LotLocation")]
[InlineData("LotUsage_Curr")]
[InlineData("LotUsage_Hist")]
[InlineData("MisData")]
[InlineData("OrgHierarchy")]
[InlineData("ProfitCenter")]
[InlineData("RouteMaster")]
[InlineData("Search")]
[InlineData("StatusCode")]
[InlineData("WorkCenter")]
[InlineData("WorkOrder_Curr")]
[InlineData("WorkOrder_Hist")]
[InlineData("WorkOrderComponent_Curr")]
[InlineData("WorkOrderComponent_Hist")]
[InlineData("WorkOrderRouting")]
[InlineData("WorkOrderStep_Curr")]
[InlineData("WorkOrderStep_Hist")]
[InlineData("WorkOrderTime_Curr")]
[InlineData("WorkOrderTime_Hist")]
public async Task RebuildIndicesAsync_ValidTableName_DoesNotThrowArgumentException(string tableName)
{
// Arrange - expect connection exception since we have no real connection
_connectionFactory.CreateLotFinderConnectionAsync(Arg.Any<CancellationToken>())
.ThrowsAsync(new ConnectionException("Test connection", "LotFinderDB"));
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
// Act & Assert - should throw QueryException (wrapped ConnectionException), not ArgumentException
var ex = await Should.ThrowAsync<QueryException>(
async () => await repository.RebuildIndicesAsync(tableName));
ex.QueryName.ShouldBe("SQL_REBUILD_INDICES");
}
[Theory]
[InlineData("InvalidTable")]
[InlineData("DropTable")]
[InlineData("Users")]
[InlineData("sys.tables")]
[InlineData("'; DROP TABLE Users; --")]
[InlineData("WorkOrder")]
[InlineData("branch")] // Case-insensitive should still work
public async Task RebuildIndicesAsync_InvalidTableName_ThrowsArgumentException(string tableName)
{
// Arrange
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
// Act & Assert
// Note: "branch" is case-insensitive match for "Branch", so it should NOT throw
if (tableName.Equals("branch", StringComparison.OrdinalIgnoreCase))
{
// Case-insensitive match - will try to connect and throw QueryException
_connectionFactory.CreateLotFinderConnectionAsync(Arg.Any<CancellationToken>())
.ThrowsAsync(new ConnectionException("Test connection", "LotFinderDB"));
await Should.ThrowAsync<QueryException>(
async () => await repository.RebuildIndicesAsync(tableName));
}
else
{
var ex = await Should.ThrowAsync<ArgumentException>(
async () => await repository.RebuildIndicesAsync(tableName));
ex.ParamName.ShouldBe("tableName");
ex.Message.ShouldContain($"Invalid table name: {tableName}");
}
}
#endregion
#region TruncateTableAsync - Table Name Validation Tests
[Theory]
[InlineData("Branch")]
[InlineData("Item")]
[InlineData("WorkOrder_Curr")]
public async Task TruncateTableAsync_ValidTableName_DoesNotThrowArgumentException(string tableName)
{
// Arrange - expect connection exception since we have no real connection
_connectionFactory.CreateLotFinderConnectionAsync(Arg.Any<CancellationToken>())
.ThrowsAsync(new ConnectionException("Test connection", "LotFinderDB"));
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
// Act & Assert - should throw QueryException (wrapped ConnectionException), not ArgumentException
await Should.ThrowAsync<QueryException>(
async () => await repository.TruncateTableAsync(tableName));
}
[Theory]
[InlineData("InvalidTable")]
[InlineData("'; DELETE FROM Users; --")]
public async Task TruncateTableAsync_InvalidTableName_ThrowsArgumentException(string tableName)
{
// Arrange
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
// Act & Assert
var ex = await Should.ThrowAsync<ArgumentException>(
async () => await repository.TruncateTableAsync(tableName));
ex.ParamName.ShouldBe("tableName");
ex.Message.ShouldContain($"Invalid table name: {tableName}");
}
#endregion
#region BulkInsertAsync - Table Name Validation Tests
[Theory]
[InlineData("Branch")]
[InlineData("Item")]
public async Task BulkInsertAsync_ValidTableName_DoesNotThrowArgumentException(string tableName)
{
// Arrange - expect connection exception since we have no real connection
_connectionFactory.CreateLotFinderConnectionAsync(Arg.Any<CancellationToken>())
.ThrowsAsync(new ConnectionException("Test connection", "LotFinderDB"));
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
var records = new List<Item>();
// Act & Assert - should throw QueryException (wrapped ConnectionException), not ArgumentException
await Should.ThrowAsync<QueryException>(
async () => await repository.BulkInsertAsync(tableName, records));
}
[Theory]
[InlineData("InvalidTable")]
[InlineData("'; TRUNCATE TABLE Users; --")]
public async Task BulkInsertAsync_InvalidTableName_ThrowsArgumentException(string tableName)
{
// Arrange
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
var records = new List<Item>();
// Act & Assert
var ex = await Should.ThrowAsync<ArgumentException>(
async () => await repository.BulkInsertAsync(tableName, records));
ex.ParamName.ShouldBe("tableName");
ex.Message.ShouldContain($"Invalid table name: {tableName}");
}
#endregion
#region Connection Exception Handling Tests
[Fact]
@@ -315,38 +157,6 @@ public class LotFinderRepositoryTests
ex.QueryName.ShouldBe(SqlObjects.SubmitSearch);
}
[Fact]
public async Task UpdateSearchStatusAsync_ConnectionFails_ThrowsQueryException()
{
// Arrange
_connectionFactory.CreateLotFinderConnectionAsync(Arg.Any<CancellationToken>())
.ThrowsAsync(new ConnectionException("Test connection error", "LotFinderDB"));
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
// Act & Assert
var ex = await Should.ThrowAsync<QueryException>(
async () => await repository.UpdateSearchStatusAsync(1, SearchStatus.Running));
ex.QueryName.ShouldBe("SQL_UPDATE_SEARCH_STATUS");
}
[Fact]
public async Task UpdateSearchResultsAsync_ConnectionFails_ThrowsQueryException()
{
// Arrange
_connectionFactory.CreateLotFinderConnectionAsync(Arg.Any<CancellationToken>())
.ThrowsAsync(new ConnectionException("Test connection error", "LotFinderDB"));
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
// Act & Assert
var ex = await Should.ThrowAsync<QueryException>(
async () => await repository.UpdateSearchResultsAsync(1, [1, 2, 3]));
ex.QueryName.ShouldBe("SQL_UPDATE_SEARCH_RESULTS");
}
#endregion
#region Reference Data Lookup Exception Handling Tests
@@ -415,22 +225,6 @@ public class LotFinderRepositoryTests
ex.QueryName.ShouldBe("SQL_SEARCH_WORK_CENTERS");
}
[Fact]
public async Task LookupWorkCentersAsync_ConnectionFails_ThrowsQueryException()
{
// Arrange
_connectionFactory.CreateLotFinderConnectionAsync(Arg.Any<CancellationToken>())
.ThrowsAsync(new ConnectionException("Test connection error", "LotFinderDB"));
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
// Act & Assert
var ex = await Should.ThrowAsync<QueryException>(
async () => await repository.LookupWorkCentersAsync(["WC01"]));
ex.QueryName.ShouldBe("SQL_LOOKUP_WORK_CENTERS");
}
[Fact]
public async Task SearchProfitCentersAsync_ConnectionFails_ThrowsQueryException()
{
@@ -447,22 +241,6 @@ public class LotFinderRepositoryTests
ex.QueryName.ShouldBe("SQL_SEARCH_PROFIT_CENTERS");
}
[Fact]
public async Task LookupProfitCentersAsync_ConnectionFails_ThrowsQueryException()
{
// Arrange
_connectionFactory.CreateLotFinderConnectionAsync(Arg.Any<CancellationToken>())
.ThrowsAsync(new ConnectionException("Test connection error", "LotFinderDB"));
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
// Act & Assert
var ex = await Should.ThrowAsync<QueryException>(
async () => await repository.LookupProfitCentersAsync(["PC01"]));
ex.QueryName.ShouldBe("SQL_LOOKUP_PROFIT_CENTERS");
}
[Fact]
public async Task SearchUsersAsync_ConnectionFails_ThrowsQueryException()
{
@@ -479,22 +257,6 @@ public class LotFinderRepositoryTests
ex.QueryName.ShouldBe("SQL_SEARCH_USERS");
}
[Fact]
public async Task LookupUsersAsync_ConnectionFails_ThrowsQueryException()
{
// Arrange
_connectionFactory.CreateLotFinderConnectionAsync(Arg.Any<CancellationToken>())
.ThrowsAsync(new ConnectionException("Test connection error", "LotFinderDB"));
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
// Act & Assert
var ex = await Should.ThrowAsync<QueryException>(
async () => await repository.LookupUsersAsync(["USER01"]));
ex.QueryName.ShouldBe("SQL_LOOKUP_USERS");
}
[Fact]
public async Task LookupLotsAsync_ConnectionFails_ThrowsQueryException()
{
@@ -532,38 +294,6 @@ public class LotFinderRepositoryTests
ex.QueryName.ShouldBe("SQL_GET_LAST_DATA_UPDATES");
}
[Fact]
public async Task GetTableSpecAsync_ConnectionFails_ThrowsQueryException()
{
// Arrange
_connectionFactory.CreateLotFinderConnectionAsync(Arg.Any<CancellationToken>())
.ThrowsAsync(new ConnectionException("Test connection error", "LotFinderDB"));
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
// Act & Assert
var ex = await Should.ThrowAsync<QueryException>(
async () => await repository.GetTableSpecAsync("Item"));
ex.QueryName.ShouldBe("SQL_GET_TABLE_COLUMNS");
}
[Fact]
public async Task PostProcessMisDataAsync_ConnectionFails_ThrowsQueryException()
{
// Arrange
_connectionFactory.CreateLotFinderConnectionAsync(Arg.Any<CancellationToken>())
.ThrowsAsync(new ConnectionException("Test connection error", "LotFinderDB"));
var repository = new LotFinderRepository(_connectionFactory, _logger, _options);
// Act & Assert
var ex = await Should.ThrowAsync<QueryException>(
async () => await repository.PostProcessMisDataAsync());
ex.QueryName.ShouldBe("SQL_POSTPROCESS_MISDATA");
}
#endregion
#region Cancellation Tests