Skip to content

Commit 952a9de

Browse files
release: v3.7.18
1 parent 53ee06f commit 952a9de

320 files changed

Lines changed: 11062 additions & 16 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

App.xaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@
6161
<DataTemplate DataType="{x:Type vm:CleanupViewModel}">
6262
<views:CleanupView/>
6363
</DataTemplate>
64+
<DataTemplate DataType="{x:Type vm:ReactPreviewViewModel}">
65+
<views:ReactPreviewView/>
66+
</DataTemplate>
6467
</ResourceDictionary>
6568
</Application.Resources>
6669
</Application>

App.xaml.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Windows;
22
using LSPDFRManager.Core;
33
using LSPDFRManager.Domain;
4+
using LSPDFRManager.LocalApi;
45
using LSPDFRManager.Services;
56
using LSPDFRManager.ViewModels;
67

@@ -21,6 +22,13 @@ protected override void OnStartup(StartupEventArgs e)
2122
ex.Handled = false;
2223
};
2324

25+
// Start local API in-process (non-blocking; React UI nav waits on PortTask)
26+
_ = Task.Run(async () =>
27+
{
28+
try { await LocalApiHost.StartAsync(); }
29+
catch (Exception ex) { AppLogger.Error("[LOCALAPI] Failed to start", ex); }
30+
});
31+
2432
try
2533
{
2634
base.OnStartup(e);
@@ -38,6 +46,12 @@ protected override void OnStartup(StartupEventArgs e)
3846
}
3947
}
4048

49+
protected override void OnExit(ExitEventArgs e)
50+
{
51+
base.OnExit(e);
52+
_ = LocalApiHost.StopAsync();
53+
}
54+
4155
private static void ValidateStartup()
4256
{
4357
var issues = new List<string>();

BASELINE_VERIFICATION.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Baseline Verification — React Migration
2+
3+
**Date/time:** 2026-05-19
4+
**Branch:** main
5+
**HEAD commit:** `53ee06f` — fix(logging): write errors to logs/errors.log in app directory
6+
**Version:** v3.7.17
7+
8+
---
9+
10+
## Working Tree Status
11+
12+
Clean. Only untracked files present (no modified tracked files):
13+
14+
```
15+
Untracked files:
16+
REACT_MIGRATION_ANALYSIS.md ← migration docs, not part of app
17+
REACT_MIGRATION_PLAN.md ← migration docs, not part of app
18+
"e unexpected files are present." ← pre-existing untracked artifact
19+
```
20+
21+
No staged changes. No modified source files. Safe to begin migration work.
22+
23+
---
24+
25+
## Commands Run
26+
27+
### 1. `dotnet restore LSPDFRManager.sln`
28+
29+
**Result: PASS**
30+
31+
```
32+
All projects are up-to-date for restore.
33+
```
34+
35+
Warnings (pre-existing, non-blocking):
36+
- `NU1902: Package 'SharpCompress' 0.38.0 has a known moderate severity vulnerability`
37+
This advisory was present before this session began and is documented in project memory as a known non-blocker.
38+
39+
---
40+
41+
### 2. `dotnet build LSPDFRManager.sln --configuration Release --no-restore`
42+
43+
**Result: PASS — 0 errors**
44+
45+
```
46+
Build succeeded.
47+
6 Warning(s)
48+
0 Error(s)
49+
Time Elapsed 00:00:04.36
50+
```
51+
52+
Outputs:
53+
- `LSPDFRManager.Api``bin\Release\net8.0\LSPDFRManager.Api.dll`
54+
- `LSPDFRManager``bin\Release\net8.0-windows\LSPDFRManager.dll`
55+
- `LSPDFRManager.Tests``LSPDFRManager.Tests\bin\Release\net8.0-windows\LSPDFRManager.Tests.dll`
56+
57+
Warnings (all pre-existing):
58+
59+
| Warning | File | Notes |
60+
|---------|------|-------|
61+
| `NU1902` SharpCompress vulnerability | Both projects | Known advisory; non-blocker |
62+
| `CS0219` variable assigned but never used (`failureRaised`) | `InstallIntegrationTests.cs:221` | Pre-existing test warning |
63+
| `CS8602` dereference of possibly null | `StreamingBufferTests.cs:47` | Pre-existing test warning |
64+
| `CS8605` unboxing possibly null | `StreamingBufferTests.cs:47` | Pre-existing test warning |
65+
| `xUnit2029` use DoesNotContain instead of Empty | `EupBackupEditorTests.cs:439` | Pre-existing xUnit analyzer suggestion |
66+
67+
---
68+
69+
### 3. `dotnet test LSPDFRManager.Tests\LSPDFRManager.Tests.csproj --configuration Release --no-build`
70+
71+
**Result: PASS — 914/914 tests passed**
72+
73+
```
74+
Total tests: 914
75+
Passed: 914
76+
Failed: 0
77+
Skipped: 0
78+
Total time: 10.7260 Seconds
79+
0 Error(s)
80+
```
81+
82+
> Note: Previous recorded baseline was 878 tests (v3.7.16 / v3.7.17). The count is now 914 — additional tests were added in commits since the last recorded snapshot. All 914 pass.
83+
84+
---
85+
86+
## Summary of Warnings / Failures
87+
88+
| Item | Type | Severity | Action |
89+
|------|------|----------|--------|
90+
| `NU1902` SharpCompress advisory | Dependency warning | Pre-existing, non-blocking | No action needed |
91+
| `CS0219` unused variable | Code warning | Pre-existing | No action needed |
92+
| `CS8602` / `CS8605` null warnings | Code warning | Pre-existing | No action needed |
93+
| `xUnit2029` | Analyzer suggestion | Pre-existing | No action needed |
94+
95+
No new warnings introduced. No errors. No failing tests.
96+
97+
---
98+
99+
## Safe to Proceed to Milestone 1?
100+
101+
**Yes.** The repository is in a fully clean, passing state.
102+
103+
- 0 build errors
104+
- 914/914 tests passing
105+
- No modified tracked source files
106+
- Pre-existing warnings are known and non-blocking
107+
108+
---
109+
110+
## Recommended Next Step
111+
112+
Begin **Milestone 1**: Scaffold `LSPDFRManager.LocalApi` — a new ASP.NET Core Minimal API project that will serve as the local management API for the React frontend.
113+
114+
Per `REACT_MIGRATION_PLAN.md` Milestone 1:
115+
1. Create `LSPDFRManager.LocalApi/` as a new `Microsoft.NET.Sdk.Web` project targeting `net8.0`.
116+
2. Add minimal `Program.cs` with a `/health` endpoint.
117+
3. Add `LocalhostOnlyMiddleware` (reject non-`127.0.0.1` Host headers).
118+
4. Add to `LSPDFRManager.sln`.
119+
5. Verify `dotnet build` — 0 errors.
120+
6. Verify `dotnet test` — all 914 tests still pass.
121+
122+
> **Important prerequisite for Milestone 2 (shared library extraction):** `Domain/`, `Services/`, and `Core/` currently live inside `LSPDFRManager.csproj` which targets `net8.0-windows`. For `LSPDFRManager.LocalApi` (targeting `net8.0`) to reference these, they must be extracted to a new `LSPDFRManager.Core` class library project. This is the highest-risk structural change and should be planned carefully before execution.

FRONTEND_SCAFFOLD_RESULT.md

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
# Frontend Scaffold Result — Milestone 3
2+
3+
**Date:** 2026-05-19
4+
**Branch:** main
5+
**Result:** Complete — all verification commands pass.
6+
7+
---
8+
9+
## 1. Framework and Tool Versions
10+
11+
| Tool | Version |
12+
|------|---------|
13+
| Node.js | v24.14.1 |
14+
| npm | 11.12.1 |
15+
| Vite | 8.0.13 |
16+
| React | 19.2.6 |
17+
| TypeScript | ~6.0.2 |
18+
| react-router-dom | 7.15.1 |
19+
| @tanstack/react-query | 5.100.11 |
20+
| tailwindcss | 4.3.0 |
21+
| @tailwindcss/vite | 4.3.0 (Tailwind v4 Vite plugin) |
22+
| @radix-ui/react-tabs | 1.1.13 |
23+
| @radix-ui/react-dialog | 1.1.15 |
24+
| @radix-ui/react-dropdown-menu | 2.1.16 |
25+
26+
---
27+
28+
## 2. Packages Added
29+
30+
### Runtime dependencies
31+
32+
| Package | Purpose |
33+
|---------|---------|
34+
| `react`, `react-dom` | UI library |
35+
| `react-router-dom` | Client-side routing (all 17 routes) |
36+
| `@tanstack/react-query` | Server state management (wired up, no real calls yet) |
37+
| `tailwindcss`, `@tailwindcss/vite` | Utility CSS (Tailwind v4 via Vite plugin) |
38+
| `@radix-ui/react-tabs` | Accessible tab primitive |
39+
| `@radix-ui/react-dialog` | Accessible dialog primitive |
40+
| `@radix-ui/react-dropdown-menu` | Accessible dropdown primitive |
41+
42+
### Dev dependencies (added by Vite template)
43+
44+
`typescript`, `@types/react`, `@types/react-dom`, `@vitejs/plugin-react`, `eslint`,
45+
`eslint-plugin-react-hooks`, `eslint-plugin-react-refresh`, `typescript-eslint`, `globals`
46+
47+
---
48+
49+
## 3. Directory Structure Created
50+
51+
```
52+
frontend/
53+
├── package.json
54+
├── tsconfig.json
55+
├── tsconfig.app.json ← strict: true added
56+
├── tsconfig.node.json
57+
├── vite.config.ts ← tailwindcss() plugin added
58+
├── dist/ ← production build output
59+
└── src/
60+
├── index.css ← Tailwind @import + dark theme CSS vars
61+
├── main.tsx ← entry: StrictMode + QueryClientProvider
62+
├── App.tsx ← createBrowserRouter, 17 routes
63+
├── routes/
64+
│ └── routeConfig.ts ← typed RouteConfig[] with all 17 entries
65+
├── pages/ ← 17 stub page components
66+
│ ├── DashboardPage.tsx
67+
│ ├── InstallPage.tsx
68+
│ ├── LibraryPage.tsx
69+
│ ├── BrowsePage.tsx
70+
│ ├── BackupsPage.tsx
71+
│ ├── ConfigPage.tsx
72+
│ ├── DiagnosticsPage.tsx
73+
│ ├── HistoryPage.tsx
74+
│ ├── ProfilesPage.tsx
75+
│ ├── SettingsPage.tsx
76+
│ ├── LogsPage.tsx
77+
│ ├── SafeModePage.tsx
78+
│ ├── DevDiagnosticsPage.tsx
79+
│ ├── OivPage.tsx
80+
│ ├── CleanupPage.tsx
81+
│ ├── PatrolReadinessPage.tsx
82+
│ └── SetupWizardPage.tsx
83+
├── components/
84+
│ ├── layout/
85+
│ │ ├── AppLayout.tsx ← Sidebar + Outlet
86+
│ │ └── Sidebar.tsx ← NavLink-based nav for 16 routes (excludes /setup)
87+
│ └── ui/
88+
│ └── StubPage.tsx ← shared stub component (label, path, sourceView, "Not migrated yet")
89+
└── lib/
90+
├── queryClient.ts ← QueryClient singleton (staleTime: 10s, retry: 1)
91+
└── api/
92+
└── client.ts ← typed fetch wrapper (get/post/put/delete); no real calls yet
93+
```
94+
95+
---
96+
97+
## 4. Route List Created
98+
99+
| Route | Label | WPF Source View |
100+
|-------|-------|----------------|
101+
| `/` | Dashboard | DashboardView |
102+
| `/install` | Install | InstallView |
103+
| `/library` | Library | LibraryView |
104+
| `/browse` | Browse | BrowseView |
105+
| `/backups` | Backups | BackupsView |
106+
| `/config` | Config | ConfigView |
107+
| `/diagnostics` | Diagnostics | DiagnosticsView |
108+
| `/history` | History | HistoryView |
109+
| `/profiles` | Profiles | ProfilesView |
110+
| `/settings` | Settings | SettingsView |
111+
| `/logs` | Log Viewer | LogViewerView |
112+
| `/safe-mode` | Safe Mode | SafeModeView |
113+
| `/dev-diagnostics` | Dev Diagnostics | DevDiagnosticsView |
114+
| `/oiv` | OIV Creator | OivView |
115+
| `/cleanup` | Cleanup | CleanupView |
116+
| `/patrol-readiness` | Patrol Readiness | PatrolReadinessDashboardView |
117+
| `/setup` | Setup Wizard | SetupWizardView |
118+
119+
---
120+
121+
## 5. Stub Screens Created
122+
123+
All 17 stub pages render identically via `StubPage`:
124+
- Screen label (heading)
125+
- Route path (`/route`)
126+
- WPF source view name
127+
- "Not migrated yet" badge
128+
129+
`/setup` is excluded from the sidebar nav (wizard flow, not a regular nav item).
130+
131+
---
132+
133+
## 6. Scripts Added to package.json
134+
135+
| Script | Command |
136+
|--------|---------|
137+
| `dev` | `vite` |
138+
| `build` | `tsc -b && vite build` |
139+
| `typecheck` | `tsc -b` |
140+
| `lint` | `eslint .` |
141+
| `preview` | `vite preview` |
142+
143+
---
144+
145+
## 7. Commands Run and Results
146+
147+
| Command | Result |
148+
|---------|--------|
149+
| `npm install` (in `frontend/`) | Pass — 214 packages, 0 vulnerabilities |
150+
| `npm run typecheck` | Pass — 0 TypeScript errors |
151+
| `npm run lint` | Pass — 0 lint errors |
152+
| `npm run build` | Pass — dist/ produced (315 kB JS, 6.6 kB CSS) |
153+
| `dotnet build LSPDFRManager.sln` | Pass — 0 errors, 11 pre-existing warnings |
154+
| `dotnet test` | Pass — 914/914 |
155+
156+
---
157+
158+
## 8. Deviations from Migration Plan
159+
160+
| Item | Plan | Actual | Reason |
161+
|------|------|--------|--------|
162+
| Tailwind setup | `tailwindcss` CSS plugin | `@tailwindcss/vite` Vite plugin | Tailwind v4 uses Vite plugin instead of PostCSS; compatible and simpler |
163+
| `ApiError` constructor | Parameter properties | Explicit field + assignment | TypeScript `erasableSyntaxOnly: true` disallows constructor parameter properties |
164+
| `/setup` in nav | Not specified | Excluded from sidebar | Setup wizard is a first-launch flow, not a regular navigation destination |
165+
166+
---
167+
168+
## 9. Remaining Frontend Setup Work
169+
170+
- [ ] Vite proxy config for LocalApi (needed in Milestone 4)
171+
- [ ] Per-feature API client modules in `lib/api/` (one per feature area, Milestones 5–13)
172+
- [ ] TypeScript DTO types in `src/types/` matching C# DTOs (Milestones 5+)
173+
- [ ] React DevTools / TanStack Query DevTools (optional, add in dev mode)
174+
- [ ] 404 / not-found route
175+
- [ ] Error boundary at app level
176+
- [ ] `frontend/.gitignore` already present from Vite scaffold (covers `dist/`, `node_modules/`)
177+
178+
---
179+
180+
## 10. How This Prepares the App for the React UI Migration
181+
182+
- **All 17 routes** are registered and navigable immediately; any stub can be replaced with a real screen without changing routing or layout.
183+
- **`routeConfig.ts`** provides a typed map from route path → WPF source → migration status; future milestones update `status` field from `'stub'` to `'in-progress'` or `'complete'`.
184+
- **`queryClient.ts`** is wired at the app root; any page can call `useQuery` or `useMutation` without additional setup.
185+
- **`lib/api/client.ts`** provides typed `get/post/put/delete` helpers; feature API modules plug in by calling these helpers with `/api/v1/...` paths once LocalApi is live.
186+
- **Tailwind v4** is configured via Vite plugin; no `tailwind.config.js` needed; CSS custom properties define the navy/blue color scheme matching the WPF dark theme.
187+
- **`dist/`** is ready to be embedded in `LSPDFRManager.LocalApi/wwwroot/` and served as static files in Milestone 4.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace LSPDFRManager.LocalApi.Dtos;
2+
3+
public record BackupFileDto(
4+
string FileName,
5+
string FilePath,
6+
long SizeBytes,
7+
string SizeDisplay,
8+
DateTime LastWriteUtc);
9+
10+
public record BackupsListResponse(IReadOnlyList<BackupFileDto> Backups);
11+
12+
public record CreateBackupResponse(string JobId);
13+
14+
public record RestoreBackupRequest(string FileName);
15+
16+
public record RestoreBackupResponse(string JobId);
17+
18+
public record DeleteBackupRequest(string FileName);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace LSPDFRManager.LocalApi.Dtos;
2+
3+
public record BrowseSearchRequest(string Query, int Page = 1);
4+
5+
public record BrowseModDto(
6+
string Id,
7+
string Name,
8+
string? Author,
9+
string? Description,
10+
string? Version,
11+
string? ImageUrl,
12+
string? DownloadUrl,
13+
string? PageUrl
14+
);
15+
16+
public record BrowseSearchResponse(
17+
IReadOnlyList<BrowseModDto> Results,
18+
int Page,
19+
int TotalResults,
20+
bool HasMore
21+
);

0 commit comments

Comments
 (0)