refactor(client): replace hardcoded API URLs with ApiRoutes constants
Centralizes all API endpoint strings in ApiRoutes for consistency and easier maintenance. Adds Hubs class for SignalR endpoints. Removes completed plan files.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,329 +0,0 @@
|
||||
# Remove Pipeline Viewer Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Remove the pipeline viewer feature from the web UI and clean up all supporting code (controllers, DTOs, client services, routes).
|
||||
|
||||
**Architecture:** Delete files in dependency order (DTOs/interfaces first would break compilation), so we delete leaf components first (views, client), then API layer, then shared contracts/DTOs. Modify DI registrations and navigation.
|
||||
|
||||
**Tech Stack:** Blazor WebAssembly, ASP.NET Core API, C#
|
||||
|
||||
---
|
||||
|
||||
## Task 1: Remove Client Components (Blazor Pages)
|
||||
|
||||
**Files:**
|
||||
- Delete: `src/JdeScoping.Client/Pages/Admin/PipelineViewer.razor`
|
||||
- Delete: `src/JdeScoping.Client/Components/Admin/PipelineScheduleSection.razor`
|
||||
- Delete: `src/JdeScoping.Client/Components/Admin/SqlQueryModal.razor`
|
||||
|
||||
**Step 1: Delete PipelineViewer.razor**
|
||||
|
||||
```bash
|
||||
rm src/JdeScoping.Client/Pages/Admin/PipelineViewer.razor
|
||||
```
|
||||
|
||||
**Step 2: Delete PipelineScheduleSection.razor**
|
||||
|
||||
```bash
|
||||
rm src/JdeScoping.Client/Components/Admin/PipelineScheduleSection.razor
|
||||
```
|
||||
|
||||
**Step 3: Delete SqlQueryModal.razor (if exists)**
|
||||
|
||||
```bash
|
||||
rm -f src/JdeScoping.Client/Components/Admin/SqlQueryModal.razor
|
||||
```
|
||||
|
||||
**Step 4: Verify files deleted**
|
||||
|
||||
```bash
|
||||
ls src/JdeScoping.Client/Pages/Admin/ | grep -i pipeline || echo "No pipeline pages remain"
|
||||
ls src/JdeScoping.Client/Components/Admin/ | grep -i pipeline || echo "No pipeline components remain"
|
||||
```
|
||||
|
||||
Expected: No pipeline-related files in Admin folders.
|
||||
|
||||
---
|
||||
|
||||
## Task 2: Remove Navigation Link
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/JdeScoping.Client/Layout/MainLayout.razor:16`
|
||||
|
||||
**Step 1: Remove the pipeline viewer nav link**
|
||||
|
||||
In `MainLayout.razor`, delete this line (around line 16):
|
||||
```razor
|
||||
<NavLink class="nav-link" href="/admin/pipeline-viewer">Pipeline Viewer</NavLink>
|
||||
```
|
||||
|
||||
**Step 2: Verify the change**
|
||||
|
||||
```bash
|
||||
grep -n "pipeline-viewer" src/JdeScoping.Client/Layout/MainLayout.razor || echo "Nav link removed"
|
||||
```
|
||||
|
||||
Expected: "Nav link removed"
|
||||
|
||||
---
|
||||
|
||||
## Task 3: Remove Client Service
|
||||
|
||||
**Files:**
|
||||
- Delete: `src/JdeScoping.Client/Services/PipelineApiClient.cs`
|
||||
- Modify: `src/JdeScoping.Client/Program.cs:58`
|
||||
|
||||
**Step 1: Delete PipelineApiClient.cs**
|
||||
|
||||
```bash
|
||||
rm src/JdeScoping.Client/Services/PipelineApiClient.cs
|
||||
```
|
||||
|
||||
**Step 2: Remove DI registration from Program.cs**
|
||||
|
||||
In `src/JdeScoping.Client/Program.cs`, delete this line (around line 58):
|
||||
```csharp
|
||||
builder.Services.AddScoped<IPipelineApiClient, PipelineApiClient>();
|
||||
```
|
||||
|
||||
**Step 3: Verify the changes**
|
||||
|
||||
```bash
|
||||
grep -n "PipelineApiClient" src/JdeScoping.Client/Program.cs || echo "DI registration removed"
|
||||
ls src/JdeScoping.Client/Services/PipelineApiClient.cs 2>/dev/null || echo "File deleted"
|
||||
```
|
||||
|
||||
Expected: Both checks show removal confirmed.
|
||||
|
||||
---
|
||||
|
||||
## Task 4: Remove API Controller and Mapper
|
||||
|
||||
**Files:**
|
||||
- Delete: `src/JdeScoping.Api/Controllers/PipelineController.cs`
|
||||
- Delete: `src/JdeScoping.Api/Mapping/PipelineMapper.cs`
|
||||
- Delete: `src/JdeScoping.Api/Mapping/IPipelineMapper.cs`
|
||||
- Modify: `src/JdeScoping.Api/DependencyInjection.cs:43`
|
||||
|
||||
**Step 1: Delete PipelineController.cs**
|
||||
|
||||
```bash
|
||||
rm src/JdeScoping.Api/Controllers/PipelineController.cs
|
||||
```
|
||||
|
||||
**Step 2: Delete PipelineMapper.cs**
|
||||
|
||||
```bash
|
||||
rm src/JdeScoping.Api/Mapping/PipelineMapper.cs
|
||||
```
|
||||
|
||||
**Step 3: Delete IPipelineMapper.cs**
|
||||
|
||||
```bash
|
||||
rm src/JdeScoping.Api/Mapping/IPipelineMapper.cs
|
||||
```
|
||||
|
||||
**Step 4: Remove DI registration from DependencyInjection.cs**
|
||||
|
||||
In `src/JdeScoping.Api/DependencyInjection.cs`, delete this line (around line 43):
|
||||
```csharp
|
||||
services.AddSingleton<IPipelineMapper, PipelineMapper>();
|
||||
```
|
||||
|
||||
**Step 5: Verify the changes**
|
||||
|
||||
```bash
|
||||
ls src/JdeScoping.Api/Controllers/PipelineController.cs 2>/dev/null || echo "Controller deleted"
|
||||
ls src/JdeScoping.Api/Mapping/*Pipeline* 2>/dev/null || echo "Mapper files deleted"
|
||||
grep -n "PipelineMapper" src/JdeScoping.Api/DependencyInjection.cs || echo "DI registration removed"
|
||||
```
|
||||
|
||||
Expected: All three checks confirm removal.
|
||||
|
||||
---
|
||||
|
||||
## Task 5: Remove Core DTOs and Interface
|
||||
|
||||
**Files:**
|
||||
- Delete: `src/JdeScoping.Core/Models/Pipelines/` (entire folder)
|
||||
- Delete: `src/JdeScoping.Core/ApiContracts/IPipelineApiClient.cs`
|
||||
|
||||
**Step 1: Delete the Pipelines DTO folder**
|
||||
|
||||
```bash
|
||||
rm -rf src/JdeScoping.Core/Models/Pipelines/
|
||||
```
|
||||
|
||||
**Step 2: Delete IPipelineApiClient.cs**
|
||||
|
||||
```bash
|
||||
rm src/JdeScoping.Core/ApiContracts/IPipelineApiClient.cs
|
||||
```
|
||||
|
||||
**Step 3: Verify deletions**
|
||||
|
||||
```bash
|
||||
ls src/JdeScoping.Core/Models/Pipelines/ 2>/dev/null || echo "Pipelines folder deleted"
|
||||
ls src/JdeScoping.Core/ApiContracts/IPipelineApiClient.cs 2>/dev/null || echo "Interface deleted"
|
||||
```
|
||||
|
||||
Expected: Both checks confirm deletion.
|
||||
|
||||
---
|
||||
|
||||
## Task 6: Remove API Routes
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/JdeScoping.Core/ApiContracts/ApiRoutes.cs:155-188`
|
||||
|
||||
**Step 1: Remove the Pipelines class from ApiRoutes.cs**
|
||||
|
||||
Delete the entire `Pipelines` static class (lines 155-188):
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// Routes for pipeline configuration API endpoints.
|
||||
/// </summary>
|
||||
public static class Pipelines
|
||||
{
|
||||
/// <summary>Base route for pipeline endpoints.</summary>
|
||||
public const string Base = "api/pipelines";
|
||||
|
||||
/// <summary>Route template for getting a pipeline by name.</summary>
|
||||
public const string ByName = "{name}";
|
||||
|
||||
/// <summary>Route template for getting pipeline status.</summary>
|
||||
public const string Status = "{name}/status";
|
||||
|
||||
/// <summary>Route template for getting pipeline executions.</summary>
|
||||
public const string Executions = "{name}/executions";
|
||||
|
||||
/// <summary>Builds the route to get a specific pipeline config.</summary>
|
||||
/// <param name="name">The pipeline name to URL-encode.</param>
|
||||
/// <returns>The formatted route.</returns>
|
||||
public static string GetByName(string name) => $"api/pipelines/{Uri.EscapeDataString(name)}";
|
||||
|
||||
/// <summary>Builds the route to get pipeline status.</summary>
|
||||
/// <param name="name">The pipeline name to URL-encode.</param>
|
||||
/// <returns>The formatted route.</returns>
|
||||
public static string GetStatus(string name) => $"api/pipelines/{Uri.EscapeDataString(name)}/status";
|
||||
|
||||
/// <summary>Builds the route to get pipeline executions.</summary>
|
||||
/// <param name="name">The pipeline name to URL-encode.</param>
|
||||
/// <param name="count">The number of recent executions to retrieve.</param>
|
||||
/// <returns>The formatted route.</returns>
|
||||
public static string GetExecutions(string name, int count = 10) =>
|
||||
$"api/pipelines/{Uri.EscapeDataString(name)}/executions?count={count}";
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Verify the change**
|
||||
|
||||
```bash
|
||||
grep -n "Pipelines" src/JdeScoping.Core/ApiContracts/ApiRoutes.cs || echo "Pipelines routes removed"
|
||||
```
|
||||
|
||||
Expected: "Pipelines routes removed"
|
||||
|
||||
---
|
||||
|
||||
## Task 7: Delete Plan Documents
|
||||
|
||||
**Files:**
|
||||
- Delete: `docs/plans/2026-01-07-pipeline-viewer-design.md`
|
||||
- Delete: `docs/plans/2026-01-07-pipeline-viewer-implementation.md`
|
||||
|
||||
**Step 1: Delete design document**
|
||||
|
||||
```bash
|
||||
rm docs/plans/2026-01-07-pipeline-viewer-design.md
|
||||
```
|
||||
|
||||
**Step 2: Delete implementation plan**
|
||||
|
||||
```bash
|
||||
rm docs/plans/2026-01-07-pipeline-viewer-implementation.md
|
||||
```
|
||||
|
||||
**Step 3: Verify deletions**
|
||||
|
||||
```bash
|
||||
ls docs/plans/*pipeline-viewer* 2>/dev/null || echo "Plan documents deleted"
|
||||
```
|
||||
|
||||
Expected: "Plan documents deleted"
|
||||
|
||||
---
|
||||
|
||||
## Task 8: Build and Verify
|
||||
|
||||
**Step 1: Build the solution**
|
||||
|
||||
```bash
|
||||
cd /Users/dohertj2/Desktop/JdeScopingTool/NEW && dotnet build
|
||||
```
|
||||
|
||||
Expected: Build succeeds with no errors.
|
||||
|
||||
**Step 2: Search for any remaining pipeline viewer references**
|
||||
|
||||
```bash
|
||||
grep -r "PipelineViewer\|PipelineApiClient\|IPipelineApiClient\|PipelineController\|IPipelineMapper\|PipelineMapper\|pipeline-viewer" src/ --include="*.cs" --include="*.razor" || echo "No references remain"
|
||||
```
|
||||
|
||||
Expected: "No references remain"
|
||||
|
||||
**Step 3: Run tests**
|
||||
|
||||
```bash
|
||||
dotnet test
|
||||
```
|
||||
|
||||
Expected: All tests pass.
|
||||
|
||||
---
|
||||
|
||||
## Task 9: Commit
|
||||
|
||||
**Step 1: Stage all changes**
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
```
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git commit -m "$(cat <<'EOF'
|
||||
refactor(webui): remove pipeline viewer feature
|
||||
|
||||
Remove the read-only pipeline viewer from the web UI:
|
||||
- Delete PipelineViewer.razor page and supporting components
|
||||
- Delete PipelineController and PipelineMapper from API
|
||||
- Delete Pipeline DTOs from Core
|
||||
- Delete PipelineApiClient from Client
|
||||
- Remove navigation link and DI registrations
|
||||
- Delete obsolete plan documents
|
||||
|
||||
The ConfigManager utility retains pipeline editing capabilities.
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Task | Action | Files Affected |
|
||||
|------|--------|----------------|
|
||||
| 1 | Delete Blazor components | 3 files deleted |
|
||||
| 2 | Remove nav link | 1 file modified |
|
||||
| 3 | Remove client service | 1 deleted, 1 modified |
|
||||
| 4 | Remove API layer | 3 deleted, 1 modified |
|
||||
| 5 | Remove Core DTOs | 5 files deleted |
|
||||
| 6 | Remove API routes | 1 file modified |
|
||||
| 7 | Delete plan docs | 2 files deleted |
|
||||
| 8 | Build and verify | - |
|
||||
| 9 | Commit | - |
|
||||
|
||||
**Total:** 14 files deleted, 4 files modified
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Net.Http.Json;
|
||||
using System.Security.Claims;
|
||||
using JdeScoping.Core.ApiContracts;
|
||||
using JdeScoping.Core.Models.Auth;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -63,7 +64,7 @@ public class AuthStateProvider : AuthenticationStateProvider, IAuthStateProvider
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.GetAsync("api/auth/me");
|
||||
var response = await _httpClient.GetAsync(ApiRoutes.Auth.Me);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return await response.Content.ReadFromJsonAsync<UserInfoDto>();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Net.Http.Json;
|
||||
using JdeScoping.Core.ApiContracts;
|
||||
using JdeScoping.Core.ViewModels;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Radzen;
|
||||
@@ -88,7 +89,7 @@ public partial class NewSyncRequestDialog : ComponentBase
|
||||
SyncType = _selectedSyncType!
|
||||
};
|
||||
|
||||
var response = await HttpClient.PostAsJsonAsync("api/manual-sync", createDto);
|
||||
var response = await HttpClient.PostAsJsonAsync(ApiRoutes.ManualSync.Base, createDto);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Net.Http.Json;
|
||||
using JdeScoping.Client.Auth;
|
||||
using JdeScoping.Core.ApiContracts;
|
||||
using JdeScoping.Core.Models.Auth;
|
||||
|
||||
namespace JdeScoping.Client.Services;
|
||||
@@ -43,7 +44,7 @@ public class AuthService : IAuthService
|
||||
var request = new EncryptedLoginRequest(encryptedData);
|
||||
|
||||
// Send encrypted request
|
||||
var response = await _httpClient.PostAsJsonAsync("api/auth/login", request);
|
||||
var response = await _httpClient.PostAsJsonAsync(ApiRoutes.Auth.Login, request);
|
||||
|
||||
var result = await response.Content.ReadFromJsonAsync<LoginResultModel>();
|
||||
if (result is null)
|
||||
@@ -72,7 +73,7 @@ public class AuthService : IAuthService
|
||||
{
|
||||
try
|
||||
{
|
||||
await _httpClient.PostAsync("api/auth/logout", null);
|
||||
await _httpClient.PostAsync(ApiRoutes.Auth.Logout, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using JdeScoping.Core.ApiContracts;
|
||||
using JdeScoping.Core.Models.Auth;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
@@ -57,7 +58,7 @@ public class CryptoService : ICryptoService, IAsyncDisposable
|
||||
if (_cachedPublicKeyPem is not null)
|
||||
return _cachedPublicKeyPem;
|
||||
|
||||
var response = await _httpClient.GetFromJsonAsync<PublicKeyResponse>("api/auth/public-key")
|
||||
var response = await _httpClient.GetFromJsonAsync<PublicKeyResponse>(ApiRoutes.Auth.PublicKey)
|
||||
?? throw new InvalidOperationException("Failed to fetch public key from server");
|
||||
|
||||
_cachedPublicKeyPem = response.PublicKeyPem;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using JdeScoping.Core.ApiContracts;
|
||||
using JdeScoping.Core.ViewModels;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
@@ -50,7 +51,7 @@ public class HubConnectionService : IHubConnectionService, IAsyncDisposable
|
||||
// In Blazor WebAssembly, the browser automatically sends cookies with requests
|
||||
// to the same origin, so we don't need to configure any special auth options
|
||||
_hubConnection = new HubConnectionBuilder()
|
||||
.WithUrl(_navigationManager.ToAbsoluteUri("/hubs/status"))
|
||||
.WithUrl(_navigationManager.ToAbsoluteUri(ApiRoutes.Hubs.Status))
|
||||
.WithAutomaticReconnect([
|
||||
TimeSpan.Zero,
|
||||
TimeSpan.FromSeconds(2),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Net.Http.Json;
|
||||
using JdeScoping.Core.ApiContracts;
|
||||
using JdeScoping.Core.Models.Infrastructure;
|
||||
|
||||
namespace JdeScoping.Client.Services;
|
||||
@@ -30,10 +31,8 @@ public class RefreshStatusService : IRefreshStatusService
|
||||
{
|
||||
try
|
||||
{
|
||||
var minDtStr = minDt.ToString("yyyy-MM-dd");
|
||||
var maxDtStr = maxDt.ToString("yyyy-MM-dd");
|
||||
var result = await _httpClient.GetFromJsonAsync<List<DataUpdateDto>>(
|
||||
$"api/refresh-status?minDT={minDtStr}&maxDT={maxDtStr}");
|
||||
ApiRoutes.RefreshStatus.Get(minDt, maxDt));
|
||||
return result ?? [];
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -192,4 +192,13 @@ public static class ApiRoutes
|
||||
/// <summary>Route to reload pipelines.</summary>
|
||||
public const string Reload = "api/pipelines/reload";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Routes for SignalR hub endpoints.
|
||||
/// </summary>
|
||||
public static class Hubs
|
||||
{
|
||||
/// <summary>Route for the status hub (real-time search updates).</summary>
|
||||
public const string Status = "/hubs/status";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user