Skip to content

refactor: move Tailwind CSS to wwwroot/css/, remove wwwroot/lib - #1

Merged
mpaulosky merged 17 commits into
mainfrom
squad/coverage-test-hardening
Apr 18, 2026
Merged

refactor: move Tailwind CSS to wwwroot/css/, remove wwwroot/lib#1
mpaulosky merged 17 commits into
mainfrom
squad/coverage-test-hardening

Conversation

@mpaulosky

Copy link
Copy Markdown
Owner
  • Output tailwind.css to wwwroot/css/ instead of wwwroot root
  • Remove empty wwwroot/lib/ (stale Bootstrap libman directory)
  • Update package.json scripts, Web.csproj, App.razor link paths

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com## Summary

Closes #

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ Feature (non-breaking change that adds functionality)
  • ♻️ Refactor (no behavior change, code cleanup/restructure)
  • 🧪 Tests (new or updated tests only)
  • 📝 Docs (README, XML docs, comments)
  • ⚙️ Infra/CI (GitHub Actions, Aspire, NuGet, deployment)
  • 🔒 Security (auth, permissions, secrets, headers)
  • 💥 Breaking change (existing behavior changes)

Domain Affected

  • 🏗️ Architecture / domain logic / CQRS → Aragorn required
  • 🔧 Backend (handlers, repositories, API endpoints, MediatR) → Sam required
  • ⚛️ Frontend (Blazor components, Razor pages, CSS, JS) → Legolas required
  • 🧪 Unit / bUnit / integration tests → Gimli required
  • 🧪 E2E / Playwright / Aspire integration tests → Pippin required
  • ⚙️ CI/CD / GitHub Actions / NuGet / Aspire AppHost → Boromir required
  • 🔒 Auth0 / authorization / security-relevant changes → Gandalf required
  • 📝 Docs / README / XML docs → Frodo required

Self-Review Checklist

Code Quality

  • I ran dotnet build IssueTrackerApp.slnx --configuration Release — 0 errors, 0 warnings
  • I ran dotnet test IssueTrackerApp.slnx --configuration Release --no-build — all pass
  • No TODO/FIXME left unless tracked in a follow-up issue (link it)
  • No secrets, API keys, or credentials committed

Architecture

  • New handlers follow the Command/Query/Handler/Validator naming conventions
  • New handlers are sealed
  • Domain layer has no references to Web or Persistence.* projects
  • Result<T> / ResultErrorCode used for expected failures (no exception-driven control flow)
  • DTOs are records in Domain.DTOs; Models are in Domain.Models
  • No DTO types embedded in Model classes

Tests

  • New code has corresponding unit tests
  • Integration tests use domain-specific collections ([Collection("XxxIntegration")])
  • No test compares two IssueDto.Empty / CommentDto.Empty instances directly

Security (check if security-relevant)

  • New endpoints have appropriate RequireAuthorization / policy applied
  • No MarkupString used with user-supplied content
  • No user input reflected in MongoDB queries without sanitization

Merge Readiness

  • Branch is up to date with main (no merge conflicts)
  • CI checks are green (do not request review while checks are pending/failing)
  • PR description is complete — reviewers should not have to ask what this does

Screenshots / Evidence

Notes for Reviewers

mpaulosky and others added 17 commits April 17, 2026 11:03
- Output tailwind.css to wwwroot/css/ instead of wwwroot root
- Remove empty wwwroot/lib/ (stale Bootstrap libman directory)
- Update package.json scripts, Web.csproj, App.razor link paths

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add startup guard that detects empty Auth0:Domain or Auth0:ClientId and
throws a clear InvalidOperationException with instructions for setting
user secrets, rather than the cryptic ArgumentException from deep in
the OpenIdConnect middleware.

Also add Auth0 placeholder keys to appsettings.Development.json to
document which secrets are required.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Browsers cannot process PostCSS/Tailwind directives in app.css
(@import tailwindcss, @theme inline, @apply, @custom-variant).
The compiled tailwind.css already includes all styles, custom
properties, dark mode variants, and color theme overrides.
Removing the duplicate app.css link fixes styling and theme toggles.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Without @rendermode InteractiveServer, Blazor renders NavMenu as static SSR.
@OnClick events are silently ignored in static SSR — no SignalR connection exists.
This caused the dark mode toggle and color theme buttons to do nothing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add text-primary to .nav-link base style so all nav links respond to
  color theme changes (not just the brand NavLink)
- Track _isDark bool in NavMenu; read initial state from DOM on first
  render via JS interop; swap icon between moon and sun on toggle

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add html:not(.dark) body.theme-* rules that shift --color-canvas and
--color-surface to the 50/100 tint of each theme color in light mode:
  blue   → blue-50 / blue-100
  red    → rose-50 / rose-100
  green  → green-50 / green-100
  yellow → yellow-50 / yellow-100

Dark mode is unaffected; the :not(.dark) guard ensures html.dark's
dark canvas values always win. This makes the color theme circles
visually change the whole page, not just primary-colored elements.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Blazor 8 enhanced navigation patches the DOM from server-rendered HTML,
which strips JS-added classes on <html> and <body> on every page
transition. Fix by:
- Extracting applyTheme() function
- Calling it on initial load (existing behaviour)
- Listening to document 'enhancedload' event (fired by Blazor after
  each enhanced navigation) to re-apply dark + color theme classes
- Defensive remove('dark') in light-mode branch
- Dedup theme class removal before re-adding

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- NavMenu: add _currentTheme state (default: theme-blue), ThemeBtnClass()
  shows ring-2+scale-110 on selected button; reads colorTheme from
  localStorage in OnAfterRenderAsync; SetTheme() updates C# + JS state
- app.css: add dark-mode per-theme canvas/surface CSS vars so nav/footer
  bg-surface renders themed dark blue/red/green/yellow instead of gray
- App.razor: MutationObserver guards html/body class attrs as backstop;
  listen to both enhancedload and blazor:navigated events; fix localStorage
  update order in toggleDark/setTheme to prevent observer race condition

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Create wwwroot/js/theme.js: window.themeManager with 12 methods,
  4 colors × 2 brightness = 8 themes stored as 'theme-blue-light' etc.
  Uses STORAGE_KEY 'tailwind-color-theme', calls initialize() on load.

- Rewrite app.css: full OKLCH primary-50..950 palettes for all 8 themes
  on :root.theme-* selectors. @theme inline exposes primary-* as Tailwind
  utilities. Semantic tokens (canvas/surface/content/muted/edge) derived
  from primary shades per theme. :root fallback prevents FOUC.

- Update App.razor: IIFE migrates old localStorage keys (colorTheme +
  darkMode) to unified 'tailwind-color-theme'. Applies theme class to
  <html> immediately. Removes MutationObserver and old window.setTheme/
  toggleDark globals. Adds <script src='js/theme.js'> before blazor.web.js.

- Update NavMenu.razor: nav uses bg-primary-400 (always colored). Links,
  brand, hamburger, controls use text-primary-50 / bg-primary-300. Theme
  select values are 'blue'/'red'/etc. (not 'theme-blue'). C# fields changed
  to _currentColor + _currentBrightness; JS interop uses themeManager
  methods. Dark toggle shows SVG sun/moon icons. Reads back brightness
  after toggle for robustness.

- Update MainLayout.razor: footer uses bg-primary-800 text-primary-50
  border-primary-700 so it is always richly colored in all themes/modes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- NavMenu: inject NavigationManager, subscribe LocationChanged to re-sync
  _currentColor and _currentBrightness from JS on every page navigation;
  implement IDisposable to unsubscribe and prevent memory leaks
- MainLayout: change footer from bg-primary-800/border-primary-700 to
  bg-primary-400/border-primary-500 to match nav bar color

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The IIFE was placed at the bottom of <body>, so the browser rendered
all page content in light mode before the script ran. Moving it to the
very top of <head> (before stylesheet links) ensures the theme class
is on <html> when the browser first calculates CSS — dark mode now
applies from the first paint with zero flash.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…avigation

- Extract applyThemeFromStorage() helper in the IIFE so it can be reused
- Add MutationObserver on <html> element: if Blazor's DOM reconciliation strips
  the theme class (because server renders <html lang='en'> without classes),
  the observer immediately re-applies from localStorage
- Add 100ms delayed retry in enhancedload handler to catch any post-navigation
  DOM patching that occurs after the initial event fires
- Disconnect any previous _themeObserver before creating a new one (prevents
  duplicate observers if the IIFE is re-executed)
- Keep blazor:navigated listener as belt-and-suspenders

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Session log (2026-04-17):
- Summarizes theme persistence bug fixes
- Documents three resolved issues
- Lists commit SHAs

Orchestration log:
- Details implementation phases
- Documents verification results
- Confirms user validation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Captures all patterns from the Tailwind migration:
- Anti-FOUC IIFE placement in <head> before stylesheets
- Unified localStorage key (tailwind-color-theme)
- Old split-key migration shim (colorTheme + darkMode)
- Blazor enhanced-navigation re-application hooks
- MutationObserver guard against DOM reconciliation
- themeManager JS object coordination
- Footer/nav color consistency pattern
- Anti-patterns

Source: feature/tailwind-migration, commits 8105239 4c41df0 c56ac47

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- routing.md: new Skills section maps theme/Tailwind work to the skill
- legolas/charter.md: standing instruction to read skill before any
  theme/FOUC/localStorage task

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 18, 2026 18:06
@mpaulosky mpaulosky added the squad Squad triage inbox — Lead will assign to a member label Apr 18, 2026
@mpaulosky
mpaulosky merged commit e0255e1 into main Apr 18, 2026
2 checks passed
@mpaulosky
mpaulosky deleted the squad/coverage-test-hardening branch April 18, 2026 18:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR shifts the Web UI styling stack fully to Tailwind (including theme persistence across Blazor enhanced navigation), removes stale Bootstrap static assets, and adds Auth0 role-claim normalization plus a set of bUnit/unit tests with coverage configuration.

Changes:

  • Move Tailwind source/compiled CSS under src/Web/wwwroot/css/, add Tailwind build scripts + MSBuild hook, and remove Bootstrap assets from wwwroot/lib/.
  • Add theme persistence implementation (head IIFE + themeManager JS + NavMenu controls) and restyle multiple Razor pages to Tailwind utilities.
  • Introduce Auth0 role-claim expansion/normalization (RoleClaimsHelper) and add unit/bUnit coverage + new tests.

Reviewed changes

Copilot reviewed 40 out of 92 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
tests/Unit.Tests/Unit.Tests.csproj Enables coverage/thresholding and adds bUnit + coverlet dependencies.
tests/Unit.Tests/Testing/TestAuthorizationService.cs Test IAuthorizationService to support AuthorizeView behaviors in bUnit.
tests/Unit.Tests/Security/RoleClaimsHelperTests.cs Unit coverage for role claim type parsing/expansion/deduplication.
tests/Unit.Tests/ResultTests.cs Unit coverage for Result/Result<T> helpers and conversions.
tests/Unit.Tests/Features/UserManagement/ProfileTests.cs bUnit tests for the new Profile page rendering/fallbacks.
tests/Unit.Tests/Components/RazorSmokeTests.cs Broad smoke coverage for key components/pages under Tailwind + auth scenarios.
tests/Unit.Tests/Components/Layout/NavMenuTests.cs bUnit coverage for nav auth gating + JS theme interactions.
src/Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css Removes Bootstrap static asset (part of wwwroot/lib cleanup).
src/Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css Removes Bootstrap static asset (part of wwwroot/lib cleanup).
src/Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css Removes Bootstrap static asset (part of wwwroot/lib cleanup).
src/Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css Removes Bootstrap static asset (part of wwwroot/lib cleanup).
src/Web/wwwroot/js/theme.js Adds window.themeManager for theme storage + DOM class application.
src/Web/wwwroot/css/tailwind.css Adds generated Tailwind output in the new wwwroot/css/ location.
src/Web/wwwroot/css/app.css Adds Tailwind v4 “CSS-first” input with @source, theme tokens, and component styles.
src/Web/wwwroot/app.css Removes the old root-level CSS (Bootstrap-era styles).
src/Web/appsettings.Development.json Adds Auth0 config placeholders for local dev discoverability.
src/Web/Web.csproj Adds an MSBuild target to build Tailwind via npm run tw:build.
src/Web/Security/RoleClaimsHelper.cs Adds role claim type selection + role expansion/deduplication utilities.
src/Web/Properties/AssemblyInfo.cs Adds InternalsVisibleTo for unit test access.
src/Web/Program.cs Adds Auth0 config guard + OIDC token validation hook to normalize role claims.
src/Web/Features/UserManagement/Profile.razor Adds an authenticated Profile page showing identity/roles/claims.
src/Web/Features/UserManagement/ManageRoles.razor Restyles Manage Roles page from Bootstrap to Tailwind.
src/Web/Features/BlogPosts/List/Index.razor Restyles list/table + alerts/buttons from Bootstrap to Tailwind.
src/Web/Features/BlogPosts/Edit/Edit.razor Restyles edit form + alerts/buttons from Bootstrap to Tailwind.
src/Web/Features/BlogPosts/Delete/ConfirmDeleteDialog.razor Replaces Bootstrap modal with Tailwind overlay/dialog.
src/Web/Features/BlogPosts/Create/Create.razor Restyles create form + alerts/buttons from Bootstrap to Tailwind.
src/Web/Components/Pages/Weather.razor Restyles sample Weather page table and copy.
src/Web/Components/Pages/Counter.razor Restyles sample Counter page button and copy.
src/Web/Components/Layout/ReconnectModal.razor.css Updates reconnect modal to use theme CSS variables instead of hardcoded colors.
src/Web/Components/Layout/NavMenu.razor.css Removes old Bootstrap/sidebar nav CSS.
src/Web/Components/Layout/NavMenu.razor Replaces sidebar nav with top nav + theme controls + mobile menu.
src/Web/Components/Layout/MainLayout.razor.css Removes old layout CSS tied to sidebar/Bootstrap layout.
src/Web/Components/Layout/MainLayout.razor Reworks layout wrapper, spacing, and footer styling for Tailwind.
src/Web/Components/App.razor Updates CSS/script links + adds head script for theme persistence/anti-FOUC.
package.json Adds Tailwind CLI build/watch scripts and devDependencies.
aspire.config.json Adds Aspire app host path configuration.
.squad/skills/blazor-tailwind-theme-persistence/SKILL.md Documents the theme persistence approach as a reusable Squad skill.
.squad/routing.md Adds routing guidance to inject the theme persistence skill for relevant work.
.squad/orchestration-log/2026-04-17T21:36:35Z-copilot-theme-fix.md Captures orchestration steps taken for theme persistence fixes.
.squad/log/2026-04-17T21:36:35Z-theme-fix-complete.md Records completion summary for theme persistence fixes.
.squad/agents/sam/history.md Documents Auth0 configuration guard rationale and changes.
.squad/agents/legolas/history.md Records Tailwind migration and CSS folder restructure learnings.
.squad/agents/legolas/charter.md Adds instruction to read the theme persistence skill for relevant tasks.
.squad/agents/aragorn/history.md Adds Tailwind migration skill review notes.
.idea/.idea.MyBlog/.idea/vcs.xml Adds Rider/IDEA project configuration (should not be tracked).
.idea/.idea.MyBlog/.idea/misc.xml Adds Rider/IDEA project configuration (should not be tracked).
.idea/.idea.MyBlog/.idea/indexLayout.xml Adds Rider/IDEA project configuration (should not be tracked).
.idea/.idea.MyBlog/.idea/encodings.xml Adds Rider/IDEA project configuration (should not be tracked).
.idea/.idea.MyBlog/.idea/dataSources.xml Adds Rider/IDEA datasource config (contains credentials — must not be tracked).
.idea/.idea.MyBlog/.idea/.gitignore Adds Rider/IDEA-local ignore file (directory should be ignored at repo root instead).
.gitignore Ignores node_modules and Tailwind output (and currently does not ignore .idea/).
Files not reviewed (6)
  • .idea/.idea.MyBlog/.idea/.gitignore: Language not supported
  • .idea/.idea.MyBlog/.idea/dataSources.xml: Language not supported
  • .idea/.idea.MyBlog/.idea/encodings.xml: Language not supported
  • .idea/.idea.MyBlog/.idea/indexLayout.xml: Language not supported
  • .idea/.idea.MyBlog/.idea/misc.xml: Language not supported
  • .idea/.idea.MyBlog/.idea/vcs.xml: Language not supported

Comment thread src/Web/Program.cs
Comment on lines +46 to +50
var existingOnTokenValidated = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async context =>
{
await existingOnTokenValidated(context);

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

existingOnTokenValidated may be null (the default for OpenIdConnectEvents.OnTokenValidated). Calling await existingOnTokenValidated(context) will throw a NullReferenceException during sign-in. Guard for null (or default to Task.CompletedTask) before awaiting, then run AddRoleClaims.

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +23
<data-source source="LOCAL" name="mongodb" uuid="1a564bcc-fc25-4ef0-a675-3bccecb8960c">
<driver-ref>mongo.4</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.dbschema.MongoJdbcDriver</jdbc-driver>
<jdbc-url>mongodb://admin:jmr1sZxmTA3JAZ0J2QpJs4@localhost:32795/?authSource=admin&amp;authMechanism=SCRAM-SHA-256</jdbc-url>
<jdbc-additional-properties>
<property name="aspireResourceId" value="mongodb-rkpqnkpt" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="redis" uuid="075bb980-ed17-416f-aade-b9c8a4868f26">
<driver-ref>redis</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>jdbc.RedisDriver</jdbc-driver>
<jdbc-url>jdbc:redis://3GtSRC0bKuYcbGKadc81Bp@localhost:32796?ssl=true</jdbc-url>
<jdbc-additional-properties>
<property name="aspireResourceId" value="redis-hwmycsny" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file contains hard-coded credentials/connection strings (e.g., MongoDB user+password in jdbc-url). These should not be committed. Remove this file from the repo history and rotate the exposed credentials; also add .idea/ (or at least .idea/**/dataSources*.xml) to .gitignore.

Suggested change
<data-source source="LOCAL" name="mongodb" uuid="1a564bcc-fc25-4ef0-a675-3bccecb8960c">
<driver-ref>mongo.4</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.dbschema.MongoJdbcDriver</jdbc-driver>
<jdbc-url>mongodb://admin:jmr1sZxmTA3JAZ0J2QpJs4@localhost:32795/?authSource=admin&amp;authMechanism=SCRAM-SHA-256</jdbc-url>
<jdbc-additional-properties>
<property name="aspireResourceId" value="mongodb-rkpqnkpt" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="redis" uuid="075bb980-ed17-416f-aade-b9c8a4868f26">
<driver-ref>redis</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>jdbc.RedisDriver</jdbc-driver>
<jdbc-url>jdbc:redis://3GtSRC0bKuYcbGKadc81Bp@localhost:32796?ssl=true</jdbc-url>
<jdbc-additional-properties>
<property name="aspireResourceId" value="redis-hwmycsny" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>

Copilot uses AI. Check for mistakes.
Comment thread package.json
Comment on lines +1 to +5
{
"name": "myblog",
"private": true,
"scripts": {
"tw:build": "npx @tailwindcss/cli -i ./src/Web/wwwroot/css/app.css -o ./src/Web/wwwroot/css/tailwind.css --minify",

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR metadata says this change is about moving Tailwind output/removing wwwroot/lib, but this PR also introduces Auth0 role-claim normalization, new Profile page + theme persistence JS, and substantial new unit/bUnit tests + coverage settings. Please update the PR title/description to match the scope, or split into separate PRs to keep reviews focused.

Copilot uses AI. Check for mistakes.
Comment thread src/Web/Web.csproj
Comment on lines +26 to +29
<!-- Build Tailwind CSS (skip on CI environments where npm is not installed) -->
<Target Name="BuildTailwind" BeforeTargets="Build" Condition="'$(CI)' != 'true'">
<Exec Command="npm run tw:build" WorkingDirectory="$(MSBuildProjectDirectory)/../.." />
</Target>

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Tailwind build target runs on every local build of the Web project. Since tests/Unit.Tests references src/Web/Web.csproj, dotnet test will also trigger npm run tw:build locally, which can fail or slow tests on machines without Node/npm. Consider gating this behind an explicit MSBuild property (opt-in), checking for npm availability, or limiting it to publish/dev builds rather than all builds.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +19
<div class="grid gap-6 lg:grid-cols-[minmax(0,1fr)_minmax(0,1.35fr)]">
<section class="card p-6">
<div class="flex flex-col items-center gap-4 text-center sm:flex-row sm:items-start sm:text-left">

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Profile.razor uses the CSS class card, but there is no .card definition in the Tailwind input (wwwroot/css/app.css) or generated output (tailwind.css). With Bootstrap removed, these sections won’t get the intended styling. Replace card with explicit Tailwind utility classes (e.g., rounded + shadow + bg-surface + border).

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +78
<section class="card overflow-hidden">
<div class="border-b border-primary-200 px-6 py-4 dark:border-primary-800">

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This second card usage has the same issue: card isn’t defined anywhere in the Tailwind CSS pipeline, so this section will render unstyled. Please replace with Tailwind utility classes or add a .card component style in wwwroot/css/app.css.

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +23
<data-source source="LOCAL" name="mongodb" uuid="1a564bcc-fc25-4ef0-a675-3bccecb8960c">
<driver-ref>mongo.4</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.dbschema.MongoJdbcDriver</jdbc-driver>
<jdbc-url>mongodb://admin:jmr1sZxmTA3JAZ0J2QpJs4@localhost:32795/?authSource=admin&amp;authMechanism=SCRAM-SHA-256</jdbc-url>
<jdbc-additional-properties>
<property name="aspireResourceId" value="mongodb-rkpqnkpt" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="redis" uuid="075bb980-ed17-416f-aade-b9c8a4868f26">
<driver-ref>redis</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>jdbc.RedisDriver</jdbc-driver>
<jdbc-url>jdbc:redis://3GtSRC0bKuYcbGKadc81Bp@localhost:32796?ssl=true</jdbc-url>
<jdbc-additional-properties>
<property name="aspireResourceId" value="redis-hwmycsny" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file also includes a Redis connection string with what appears to be an access token/password in jdbc-url. Please remove it from the repo history and rotate the credential; IDE datasource files should not be tracked.

Suggested change
<data-source source="LOCAL" name="mongodb" uuid="1a564bcc-fc25-4ef0-a675-3bccecb8960c">
<driver-ref>mongo.4</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.dbschema.MongoJdbcDriver</jdbc-driver>
<jdbc-url>mongodb://admin:jmr1sZxmTA3JAZ0J2QpJs4@localhost:32795/?authSource=admin&amp;authMechanism=SCRAM-SHA-256</jdbc-url>
<jdbc-additional-properties>
<property name="aspireResourceId" value="mongodb-rkpqnkpt" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="redis" uuid="075bb980-ed17-416f-aade-b9c8a4868f26">
<driver-ref>redis</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>jdbc.RedisDriver</jdbc-driver>
<jdbc-url>jdbc:redis://3GtSRC0bKuYcbGKadc81Bp@localhost:32796?ssl=true</jdbc-url>
<jdbc-additional-properties>
<property name="aspireResourceId" value="redis-hwmycsny" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>

Copilot uses AI. Check for mistakes.
})();
</script>
<ResourcePreloader />
<link rel="stylesheet" href="css/tailwind.css" />

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tailwind.css is referenced via a plain URL (href="css/tailwind.css") while other static assets in this file use @Assets[...] (fingerprinting/cache busting). For consistency and correct long-term caching, consider switching to @Assets["css/tailwind.css"].

Suggested change
<link rel="stylesheet" href="css/tailwind.css" />
<link rel="stylesheet" href="@Assets["css/tailwind.css"]" />

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +20
<PackageReference Include="bunit" Version="2.7.2" />
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="coverlet.msbuild" Version="10.0.0">

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This project references both coverlet.collector and coverlet.msbuild and also sets CollectCoverage=true. That’s usually redundant and can result in confusing/double coverage runs depending on how dotnet test is invoked. The other test projects in this repo appear to use only coverlet.collector, so consider standardizing on a single approach here too.

Copilot uses AI. Check for mistakes.
<script src="@Assets["_framework/blazor.web.js"]"></script>
<Routes />
<ReconnectModal />
<script src="js/theme.js"></script>

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

theme.js is referenced via a plain URL (src="js/theme.js") while other static assets in this file use @Assets[...]. Consider using @Assets["js/theme.js"] so it participates in fingerprinting/cache busting the same way as MyBlog.Web.styles.css and blazor.web.js.

Suggested change
<script src="js/theme.js"></script>
<script src="@Assets["js/theme.js"]"></script>

Copilot uses AI. Check for mistakes.
mpaulosky added a commit that referenced this pull request Apr 19, 2026
Add explicit hard gate to routing.md, sprint-planning.md, and pr-merge-process.md
so no agent can start coding without a GitHub issue linked to a milestone.

Changes:
- routing.md: guardrail #1 (absolute pre-code issue check) and guardrail #8 (direct
  user request gate): any coding request triggers an issue existence check first
- sprint-planning.md: new 'Hard Gate — No Code Before Issue' section with
  enforcement sequence; two new anti-pattern entries covering no-issue code and
  plan-without-ceremony patterns
- pr-merge-process.md: Ralph's Pre-Review Gate table now includes 'GitHub issue
  exists' check (Closes #N required); new anti-pattern for PRs missing issue link

Closes #50

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mpaulosky added a commit that referenced this pull request Apr 19, 2026
## Summary

Closes #50

Adds an explicit **"no code before issue"** hard gate to prevent future
process violations where implementation starts before a GitHub issue is
created.

## Changes

### `routing.md`
- **Guardrail #1** (new): Absolute pre-code issue check — any work must
have an existing GitHub issue before any file is touched
- **Guardrail #8** (new): Direct user coding requests trigger the same
issue-first check

### `sprint-planning.md`
- **New section: Hard Gate — No Code Before Issue** — enforcement
sequence with explicit YES/NO decision tree
- **Anti-patterns**: Added `❌ Writing any code before a GitHub issue
exists` and `❌ Implementing a [[PLAN]] request without running the
sprint planning ceremony`

### `pr-merge-process.md`
- **Ralph's Pre-Review Gate**: Added `GitHub issue exists` row — PR body
must contain `Closes #N`; if missing, Ralph creates the issue before
review proceeds
- **Anti-patterns**: Added `❌ Opening a PR without a Closes #N link`

## Testing

This is a documentation/process change. No code was modified; no
build/test verification needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mpaulosky added a commit that referenced this pull request Apr 19, 2026
- sprint-planning.md: rename Hard Gate to 'No Code Before Issue / No
  Issue Without Sprint'; add explicit sprint-stamp check (title prefix +
  milestone + board); add two new anti-patterns for missing prefix and
  milestone; strengthen Step 3 with must-have callout
- routing.md: update Guardrails #1 and #8 to require [Sprint N] title
  prefix and milestone in addition to issue existence
- issue-lifecycle.md: add Mandatory Issue Format section with canonical
  create command and three-requirement table

No issue may be created, branched, or PR'd without [Sprint N] title and
milestone set to Sprint N: {Theme}.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mpaulosky added a commit that referenced this pull request Apr 19, 2026
- sprint-planning.md: strengthen Hard Gate to require [Sprint N] title prefix
  and milestone before any branch; add 2 new anti-patterns
- sprint-planning.md: Step 3 gains mandatory-format table
- routing.md: Guardrails #1 and #8 require milestone + sprint prefix on every issue
- issue-lifecycle.md: add mandatory issue format block to GitHub section

Closes #66

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mpaulosky added a commit that referenced this pull request Apr 19, 2026
- routing.md: Add Guardrails #9 (Gimli parallel), #10 (no-verify prohibition),
  #11 (rubber duck for new patterns); strengthen Rule #6 to name Gimli+Frodo+Pippin
- ceremonies.md: Add Feature Work Kickoff ceremony; harden Retrospective with
  coverage-gate trigger and closure requirement
- pre-push-process.md: Add hard block on git push --no-verify at top of file
  with SDK mismatch fix instructions
- pr-merge-process.md: Step 3 now explicitly checks coverage gate (not just
  tests passing); adds 'Tests authored' gate for Gimli coverage
- gimli/charter.md: Fix Critical Rule #1 paths from IssueTracker to MyBlog
  (tests/Unit.Tests, tests/Architecture.Tests); add coverage gate (89%);
  add Rule #9 enforcing parallel spawn

Closes #68 (retrospective action items)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mpaulosky added a commit that referenced this pull request Apr 19, 2026
Closes #66

Working as Ralph (Meta / squad maintenance)

## Summary

Strengthens three squad process documents so that no issue can exist
without a sprint assignment and every issue title carries the `[Sprint
N]` prefix.

## Changes

- **`sprint-planning.md`** — Hard Gate updated to require `[Sprint N]`
title prefix + milestone before any branch; Step 3 gains a
mandatory-format table; two new anti-patterns added
- **`routing.md`** — Guardrails #1 and #8 updated to require both
milestone and sprint prefix on every issue before code starts
- **`issue-lifecycle.md`** — Mandatory issue format block added to
GitHub section (title pattern + milestone field rules)

## Testing

Squad process documents — no build or test suite applies.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

squad Squad triage inbox — Lead will assign to a member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants