The UpdateBotDiscoveryStatus method was a stub that only logged but never
saved the RemoteAddress, RemotePort, DiscoveryStatus, and RemoteInstanceId
to the database. Now it properly calls UpdateRemoteInfoAsync.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Modified OrdersController to include Processing (legacy) status in pending tab
- Updated badge count to include Processing orders in PendingPaymentCount
- Added database reset script that preserves bot tokens and integrations
Processing status (OrderStatus=20) is a legacy unpaid status that should be visible
in the Pending Payment workflow to allow staff to retry failed payment creation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fixed BotService to prevent duplicate bot registrations by checking for existing bot with same name/type
- Updated existing bot record instead of creating duplicates on re-registration
- Configured SilverPay integration with production API key
- Updated TeleBot configuration for local development (localhost API URL, Tor disabled)
This ensures single bot instances and proper payment gateway integration for testing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major Feature Additions:
- Customer management: Full CRUD with data export and privacy compliance
- Payment management: Centralized payment tracking and administration
- Push notification subscriptions: Manage and track web push subscriptions
Security Enhancements:
- IP whitelist middleware for administrative endpoints
- Data retention service with configurable policies
- Enhanced push notification security documentation
- Security fixes progress tracking (2025-11-14)
UI/UX Improvements:
- Enhanced navigation with improved mobile responsiveness
- Updated admin dashboard with order status counts
- Improved product CRUD forms
- New customer and payment management interfaces
Backend Improvements:
- Extended customer service with data export capabilities
- Enhanced order service with status count queries
- Improved crypto payment service with better error handling
- Updated validators and configuration
Documentation:
- DEPLOYMENT_NGINX_GUIDE.md: Nginx deployment instructions
- IP_STORAGE_ANALYSIS.md: IP storage security analysis
- PUSH_NOTIFICATION_SECURITY.md: Push notification security guide
- UI_UX_IMPROVEMENT_PLAN.md: Planned UI/UX enhancements
- UI_UX_IMPROVEMENTS_COMPLETED.md: Completed improvements
Cleanup:
- Removed temporary database WAL files
- Removed stale commit message file
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
CRITICAL BUG FIX: Orders were totaling £0 because imported products had:
- Base price set to £0
- Variants stored as ProductMultiBuys (not ProductVariants)
- Order creation couldn't find variant prices → used base price of £0
Changes:
- CSV import now detects format: semicolons (;) = variants, colons (:) = multi-buys
- Added ImportProductVariantsAsync() to handle pipe-delimited variant format
- Format: "value; price; stock|value; price; stock" (e.g., "10; 30.00; 100|25; 70.00; 50")
- Updated CSV export to prioritize ProductVariants over MultiBuys
- Updated CSV template with correct variant format examples
- Added comprehensive documentation in VARIANT_CSV_FORMAT.md
Migration Required:
- Existing products with incorrect MultiBuy data need re-import
- Convert format from "name:qty:price;name:qty:price" to "value; price; stock|value; price; stock"
- Ensure base price is 0 for variant-based products
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added detailed logging to ParseAndImportVariantLine to output:
- Variant name/value
- Price override
- Stock quantity
- Variant type
This will help diagnose why variant price and stock aren't showing up
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix optimistic concurrency errors in product import by using ExecuteSqlRaw instead of EF tracking
- Add DeleteAllOrdersAndSalesDataAsync() method to clear orders, payments, customers, and messages
- Add DeleteAllSalesData endpoint to ProductsController for admin access
- Proper deletion order to avoid foreign key violations
- Enhanced logging for troubleshooting data cleanup operations
Resolves: Import errors with 'database operation expected to affect 1 row(s)'
- Added Replace All checkbox to import UI for clean slate imports
- Implemented DeleteAllProductsAndCategoriesAsync for complete data wipe
- Added auto-creation of categories during CSV import
- Created products_import.csv with 13 products across 4 categories
- Added comprehensive IMPORT_INSTRUCTIONS.md documentation
Technical changes:
- ProductImportService: Added replaceAll parameter to all import methods
- ProductImportService: Categories now auto-created if missing from CSV
- ProductsController: Added replaceAll parameter to Import action
- Import.cshtml: Added Replace All checkbox with danger warnings
Categories: Flour, Cereal, Vitamins, Herbal
Products: 13 products with full variant pricing structures
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Created NotificationHub for instant browser notifications
- Updated CryptoPaymentService to broadcast via SignalR
- Added JavaScript client with toast notifications
- Works with custom SSL certificates (no FCM dependency)
- Automatic reconnection with exponential backoff
- Notification sound and visual indicators
- Bypasses all Web Push SSL certificate issues
TeleBot Configuration:
- Added TeleBot API URL and API key to docker-compose.yml
- Configured to connect to telebot-service:5000 internally
- Enables customer notifications via Telegram bot
Expired Payment Handling:
- Auto-cancel orders when payment status is Expired
- Only cancels orders in PendingPayment status
- Logs cancellation for audit trail
Customer View Improvements:
- Hide cancelled orders from customer order lists
- Filters applied to both GetOrdersByIdentityAsync and GetOrdersByCustomerIdAsync
- Prevents confusion from displaying cancelled/expired orders
This resolves:
- No notifications to customers (TeleBot not configured)
- No notifications to admin (TeleBot connection failed)
- Expired orders remaining visible to customers
- Orders not auto-cancelled when payment expires
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Webhook Improvements:
- Added Confirmations field to PaymentWebhookDto (default: 0)
- Updated webhook controller to pass confirmations to service layer
- Fixed notification logic to match order update conditions
Payment Confirmation Logic:
- Paid (2): Confirmed immediately regardless of confirmations
- Overpaid (3): Confirmed immediately regardless of confirmations
- Completed (7): Requires 3+ blockchain confirmations
- Notifications only sent when order is actually updated
This prevents premature notifications for unconfirmed 'Completed' status
while maintaining immediate processing for 'Paid' and 'Overpaid' statuses.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added PaymentStatus.Overpaid to notification trigger conditions
- Overpaid payments now update order status to PaymentReceived
- Overpaid payments now send admin push notifications
- Overpaid payments now send TeleBot customer notifications
- Resolves issue where successful overpayments were silent
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root cause: Orders created with CustomerInfo had NULL IdentityReference
- CancelOrderAsync checked order.IdentityReference != identityReference
- NULL != "telegram:12345:username" → always returned false
- User saw "already processed" error even for pending orders
Fix implemented:
- Include Customer entity in CancelOrderAsync query
- Extract Telegram user ID from identity reference format
- Match against Customer.TelegramUserId for modern orders
- Fallback to IdentityReference matching for legacy orders
- Enhanced logging to debug ownership/status issues
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root cause: Order queries were missing .ThenInclude(oi => oi.ProductVariant)
which caused ProductVariantName to be null in order DTOs even though
ProductVariantId was stored correctly.
Fixed queries:
- GetAllOrdersAsync (admin panel order list)
- GetOrdersByIdentityAsync (TeleBot order lookup)
- GetOrdersByCustomerIdAsync (customer order history)
- UpdateOrderStatusAsync (order status updates)
Now both TeleBot and admin panel will show which product variation
was selected in order details and order lists.
**Root Cause**: EF Core Include() was not properly materializing the Variants navigation
property despite correct SQL JOIN generation.
**Solution**: Load variants separately and manually group by ProductId for DTO mapping.
This bypasses EF Core's navigation property fixup issues.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
AsNoTracking() prevents EF Core from properly wiring up navigation properties.
Removing it allows Include() to populate Variants collection correctly.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
**Problem**: EF Core was not materializing Variants navigation property when using
.Select() projection directly in the query. The .Include() was being ignored.
**Solution**: Changed approach to:
1. Load entities with .Include() + .ToListAsync() first
2. Then project to DTO with in-memory .Select()
This ensures navigation properties are fully loaded before mapping to DTOs.
**Impact**: Variants will now properly appear in all product API responses.
🤖 Generated with Claude Code
https://claude.com/claude-code
Co-Authored-By: Claude <noreply@anthropic.com>
Previous commit (e931f77) only fixed GetAllProductsAsync and GetProductByIdAsync.
This commit fixes GetProductsByCategoryAsync which also had the broken filtered Include syntax.
**Impact**: Variants will now appear when browsing products by category in TeleBot.
🤖 Generated with Claude Code
https://claude.com/claude-code
Co-Authored-By: Claude <noreply@anthropic.com>
Critical bug where ProductVariants were never loaded from database.
**Problem:**
`.Include(p => p.Variants.Where(v => v.IsActive))` syntax was NOT
generating SQL JOIN statements in EF Core 9.0, causing all products
to return empty variants array even when variants exist in database.
**Solution:**
- Changed to simple `.Include(p => p.Variants)`
- Filtering still happens in DTO mapping (Select statement)
- Only IsActive variants are returned to API consumers
**Impact:**
- TeleBot can now display product variants with selection UI
- Variant pricing and stock levels now visible to customers
- Multi-variant products (e.g., Size/Color) now functional
**Test Case:**
Product 131cc3ad-07f4-4ec9-89ca-b05a0b4cfb41 has 7 variants:
- Size: Small, Medium, Large, XL
- Color: Black, White, Navy Blue
These will now appear in API responses and TeleBot UI.
🤖 Generated with Claude Code
https://claude.com/claude-code
Co-Authored-By: Claude <noreply@anthropic.com>
Enables individual variants to have their own prices, overriding the base product price.
**Database Changes:**
- Added Price (decimal?, nullable) to ProductVariants table
- Added ProductVariantId to OrderItems table with foreign key relationship
- Created index on OrderItems.ProductVariantId for performance
**API Changes:**
- ProductVariantDto: Added Price field
- CreateProductVariantDto: Added Price field with validation
- UpdateProductVariantDto: Added Price field
- OrderItemDto: Added ProductVariantId and ProductVariantName
- CreateOrderItemDto: Added ProductVariantId
**Business Logic:**
- OrderService: Variant price overrides base price (but multi-buy takes precedence)
- ProductService: All variant CRUD operations support Price field
**Admin UI:**
- CreateVariant: Price input with £ symbol and base price placeholder
- EditVariant: Price editing with £ symbol
- ProductVariants list: Shows variant price or "(base)" indicator
**Client Library:**
- Updated all DTOs to match server-side changes
- Full support for variant pricing in order creation
**Migration:**
- EF Core migration: 20251003173458_AddVariantPricing
- Backward compatible: NULL values supported for existing data
**Use Case:**
Products with size/color variants can now have different prices:
- Small T-shirt: £15.00 (variant override)
- Medium T-shirt: £18.00 (uses base price)
- Large T-shirt: £20.00 (variant override)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented a professional loading screen for the PWA to eliminate the
"hang and wait" experience during app initialization.
Changes:
- Added full-screen gradient loading overlay with TeleShop branding
- Implemented animated triple-ring spinner with smooth animations
- Added automatic removal after PWA initialization (500ms fade-out)
- Included 5-second fallback timeout to prevent infinite loading
- Updated service worker cache version to v2
- Enhanced JWT validation to detect test/temporary keys
- Updated appsettings.json with secure JWT key
Design Features:
- Purple/blue gradient background matching brand colors
- Pulsing logo animation for visual interest
- Staggered spinner rings with cubic-bezier easing
- Fade-in-out loading text animation
- Mobile-responsive design (scales appropriately on all devices)
Technical Implementation:
- Loading screen visible by default (no FOUC)
- Removed via JavaScript when PWA manager initialization completes
- Graceful fade-out animation before DOM removal
- Console logging for debugging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed VAPID subject from public URL to mailto format
- Updated docker-compose.yml to use mailto:admin@littleshop.local
- Removed dependency on thebankofdebbie.giize.com public domain
- All push notifications now work through VPN (admin.dark.side) only
- Added update-push-internal.sh helper script for deployment
- Improved security by keeping all admin traffic internal
Push notifications will continue working normally through FCM,
but all configuration and management stays on the internal network.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit introduces a comprehensive variant management system and enhances
the existing ProductVariant model with per-variant weight overrides and stock
tracking, integrated across Admin Panel and TeleBot.
Features Added:
- Variant Collections: Reusable variant templates (e.g., "Standard Sizes")
- Admin UI for managing variant collections (CRUD operations)
- Dynamic variant editor with JavaScript-based UI
- Per-variant weight and weight unit overrides
- Per-variant stock level tracking
- SalesLedger model for financial tracking
ProductVariant Enhancements:
- Added Weight (decimal, nullable) field for variant-specific weights
- Added WeightUnit (enum, nullable) field for variant-specific units
- Maintains backward compatibility with product-level weights
TeleBot Integration:
- Enhanced variant selection UI to display stock levels
- Shows weight information with proper unit conversion (µg, g, oz, lb, ml, L)
- Compact button format: "Medium (15 in stock, 350g)"
- Real-time stock availability display
Database Migrations:
- 20250928014850_AddVariantCollectionsAndSalesLedger
- 20250928155814_AddWeightToProductVariants
Technical Changes:
- Updated Product model to support VariantCollectionId and VariantsJson
- Extended ProductService with variant collection operations
- Enhanced OrderService to handle variant-specific pricing and weights
- Updated LittleShop.Client DTOs to match server models
- Added JavaScript dynamic variant form builder
Files Modified: 15
Files Added: 17
Lines Changed: ~2000
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major changes:
• Remove BTCPay Server integration in favor of SilverPAY manual verification
• Add test data cleanup mechanisms (API endpoints and shell scripts)
• Fix compilation errors in TestController (IdentityReference vs CustomerIdentity)
• Add deployment automation scripts for Hostinger VPS
• Enhance integration testing with comprehensive E2E validation
• Add Blazor components and mobile-responsive CSS for admin interface
• Create production environment configuration scripts
Key Features Added:
• Manual payment verification through Admin panel Order Details
• Bulk test data cleanup with proper cascade handling
• Deployment automation with systemd service configuration
• Comprehensive E2E testing suite with SilverPAY integration validation
• Mobile-first admin interface improvements
Security & Production:
• Environment variable configuration for production secrets
• Proper JWT and VAPID key management
• SilverPAY API integration with live credentials
• Database cleanup and maintenance tools
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix admin panel to show all pending orders (PendingPayment + PaymentReceived)
- Fix currency display from USD ($) to GBP (£) throughout TeleBot
- Update payment methods to use dynamic SilverPay currency list
- Consolidate shipping address collection into single message
- Implement cart backup/restore on payment failure
- Remove unsupported XMR from TeleBot config
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated Docker configuration for production deployment
- Added SilverPay integration settings
- Configured for admin.thebankofdebbie.giize.com deployment
- Includes all recent security fixes and improvements
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed JSON naming policy from CamelCase to SnakeCaseLower for SilverPay API compatibility
- Fixed field name from 'fiat_amount' to 'amount' in request body
- Used unique payment ID instead of order ID to avoid duplicate external_id conflicts
- Modified SilverPayApiResponse to handle string amounts from API
- Added [JsonIgnore] attributes to computed properties to prevent JSON serialization conflicts
- Fixed test compilation errors (mock service and enum casting issues)
- Updated SilverPay endpoint to http://10.0.0.52:8001/🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major restructuring of product variations:
- Renamed ProductVariation to ProductMultiBuy for quantity-based pricing (e.g., "3 for £25")
- Added new ProductVariant model for string-based options (colors, flavors)
- Complete separation of multi-buy pricing from variant selection
Features implemented:
- Multi-buy deals with automatic price-per-unit calculation
- Product variants for colors/flavors/sizes with stock tracking
- TeleBot checkout supports both multi-buys and variant selection
- Shopping cart correctly calculates multi-buy bundle prices
- Order system tracks selected variants and multi-buy choices
- Real-time bot activity monitoring with SignalR
- Public bot directory page with QR codes for Telegram launch
- Admin dashboard shows multi-buy and variant metrics
Technical changes:
- Updated all DTOs, services, and controllers
- Fixed cart total calculation for multi-buy bundles
- Comprehensive test coverage for new functionality
- All existing tests passing with new features
Database changes:
- Migrated ProductVariations to ProductMultiBuys
- Added ProductVariants table
- Updated OrderItems to track variants
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Complete MockSilverPayService with GetExchangeRateAsync method
- Fix compilation errors and webhook response types
- Successful e2e testing with real SilverPAY server integration
- TeleBot integration verified with production payment flow
- Database optimization with Alembic migration system
- Webhook integration confirmed and operational
- All code quality checks passed (0 errors, 0 warnings)
System now production-ready with full cryptocurrency payment support.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Removed all BTCPay references from services and configuration
- Implemented SilverPAY as sole payment provider (no fallback)
- Fixed JWT authentication with proper key length (256+ bits)
- Added UsersController with full CRUD operations
- Updated User model with Email and Role properties
- Configured TeleBot with real Telegram bot token
- Fixed launchSettings.json with JWT environment variable
- E2E tests passing for authentication, catalog, orders
- Payment creation pending SilverPAY server fix
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>