Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 26 additions & 21 deletions .squad/agents/beast/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,38 @@
- Run 9 Skill Fixes — 6 RF items across 4 skill files (2026-03-07)
- Run 9 RCA Documentation — path preservation + CSS verification rules (2026-03-07)

### Issue #438: Deprecation Guidance Docs (Latest)
### Issue #438: Deprecation Guidance Docs

📌 **Team update (2026-03-17):** #471 & #472 resolved. GUID IDs removed from CheckBox/RadioButton/RadioButtonList; L1 script test suite 100%. 2105 tests passing. — decided by Cyclops

**Delivered:** Comprehensive deprecation guidance page (`docs/Migration/DeprecationGuidance.md`) covering Web Forms patterns with no Blazor equivalent.

**Content:**
- `runat="server"` → Blazor native components
- `ViewState` → Component fields + scoped services
- `UpdatePanel` → Blazor's incremental component rendering
- `ScriptManager` → `IJSRuntime` + `HttpClient`
- PostBack events → Component lifecycle + event handlers
- Page lifecycle (`Page_Load`, `Page_Init`) → `OnInitializedAsync`, `OnParametersSetAsync`
- `IsPostBack` → Removed (use `OnInitializedAsync`)
- Server-side control properties → Declarative data binding
- Application/Session state → Singleton/scoped services
- Data binding events (`ItemDataBound`) → Component templates with `@context`

**Format:** Before/after tabbed code examples, migration checklist table, lifecycle mapping.
**✅ DELIVERED** — Comprehensive deprecation guidance page covering Web Forms patterns with no Blazor equivalent.

**Branch:** `squad/438-deprecation-docs` — pushed to FritzAndFriends upstream. Commit 5b17682b.
**Session (2026-03-17 by Beast):**
- Created `docs/Migration/DeprecationGuidance.md` — 32 KB, ~600 lines covering 8 deprecation patterns
- Updated `mkdocs.yml` — added "Deprecation Guidance" to Migration navigation section (after "Automated Migration Guide")
- Created decision record: `.squad/decisions/inbox/beast-deprecation-docs.md`

**Files:**
- Created `docs/Migration/DeprecationGuidance.md` (23.3 KB, ~400 lines)
- Updated `mkdocs.yml` — added to Migration section navigation
**Content patterns documented:**
- `runat="server"` — Scope marker; remove (Blazor components always server-side)
- `ViewState` — Use component fields + scoped/singleton services instead
- `UpdatePanel` — Blazor incremental rendering makes triggers obsolete; UpdatePanel is now just a CSS-compatible wrapper
- `Page_Load` / `IsPostBack` → `OnInitializedAsync` + event handlers + lifecycle mapping table
- `ScriptManager` — Stub for migration compat; replace with `IJSRuntime` + `HttpClient` + DI
- Server control properties → Reactive data binding (fields, not imperative assignment)
- Application/Session state → Singleton/scoped services
- Data binding events (`ItemDataBound`) → Component templates with `@context`

**Design decision:** Placed after "Automated Migration Guide" in nav to catch developers early in their migration journey. Each section pairs Web Forms pattern with clear Blazor alternative, supporting the library's goal of enabling code reuse with minimal markup changes.
**Format & Tone:**
- Each pattern: "What It Was" → "Why Deprecated" → "What To Do Instead" + before/after code
- Tabbed markdown for side-by-side comparison of Web Forms vs Blazor
- Lifecycle mapping table (Page_Init → OnInitializedAsync, etc.)
- Empathetic tone — acknowledges these are familiar patterns being left behind
- Audience: Experienced Web Forms developers learning Blazor

**Design decision rationale:**
- Placed after "Automated Migration Guide" in nav — developers run L1 automation first, then encounter these patterns; this doc is their reference
- Each section pairs Web Forms pattern with clear Blazor alternative — supports library goal of enabling code reuse with minimal markup changes
- Comprehensive coverage including derived patterns (e.g., application state → services)

**Summary (2026-03-05 through 2026-03-07 pre-Run 11)

Expand Down
11 changes: 11 additions & 0 deletions .squad/agents/cyclops/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,17 @@ Team update: ModalPopupExtender and CollapsiblePanelExtender implemented by Cycl
- `src/BlazorWebFormsComponents.Test/RadioButtonList/StableIds.razor` (WithoutID expects no id attr)


### ASHX and AXD URL Handling Middleware (#423)

**Summary:** Extended UseBlazorWebFormsComponents() middleware to handle legacy .ashx (HTTP handler) and .axd (Web Resource) URL patterns per issue #423.

**Changes:**
- BlazorWebFormsComponentsOptions: Added EnableAshxHandling (default: true), EnableAxdHandling (default: true), and AshxRedirectMappings dictionary for custom .ashx redirects.
- AshxHandlerMiddleware: Intercepts .ashx requests. Returns 410 Gone by default; 301 redirect if a custom mapping exists in AshxRedirectMappings.
- AxdHandlerMiddleware: Intercepts .axd requests. Returns 404 for WebResource/ScriptResource/Trace.axd; 410 Gone for ChartImg.axd.
- ServiceCollectionExtensions.UseBlazorWebFormsComponents(): Conditionally registers both new middleware alongside existing AspxRewriteMiddleware.

**Impact:** Existing .aspx rewriting unchanged. All three middleware classes follow the same internal pattern (constructor injection, Invoke method, early return on match). ar used everywhere per IDE0007 rule. Build: 0 errors.
### HttpHandlerBase Implementation for Issue #473 (2026-07-25)

**Summary:** Implemented core HttpHandlerBase feature — 7 new files in src/BlazorWebFormsComponents/Handlers/ enabling migration of ASP.NET Web Forms .ashx handlers to ASP.NET Core with minimal code changes.
Expand Down
14 changes: 14 additions & 0 deletions .squad/agents/rogue/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,20 @@ Test file: `src/BlazorWebFormsComponents.Test/UpdatePanel/ContentTemplateTests.r
- _Imports.razor provides `@inherits BlazorWebFormsTestContext` — no need for explicit @inherits in test files
- `@using Shouldly` added locally when not using _Imports default assertions

### ASHX/AXD Middleware Tests — Issue #423 (2026-03-17)

**46 integration tests for UseBlazorWebFormsComponents middleware (all pass).** Test file: `src/BlazorWebFormsComponents.Test/Middleware/AspxRewriteMiddlewareTests.cs`. Uses `Microsoft.AspNetCore.TestHost` + `TestServer` for full pipeline integration testing — first middleware test file in the project.

**Test categories (46 total):**
- .aspx rewriting regression (5 tests): 301 redirect, Default.aspx→root, query string preservation, subdirectory Default.aspx, aspx works with ashx/axd disabled
- .ashx handler interception (7 tests): 410 Gone default, descriptive body, query string, mixed case (Theory×3), subdirectory path, disabled passthrough
- .ashx custom redirect mappings (6 tests): 301 redirect, Location header, case-insensitive lookup, unmapped returns 410, multiple mappings, query string preservation on redirect
- .axd resource interception (12 tests): 404 for WebResource/ScriptResource/Trace (Theory×3), ChartImg.axd 410 Gone, query strings, mixed case (Theory×3 for 404, Theory×3 for 410), unknown .axd returns 404, disabled passthrough, ChartImg disabled passthrough
- Edge cases (16 tests): ashx/axd substrings passthrough, .html/.api/root passthrough, all disabled passthrough, file-name-only paths, .ashx.bak/.axd.old non-extension paths, 404 empty body, ChartImg descriptive body, subdirectory ChartImg

**Key patterns:** TestServer creates full ASP.NET Core pipeline via `UseBlazorWebFormsComponents` extension. Terminal `app.Run` returns 200 "PASSTHROUGH" — any request reaching it means middleware didn't intercept. `CreateServerAndClient` helper for custom options with proper disposal. Added `Microsoft.AspNetCore.TestHost 10.0.5` package to test csproj.

**Middleware implementation review:** AshxHandlerMiddleware uses `StringComparer.OrdinalIgnoreCase` dictionary for case-insensitive custom mappings. AxdHandlerMiddleware special-cases ChartImg.axd for 410 Gone, all others get 404. Both use `path.EndsWith` with `OrdinalIgnoreCase` — correct for URL path matching.


### HttpHandler Test Coverage (2026-03-23, Issue #473)
Expand Down
129 changes: 129 additions & 0 deletions .squad/decisions/inbox/beast-deprecation-docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Decision: Deprecation Guidance Documentation (#438)

**Date:** 2026-03-17 (Session by Beast)
**Issue:** #438 — Add deprecation guidance docs for runat=server, ViewState, UpdatePanel
**Decision Owner:** Beast (Technical Writer)
**Status:** SHIPPED

## What We Decided

Create a comprehensive `docs/Migration/DeprecationGuidance.md` page documenting Web Forms patterns that **do not have direct Blazor equivalents** and explaining the Blazor alternative for each.

## Why

Web Forms developers migrating to Blazor encounter patterns they can't directly replicate:
- `runat="server"` — Just a scope marker; Blazor components are always server-side
- `ViewState` — BWFC provides it for compatibility, but developers should use component fields
- `UpdatePanel` — Blazor's component model handles incremental rendering natively
- `ScriptManager` — Migration compatibility stub; use `IJSRuntime` instead
- Page lifecycle (`Page_Load`, `IsPostBack`) — Blazor uses different lifecycle hooks
- Server control property manipulation — Use reactive binding instead

Without guidance, developers might:
- Attempt to recreate obsolete patterns (wasting time)
- Misunderstand why familiar APIs are gone (frustration)
- Miss the Blazor-native alternatives (produce suboptimal code)

## What We Built

**File:** `docs/Migration/DeprecationGuidance.md` (32 KB, ~600 lines)

**Content Structure:**
- Each deprecated pattern has a section: "What It Was" → "Why It's Deprecated" → "What To Do Instead"
- Before/after code examples using markdown tabs for easy comparison
- Pattern-specific migration checklists (e.g., lifecycle mapping table)
- Explanation of why the deprecation makes sense in Blazor architecture

**Patterns Covered:**
1. `runat="server"` — Scope marker; just remove it
2. `ViewState` — Use component fields and scoped services
3. `UpdatePanel` → Blazor incremental rendering (no trigger coordination needed)
4. `Page_Load` / `IsPostBack` → `OnInitializedAsync` / event handlers
5. `ScriptManager` → `IJSRuntime` + `HttpClient` + dependency injection
6. Server control properties → Declarative data binding
7. Application/Session state → Singleton/scoped services
8. Data binding events → Component templates with `@context`

**Navigation Update:**
- Added "Deprecation Guidance" to `mkdocs.yml` Migration section
- Placed after "Automated Migration Guide" (early in the migration journey)

## Tone & Audience

**Audience:** Experienced Web Forms developers learning Blazor

**Tone:**
- ✅ Empathetic — Acknowledges these are familiar patterns being left behind
- ✅ Educational — Explains *why* Blazor works differently
- ✅ Practical — Shows clear, working code examples
- ✅ Non-judgmental — No "ViewState was bad"; just "here's the Blazor way"

**Example language:**
> "In Web Forms, you could manipulate control properties on the server in code-behind... This approach worked because Web Forms re-rendered the entire page on each postback. **Blazor uses reactive data binding.** Control properties are derived from component state, not set imperatively."

## Design Decisions

**Placement in Navigation:**
- *After* Automated Migration Guide (not before)
- *Before* Migration Strategies (guides thinking about approach)
- Rationale: Developers run L1 automation first, then encounter these patterns — this doc addresses them early

**Format: Tabbed Before/After Code:**
- **Why tabbed?** MkDocs markdown supports tabbed syntax; easy to read side-by-side
- **Why always paired?** No Web Forms example without Blazor equivalent
- **Why both `razor` and `csharp` blocks?** Shows markup + code-behind for complete picture

**Lifecycle Mapping Table:**
- Explicit table mapping Web Forms lifecycle to Blazor equivalents
- Helps developers quickly find the right hook (`Page_Load` → `OnInitializedAsync`)

## Success Criteria Met

✅ Covers all 5 core patterns from issue #438:
- runat="server"
- ViewState
- UpdatePanel
- Page_Load / IsPostBack
- ScriptManager

✅ Includes one additional critical pattern:
- Server-side control property manipulation → Reactive binding

✅ Covers derived patterns:
- Application/Session state → Services
- Data binding events → Component templates
- All patterns have before/after code examples

✅ Accessible to Web Forms developers:
- Explains each pattern in Web Forms terms first
- Shows clear "Blazor way" alternative
- Empathetic, non-judgmental tone

## Future Maintenance

**When to update this doc:**
- New BWFC components or patterns added (link to new docs)
- Migration toolkit adds new L1 patterns that lack Blazor equivalents
- Team discovers common migration anti-patterns

**Cross-references to maintain:**
- Migration Strategy Guide (link there from Overview section)
- Automated Migration Guide (link there from Overview section)
- Page Service docs (linked in IsPostBack → lifecycle section)

## Files Modified

1. **Created:** `docs/Migration/DeprecationGuidance.md`
- 32 KB, ~600 lines
- 8 major sections + summary checklist
- Markdown with tabs, admonitions, code blocks

2. **Updated:** `mkdocs.yml`
- Added "Deprecation Guidance: Migration/DeprecationGuidance.md" entry
- Positioned after "Automated Migration Guide"

## Related Issues & PRs

- **Linked Issue:** #438
- **Related Skill:** documentation (component-documentation practices applied)
- **Related Docs:** Strategies.md, AutomatedMigration.md, MasterPages.md, User-Controls.md
23 changes: 23 additions & 0 deletions .squad/decisions/inbox/cyclops-ashx-axd-middleware.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Decision: ASHX/AXD Middleware Design (#423)

**Author:** Cyclops
**Date:** 2026-03-18
**Status:** Implemented on `feature/docs-middleware-reports`

## Context

Issue #423 requires handling legacy `.ashx` and `.axd` URLs in the existing `UseBlazorWebFormsComponents()` middleware pipeline.

## Decision

- **Separate middleware classes** for each URL type (`.aspx`, `.ashx`, `.axd`) rather than one monolith. Each is focused and independently toggleable.
- **AshxHandlerMiddleware** takes `BlazorWebFormsComponentsOptions` via constructor injection to access `AshxRedirectMappings`. Returns 410 Gone by default; 301 redirect when a mapping exists.
- **AxdHandlerMiddleware** is stateless (no options needed). Uses path suffix matching: `ChartImg.axd` → 410 Gone; everything else → 404.
- **Registration order** in `UseBlazorWebFormsComponents()`: aspx → ashx → axd. Order doesn't matter since each targets a distinct file extension.
- **`AshxRedirectMappings`** uses `StringComparer.OrdinalIgnoreCase` for case-insensitive path matching, consistent with how ASP.NET handles URLs.

## Team Impact

- No breaking changes. All three features default to `true`.
- Sample projects continue to work with no config changes.
- Future work: if we need more granular .axd control, we can add an `AxdResponseMappings` dictionary similar to `AshxRedirectMappings`.
25 changes: 25 additions & 0 deletions .squad/decisions/inbox/rogue-ashx-axd-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Decision: Middleware Integration Testing Pattern with TestServer

**By:** Rogue (QA Analyst)
**Date:** 2026-03-17
**Issue:** #423

## What

Established `Microsoft.AspNetCore.TestHost` + `TestServer` as the standard middleware testing pattern for this project. Added `Microsoft.AspNetCore.TestHost 10.0.5` package to the test csproj. Created `src/BlazorWebFormsComponents.Test/Middleware/AspxRewriteMiddlewareTests.cs` with 46 integration tests covering the full `UseBlazorWebFormsComponents` middleware pipeline (.aspx, .ashx, .axd handling).

## Pattern

Tests create a `TestServer` with `UseBlazorWebFormsComponents()` in the pipeline and a terminal `app.Run` returning 200 "PASSTHROUGH". Any request that reaches the terminal means no middleware intercepted it. Tests send HTTP requests via `TestServer.CreateClient()` and assert on status codes, headers, and body content.

For custom options, a `CreateServerAndClient` helper creates a fresh server+client pair with proper disposal.

## Why

- **Integration over unit tests:** Testing through the extension method validates the full registration + middleware chain, not individual classes in isolation. Catches wiring bugs.
- **TestServer is lightweight:** No ports, no networking, sub-millisecond per request. 46 tests run in under 1 second.
- **Aligned with ASP.NET Core conventions:** This is the recommended Microsoft pattern for middleware testing.

## Impact

Future middleware (e.g., .asmx handling, custom URL rewriting rules) should follow this same TestServer pattern in the `Middleware/` test folder.
Loading
Loading