element in wwwroot/index.html.
builder.RootComponents.Add
("#app");
// HeadOutlet manages elements (title, meta tags) from Razor components.
builder.RootComponents.Add("head::after");
// Read the API base URL from configuration (wwwroot/appsettings.json).
// This file is PUBLIC -- never put secrets here.
var apiBaseUrl = builder.Configuration["ApiBaseUrl"]
?? "https://localhost:7100";
// Register ChatApiClient as a typed HttpClient.
// AddHttpClient uses IHttpClientFactory internally, which:
// - Manages HttpClient lifetimes properly (avoids socket exhaustion)
// - Allows per-client configuration (base address, headers)
// - Makes the service injectable via constructor DI
builder.Services.AddHttpClient(client =>
{
client.BaseAddress = new Uri(apiBaseUrl);
});
await builder.Build().RunAsync();
```
### API Program.cs (Server)
```csharp
// Program.cs -- ASP.NET Core Web API entry point
// This is the backend server that the Blazor WASM client talks to.
// It will eventually proxy OpenAI calls and manage JSON file storage.
// In Phase 1, it only serves a health check endpoint.
var builder = WebApplication.CreateBuilder(args);
// AddControllers() registers MVC controller services.
// We use Controllers (not Minimal API) for explicit structure (D-05).
builder.Services.AddControllers();
// CORS (Cross-Origin Resource Sharing) configuration.
// The WASM client runs on a different origin (different port),
// so the browser blocks requests unless the server explicitly allows them.
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowBlazorClient", policy =>
{
// TODO: Read from configuration instead of hardcoding
policy.WithOrigins("https://localhost:5200")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
var app = builder.Build();
// Middleware order matters in ASP.NET Core.
// CORS must be applied before routing and authorization.
app.UseCors("AllowBlazorClient");
app.UseAuthorization();
// MapControllers() discovers all [ApiController] classes
// and maps their [HttpGet], [HttpPost], etc. attributes to routes.
app.MapControllers();
app.Run();
```
## State of the Art
| Old Approach | Current Approach | When Changed | Impact |
|--------------|------------------|--------------|--------|
| Hosted Blazor WASM template (Client+Server+Shared in one template) | Separate projects added to a manual solution | .NET 8 (Nov 2023) | Must create three projects manually; no `--hosted` flag |
| `Newtonsoft.Json` for serialization | `System.Text.Json` built into .NET | .NET Core 3.0+ | No extra dependency; source generators for trim safety |
| `HttpClient` registered directly as Singleton/Scoped | `IHttpClientFactory` via `AddHttpClient` | .NET Core 2.1+ | Proper socket management; typed clients for clean architecture |
## .NET Version Decision (Claude's Discretion)
**Recommendation: Target .NET 9 (`net9.0`)**
Rationale:
- CLAUDE.md explicitly specifies .NET 9 as the target
- .NET 9.0.312 SDK is installed on this machine
- .NET 10 SDK (10.0.201) is also available but is not yet at LTS; using it in a tutorial project risks encountering preview-stage breaking changes
- All recommended packages (OpenAI 2.9.1, Markdig 1.1.1, MudBlazor 9.2.0) are confirmed compatible with .NET 9
- The `blazorwasm` template with `--framework net9.0` is verified working
## Validation Architecture
### Test Framework
| Property | Value |
|----------|-------|
| Framework | None yet (greenfield) |
| Config file | None -- see Wave 0 |
| Quick run command | `dotnet build ChatAgent.sln` |
| Full suite command | `dotnet build ChatAgent.sln && dotnet publish src/ChatAgent.Client/ChatAgent.Client.csproj -c Release --nologo` |
### Phase Requirements -> Test Map
| Req ID | Behavior | Test Type | Automated Command | File Exists? |
|--------|----------|-----------|-------------------|-------------|
| CODE-01 | Every file has inline comments explaining Blazor concepts | manual | Manual review of all `.cs` and `.razor` files | N/A |
| CODE-02 | Phase introduces one concept incrementally | manual | Manual review -- Phase 1 concept = "solution structure and project boundaries" | N/A |
| (SC-1) | `dotnet run` starts both projects without errors | smoke | `dotnet build ChatAgent.sln` (build verification) | N/A -- Wave 0 |
| (SC-2) | WASM client reaches API server (CORS working) | integration | Manual -- start both projects, verify health endpoint from client UI | N/A |
| (SC-3) | Shared models referenced by both projects | build | `dotnet build ChatAgent.sln` (compile-time check) | N/A -- Wave 0 |
| (SC-4) | `dotnet publish` completes with no IL trim warnings | smoke | `dotnet publish src/ChatAgent.Client/ChatAgent.Client.csproj -c Release --nologo 2>&1 \| grep -c "warning IL"` | N/A -- Wave 0 |
| (SC-5) | Every file contains inline comments | manual | Manual review | N/A |
### Sampling Rate
- **Per task commit:** `dotnet build ChatAgent.sln`
- **Per wave merge:** `dotnet build ChatAgent.sln && dotnet publish src/ChatAgent.Client/ChatAgent.Client.csproj -c Release --nologo`
- **Phase gate:** Full build + publish clean + manual CORS verification
### Wave 0 Gaps
- No formal test project needed in Phase 1 -- the verification is build success + publish success + manual CORS check
- The `dotnet build` and `dotnet publish` commands serve as the automated validation
- CODE-01 and CODE-02 are inherently manual-review requirements
## Environment Availability
| Dependency | Required By | Available | Version | Fallback |
|------------|------------|-----------|---------|----------|
| .NET 9 SDK | All projects | Yes | 9.0.312 | -- |
| .NET 10 SDK | Not required | Yes | 10.0.201 | -- |
| `dotnet new blazorwasm` template | Client project | Yes | Included in SDK | -- |
| `dotnet new webapi` template | API project | Yes | Included in SDK | -- |
| `dotnet new classlib` template | Shared project | Yes | Included in SDK | -- |
| HTTPS dev certificate | Local HTTPS | Unknown | -- | Use `--no-https` flag or run `dotnet dev-certs https --trust` |
**Missing dependencies with no fallback:** None.
**Missing dependencies with fallback:**
- HTTPS dev certificate status is unknown -- if untrusted, can use HTTP for Phase 1 local dev or run the trust command.
## Open Questions
1. **Port numbers for local development**
- What we know: Templates assign ports in `launchSettings.json` which vary per creation
- What's unclear: Exact ports until projects are actually created
- Recommendation: After project creation, inspect both `launchSettings.json` files and align CORS config with actual client URL. Consider setting explicit predictable ports (e.g., Client: 5200, API: 7100).
2. **HTTPS vs HTTP for Phase 1 local dev**
- What we know: HTTPS requires a trusted dev certificate
- What's unclear: Whether the dev cert is already trusted on this machine
- Recommendation: Attempt HTTPS first. If certificate issues arise, fall back to HTTP for Phase 1 (add `--no-https` and use `http://` URLs). HTTPS can be re-enabled in later phases.
## Project Constraints (from CLAUDE.md)
- **Tech stack**: .NET / C# / Blazor WebAssembly -- non-negotiable
- **LLM provider**: OpenAI GPT API (not used in Phase 1, but architecture must support it)
- **Storage**: JSON files on local disk (not used in Phase 1, but architecture must support it)
- **Architecture**: WASM client + backend API (API key stays server-side)
- **Code style**: Every Blazor concept introduced must have inline comments explaining what it does and why
- **GSD Workflow**: Use GSD entry points for all file changes
## Sources
### Primary (HIGH confidence)
- .NET 9 SDK verified installed: `dotnet --list-sdks` shows 9.0.312
- `blazorwasm` template verified: `dotnet new list blazorwasm` confirms availability
- `webapi --use-controllers` flag verified: `dotnet new webapi --help` confirms option exists
- Template output verified: Created temporary projects to confirm `Program.cs` structure, `.csproj` contents, and default file layout
### Secondary (MEDIUM confidence)
- `.planning/research/ARCHITECTURE.md` -- pre-existing project research on WASM/API split patterns
- `.planning/research/STACK.md` -- pre-existing stack research with NuGet-verified versions
- `.planning/research/PITFALLS.md` -- pre-existing pitfalls research from official GitHub issues
### Tertiary (LOW confidence)
- None -- all findings verified against installed SDK and official templates
## Metadata
**Confidence breakdown:**
- Standard stack: HIGH -- verified against installed SDK and templates
- Architecture: HIGH -- three-project structure is well-documented Microsoft pattern; template output confirmed
- Pitfalls: HIGH -- CORS ordering, port mismatch, and IL trimming are well-known ASP.NET Core issues documented in official sources
**Research date:** 2026-03-27
**Valid until:** 2026-04-27 (stable -- .NET 9 is mature, templates are not changing)