| name | create-card-and-page skill |
| description | Use this skill when asked to add a new entity type with a card grid page to FanHub. It scaffolds the full stack: backend model, DbContext registration, seed data, EF Core migration, REST controller (GET + POST), frontend model, homepage stat card + nav-card, and a Blazor list page with an inline add form.
|
New Card Skill — FanHub Full-Stack Entity Scaffold
Use this skill when the user asks to add a new type of data (e.g. Locations, Factions, Characters, Themes) to FanHub as a browsable card page, following the same pattern used to add the Lore feature.
What to ask the user before starting
If any of the following are not clear from context, ask before proceeding:
- Entity name — singular PascalCase (e.g.
Location, Faction, Theme)
- Properties — beyond
Id and ShowId, what fields does this entity have? (e.g. string Title, string Description, string Category)
- Form fields — which properties should appear in the add form on the page?
- Nav card label — plural display label for the homepage (e.g. "Locations", "Lore Facts")
- Nav card icon — emoji for the homepage nav-card (e.g. 📍, 📖, ⚗️)
- Seed source — which file to draw seed data from (default:
docs/breaking-bad-universe.md)
Implementation steps
Follow these steps in order. Complete and verify each before moving to the next.
Step 1 — Backend model
Create dotnet/Backend/Models/{EntityName}.cs using the template in templates/BackendModel.cs.
Replace the example properties with the ones requested. Rules:
- No navigation properties, no data annotations
- All string properties should be non-nullable (no
?) to match existing model style
Step 2 — Register DbSet
In dotnet/Backend/Data/FanHubContext.cs, add after the last existing DbSet:
public DbSet<{EntityName}> {EntityName}s { get; set; }
Do not modify OnModelCreating or anything else in this file.
Step 3 — Seed data
In dotnet/Backend/Data/SeedData.cs, add a new seed block immediately after the last existing seed block using the template in templates/SeedBlock.cs.
All records must use ShowId = 1. Draw content faithfully from the seed source file. Generate 12–15 records.
Step 3.5 — Pre-migration check
Before running the migration, verify all files are in place:
.github/skills/create-card-and-page skill/scripts/check-scaffold.ps1 -EntityName {EntityName}
Fix any missing items reported before continuing.
Step 4 — EF migration
Run the migration script:
.github/skills/create-card-and-page skill/scripts/run-migration.ps1 -EntityName {EntityName}
Or run manually in dotnet/Backend/:
dotnet ef migrations add Add{EntityName}
dotnet ef database update
Stop and report any errors — do not continue to later steps if migration fails.
Step 5 — Controller
Create dotnet/Backend/Controllers/{EntityName}Controller.cs using the template in templates/Controller.cs.
No authentication attribute. No services layer. No DTO.
Step 6 — Frontend model
Create dotnet/Frontend/Models/{EntityName}.cs using the template in templates/FrontendModel.cs.
Mirror the backend model exactly — same properties, same types, same order. No EF attributes, no navigation properties.
Step 7 — Update Home.razor (stat card)
Apply the snippets from templates/HomeStatCard.razor.txt to dotnet/Frontend/Components/Pages/Home.razor:
- The
@code field goes in the @code block
- The
OnInitializedAsync line goes inside that method
- The
<div class="summary-stat"> block goes after the last existing stat in <div class="summary-card">
Do not touch any other stat card.
Step 8 — Update Home.razor (nav card)
Apply the template from templates/HomeNavCard.razor.txt to the <section class="nav-cards"> in Home.razor, after the last existing <a class="nav-card"> block. Do not alter any other nav card.
Step 9 — Create list page with add form
Create dotnet/Frontend/Components/Pages/{EntityName}.razor using the template in templates/ListPage.razor.txt.
Adjust bound fields and card markup to match the actual properties requested. Do not use <EditForm>. Do not add authentication.
Conventions to follow
- Namespace pattern:
Backend.Controllers, Backend.Models, Frontend.Models
- Async pattern:
FindAsync, ToListAsync, SaveChangesAsync
- Frontend data fetch:
await Http.GetFromJsonAsync<T>("api/endpoint")
- No repository pattern — controllers inject
FanHubContext directly
- POST returns
Ok() (matches existing controller pattern)
- See
.github/copilot-instructions.md for full conventions reference
Verification checklist
After all steps are complete, run the endpoint verification script (requires the backend to be running):
.github/skills/create-card-and-page skill/scripts/verify-endpoints.ps1 -EntityName {EntityName}
Then confirm manually:
Scripts