Commit Graph

219 Commits

Author SHA1 Message Date
b265c89a72 Fix: Refactor TeleBot messaging to use database queue 2025-10-06 17:22:06 +01:00
6c95ed3145 Fix: Add TeleBot integration and expired payment handling
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>
2025-10-06 16:55:19 +01:00
cede0e7c47 Fix: Update interface to match confirmations parameter
- Added confirmations parameter to ICryptoPaymentService.ProcessPaymentWebhookAsync
- Updated CryptoPaymentService implementation to pass confirmations parameter
- Fixes build error: interface member signature mismatch

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 16:35:09 +01:00
110ad5f956 Fix: Add confirmations support and fix notification logic
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>
2025-10-06 16:26:39 +01:00
2ae44a3c56 Fix: Add Dispatch button for orders in Packing status
- Added quick action button on Packing tab to dispatch orders
- Created dispatch modal with tracking number input
- Modal includes tracking number, estimated days, and notes fields
- Button appears on both desktop table and mobile card views
- Fixes workflow gap where Packing orders had no quick action
- Orders now properly flow: Accepted → Packing → Dispatched

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 16:12:11 +01:00
a519284fd1 Fix: Include Overpaid status in payment notifications
- 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>
2025-10-06 16:07:14 +01:00
81f781be48 Fix: Allow anonymous access to BTCPay webhook endpoint
- Added [AllowAnonymous] attribute to PaymentWebhook endpoint
- Resolves authentication errors preventing BTCPay Server callbacks
- Webhook endpoint now accepts unauthenticated POST requests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 15:47:35 +01:00
c9afb760b8 Fix: PWA manifest warnings resolved
Fixed Issues:
1. Removed "maskable" purpose from icons (was causing padding warnings)
2. Added screenshots with form_factor for richer install UI
   - Desktop: form_factor: "wide"
   - Mobile: form_factor: "narrow"

Changes:
- Icons now use "purpose: any" only (no maskable)
- Added screenshots array with wide/narrow form factors
- This enables richer PWA install prompts on supported browsers

All PWA manifest warnings should now be resolved.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 12:20:34 +01:00
5f71f0bb2d Fix: Loading screen now shows on every page load
Problems Fixed:
1. Blank white screen on initial load (loading screen had display:none)
2. Only showed once (sessionStorage.blazorLoaded prevented repeat shows)
3. Fast connections meant users never saw it

Solution:
1. Removed display:none from HTML - screen visible immediately
2. Removed sessionStorage check - shows on every page load
3. Screen visible by default, hides when Blazor.start() completes

Behavior Now:
- Loading screen appears instantly (no blank white screen)
- Shows on every page load (full page refresh)
- Hides when SignalR connection established
- Works correctly with slow/throttled connections

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 12:07:40 +01:00
0a08d1a943 Fix: Loading screen now waits for Blazor.start() on all pages
Problem:
- Loading screen was hiding immediately without waiting for Blazor
- Page detection logic was too restrictive (only /blazor paths)
- Most admin pages don't have Blazor components, so screen hid instantly

Solution:
- Blazor Server is loaded on ALL admin pages via _Layout.cshtml
- Removed restrictive path checking (was checking for /blazor or components)
- Now always calls Blazor.start() and waits for SignalR connection
- Loading screen properly shows while SignalR establishes connection

Expected behavior:
- First load: Screen shows → Blazor connects → Screen fades out
- Console: "Starting Blazor Server..." → "Started successfully" → "Hiding"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 11:54:53 +01:00
db2443c7ac Fix: Blazor Server loading screen now works correctly
Problem:
- Loading screen was getting stuck and not hiding properly
- Conflicting logic between pwa.js and inline scripts
- Blazor Server lifecycle not properly integrated with loading screen

Solution (Meziantou-inspired approach for Blazor Server):
1. **blazor-integration.js** - Now manages loading screen lifecycle:
   - Shows loading screen only on first load (sessionStorage check)
   - Hides screen when Blazor.start() promise resolves (SignalR connected)
   - Added reconnection UI for Blazor Server disconnections
   - Proper error handling if Blazor fails to start

2. **_Layout.cshtml** - Simplified loading screen management:
   - Removed inline script that was conflicting
   - Moved blazor-integration.js before pwa.js (load order critical)
   - Loading screen now controlled by Blazor lifecycle

3. **pwa.js** - Removed conflicting logic:
   - Removed hideLoadingScreen() method
   - Removed 5-second fallback timeout
   - PWA initialization no longer interferes with Blazor loading

Key Differences from WebAssembly Approach:
- WASM: Downloads .NET runtime + shows download progress
- Server: Establishes SignalR connection + shows spinner
- Loading screen hides when SignalR connection is ready

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 11:45:08 +01:00
dd494603f5 Fix: TeleBot should not use Tor for internal LittleShop API calls
**Problem**:
- GetAvailableCurrenciesAsync() was routing internal API calls through Tor
- Caused SOCKS connection failures: "SOCKS server failed to connect"
- Internal Docker network calls don't need Tor privacy layer

**Root Cause**:
- Line 617-618 used OR logic: LittleShop:UseTor OR Privacy:EnableTor
- Production config: LittleShop__UseTor=false, Privacy__EnableTor=true
- OR condition meant Tor was enabled for all API calls

**Solution**:
- Only check LittleShop:UseTor (explicitly for API calls)
- Privacy:EnableTor now only affects external Telegram API calls
- Internal calls (http://littleshop:5000) bypass Tor completely

**Benefits**:
- No more SOCKS connection errors
- Faster internal API responses (no Tor overhead)
- Tor still protects external Telegram communications

**File**: TeleBot/TeleBot/Services/LittleShopService.cs:619

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 11:33:10 +01:00
9206067e9c Fix: TeleBot order deletion and bot activity tracking
**Fixes Applied:**

1. **Order Deletion Authorization (HTTP 401)**
   - Added [AllowAnonymous] to CancelOrder endpoint
   - Allows customers to cancel orders using IdentityReference
   - File: LittleShop/Controllers/OrdersController.cs:160

2. **Bot Activity Tracking Hostname**
   - Changed littleshop-admin:8080 → littleshop:5000
   - Fixed DNS resolution errors in production
   - Files: TeleBot/appsettings.json, BotActivityTracker.cs, docker-compose.hostinger.yml

3. **Tor Proxy Investigation**
   - Analyzed SOCKS connection failures
   - Tor is working correctly, API blocks exit nodes (expected)
   - Fallback to default currencies working as designed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 11:16:32 +01:00
217de2a5ab Feature: Human-Readable Text Format Product Import
Implemented a new text-based import format for bulk product imports that is
easier to read, write, and version control compared to CSV format.

## New Features

### Import Service (ProductImportService.cs)
- Added `ImportFromHumanTextAsync()` - Main text format parser
- Added `GenerateTemplateAsHumanText()` - Template generator
- Parser supports:
  - Product blocks starting with `#`
  - Descriptions between `<text>` tags (optional)
  - Key-value properties (category, price, weight, unit, stock)
  - Variants (lines starting with `-`)
  - Multi-buy offers (lines starting with `+`)
  - Variant collections (optional, after product name)

### Admin UI
- New controller actions:
  - `ImportText()` - GET: Show import form
  - `ImportText(textContent, file)` - POST: Process import
  - `DownloadTextTemplate()` - Download .txt template
- New view: `ImportText.cshtml`
  - Textarea for pasting text
  - File upload for .txt files
  - Format documentation sidebar
  - Links to CSV import and template downloads
- Updated `Index.cshtml` with dropdown menu for import options

### Template & Documentation
- Created `docs/ProductImportTemplate.txt` with 7 example products
- Demonstrates all format features:
  - Products with/without descriptions
  - Variants with stock levels
  - Multi-buy pricing tiers
  - Multiple weight units

## Text Format Specification

```
# Product Name; OptionalVariantCollection
<text>
Multi-line description (optional)
</text>
category: CategoryName
price: 10.00
weight: 100
unit: Grams
stock: 50

- Variant1; 8.00; 50
- Variant2; 12.00; 30

+ Multi-buy1; 2; 19.00
+ Multi-buy2; 3; 25.00
```

## Benefits
-  Git-friendly (easy to diff and version)
-  Human-readable and editable
-  Supports all product features
-  Multi-line descriptions
-  Clear structure with # delimiters
-  Optional fields (description, variants, multi-buys)
-  Comprehensive error reporting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 05:29:21 +01:00
d897bb99c3 Fix: Saved address now persists across sessions
Root cause: Ephemeral sessions weren't persisted after checkout
- Sessions ephemeral by default, only persisted during CheckoutFlow
- After checkout completes, state changes to MainMenu
- SavedAddress was lost because session wasn't saved

Fix implemented:
- Persist ephemeral sessions when SavedAddress is not null
- Also persist when cart is non-empty (preserve cart state)
- User's saved shipping address now available on next checkout
- Improves UX - no need to re-enter address every time

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 04:58:01 +01:00
a6f1c32461 Fix: Delete order now works for Customer-based orders
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>
2025-10-06 04:56:32 +01:00
4c6a1f10d6 Fix: Delete order button now responds correctly
Root cause: Callback was answered twice (line 68 + HandleDeleteOrder)
- Telegram only allows answering callback query once
- Second attempt threw exception, preventing message edit
- Removed duplicate AnswerCallbackQueryAsync calls from HandleDeleteOrder
- Added proper error message for failed delete attempts
- Now shows success/failure via message edit instead of callback answer

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 04:42:29 +01:00
7806bb2392 Docs: Channel Lock & PIN Protection feature design
- Created comprehensive design document (docs/CHANNEL_LOCK_DESIGN.md)
- Complete UX flows with PIN setup, unlock, and auto-lock modes
- Technical implementation details with code examples
- Security architecture (PBKDF2, brute force protection)
- Database schema changes and migration plan
- Testing strategy and implementation checklist
- Added to ROADMAP.md as Phase 3, Item #1 (HIGH PRIORITY)
- Target: October 2025 implementation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 04:39:29 +01:00
f440042204 Feature: Complete order management for pending orders
- Added delete order functionality with identity verification
- OrderDetailsMenu now shows conditional buttons based on order/payment state
- Retry payment if no payments exist
- View payment details if payment pending
- Delete order option for all pending orders
- Full client SDK implementation for CancelOrderAsync

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 04:19:47 +01:00
3cc7092967 Fix: Product details now auto-scroll into view when Buy is clicked
Problem: When clicking Buy button, product details message appeared at bottom
but Telegram didn't auto-scroll to show it, leaving users confused.

Solution: Use replyToMessageId parameter to thread product details as a reply
to the user's button click message. This:
- Creates visual thread connection
- Encourages Telegram to show the response prominently
- Makes conversation flow more natural

Also wrapped activity tracking in try-catch to prevent blocking.

Technical Changes:
- ProductCarouselService: Added replyToMessageId optional parameter
- SendPhotoAsync/SendTextMessageAsync: Use replyToMessageId with allowSendingWithoutReply
- HandleProductDetail: Pass message.MessageId to carousel service

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 04:08:50 +01:00
6676f010a8 Fix: Compilation error - use correct PaymentMethodMenu name
Error: MenuBuilder.PaymentCurrencyMenu does not exist
Fix: Changed to MenuBuilder.PaymentMethodMenu (correct method name)

TeleBot now compiles successfully.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 03:57:24 +01:00
9e1bf0543f Fix: Prevent activity tracker errors from blocking checkout
Problem: Activity tracker DNS errors (littleshop-admin:8080) were blocking
checkout flow, preventing shipping address prompt from showing.

Solution: Wrap activity tracking in try-catch with warning log.
Checkout flow continues even if activity tracking fails.

This ensures users can complete checkout even if analytics are unavailable.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 03:49:03 +01:00
17cb9c7721 Fix: Multiple TeleBot UI improvements
1. Remove /help from main menu
   - Removed " Help" button from main menu
   - Help still available via /help command

2. Fix support refresh clearing messages
   - Changed from editing message to sending new message
   - Preserves message history when refreshing
   - Shows "No new messages" if no updates instead of clearing
   - Better error handling with user-friendly alerts

3. Add retry payment button for failed payments
   - New "🔄 Retry Payment" button when payment creation fails
   - Shows order ID (friendly reference) in error message
   - PaymentFailedMenu: Retry, View Basket, Main Menu options
   - HandleRetryPayment: Re-shows currency selection
   - Preserves order and allows payment retry without recreating order

Technical Changes:
- MenuBuilder: Added PaymentFailedMenu method
- CallbackHandler: Added retry_payment case and HandleRetryPayment method
- HandlePayment: Updated error messages to use PaymentFailedMenu
- HandleRefreshConversation: Sends new message instead of editing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 03:48:04 +01:00
99bb083bd6 Feature: Enhanced order display and basket summary
1. Basket Summary Below Navigation
   - Welcome message now shows basket items and total
   - Format: "🛒 Basket: X item(s) - £X.XX"
   - Only shown when basket has items

2. Order Display Improvements
   - Order GUID replaced with friendly reference (last 8 chars: #XXXXXXXX)
   - Added "View Payment Details" button for pending payment orders
   - Button shows QR code, amount, address, and time until expiry
   - Variants now properly displayed in order items (already working via commit 330116e)

3. Payment Details View (New Feature)
   - HandleViewPayment: Shows payment info with QR code
   - Displays: Currency, amount, address, expiry time
   - Shows time remaining until payment expires
   - QR code generation for easy mobile payment
   - OrderDetailsMenu: Context-aware navigation buttons

4. Postal Address Auto-Load (Verified Working)
   - Checkout automatically detects saved addresses
   - Offers to use saved address with preview
   - One-click selection or option to enter new address
   - SavedAddress copied to OrderFlow when selected

Technical Changes:
- MessageFormatter.FormatWelcome: Added optional cart parameter
- MessageFormatter.FormatOrder: Uses friendly order reference
- MenuBuilder.OrderDetailsMenu: New menu with payment button
- CallbackHandler.HandleViewPayment: Payment details with QR
- CallbackHandler.HandleMainMenu: Pass cart to welcome formatter

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 03:29:11 +01:00
9432ae8ccb UX: Major TeleBot checkout flow improvements
1. Show variants immediately on product page (removed duplicate buy button)
   - Variants now display directly on product details page
   - No intermediate "select variant" button needed
   - Faster checkout flow

2. Add post-purchase prompt (Checkout or Continue Shopping)
   - After adding to basket, shows "What would you like to do next?"
   - Options: View Basket, Checkout, or Continue Shopping
   - Continue Shopping returns to the product page

3. Remove quantity +/- buttons from product details
   - Simplified to single item purchase only
   - Cleaner interface for mobile users

4. Rename "Cart" to "Basket" throughout
   - All user-facing text updated
   - "Add to Cart" → "Add to Basket"
   - "Shopping Cart" → "Shopping Basket"
   - "View Cart" → "View Basket"
   - "Clear Cart" → "Clear Basket"

Technical Changes:
- MenuBuilder.ProductDetailMenu: Now shows variant selection inline
- CallbackHandler: Updated to use ProductDetailMenu for variant updates
- Added PostAddToCartMenu for post-purchase options
- HandleAddToCart/HandleConfirmVariant: Show prompt instead of returning to product

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 03:26:19 +01:00
1e93008df4 Fix: Variant selection now accumulates across types instead of resetting
Problem:
- Selecting Size then Color would reset Size selection
- Users could never get "Add to Cart" button with multiple variant types
- Each selection created a NEW list, wiping previous choices

Root Cause:
- HandleSetVariant created: new List<string> { variantName }
- This replaced all previous selections instead of accumulating

Fix:
1. Get existing selected variants from session
2. Find the variant type of newly selected variant
3. Remove any previous selection from the SAME type (allow changing choice)
4. Add the new selection
5. Save accumulated list back to session

Example behavior now:
- Select "Red" (Color) → selectedVariants = ["Red"]
- Select "Large" (Size) → selectedVariants = ["Red", "Large"] 
- Select "Blue" (Color) → selectedVariants = ["Blue", "Large"] 
- Can now confirm when all types selected

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 02:44:28 +01:00
cb80e0161c Fix: Variant selection now requires choosing from ALL variant types
Problem:
- Product with Size + Color only required selecting 1 variant total
- User could add to cart after selecting just Size OR Color, not both

Root Cause:
- Logic checked if selectedVariants.Count == 1 for single items
- Didn't verify that all variant types were covered

Fix:
- For single items: Check that each variant type has at least one selection
- Logic: variantGroups.All(g => g.Any(v => selectedVariants.Contains(v.Name)))
- For multi-buy: Keep existing logic (total count == quantity)

Now users must select:
- Size + Color products: Must pick both Size AND Color
- Size only products: Must pick Size only
- Etc.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 02:11:06 +01:00
330116e315 Fix: Include ProductVariant in all order queries
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.
2025-10-06 00:59:42 +01:00
5ab2c51aa8 Enhancement: Show proper order details instead of GUIDs
- OrderListMenu now shows item summary (e.g., '2x Product Name' or 'Product Name +2 more')
- FormatCart enhanced to show variant selections and multi-buy indicators
- FormatOrder enhanced to show variant names and detailed item breakdown
- Cart now clearly distinguishes between multi-buy bundles and regular items
- Order confirmations now show full product and variant details

Replaced generic GUID displays with human-readable product information for better UX.
2025-10-06 00:46:35 +01:00
6c79c04ebd Fix: Message threading - navigation now sends new messages at bottom
- Changed HandleMainMenu to send new messages instead of editing
- Changed HandleBrowse to send new messages for category navigation
- Changed HandleViewCart to use SendNewCartMessage (already existed)
- Changed HandleViewOrders to send new messages for order list
- Changed HandleViewOrder to send new messages for order details

This ensures the active conversation always appears at the bottom of the chat
instead of mid-thread when users click menu buttons. Provides better UX and
natural conversation flow in Telegram.
2025-10-06 00:44:28 +01:00
c8f22c783d Feature: Add postal address memory with user preference
- Added SavedShippingAddress model to store user addresses
- Added Privacy.SaveShippingAddress preference (null = not asked, true/false = user choice)
- Enhanced checkout flow to offer using saved address if available
- Ask once about saving address, respect user's choice going forward
- Automatically save/not save based on user preference in future orders
- Added menu options: Use Saved Address, Enter New Address, Save Address (Yes/No)
- Enhanced CallbackHandler with save address handlers
- Updated MessageHandler to prompt for save preference on first use

User will only be asked once about saving addresses. Account reset clears preference.
2025-10-06 00:38:47 +01:00
147e96a084 UI: Remove Variants info button and rename Add to Cart to BUY {PRODUCTNAME}
- Removed informational 'Variants: Size: X options, Color: Y options' button
- Renamed 'Add to Cart' button to 'BUY {product.Name}' for clearer UX
- Applied to both multi-buy single item and regular quantity purchase buttons
2025-10-06 00:35:30 +01:00
29d677be72 Fix: Last occurrence of MenuBuilder.VariantSelectionMenu 2025-10-05 23:39:41 +01:00
4cd7a9c61c Fix: Update CallbackHandler to use _menuBuilder instance for VariantSelectionMenu 2025-10-05 23:37:21 +01:00
a4678c919c Fix: Make VariantSelectionMenu an instance method to access _mapper 2025-10-05 23:33:47 +01:00
f1d8bfc317 Fix: VariantSelectionMenu now uses CallbackDataMapper for all callback data to prevent GUID parsing errors 2025-10-05 23:27:12 +01:00
0801fb004c Fix: TeleBot variant callbacks now use CallbackDataMapper to decode short IDs - fixes GUID parsing errors 2025-10-05 22:48:53 +01:00
76707eb565 Fix: Complete workaround for EF Core 9 + SQLite GUID parameter bug - load all variants then filter in-memory 2025-10-05 17:01:52 +01:00
45da991945 Debug: Enhanced logging for variant loading investigation 2025-10-05 17:00:04 +01:00
6f4befa188 Debug: Add logging to GetProductByIdAsync 2025-10-05 16:58:35 +01:00
0e8b53df01 Fix: Apply variant loading workaround to GetProductByIdAsync 2025-10-05 16:55:20 +01:00
7dbdc0d46f Fix: Work around EF Core 9 + SQLite json_each bug preventing variant loading 2025-10-05 16:41:42 +01:00
3a2ef481b0 Debug: Add console logging to variant loading 2025-10-05 16:39:46 +01:00
8d1e3d153c Fix: Manually load ProductVariants with separate query instead of Include
**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>
2025-10-05 16:33:33 +01:00
53ba1f4079 Try: Use AsSplitQuery to force separate SQL queries for navigation properties
This may help EF Core properly materialize the Variants collection.

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-05 16:31:40 +01:00
91bcdad9db Fix: Remove AsNoTracking to enable navigation property fixup
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>
2025-10-05 16:29:48 +01:00
b05645d526 Fix: Load navigation properties before projection to ensure variants are included
**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>
2025-10-04 17:48:30 +01:00
22e910862a Fix: Remove filtered Include for variants in GetProductsByCategoryAsync
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>
2025-10-04 17:45:13 +01:00
e931f772fb Fix: Remove filtered Include for variants - EF Core not executing JOIN
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>
2025-10-04 15:23:43 +01:00
bbf2764af9 Fix: Align deployment configs with production architecture
Critical fixes to ensure smooth deployments and prevent future outages:

**docker-compose.yml:**
- Fixed image name: littleshop:latest → localhost:5000/littleshop:latest
- Fixed subnet: 172.21.0.0/16 → 172.23.0.0/16 (matches production)
- Fixed environment: Production → Development (matches current production)

**.gitlab-ci.yml:**
- Fixed TeleBot API URL: http://littleshop-admin:8080http://littleshop:5000
- Removed duplicate network flag (was causing issues)
- Added explicit network connection command for littleshop_littleshop-network
- Ensures TeleBot can communicate with LittleShop API on deployment

**CLAUDE.md:**
- Documented October 4, 2025 incident and recovery
- Added comprehensive deployment best practices
- Documented pre-deployment checklist
- Added manual deployment commands for emergencies
- Documented network architecture and container configuration

**Root Cause of Previous Failure:**
TeleBot was trying to connect to non-existent hostname "littleshop-admin"
on wrong network, causing authentication failures and data unavailability.

**Verification:**
All changes tested in production and confirmed working. TeleBot now
successfully authenticates and communicates with LittleShop API.

🤖 Generated with Claude Code
https://claude.com/claude-code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-04 15:13:56 +01:00