7.1 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this is
SteUP is an Integry .NET MAUI Blazor Hybrid app for field inspections ("ispezioni") of retail stores — the operator scans product barcodes (including via Honeywell handheld scanners), fills in inspection sheets ("schede"), attaches photos, and syncs with the Integry backend. Work is stored locally (offline-first via SQLite) and pushed to the server. The same Blazor UI also runs as a standalone WebAssembly app.
Note:
README.mdis the leftover Microsoft sample template and does NOT describe this app. Ignore it.
Design Context
For any UI/design work, read PRODUCT.md (strategy) and DESIGN.md (visual system) at the repo root first; they are the source of truth for the impeccable design skill.
- Register: product (a field tool; the UI serves the task, it is not a marketing surface).
- Users: field inspectors ("rilevatori") in stores — one-handed / gloved, outdoors in sunlight, often offline.
- North Star: "Il taccuino da campo" — works like paper and ink: always, offline, readable in full sun.
- Core principles: offline state is never ambiguous · thumb-first (touch ≥44px) · high contrast for sunlight · immediate feedback per scan · fewer steps, fewer errors.
- Visual system: MudBlazor · single font Nunito · accent
#ec4c41(Arancio-Rosso Allerta, action/state only), anchor#002339(Blu Profondo) · rounded (9px/20px/1em) · localeit-IT. - Anti-references: no dated/dense back-office look; no playful consumer-social aesthetic.
Build & run
global.json pins SDK 8.0.0 with rollForward: latestMajor, but all projects target .NET 10 (MAUI targets net10.0-android / net10.0-ios). A .NET 10 SDK must be installed.
NuGet restores from a private Integry feed only (NuGet.Config clears nuget.org and uses nuget.studioml.it). The IntegryApiClient.* packages come from there.
# MAUI app (primary target) — Android
dotnet build SteUp.Maui/SteUp.Maui.csproj -t:Run -f net10.0-android
# MAUI app — iOS (requires Mac build host; codesigning wired in csproj)
dotnet build SteUp.Maui/SteUp.Maui.csproj -f net10.0-ios
# Web (Blazor WASM) app
dotnet run --project SteUp.Web/SteUp.Web.csproj
There is no test project in the solution. There is no lint config beyond Nullable/ImplicitUsings enabled per csproj.
Projects (5)
- SteUp.Shared — Razor Class Library holding almost everything: all Blazor pages/components, DTOs, entities, enums, the auth state provider, API service wrappers, messaging, and business orchestration (
SteupDataService). Both MAUI and Web reference it. Uses MudBlazor + MudExtensions for UI. - SteUp.Maui — the native host. Owns platform services (DI registration in
Core/CoreModule.cs), theBlazorWebViewhost (MainPage.xaml.cs), file/logging/network/scanner implementations, and app config. - SteUp.Web — Blazor WebAssembly host of the same shared UI. Its
Program.csmirrors a subset of the MAUI DI setup. - SteUp.Data — EF Core + SQLite local database (
AppDbContext, migrations,IspezioniService). References Shared for the entity types. - Steup.HoneywellScanner — Android-only binding library wrapping Honeywell
DataCollection.aar. Referenced by MAUI only on the Android target.
Architecture
Interface / implementation split (important convention)
Interfaces live in SteUp.Shared (Core/Interface/...) so the shared UI depends only on abstractions. Concrete platform implementations live in SteUp.Maui (Core/Services, Core/System) and are registered per-host:
- MAUI wires everything in
SteUp.Maui/Core/CoreModule.csviaRegister*extension methods called fromMauiProgram.cs. - Web wires a smaller subset directly in
SteUp.Web/Program.cs(onlyIFormFactor+ auth; it has no local DB, scanner, or file manager).
When adding a service consumed by the shared UI: define the interface in SteUp.Shared/Core/Interface, implement it in the host, and register it in both CoreModule.cs and (if the Web app needs it) Program.cs.
Auth
AppAuthenticationStateProvider (Shared) bridges Integry's IUserSession/IUserAccountService (from IntegryApiClient) to Blazor's AuthenticationStateProvider, building ClaimsPrincipal from the JWT. Both hosts call builder.UseIntegry(appToken, useLoginAzienda: true) — the AppToken is the same GUID in MauiProgram.cs and SteUp.Web/Program.cs.
Backend calls
Two service wrappers over IIntegryApiRestClient:
IntegrySteupService— the app-specificsteup/*endpoints (retrieve punti vendita, reparti, griglia PLU, barcode lookup, save/complete/delete schede, upload attachments).IntegryApiService— generic Integry endpoints (system health, activity descriptions, email).
Offline-first data flow
SteupDataService (Shared) is the orchestrator: on Init() it runs EF migrations (DbInitializer.InitializeAsync → db.Database.MigrateAsync()), loads reference data from the API, reconciles inspection status, and prunes closed inspections older than 60 days. Local reads/writes go through IspezioniService (SteUp.Data).
Local DB model
AppDbContext: Ispezione → Scheda → SchedaArticolo. Ispezione has a composite key (CodMdep, Data, Rilevatore) which is also the FK from Scheda. Scheda.ImageNames is a List<string> persisted as JSON via a value converter. DB file: steup_db.db3 in FileSystem.AppDataDirectory (see DbPathProvider).
Add a migration (from repo root; AppDbContextFactory provides the design-time context using a throwaway design-time.db3):
dotnet ef migrations add <Name> --project SteUp.Data
Migrations are applied automatically at app startup, not via database update.
Messaging (in-app events)
Uses CommunityToolkit.Mvvm WeakReferenceMessenger. Singleton "services" in Shared/Core/Messages (NewSchedaService, OnScannerService, CompleteInspectionService) publish/relay messages that decouple the barcode scanner and page components.
Barcode scanning
IBarcodeReaderService is implemented by HoneywellScannerService (MAUI, partial class with Android-specific parts + the Honeywell binding lib). IBarcodeManager/BarcodeManager (Shared) is the host-agnostic front the UI talks to. Scans flow to the UI through the messaging services above.
Attached images
Photos are served into the BlazorWebView through a custom scheme: MainPage.xaml.cs intercepts WebResourceRequested for https://localfiles/attached/<file> and streams files from CacheDirectory/attached (with path-traversal guards).
Error tracking
Sentry is configured in both hosts (.UseSentry(...) in MAUI, Sentry package in Shared). MAUI also has a GlobalExceptionHandler (registered in App.xaml.cs) and a FileLogger/FileLoggerProvider writing to AppDataDirectory/logs.
Versioning
App version lives in SteUp.Maui.csproj (ApplicationDisplayVersion + ApplicationVersion). Commit messages track releases (e.g. "-> v1.0.2 (3)"). Bump both when releasing. ApplicationId is it.integry.SteUp.