您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

11KB

CLAUDE.md — CartWise v1 Development Guide

Read First

This repository builds CartWise, a mobile-first grocery companion implemented as a conventional ASP.NET Core MVC application.

The canonical architecture and scope are defined in AGENTS.md. Read AGENTS.md completely before making architectural changes. This file gives Claude-specific operating guidance and a compact execution map.


Core Stack

Use:

  • ASP.NET Core MVC
  • C#
  • Razor Views
  • HTML5
  • CSS3
  • jQuery
  • vanilla JavaScript
  • EF Core
  • PostgreSQL
  • ASP.NET Core Identity

Do not introduce React, Vue, Angular, Blazor, MAUI, Flutter, SPA architecture, microservices, MediatR, or unnecessary repository/unit-of-work wrappers unless explicitly requested.


Product Goal

CartWise v1 must help a household:

  1. Maintain a shared grocery list.
  2. Add generic concepts such as “milk” without requiring exact product selection.
  3. Resolve exact packaged products when useful.
  4. Scan UPC/GTIN barcodes.
  5. Record purchases and prices.
  6. Build personal price history.
  7. Show typical/low/latest/unit price intelligence.
  8. Suggest repeat items that are likely running low.
  9. Shop from a simple phone-friendly shopping mode.

CartWise must still be useful with zero retailer API access.


Architectural Boundaries

Web

CartWise.Web

  • Controllers
  • Razor Views
  • ViewModels
  • HTML/CSS/JS
  • ASP.NET-specific concerns

Application

CartWise.Application

  • use cases
  • services
  • interfaces
  • validation
  • DTOs/results

Domain

CartWise.Domain

  • entities
  • enums
  • value objects
  • business rules

No EF Core, HTTP, Razor, or provider SDK dependencies here.

Infrastructure

CartWise.Infrastructure

  • DbContext
  • EF configurations/migrations
  • PostgreSQL
  • Open Food Facts/USDA integrations
  • future retailer adapters

Dependency direction should remain clean.


Critical Domain Distinction

Never collapse these concepts:

GroceryConcept: Peanut Butter

Product: Jif Creamy Peanut Butter 16 oz

ProductIdentifier: UPC/GTIN identifying that package

A shopping list item may exist with only free text / concept data. Product resolution must not be mandatory to make a useful list.

UPC/GTIN is never the Product primary key.


Core Entities

Implement in the order given in AGENTS.md.

Identity / Household

  • ApplicationUser
  • Household
  • HouseholdMember

Product Catalog

  • GroceryConcept
  • ProductCategory
  • Brand
  • Product
  • ProductIdentifier
  • HouseholdProductPreference

Shopping

  • ShoppingList
  • ShoppingListItem

Retail / Location

  • Retailer
  • StoreLocation

History

  • Purchase
  • PurchaseItem
  • PriceObservation

See AGENTS.md for exact fields, indexes, enums, and relationships.


Required Services

Keep controllers thin and use:

  • IHouseholdService
  • IShoppingListService
  • IProductService
  • IProductEnrichmentService
  • IPriceService
  • IPurchaseService
  • IReplenishmentService
  • IShoppingModeService
  • IStoreService

Do not create one giant CartWiseService.

Do not add abstractions without a real responsibility or testability benefit.


Product Provider Rule

External provider models stay inside Infrastructure.

Use a normalized contract similar to:

public interface IProductDataProvider
{
    string Name { get; }

    Task<ProductLookupResult?> FindByBarcodeAsync(
        string barcode,
        CancellationToken cancellationToken = default);

    Task<IReadOnlyList<ProductSearchResult>> SearchAsync(
        string query,
        CancellationToken cancellationToken = default);
}

Lookup is always local first, provider second, then normalize and cache.

Open Food Facts should be the first packaged-product provider. USDA can enrich generic/nutrition data later.

Never expose an external provider's API response object to a controller or Razor view.


Retailer API Rule

Retailer integrations are optional.

Do not build application logic around specific retailer names. Use capability-aware adapters.

Never assume that price, inventory, promotions, or aisle data are available.

When data is stale or unavailable, show that state explicitly instead of guessing.


MVC Routes

Preserve these route intentions unless existing code requires a compatible adjustment.

GET  /                         Home
GET  /household               Household
GET  /list                    Active grocery list
POST /list/items              Add list item
POST /list/items/{id}/toggle  Toggle purchased
POST /list/items/{id}/skip
POST /list/items/{id}/delete

GET  /products/{id}
GET  /products/search?q=
GET  /products/barcode/{barcode}

GET  /scan

GET  /shopping/start
POST /shopping/items/{id}/purchase
POST /shopping/items/{id}/skip
POST /shopping/items/{id}/unavailable
POST /shopping/items/{id}/substitute
POST /shopping/complete

GET  /prices
GET  /prices/product/{productId}
POST /prices/product/{productId}/observe

GET  /purchases
GET  /purchases/{id}

Use /api/... only where browser JavaScript genuinely benefits from JSON.


Razor / JavaScript Rules

Razor is primary rendering. jQuery and vanilla JavaScript are both approved.

Prefer jQuery for:

  • DOM selection and manipulation
  • delegated event handlers
  • form serialization
  • AJAX requests
  • lightweight partial refreshes
  • shopping-mode UI interactions

Prefer vanilla JavaScript for:

  • barcode camera/scanner browser APIs
  • navigator.mediaDevices
  • IndexedDB and Service Workers
  • focused browser-native functionality where jQuery adds no value

Organize JavaScript under:

wwwroot/js/pages/
wwwroot/js/services/
wwwroot/js/components/
wwwroot/js/utils/

Do not create a global monolithic app.js. Do not reinvent client-side framework patterns by hand. Do not mix jQuery and native DOM approaches arbitrarily inside the same function. Use $.ajax/$.get/$.post where jQuery is the clearer choice and fetch where native code is more appropriate.

Use anti-forgery tokens for every state-changing JavaScript request.


Database Rules

  • PostgreSQL UUID domain keys.
  • Identity's normal user key can remain its native string unless deliberately changed project-wide.
  • UTC timestamps / timestamptz.
  • decimal/numeric for money and quantities.
  • no float/double for prices.
  • explicit EF entity configurations.
  • no lazy loading.
  • AsNoTracking() for read paths.
  • protect historical data from accidental cascade deletion.
  • PriceObservation is append-only.
  • add indexes described in AGENTS.md.

Every schema change requires an EF Core migration.


Price Intelligence

Do not call a stale observation a current price.

Every price observation includes:

  • Product
  • optional Store
  • Price/SalePrice
  • ObservedUtc
  • SourceType
  • ConfidenceScore

Display source/freshness where material.

For a household's typical price, favor median as the robust statistic; average may also be shown.

Only label a price “good” after enough history exists.

Unit price comparisons must use compatible units.


Replenishment Algorithm v1

No ML or LLM required.

Use purchase history:

  1. get recent purchase dates
  2. calculate intervals
  3. use median interval when enough data exists
  4. estimate next due date
  5. return a suggestion with confidence and reason

Never automatically add predicted groceries to the list. The user chooses.


Authorization

Household isolation is critical.

For every household-scoped resource:

  • derive or validate household context server-side
  • verify current user membership
  • do not trust posted HouseholdId alone
  • prevent IDOR

Use centralized household authorization/service logic.

All state-changing MVC requests require anti-forgery protection.


Working Style for Claude

Before modifying code:

  1. Read AGENTS.md.
  2. Inspect the relevant existing controller/service/entity/configuration/tests.
  3. Identify the smallest vertical change that satisfies the request.
  4. Preserve existing architecture unless it conflicts with the specification.

While implementing:

  1. Keep methods small and intention-revealing.
  2. Prefer conventional C#.
  3. Use async I/O.
  4. Pass CancellationToken through external/database-heavy application paths where appropriate.
  5. Add validation close to the boundary and invariants in the domain where appropriate.
  6. Avoid duplicate normalization or authorization logic.

After implementing:

  1. Build the solution.
  2. Run relevant tests.
  3. Run the full test suite when practical.
  4. Check migrations when data model changes.
  5. Report files changed and any intentionally deferred work.

Do not claim a feature works without running the relevant build/tests when the environment permits it.


Exact Build Order

Follow this progression:

0. Baseline

  • solution/projects
  • dependencies
  • PostgreSQL
  • Identity
  • test harness

1. Household

  • household entities
  • membership
  • authorization
  • create/select household

2. Grocery List

  • concepts/categories
  • list/list items
  • add/toggle/delete
  • mobile Razor view

3. Products and Scan

  • brand/product/identifiers
  • household product preferences
  • local product lookup
  • Open Food Facts provider
  • barcode scan page

4. Purchase and Price History

  • retailer/store
  • purchase/purchase item
  • price observations
  • price service and views

5. Shopping Mode

  • grouped mobile list
  • purchase/skip/unavailable
  • optional entered price
  • complete trip

6. Running Low

  • deterministic replenishment service
  • suggestions on Home/List

7. Polish

  • accessibility
  • mobile/responsive testing
  • performance
  • PWA/offline only when core workflows are stable

Do not jump to Phase 6 features while Phase 2 is incomplete unless the user explicitly requests it.


First End-to-End Slice

When asked to begin implementation, build this before broad scaffolding:

Register/Login
  -> Create Household
  -> Open /list
  -> Add “Milk”
  -> Persist item
  -> Toggle Purchased
  -> Reload
  -> Verify correct household-scoped state

This proves authentication, household authorization, EF persistence, MVC routing, Razor rendering, and form/JS behavior.


Out of Scope Unless Explicitly Added

Do not implement proactively:

  • meal planning
  • recipes
  • AI chat
  • nutrition optimization
  • receipt OCR
  • coupon clipping
  • retailer loyalty accounts
  • delivery/checkout
  • live universal inventory
  • store aisle maps
  • indoor navigation
  • multi-store routing
  • shrinkflation analysis
  • push notifications

Leave clean seams for future work; do not build speculative infrastructure.


Definition of a Good CartWise Change

A good change:

  • improves the shopper's grocery memory
  • keeps MVC server-rendered
  • works on a phone
  • does not require a retailer API unless specifically implementing one
  • preserves price source/freshness
  • maintains household isolation
  • adds tests for meaningful rules
  • avoids unnecessary framework or architecture expansion

North star:

CartWise remembers what the household needs, what it buys, and what it normally pays.

Powered by TurnKey Linux.