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
73 changes: 73 additions & 0 deletions .squad/agents/aragorn/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,43 @@ All labeled: `squad`, `squad:gimli`

---

## 2026-03-04 21:40Z — Squad Team Portability Design

**Task:** Investigate and design a solution for reusing the squad team across multiple projects with accumulated experience

**Context:** Matthew wants to reuse the IssueManager squad team (Aragorn, Gimli, Sam, Boromir, Legolas, Frodo, Gandalf, Scribe, Ralph) across new projects while preserving accumulated learnings and maintaining team identity.

**Decision: Personal Team Repository with Career Summaries**

Created `github.com/mpaulosky/squad-team` repository containing:
- Portable team files: team.md, routing.md, ceremonies.md, casting/, agents/*/charter.md, skills/
- NEW: agents/*/career.md — cross-project learnings per agent
- Installation script: install-squad.ps1 (PowerShell)
- Project-specific files generated fresh: decisions.md, history.md, orchestration-log/, log/, identity/now.md

**Key Design Points:**
1. **Career Memory** — Each agent maintains career.md with transferable learnings (patterns, anti-patterns, principles that apply broadly). Full history.md stays in each project (too noisy to carry forward).
2. **Versioning** — Team repo uses semantic versioning tags (v0.5.2, v0.5.3). Each project's team.md shows installed version.
3. **Installation** — One-command setup: `install-squad.ps1 -ProjectName "X" -Stack "Y"` copies team files, generates fresh project files, updates team.md context.
4. **Updates** — After each project, extract key learnings from history.md → career.md, commit to team repo, tag new version.

**Why This Approach:**
- Simple (no git submodules, no CLI dependency)
- Matthew owns it (full control)
- Career memory co-located with charters
- Versioned and traceable
- Transferable skills travel with team

**Files Created:**
- `.squad/decisions/inbox/aragorn-team-portability-design.md` — Full design decision document
- `docs/squad-team-portability.md` — Practical quick-start guide for Matthew

**Result:** Complete portable team solution ready for implementation. Next: create mpaulosky/squad-team repo and extract IssueManager career learnings.

**Key Learning:** Squad team portability requires separating team identity (portable: charters, routing, ceremonies, career summaries) from project state (ephemeral: decisions, history, logs). Career files (50-line curated learnings) are more valuable than full history files (200+ lines of project-specific detail) for cross-project knowledge transfer.

---

---

## 2026-03-04 — Copyright Header Standardization and Automation
Expand Down Expand Up @@ -316,3 +353,39 @@ For `.razor` files: `@* ... *@` comment syntax
- Pushed to main: 2 commits (cb6f9bf tests, 91eee02 src+automation)

**Key Learning:** Lightweight automation (Copilot instructions + charter rules) provides immediate value without build system complexity. No StyleCop or .editorconfig changes needed — instructions file is sufficient for consistent headers on new files.

---

## 2026-03-05 — IssueTrackerApp UI Modernization Feasibility Review

**Task:** Reviewed `E:\github\IssueTrackerApp\src\Web\Components` vs `E:\github\IssueManager\src\Web` to assess feasibility of modernizing IssueTrackerApp's UI.

### What I Found in IssueTrackerApp
- **Tech stack:** Blazor Interactive Server, .NET 10 — same rendering model as IssueManager ✅
- **CSS:** Bootstrap 5 + scoped `.razor.css` per component. No utility-first framework, no CSS variables, no dark mode.
- **Component library:** Radzen.Blazor — heavy use of `RadzenDataGrid` (inline edit mode), `RadzenButton`, `RadzenTextBox`, validators. This is the largest single replacement cost.
- **Auth:** Microsoft Identity Web (Azure AD / Entra ID). Claims use `objectidentifier`, `givenname`, `surname`.
- **Data access:** Direct service injection (`ICategoryService`, `IIssueService`, etc.) — no HTTP clients, no Aspire service discovery.
- **Navigation:** Left sidebar (dark background, checkbox-toggle collapse). No mobile hamburger, no theme controls.
- **Theme system:** Absent — hardcoded colors, no dark/light toggle.
- **Pages beyond IssueManager:** Admin (approve/reject issues), Profile, Comment detail.
- **Session state:** Blazored.SessionStorage used for filter state persistence on Index page.

### Feasibility Verdict: ✅ FEASIBLE — Pure UI Modernization
Because both projects share the same Blazor rendering model, a UI-only modernization pass is achievable without touching the service layer or auth provider:
- Remove Bootstrap → add Tailwind CSS + CSS custom properties
- Replace all Radzen components → IssueManager's custom DataTable, ConfirmDialog, etc.
- Port layouts and pages to Tailwind markup (code-behind logic preserved)
- Add dark/light toggle + 4 color themes (ThemeToggle, ThemeColorSelector, theme.js)
- Port navigation to top horizontal responsive nav

### Scope Boundaries
- **In scope:** CSS framework swap, component replacement, layout port, theme system
- **Out of scope:** Auth provider migration (MS Identity → Auth0), service-to-API-client migration — both are separate architectural sprints

### Key Risks
1. RadzenDataGrid inline edit mode → must decide: keep inline or switch to separate edit pages
2. Auth claims shape differs between MS Identity and Auth0 — if auth stays as-is, NavMenu must read the right claim types
3. Remove Radzen package from csproj after replacement

**Decision doc:** `.squad/decisions/inbox/aragorn-issuetracker-ui-review.md`
31 changes: 31 additions & 0 deletions .squad/agents/boromir/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,34 @@ DevOps on IssueManager (.NET 10, GitHub Actions, Aspire, NuGet centralized packa
- Do NOT commit incomplete application refactoring
- Escalated to .squad/decisions/inbox/boromir-issue89-incomplete-refactoring.md
- Request: Matthew/application team must complete refactoring, test locally, then resubmit

### 2026-03-04: CI Test Failures — _Imports.razor Copyright Header Placement

**Issue:** GitHub CI Test Suite workflow failing with 8 CS0103 errors on `FooterComponent.razor` after copyright header sweep by Aragorn and Gimli.

**Root Cause:**
- Aragorn's commit `acd39d6` added copyright header to `src/Web/_Imports.razor` BEFORE the `@using` directives
- In Razor files, copyright comments that reference imported types CANNOT precede the `@using` directives that import those types
- When copyright header was placed at line 1-8, all subsequent `@using` statements were parsed but the BuildInfo class (from `@using Web`) was not accessible in FooterComponent.razor
- Result: 8 errors like `error CS0103: The name 'BuildInfo' does not exist in the current context`

**Fix:**
- Moved copyright header in `_Imports.razor` to END of file (after all `@using` directives)
- For `_Imports.razor` specifically: copyright header must come AFTER imports, not before
- Build + all tests now pass locally (Unit.Tests: 417 passed, Blazor.Tests: 164 passed, Architecture.Tests: 9 passed, Aspire.Tests: 18 passed)

**Pre-Push Hook Validation:**
- Pre-push hook in `scripts/hooks/pre-push` already enforces Unit.Tests + Blazor.Tests + Architecture.Tests before any push
- Updated `.git/hooks/pre-push` to match committed version from `scripts/hooks/`
- Updated Aragorn and Gimli charters: added Critical Rule #1 mandating full local test run before push

**Key Learning:**
- CI must NEVER be the first place test failures are discovered
- Local validation: `dotnet test tests/Unit.Tests tests/Blazor.Tests tests/Architecture.Tests` before every push
- Razor `_Imports.razor` files: copyright header MUST come after `@using` directives if header text references any imported types

**Commit:** `100cb77` on main
**Files Modified:**
- src/Web/_Imports.razor (copyright header moved to end)
- .squad/agents/aragorn/charter.md (added mandatory full test run rule)
- .squad/agents/gimli/charter.md (added mandatory full test run rule)
18 changes: 18 additions & 0 deletions .squad/agents/gandalf/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ Key security concerns to address from day one:
## Learnings
<!-- Gandalf appends learnings here after each session -->

### 2026-03-04: Role-Based Access Control Implementation
**Sprint:** Security Hardening
**Status:** Complete
**What:** Implemented comprehensive RBAC across Categories, Statuses, and Issues pages:
1. Created NotAuthorizedPage.razor — friendly "Access Denied" page with navigation options
2. Updated Routes.razor to distinguish between unauthenticated users (redirect to login) vs authenticated users with wrong role (show NotAuthorizedPage)
3. Restricted all Category CRUD pages to Admin role only (CategoriesPage, CreateCategoryPage, EditCategoryPage)
4. Restricted all Status CRUD pages to Admin role only (StatusesPage, CreateStatusPage, EditStatusPage)
5. Enforced Admin OR Author access on EditIssuePage — reads auth state and redirects unauthorized users to /not-authorized
6. Created decision inbox file documenting Auth0 role claim mapping requirement
**Key Implementation:**
- NotAuthorizedPage provides user-friendly access denial with navigation to home/issues
- Routes.razor uses nested AuthorizeView to detect auth state: authenticated users without role see NotAuthorizedPage, unauthenticated users redirect to login
- All Category/Status pages now require `[Authorize(Roles = "Admin")]` attribute
- EditIssuePage checks `user.IsInRole("Admin") || user.Identity?.Name == _issue.Author.Name` in OnInitializedAsync
**Why:** P0 security gap — anonymous and non-admin users could access admin-only CRUD pages. Issue editing was unrestricted.
**Security Note:** For RBAC to work, Auth0 must be configured to include roles in JWT claims and Web/Extensions/AuthExtensions.cs must map those claims to ClaimTypes.Role. Without this, all Admin checks will fail. Documented in decisions/inbox.

### 2026-02-27: Auth0 Scaffold Implementation — Passive Configuration Pattern
**Sprint:** Sprint 3 Hardening
**Branch:** feat/sprint-3-hardening
Expand Down
19 changes: 19 additions & 0 deletions .squad/agents/gimli/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,25 @@ Tester on IssueManager (.NET 10, xUnit, FluentAssertions, NSubstitute, bUnit, Te

**Next:** Ready for merge; Gimli available for next test coverage task

---

## 2026-03-04 21:25Z — Matthew's Test File Review (Copyright Headers & Warning Fixes)

**Task:** Review 33 manually-changed test files for copyright header consistency and `#pragma warning` scope

**Result:** ✅ ALL APPROVED

**Verification:**
- ✓ Copyright headers: Microsoft license + "All rights reserved" + correct year (2025-2026)
- ✓ Warning suppressions: Minimal scope, only where needed, proper `#pragma restore` placement
- ✓ Test logic: Unchanged, ready for merge

**Build Status:** 0 errors

**Files Reviewed:** 33 across Unit.Tests, Integration.Tests, Blazor.Tests, Architecture.Tests

**Next:** Ready for merge; Gimli available for next test coverage task

### 2026-02-28: bUnit 2.x Migration — Complete

**Task:** Migrate all Blazor test files from bUnit 1.29.5 → 2.6.2 API following Boromir's package upgrade.
Expand Down
9 changes: 9 additions & 0 deletions .squad/agents/legolas/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,12 @@ Frontend Developer on IssueManager (.NET 10, Blazor Interactive Server Rendering
- Added global usings: Microsoft.AspNetCore.Authorization and Microsoft.AspNetCore.Components.Authorization in _Imports.razor
- Auth endpoints: /auth/login and /auth/logout already wired by Sam (backend)
- List/view pages intentionally left public: IssuesPage, IssueDetailPage, CategoriesPage, StatusesPage

### Auth UI Visibility Fixes (2026-02-27)
- Added `@rendermode InteractiveServer` to NavMenu.razor: Enables ThemeToggle, ThemeColorSelector, and mobile hamburger to work (previously static SSR made @onclick non-functional)
- NavMenu auth visibility: Wrapped "New Issue" links (desktop + mobile) in `<AuthorizeView><Authorized>` blocks
- NavMenu admin visibility: Wrapped "Categories" and "Statuses" links (desktop + mobile) in `<AuthorizeView Roles="Admin"><Authorized>` blocks
- IssuesPage: Added `@rendermode InteractiveServer`, injected AuthenticationStateProvider, loaded current user name, and restricted Edit links to Admin role OR issue author
- IssueDetailPage: Added `@rendermode InteractiveServer`, injected AuthenticationStateProvider, loaded current user name, and restricted Edit Issue button to Admin role OR issue author
- Auth pattern: Use `<AuthorizeView Roles="Admin"><Authorized>` for admin-only, and `<NotAuthorized>` with manual author name check (`_currentUserName == issue.Author.Name`) for author access
- Interactive components must have `@rendermode InteractiveServer` to support @onclick handlers and JS interop (IJSRuntime)
12 changes: 12 additions & 0 deletions .squad/agents/sam/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,15 @@ Backend Developer on IssueManager (.NET 10, MongoDB, EF Core, CQRS, MediatR, Min
- **Edit tool unreliability:** The dit tool reports "File updated with changes" even when old_str doesn't match. Use PowerShell Set-Content with regex (-replace) for reliable bulk text replacement across many files
- **Pre-push gate note:** Test files (Gimli scope) had cascading compilation errors; pushed with --no-verify per issue instructions that test failures are expected and assigned to #82-88
- **PR:** #91 — do NOT merge until Gimli's test issues (#82, #84, #86, #88) are resolved

### Database Seeding Implementation (2026-03-04)
- **DatabaseSeeder.cs:** Created `src/Api/Data/DatabaseSeeder.cs` to seed default Category and Status data at API startup
- **Seeding pattern:** Check `CountAsync()` on repository; if count > 0, skip seeding (idempotent). Log info for both seeded and skipped scenarios
- **Default categories:** Bug, Feature, Enhancement, Documentation, Question
- **Default statuses:** Open, In Progress, Resolved, Closed, Won't Fix
- **DTO construction:** CategoryDto and StatusDto are records with positional constructor. Seed data uses: `new CategoryDto(ObjectId.Empty, "Name", "Description", DateTime.UtcNow, null, false, UserDto.Empty)`
- **IStatusRepository.CountAsync:** Added `CountAsync()` method to interface (was missing but implementation had it)
- **DI registration:** Registered `DatabaseSeeder` as Transient in `ServiceCollectionExtensions.AddRepositories()` (after repository registrations)
- **Program.cs startup:** After `var app = builder.Build()`, create scope, resolve `DatabaseSeeder`, call `SeedAsync()`. Runs BEFORE middleware pipeline setup
- **Result<T> API:** Properties are `Success` (not IsSuccess), `Failure`, `Error` (not ErrorMessage), `Value`. Check `result.Success` before accessing `result.Value`. Log `result.Error` on failure
- **Program.cs partial class:** Added `public partial class Program { }` at end of file for WebApplicationFactory test access (standard backend pattern)
Loading
Loading