Skip to content

Part 9: add an AI-free eShopLite-start so the lab has a starting state - #584

Merged
jongalloway merged 2 commits into
mainfrom
fix/part09-starting-state
Jul 27, 2026
Merged

Part 9: add an AI-free eShopLite-start so the lab has a starting state#584
jongalloway merged 2 commits into
mainfrom
fix/part09-starting-state

Conversation

@jongalloway

Copy link
Copy Markdown
Contributor

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 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.

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 Products and Store both throw at startup when AzureOpenAI:Endpoint / AzureOpenAI:Key are 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:

  • deletes Products/Ai/, Store/Ai/, Discovery.razor, 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

  • Step 0 points at eShopLite-start/, with a short table explaining the two folders
  • Step 1.1 drops the two dotnet add package lines that are now no-ops, with a note on why those pins are already there
  • the vague references to "the snapshot" are now explicit about eShopLite/

Also registers the new solution in the CI build matrix and in the build table in copilot-instructions.md.

Verification

  • Both solutions build in Release with 0 warnings
  • The starting app runs with no user secrets set at all — something the finished app cannot do
  • Seeds 12 products; search/water returns 3 (Outdoor Rain Jacket, Insulated Water Bottle, Daypack); search/warm at night returns 0, which is the moment the lab is built on
  • /api/product/aisearch/... returns 404
  • markdownlint clean against the CI glob

Fixes #570

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 mirrors eShopLite/ with AI-related code/packages removed.
  • Updates the Part 9 README to explicitly direct attendees to eShopLite-start/ and clarify eShopLite/ as the answer key.
  • Updates CI + repo build guidance to include building the new eShopLite-start solution.
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

Comment on lines +33 to 45
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 .
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

@jongalloway
jongalloway merged commit b4917b2 into main Jul 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P1] Part 9 has no "before" version of eShopLite — the only snapshot is the finished app

3 participants