Initial commit: JDE Scoping Tool migration project
Set up repository with legacy .NET Framework 4.8 source (OLD/), new .NET 10 Blazor solution (NEW/), OpenSpec specifications, documentation, and project configuration.
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\JdeScoping.Api\JdeScoping.Api.csproj" />
|
||||
<ProjectReference Include="..\JdeScoping.Client\JdeScoping.Client.csproj" />
|
||||
<ProjectReference Include="..\JdeScoping.Core\JdeScoping.Core.csproj" />
|
||||
<ProjectReference Include="..\JdeScoping.Database\JdeScoping.Database.csproj" />
|
||||
<ProjectReference Include="..\JdeScoping.DataAccess\JdeScoping.DataAccess.csproj" />
|
||||
<ProjectReference Include="..\JdeScoping.DataSync\JdeScoping.DataSync.csproj" />
|
||||
<ProjectReference Include="..\JdeScoping.ExcelIO\JdeScoping.ExcelIO.csproj" />
|
||||
<ProjectReference Include="..\JdeScoping.Infrastructure\JdeScoping.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="10.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="10.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,81 @@
|
||||
using JdeScoping.Api;
|
||||
using JdeScoping.Core.Interfaces;
|
||||
using JdeScoping.Core.Options;
|
||||
using JdeScoping.DataAccess.Configuration;
|
||||
using JdeScoping.Database;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Windows Service support (no-op on non-Windows)
|
||||
builder.Host.UseWindowsService();
|
||||
|
||||
// Run database migrations (skip in Testing environment)
|
||||
if (!builder.Environment.IsEnvironment("Testing"))
|
||||
{
|
||||
var migrator = new DatabaseMigrator(builder.Configuration);
|
||||
var migrationResult = migrator.Migrate();
|
||||
|
||||
if (!migrationResult.Successful)
|
||||
{
|
||||
Console.WriteLine($"Database migration failed: {migrationResult.Error?.Message}");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ASP.NET Core services
|
||||
builder.Services.AddRazorPages();
|
||||
|
||||
// Module registration (in dependency order)
|
||||
builder.Services
|
||||
.AddDataAccess(builder.Configuration) // 1. Database access + search processing
|
||||
.AddInfrastructure(builder.Configuration) // 2. Infrastructure (JDE/CMS/Auth)
|
||||
.AddDataSyncServices(builder.Configuration) // 3. Data sync background service
|
||||
.AddExcelIO(builder.Configuration) // 4. Result export
|
||||
.AddWebApi(builder.Configuration); // 5. Web API (controllers, auth, SignalR)
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Startup validation - verify critical services are registered
|
||||
ValidateServices(app.Services);
|
||||
|
||||
// Configure the HTTP request pipeline
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseWebAssemblyDebugging();
|
||||
}
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseBlazorFrameworkFiles();
|
||||
app.UseRouting();
|
||||
|
||||
// Configure Web API middleware (authentication, authorization, controllers, SignalR hub)
|
||||
app.UseWebApi();
|
||||
|
||||
app.MapRazorPages();
|
||||
app.MapFallbackToFile("index.html");
|
||||
|
||||
app.Run();
|
||||
|
||||
return 0;
|
||||
|
||||
// Validates that critical services are properly registered
|
||||
static void ValidateServices(IServiceProvider services)
|
||||
{
|
||||
using var scope = services.CreateScope();
|
||||
var provider = scope.ServiceProvider;
|
||||
|
||||
// Validate Options classes are bound
|
||||
_ = provider.GetRequiredService<IOptions<DataAccessOptions>>();
|
||||
_ = provider.GetRequiredService<IOptions<DataSyncOptions>>();
|
||||
_ = provider.GetRequiredService<IOptions<JdeScoping.DataSync.Configuration.DataSyncOptions>>();
|
||||
_ = provider.GetRequiredService<IOptions<ExcelExportOptions>>();
|
||||
_ = provider.GetRequiredService<IOptions<SearchProcessingOptions>>();
|
||||
_ = provider.GetRequiredService<IOptions<DataSourceOptions>>();
|
||||
|
||||
// Validate data source services
|
||||
_ = provider.GetRequiredService<IJdeDataSource>();
|
||||
_ = provider.GetRequiredService<ICmsDataSource>();
|
||||
|
||||
Console.WriteLine("Service validation completed successfully.");
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://localhost:5294",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:7159;http://localhost:5294",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"LotFinder": "Server=localhost,1434;Database=ScopingTool;User Id=scopingapp;Password=Sc0ping@pp_Dev#2024;TrustServerCertificate=true",
|
||||
"JDE": "Data Source=jde-server:1521/JDEPROD;User Id=${JDE_USER};Password=${JDE_PASSWORD}",
|
||||
"CMS": "Data Source=cms-server:1521/CMSPROD;User Id=${CMS_USER};Password=${CMS_PASSWORD}"
|
||||
},
|
||||
"DataAccess": {
|
||||
"CommandTimeoutSeconds": 120,
|
||||
"EnableDetailedLogging": false
|
||||
},
|
||||
"DataSync": {
|
||||
"Enabled": true,
|
||||
"CheckInterval": "00:01:00",
|
||||
"MaxDegreeOfParallelism": 8,
|
||||
"BatchSize": 1000000,
|
||||
"BulkCopyBatchSize": 10000,
|
||||
"LookbackMultiplier": 3,
|
||||
"PurgeRetentionDays": 30,
|
||||
"SyncTimeoutSeconds": 3600,
|
||||
"DataSources": [
|
||||
{
|
||||
"TableName": "WorkOrder_Curr",
|
||||
"SourceSystem": "JDE",
|
||||
"SourceData": "WORKORDER",
|
||||
"FetcherTypeName": "JdeWorkOrderFetcher",
|
||||
"IsEnabled": true,
|
||||
"MassConfig": { "Enabled": true, "IntervalMinutes": 10080, "PrepurgeData": true, "ReIndexData": true },
|
||||
"DailyConfig": { "Enabled": true, "IntervalMinutes": 1440 },
|
||||
"HourlyConfig": { "Enabled": true, "IntervalMinutes": 60 }
|
||||
},
|
||||
{
|
||||
"TableName": "LotUsage_Curr",
|
||||
"SourceSystem": "JDE",
|
||||
"SourceData": "LOTUSAGE",
|
||||
"FetcherTypeName": "JdeLotUsageFetcher",
|
||||
"IsEnabled": true,
|
||||
"MassConfig": { "Enabled": true, "IntervalMinutes": 10080, "PrepurgeData": true, "ReIndexData": true },
|
||||
"DailyConfig": { "Enabled": true, "IntervalMinutes": 1440 },
|
||||
"HourlyConfig": { "Enabled": true, "IntervalMinutes": 60 }
|
||||
},
|
||||
{
|
||||
"TableName": "Item",
|
||||
"SourceSystem": "JDE",
|
||||
"SourceData": "ITEM",
|
||||
"FetcherTypeName": "JdeItemFetcher",
|
||||
"IsEnabled": true,
|
||||
"MassConfig": { "Enabled": true, "IntervalMinutes": 10080, "PrepurgeData": true, "ReIndexData": true },
|
||||
"DailyConfig": { "Enabled": true, "IntervalMinutes": 1440 },
|
||||
"HourlyConfig": { "Enabled": false }
|
||||
},
|
||||
{
|
||||
"TableName": "Lot",
|
||||
"SourceSystem": "JDE",
|
||||
"SourceData": "LOT",
|
||||
"FetcherTypeName": "JdeLotFetcher",
|
||||
"IsEnabled": true,
|
||||
"MassConfig": { "Enabled": true, "IntervalMinutes": 10080, "PrepurgeData": true, "ReIndexData": true },
|
||||
"DailyConfig": { "Enabled": true, "IntervalMinutes": 1440 },
|
||||
"HourlyConfig": { "Enabled": true, "IntervalMinutes": 60 }
|
||||
},
|
||||
{
|
||||
"TableName": "WorkCenter",
|
||||
"SourceSystem": "JDE",
|
||||
"SourceData": "WORKCENTER",
|
||||
"FetcherTypeName": "JdeWorkCenterFetcher",
|
||||
"IsEnabled": true,
|
||||
"MassConfig": { "Enabled": true, "IntervalMinutes": 10080, "PrepurgeData": true, "ReIndexData": true },
|
||||
"DailyConfig": { "Enabled": true, "IntervalMinutes": 1440 },
|
||||
"HourlyConfig": { "Enabled": false }
|
||||
},
|
||||
{
|
||||
"TableName": "ProfitCenter",
|
||||
"SourceSystem": "JDE",
|
||||
"SourceData": "PROFITCENTER",
|
||||
"FetcherTypeName": "JdeProfitCenterFetcher",
|
||||
"IsEnabled": true,
|
||||
"MassConfig": { "Enabled": true, "IntervalMinutes": 10080, "PrepurgeData": true, "ReIndexData": true },
|
||||
"DailyConfig": { "Enabled": true, "IntervalMinutes": 1440 },
|
||||
"HourlyConfig": { "Enabled": false }
|
||||
},
|
||||
{
|
||||
"TableName": "JdeUser",
|
||||
"SourceSystem": "JDE",
|
||||
"SourceData": "JDEUSER",
|
||||
"FetcherTypeName": "JdeUserFetcher",
|
||||
"IsEnabled": true,
|
||||
"MassConfig": { "Enabled": true, "IntervalMinutes": 10080, "PrepurgeData": true, "ReIndexData": true },
|
||||
"DailyConfig": { "Enabled": true, "IntervalMinutes": 1440 },
|
||||
"HourlyConfig": { "Enabled": false }
|
||||
},
|
||||
{
|
||||
"TableName": "Branch",
|
||||
"SourceSystem": "JDE",
|
||||
"SourceData": "BRANCH",
|
||||
"FetcherTypeName": "JdeBranchFetcher",
|
||||
"IsEnabled": true,
|
||||
"MassConfig": { "Enabled": true, "IntervalMinutes": 10080, "PrepurgeData": true, "ReIndexData": true },
|
||||
"DailyConfig": { "Enabled": true, "IntervalMinutes": 1440 },
|
||||
"HourlyConfig": { "Enabled": false }
|
||||
},
|
||||
{
|
||||
"TableName": "MisData",
|
||||
"SourceSystem": "CMS",
|
||||
"SourceData": "MISDATA",
|
||||
"FetcherTypeName": "CmsMisDataFetcher",
|
||||
"PostProcessorTypeName": "MisDataPostProcessor",
|
||||
"IsEnabled": true,
|
||||
"MassConfig": { "Enabled": true, "IntervalMinutes": 10080, "PrepurgeData": true, "ReIndexData": true },
|
||||
"DailyConfig": { "Enabled": true, "IntervalMinutes": 1440 },
|
||||
"HourlyConfig": { "Enabled": false }
|
||||
}
|
||||
]
|
||||
},
|
||||
"Auth": {
|
||||
"UseFakeAuth": false,
|
||||
"CookieName": "ScopingTool.Auth",
|
||||
"CookieExpirationMinutes": 480,
|
||||
"AdminBypassUsers": []
|
||||
},
|
||||
"Ldap": {
|
||||
"ServerUrls": ["ldap.corp.example.com"],
|
||||
"GroupDn": "CN=ScopingTool-Users,OU=Groups,DC=corp,DC=example,DC=com",
|
||||
"SearchBase": "DC=corp,DC=example,DC=com",
|
||||
"ConnectionTimeoutSeconds": 30
|
||||
},
|
||||
"ExcelExport": {
|
||||
"TempDirectory": "/tmp/lotfinder",
|
||||
"MaxRowsPerSheet": 1048576,
|
||||
"DefaultDateFormat": "yyyy-MM-dd HH:mm:ss"
|
||||
},
|
||||
"SearchProcessing": {
|
||||
"PollingIntervalSeconds": 5,
|
||||
"MaxConcurrentSearches": 2,
|
||||
"SearchTimeoutMinutes": 30
|
||||
},
|
||||
"DataSource": {
|
||||
"UseFileDataSource": false,
|
||||
"FileDirectory": "DevData"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
Reference in New Issue
Block a user