Part 9: add an AI-free eShopLite-start so the lab has a starting state - #584
Conversation
Part 9 is the only code part with no starting snapshot. The README opens with
"Five projects, none of which reference an AI package yet" and builds its whole
narrative on searching "warm at night" and getting nothing back, but the
committed eShopLite/ is the finished app: the AI packages, Products/Ai/,
Store/Ai/, Discovery.razor, Operations.razor and the nav links are all already
there. An attendee following the instructions is asked to create files that
exist and add packages that are already referenced, and the "keyword search
fails" moment cannot be reproduced. Worse, the finished Products and Store both
throw at startup when AzureOpenAI:Endpoint and AzureOpenAI:Key are missing, so
the app will not even start until credentials are set - which the README does
not ask for until later.
Adds eShopLite-start/ as a full copy of the solution with the AI removed:
- deletes Products/Ai/, Store/Ai/, Discovery.razor and Operations.razor
- drops the AI package references from Products.csproj and Store.csproj
- removes the AI service registrations and usings from both Program.cs files,
including the semantic index build inside the seeding scope
- removes the /aisearch/{search} endpoint and ProductService.AiSearchProducts
- removes the Ask and Operations entries from NavMenu.razor
SQLitePCLRaw.bundle_e_sqlite3 3.0.4 stays in Products.csproj. It is not an AI
package - it pins the native SQLite bundle above the version EF Core pulls in
transitively, which still has an open advisory. Removing it reintroduces two
NU1903 warnings.
eShopLite/ is unchanged and is now documented as the answer key, which keeps a
runnable finished app for instructor demos and for attendees who want to see
where they are heading.
README changes: point Step 0 at eShopLite-start/, add a table explaining the two
folders, drop the two now-redundant dotnet add package lines from Step 1.1 with
a note on why those pins are already present, and replace the vague references
to "the snapshot" with eShopLite/.
Also registers the new solution in the CI build matrix and the build table in
copilot-instructions.md.
Verified: both solutions build in Release with 0 warnings; the starting app runs
with no user secrets set, seeds 12 products, returns 3 results for "water" and
0 for "warm at night", and 404s on /api/product/aisearch. markdownlint clean.
Fixes #570
There was a problem hiding this comment.
Pull request overview
Adds an AI-free starting state for Part 9 so attendees can follow the lab narrative as written (keyword search fails first, then AI features are added), while keeping the existing eShopLite/ snapshot as the finished answer key.
Changes:
- Adds a new
eShopLite-start/Aspire solution that mirrorseShopLite/with AI-related code/packages removed. - Updates the Part 9 README to explicitly direct attendees to
eShopLite-start/and clarifyeShopLite/as the answer key. - Updates CI + repo build guidance to include building the new
eShopLite-startsolution.
Show a summary per file
| File | Description |
|---|---|
| Part 09 - Adding AI to an Existing App/README.md | Points attendees at eShopLite-start/ and clarifies eShopLite/ as the answer key. |
| .github/workflows/dotnet-build.yml | Adds eShopLite-start/eShopLite.slnx to the CI build matrix. |
| .github/copilot-instructions.md | Updates Part 9 snapshot description and build matrix documentation to include eShopLite-start/. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/eShopLite.slnx | New “starting state” solution definition. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/DataEntities/DataEntities.csproj | Shared model project for the starting solution. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/DataEntities/Product.cs | Shared Product entity for API + store. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/eShopLite.AppHost/eShopLite.AppHost.csproj | Aspire AppHost project for starting solution. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/eShopLite.AppHost/AppHost.cs | AppHost wiring for products and store (AI-free). |
| Part 09 - Adding AI to an Existing App/eShopLite-start/eShopLite.AppHost/aspire.config.json | Aspire config for the AppHost project path. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/eShopLite.AppHost/appsettings.json | AppHost logging settings. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/eShopLite.AppHost/appsettings.Development.json | Dev logging settings for AppHost. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/eShopLite.AppHost/Properties/launchSettings.json | Launch profiles for AppHost. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/eShopLite.ServiceDefaults/eShopLite.ServiceDefaults.csproj | Aspire service defaults shared project. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/eShopLite.ServiceDefaults/Extensions.cs | Adds service discovery, resilience, health checks, and OpenTelemetry defaults. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Products/Products.csproj | Starting Products API project (AI-free package set + security pin comment). |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Products/Program.cs | Products API startup, EF Core Sqlite, OpenAPI, and seeding. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Products/Products.http | HTTP scratch file demonstrating keyword search behavior. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Products/appsettings.json | Products API logging + AllowedHosts. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Products/appsettings.Development.json | Products API dev logging. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Products/Properties/launchSettings.json | Launch profiles for Products API. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Products/Data/ProductDataContext.cs | EF Core DbContext for product catalog. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Products/Data/SeedData.cs | Seeds the 12 starter products for the lab narrative. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Products/Endpoints/ProductEndpoints.cs | Keyword search + product endpoints (AI-free baseline). |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Store.csproj | Starting Store (Blazor) project file. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Program.cs | Store startup + service defaults + HttpClient wiring (AI-free). |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/appsettings.json | Store logging + AllowedHosts. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/appsettings.Development.json | Store dev logging. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Properties/launchSettings.json | Launch profiles for Store. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Services/ProductService.cs | Store-side service for calling Products API endpoints. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/_Imports.razor | Common Razor imports for Store components. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/App.razor | Root HTML + static assets wiring for Store. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Routes.razor | Router configuration + NotFound page mapping. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Pages/Home.razor | Home page for starting Store UI. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Pages/Products.razor | Keyword-search UI for the starting lab scenario. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Pages/Error.razor | Error page for Store. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Pages/NotFound.razor | NotFound page for Store. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Layout/MainLayout.razor | Main layout shell for Store. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Layout/MainLayout.razor.css | Layout styling for Store. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Layout/NavMenu.razor | Navigation menu (AI-free entries). |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Layout/NavMenu.razor.css | Nav styling for Store. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Layout/ReconnectModal.razor | Reconnect modal UI. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Layout/ReconnectModal.razor.css | Reconnect modal styling. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/Components/Layout/ReconnectModal.razor.js | Reconnect modal behavior script. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/app.css | Store static CSS baseline. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/favicon.png | Store favicon. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap.css | Bootstrap CSS asset (template static file). |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map | Bootstrap CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css | Bootstrap minified CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map | Bootstrap minified CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css | Bootstrap RTL CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map | Bootstrap RTL CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css | Bootstrap RTL minified CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map | Bootstrap RTL minified CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css | Bootstrap grid CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map | Bootstrap grid CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css | Bootstrap grid minified CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map | Bootstrap grid minified CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css | Bootstrap grid RTL CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map | Bootstrap grid RTL CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css | Bootstrap grid RTL minified CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map | Bootstrap grid RTL minified CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css | Bootstrap reboot CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map | Bootstrap reboot CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css | Bootstrap reboot minified CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map | Bootstrap reboot minified CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css | Bootstrap reboot RTL CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map | Bootstrap reboot RTL CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css | Bootstrap reboot RTL minified CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map | Bootstrap reboot RTL minified CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css | Bootstrap utilities CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map | Bootstrap utilities CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css | Bootstrap utilities minified CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map | Bootstrap utilities minified CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css | Bootstrap utilities RTL CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map | Bootstrap utilities RTL CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css | Bootstrap utilities RTL minified CSS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map | Bootstrap utilities RTL minified CSS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.js | Bootstrap JS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map | Bootstrap JS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js | Bootstrap minified JS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map | Bootstrap minified JS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js | Bootstrap bundle JS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map | Bootstrap bundle JS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js | Bootstrap minified bundle JS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map | Bootstrap minified bundle JS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js | Bootstrap ESM JS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map | Bootstrap ESM JS sourcemap. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js | Bootstrap minified ESM JS asset. |
| Part 09 - Adding AI to an Existing App/eShopLite-start/Store/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map | Bootstrap minified ESM JS sourcemap. |
Review details
- Files reviewed: 44/89 changed files
- Comments generated: 1
- Review effort level: Low
| This part ships two copies of the same solution: | ||
|
|
||
| | Folder | What it is | | ||
| | --- | --- | | ||
| | `eShopLite-start/` | The store **before** any AI. This is the one you work in. | | ||
| | `eShopLite/` | The finished app with all three steps already done — the answer key. Look here if you get stuck, or run it if you want to see where you are heading. | | ||
|
|
||
| Open the starting solution: | ||
|
|
||
| ```bash | ||
| cd "Part 09 - Adding AI to an Existing App/eShopLite" | ||
| cd "Part 09 - Adding AI to an Existing App/eShopLite-start" | ||
| code . | ||
| ``` |
There was a problem hiding this comment.
Moved the "Configure credentials" section to step 1.4 — immediately before the service registrations that first read AzureOpenAI:Endpoint and AzureOpenAI:Key. The starting-app run now has no credentials requirement, and the credential setup lands at the exact moment it becomes necessary. Also renumbered the subsequent sub-steps (old 1.4→1.5, old 1.5→1.6, old 1.6→1.7). Addressed in commit Part 9 README: move Configure credentials to step 1.4.
… services are registered
Part 9 is the only code part with no starting state, so the lab as written cannot be followed.
The README opens with "Five projects, none of which reference an AI package yet" and the whole narrative hangs on searching
warm at nightand getting nothing back. But the committedeShopLite/is the finished app — the AI packages,Products/Ai/,Store/Ai/,Discovery.razor,Operations.razorand the nav links are all already there.So an attendee is asked to create files that already exist and add packages that are already referenced, and the "keyword search fails" moment cannot be reproduced. Worse: the finished
ProductsandStoreboth throw at startup whenAzureOpenAI:Endpoint/AzureOpenAI:Keyare missing, so the app will not start at all until credentials are set — which the README does not ask for until later.This takes Option A from the issue.
What changed
eShopLite-start/is a full copy of the solution with the AI removed:Products/Ai/,Store/Ai/,Discovery.razor,Operations.razorProducts.csprojandStore.csprojProgram.csfiles, including the semantic index build inside the seeding scope/aisearch/{search}endpoint andProductService.AiSearchProductsNavMenu.razorSQLitePCLRaw.bundle_e_sqlite33.0.4 stays inProducts.csproj. It is not an AI package — it pins the native SQLite bundle above the version EF Core pulls in transitively, which still has an open advisory. Removing it reintroduces twoNU1903warnings.eShopLite/is unchanged and is now documented as the answer key, which keeps a runnable finished app for instructor demos and for attendees who want to see where they are heading.README
eShopLite-start/, with a short table explaining the two foldersdotnet add packagelines that are now no-ops, with a note on why those pins are already thereeShopLite/Also registers the new solution in the CI build matrix and in the build table in
copilot-instructions.md.Verification
search/waterreturns 3 (Outdoor Rain Jacket, Insulated Water Bottle, Daypack);search/warm at nightreturns 0, which is the moment the lab is built on/api/product/aisearch/...returns 404Fixes #570