feat: add extraction schema, sidebar nav, few-shot prompting, and prompt settings

Overhaul extraction pipeline with new TradeItem model, conversation flow,
and dedicated extraction endpoint. Add sidebar navigation with NavMenu
component and landing page. Introduce few-shot prompting service and
tests. Add prompt settings and email upload specs. Update OpenSpec
tooling with improved export-spec and extract-feature commands. Archive
completed changes and export full specs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
local
2026-04-06 23:39:23 +01:00
parent 7a5c22593a
commit 5b027eb0db
83 changed files with 4242 additions and 296 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-04-05

View File

@@ -0,0 +1,42 @@
## Context
The app currently uses a minimal MudLayout with just MudAppBar (Dense) + MudMainContent, and a single page at `/`. To support multiple pages, we need standard MudBlazor navigation: a collapsible MudDrawer with a NavMenu component.
## Goals / Non-Goals
**Goals:**
- Add collapsible MudDrawer with hamburger toggle in the AppBar
- Create a NavMenu component with a "Sales Assistant" link
- Move chat page to `/sales-assistant` route
- Maintain the Blazor tutorial style with inline comments
**Non-Goals:**
- Adding multiple pages beyond the existing chat (just the navigation structure)
- Changing the AppBar from Dense to regular
- Adding a default landing page (redirect `/``/sales-assistant` instead)
## Decisions
### MudDrawer configuration
- **Variant**: `DrawerVariant.Mini` — collapses to icon-width rather than fully hiding, so the user always sees the nav rail
- **Alternative considered**: `DrawerVariant.Responsive` — auto-hides on small screens. Rejected because Mini gives a more consistent desktop experience and the app is desktop-first.
- **ClipMode**: `DrawerClipMode.Always` — drawer sits below the AppBar, not beside it
### NavMenu as separate component
- Extract `NavMenu.razor` into `Layout/` alongside MainLayout rather than inlining nav links
- This is standard Blazor project structure and keeps MainLayout focused on shell layout
- The NavMenu will use `MudNavMenu` with `MudNavLink` items
### Route change: `/` → `/sales-assistant`
- The chat page moves to `/sales-assistant` to match navigation naming
- Add a redirect component at `/` that navigates to `/sales-assistant` on init
- This avoids a blank landing page while keeping the URL structure clean
### AppBar hamburger toggle
- Add `MudIconButton` with `Icons.Material.Filled.Menu` as the first element in the AppBar
- Toggle `_drawerOpen` bool that binds to `MudDrawer.Open`
## Risks / Trade-offs
- **Chat container height**: Currently uses `calc(100vh - 48px)` assuming Dense AppBar (48px). MudDrawer with ClipMode.Always doesn't affect vertical calc, so this should remain correct. Verify after implementation.
- **Breaking bookmarks**: Anyone bookmarking `/` will need to update to `/sales-assistant`. Mitigated by the redirect at `/`.

View File

@@ -0,0 +1,26 @@
## Why
The app currently has no navigation — just a single page at `/`. Adding a sidebar drawer with navigation enables the app to grow to multiple pages while providing standard MudBlazor layout structure (AppBar + Drawer + MainContent).
## What Changes
- Add a MudDrawer to MainLayout with a NavMenu component containing a "Sales Assistant" link
- Add a hamburger toggle button in the AppBar to open/close the drawer
- Move the existing chat page from `/` to `/sales-assistant`
- Add a landing page or redirect at `/` so the app has a default route
## Capabilities
### New Capabilities
- `sidebar-navigation`: Collapsible sidebar drawer with navigation menu, hamburger toggle, and route structure
### Modified Capabilities
- `chat-ui`: Route changes from `/` to `/sales-assistant`
## Impact
- **MainLayout.razor**: Add MudDrawer, hamburger icon, drawer toggle state
- **New NavMenu component**: Shared/NavMenu.razor with MudNavGroup/MudNavLink items
- **Chat.razor**: Route changes from `@page "/"` to `@page "/sales-assistant"`
- **Chat.razor.css**: Height calc may need adjustment if AppBar Dense changes
- No new packages — MudDrawer/MudNavMenu are part of MudBlazor

View File

@@ -0,0 +1,15 @@
## MODIFIED Requirements
### Requirement: Chat page is default route
The chat page SHALL be routed at `/sales-assistant`. The root URL (`/`) SHALL redirect to `/sales-assistant`.
#### Scenario: App opens to chat via redirect
- **WHEN** the user navigates to the root URL `/`
- **THEN** the browser redirects to `/sales-assistant` and the chat page is displayed
#### Scenario: Direct navigation to sales-assistant
- **WHEN** the user navigates to `/sales-assistant`
- **THEN** the chat page is displayed

View File

@@ -0,0 +1,38 @@
## ADDED Requirements
### Requirement: Collapsible sidebar drawer
The application SHALL have a MudDrawer in MainLayout that contains a navigation menu. The drawer SHALL be toggleable via a hamburger icon button in the AppBar.
#### Scenario: Drawer visible on load
- **WHEN** the application loads
- **THEN** the sidebar drawer is displayed in its default open state with navigation links visible
#### Scenario: Drawer toggles on hamburger click
- **WHEN** the user clicks the hamburger icon in the AppBar
- **THEN** the drawer toggles between open and collapsed states
### Requirement: Navigation menu with Sales Assistant link
The sidebar drawer SHALL contain a MudNavMenu with a "Sales Assistant" navigation link that routes to `/sales-assistant`.
#### Scenario: Sales Assistant link present
- **WHEN** the drawer is open
- **THEN** a "Sales Assistant" link with a SmartToy icon is visible in the navigation menu
#### Scenario: Clicking Sales Assistant navigates to chat
- **WHEN** the user clicks the "Sales Assistant" link
- **THEN** the browser navigates to `/sales-assistant` and the chat page renders in MudMainContent
### Requirement: NavMenu is a separate component
The navigation menu SHALL be implemented as a separate `NavMenu.razor` component in the Layout folder, referenced from MainLayout.
#### Scenario: NavMenu renders inside drawer
- **WHEN** MainLayout renders
- **THEN** the NavMenu component renders inside the MudDrawer with its navigation links

View File

@@ -0,0 +1,29 @@
## 1. MainLayout: Add Drawer and Hamburger Toggle
- [x] 1.1 Add a `_drawerOpen` bool field (default `true`) and a `ToggleDrawer` method to MainLayout.razor
- [x] 1.2 Add a `MudIconButton` with `Icons.Material.Filled.Menu` as the first element in the MudAppBar, wired to `ToggleDrawer`
- [x] 1.3 Add a `MudDrawer` with `Open="@_drawerOpen"`, `ClipMode="DrawerClipMode.Always"`, `Elevation="2"` inside the MudLayout, before MudMainContent
- [x] 1.4 Reference `<NavMenu />` inside the MudDrawer
## 2. NavMenu Component
- [x] 2.1 Create `Layout/NavMenu.razor` with a `MudNavMenu` containing a single `MudNavLink` — text "Sales Assistant", icon `Icons.Material.Filled.SmartToy`, href `/sales-assistant`
- [x] 2.2 Add inline tutorial comments explaining MudNavMenu, MudNavLink, and how href-based navigation works in Blazor
## 3. Chat Page Route Change
- [x] 3.1 Change `Chat.razor` route from `@page "/"` to `@page "/sales-assistant"`
- [x] 3.2 Update the page title from "Chat Agent" to "Sales Assistant"
## 4. Root Redirect
- [x] 4.1 Create a `Pages/Index.razor` component at `@page "/"` that redirects to `/sales-assistant` on initialization using `NavigationManager.NavigateTo` (Home.razor already exists as health check page at /health)
## 5. Chat Container Height Adjustment
- [x] 5.1 Verify `Chat.razor.css` height calc still works with the drawer layout — Dense AppBar is 48px, drawer does not affect vertical space. Adjust if needed.
## 6. Verification
- [x] 6.1 Build the client project (`dotnet build`) and confirm no compilation errors
- [x] 6.2 Run existing tests (`dotnet test`) and confirm they pass