# LittleShop Development - Technical Lessons Learned

## 🔑 Critical Discoveries & Solutions

### 1. **ASP.NET Core 9.0 Authentication Architecture**
- **Dual Authentication Schemes**: Successfully implemented both Cookie (for MVC Admin Panel) and JWT Bearer (for API) authentication in the same application
- **Key Learning**: Must specify authentication scheme explicitly when using multiple schemes
- **Implementation**: Cookie auth uses `[Authorize(AuthenticationSchemes = "Cookies")]`, JWT uses `[Authorize(AuthenticationSchemes = "Bearer")]`

### 2. **Entity Framework Core with SQLite**
- **Decimal Ordering Issue**: SQLite cannot order by decimal columns directly
- **Solution**: Load data into memory first, then apply ordering
```csharp
// Won't work in SQLite:
.OrderBy(sr => sr.MinWeight)

// Solution:
var rates = await _context.ShippingRates.ToListAsync();
return rates.OrderBy(sr => sr.MinWeight);
```

### 3. **Service Constructor Dependencies**
- **ProductService Evolution**: Initially had IMapper dependency, later changed to IWebHostEnvironment for file handling
- **CategoryService**: Simplified to only require DbContext, no mapper needed
- **Lesson**: Services evolved based on actual needs rather than anticipated patterns

### 4. **Model Property Naming Conventions**
- **Initial Design**: Used non-standard names (BasePrice, ProductWeight, ProductWeightUnit)
- **Refactored To**: Standard e-commerce names (Price, Weight, WeightUnit)
- **Impact**: Required updating all DTOs, services, views, and tests
- **Lesson**: Follow industry-standard naming conventions from the start

### 5. **Test Project Configuration**
- **Mock Dependencies**: Use Moq for IWebHostEnvironment in unit tests
- **In-Memory Database**: Works well for testing with `UseInMemoryDatabase()`
- **Authentication in Tests**: Create JWT tokens manually for integration tests
```csharp
var token = JwtTokenHelper.GenerateJwtToken();
_client.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue("Bearer", token);
```

### 6. **File Upload Implementation**
- **LINQ Translation Issues**: Complex LINQ queries with DefaultIfEmpty() don't translate to SQL
- **Solution**: Use nullable casts and null coalescing
```csharp
// Problematic:
.Select(pp => pp.SortOrder).DefaultIfEmpty(0).Max()

// Solution:
.Select(pp => (int?)pp.SortOrder).MaxAsync() ?? 0
```

### 7. **Git Commit in Windows/WSL**
- **Issue**: Complex multi-line commit messages fail with standard quotes
- **Solution**: Write commit message to file, use `-F` flag
```bash
git commit -F commit_msg.txt
```

### 8. **API Security Design Decision**
- **Critical Requirement**: NO public endpoints - all require authentication
- **Implementation**: Every API endpoint requires JWT token
- **Rationale**: Client applications handle public presentation after authentication
- **Impact**: Simplified security model, consistent authorization

### 9. **WSL2 Development Environment**
- **Command Execution**: Must use `cmd.exe /c` for .NET commands in WSL
- **File Locking**: Application must be stopped before rebuilding (common WSL issue)
- **Path Handling**: Use `/mnt/c/` for Windows paths in WSL

### 10. **Client SDK Design Patterns**
- **Retry Policies**: Polly integration for transient failure handling
- **Error Handling**: Middleware pattern for consistent error responses
- **DI Integration**: Extension methods for easy service registration
- **Response Wrapping**: ApiResponse<T> pattern for consistent error handling

## 📊 Database Design Decisions

### Shipping Information
- **Added to Orders**: Full shipping details (Name, Address, City, PostCode, Country)
- **Separate ShippingRates Table**: Weight-based calculation system
- **Lesson**: E-commerce requires comprehensive shipping information upfront

### Payment Status Evolution
- **Original Enum Values**: Pending, Confirmed, Failed
- **Changed To**: Pending, Paid, Failed, Expired, Cancelled
- **Reason**: Better alignment with cryptocurrency payment lifecycle

### Order Status Values
- **Original**: Pending, Processing, Shipped
- **Updated**: PendingPayment, PaymentReceived, Processing, Shipped, Delivered, Cancelled
- **Benefit**: More granular order tracking

## 🏗️ Architecture Patterns That Worked

### 1. **Service Layer Pattern**
- Clean separation between controllers and business logic
- Each service has its interface
- Easy to mock for testing

### 2. **DTO Pattern**
- Separate DTOs for Create, Update, and View operations
- Prevents over-posting attacks
- Clear API contracts

### 3. **Repository Pattern (via EF Core)**
- DbContext acts as Unit of Work
- No need for additional repository layer with EF Core
- Simplified data access

### 4. **Areas for Admin Panel**
- `/Areas/Admin/` structure keeps admin code separate
- Own controllers, views, and routing
- Clear separation of concerns

## 🐛 Common Issues & Fixes

### View Compilation Issues
- **Problem**: Runtime changes to views not reflected
- **Solution**: Restart application in production mode
- **Better Solution**: Use development mode for active development

### ModelState Validation
- **Issue**: Empty validation summaries appearing
- **Cause**: ModelState checking even for GET requests
- **Fix**: Only display validation summary on POST

### Nullable Reference Warnings
- **Common in Views**: `Model.Property` warnings
- **Solution**: Use null-conditional operator `Model?.Property`
- **Alternative**: Use `new()` initialization in view model

## 🚀 Performance Optimizations

### 1. **Query Optimization**
- Use `.Include()` for eager loading
- Use `.AsNoTracking()` for read-only queries
- Project to DTOs in queries to reduce data transfer

### 2. **Pagination Implementation**
- Always implement pagination for list endpoints
- Return metadata (total count, page info)
- Client-side should handle pagination UI

### 3. **File Upload Strategy**
- Store files on disk, not in database
- Save only file paths in database
- Implement file size limits

## 🔒 Security Best Practices Implemented

### 1. **Authentication**
- JWT tokens expire after 60 minutes
- Refresh token mechanism available
- No sensitive data in JWT claims

### 2. **Password Security**
- PBKDF2 with 100,000 iterations
- Unique salt per password
- Never store plain text passwords

### 3. **Input Validation**
- FluentValidation for complex validation
- Data annotations for simple validation
- Server-side validation always enforced

### 4. **CORS Configuration**
- Configured for specific domains in production
- AllowAll only in development
- Credentials handled properly

## 🎯 Key Takeaways

1. **Start with Standard Naming**: Use industry-standard property names from the beginning
2. **Plan Authentication Early**: Decide on authentication strategy before implementation
3. **Test Continuously**: Fix test issues as they arise, don't let them accumulate
4. **Document as You Go**: Keep CLAUDE.md updated with decisions and patterns
5. **Consider the Database**: Some features (like decimal ordering) are database-specific
6. **Mock External Dependencies**: Always mock file system, email, etc. in tests
7. **Use DTOs Consistently**: Don't expose entities directly through APIs
8. **Handle Errors Gracefully**: Implement proper error handling at all layers
9. **Security First**: Never have public endpoints if not required
10. **Client SDK Value**: A well-designed client SDK greatly improves API usability

## 🔄 Refactoring Opportunities

### Future Improvements
1. **Caching Layer**: Add Redis for frequently accessed data
2. **Message Queue**: Implement for order processing
3. **Event Sourcing**: For order status changes
4. **API Versioning**: Prepare for future API changes
5. **Health Checks**: Add health check endpoints
6. **Metrics**: Implement application metrics
7. **Rate Limiting**: Add rate limiting to API endpoints
8. **Background Jobs**: Use Hangfire or similar for async processing

## 📝 Development Workflow Tips

1. **Always Check CLAUDE.md**: Project-specific instructions override defaults
2. **Use TodoWrite Tool**: Track multi-step tasks systematically
3. **Build Frequently**: Catch compilation errors early
4. **Commit Logically**: Group related changes in commits
5. **Test After Major Changes**: Run tests after significant refactoring
6. **Document Decisions**: Record why, not just what
7. **Consider Side Effects**: Model changes affect DTOs, services, views, and tests

## 🛠️ Tool-Specific Lessons

### Visual Studio Code / WSL
- Use `cmd.exe /c` wrapper for Windows commands
- File watchers don't always work in WSL
- Hot reload is unreliable with WSL

### Entity Framework Core
- Migrations not always needed for development
- `EnsureCreated()` sufficient for prototyping
- Use migrations for production deployments

### Git in Mixed Environments
- Line ending issues (CRLF vs LF)
- Use `.gitattributes` to standardize
- Commit from consistent environment

## Final Wisdom

**"All endpoints must be authenticated"** - This single decision simplified the entire security model and eliminated a class of vulnerabilities. Sometimes the most restrictive choice is the best choice.

**"Standard names matter"** - Using `Price` instead of `BasePrice` seems trivial, but non-standard names cascade through the entire codebase, tests, and documentation.

**"Test the workflow, not just the code"** - Creating sample data that demonstrates the complete order workflow (pending → paid → shipped → delivered) helps validate the business logic, not just the technical implementation.