Subscription expiry (SubscriptionExpiryBackgroundService): - Trials with no grace period now go directly Active -> Expired instead of briefly entering GracePeriod for a day, which was causing repeated 'Grace Period Started' admin notification emails - Remove redundant isTrial variable (query already filters to non-Stripe companies, so all processed companies are trials by definition) - Save per-company inside the loop so a single SaveChangesAsync failure no longer discards all other companies' status changes and notification log entries (which was the other cause of repeated emails) HTML entities in page titles (33 views): - Replace – / — with plain ' - ' in ViewData["Title"] C# strings; Razor HTML-encodes these when rendering @ViewData["Title"], causing browsers to display the literal text '–' instead of a dash Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Powder Coating Management System
A comprehensive ASP.NET Core MVC application for managing powder coating operations, including customer management, job tracking, quoting, inventory, equipment maintenance, and shop floor display.
🎯 Features
Core Modules
- Customer Management - Track customer information, pricing tiers, and contact history
- Job Management - Complete job lifecycle from creation to completion
- Quoting System - AI-powered quote generation for commercial and non-commercial jobs
- Inventory Management - Powder coating materials, supplies, and reorder alerts
- Equipment & Maintenance - Equipment tracking and maintenance scheduling
- Shop Floor Display - Real-time job board for production floor (SignalR)
- Multi-User Support - Role-based access with customizable user preferences
Technical Features
- Clean Architecture with separation of concerns
- ASP.NET Core MVC 8.0 with Identity
- Entity Framework Core with SQL Server
- RESTful API for mobile applications
- JWT authentication for API
- Real-time updates with SignalR
- AI integration ready (ML.NET, Semantic Kernel, OpenAI)
- Comprehensive logging with Serilog
- Unit and Integration testing
📋 Prerequisites
- .NET 10.0 SDK or later
- SQL Server 2019 or later (or SQL Server Express/LocalDB)
- Visual Studio 2022 (version 17.12 or later) or VS Code
- Node.js (optional, for frontend tooling)
🚀 Getting Started
1. Clone the Repository
git clone <repository-url>
cd PowderCoatingApp
2. Update Database Connection String
Update the connection string in both:
src/PowderCoating.Web/appsettings.jsonsrc/PowderCoating.Api/appsettings.json
"ConnectionStrings": {
"DefaultConnection": "Server=YOUR_SERVER;Database=PowderCoatingDb;Trusted_Connection=true;MultipleActiveResultSets=true"
}
For Azure SQL or SQL Server Authentication:
"DefaultConnection": "Server=YOUR_SERVER;Database=PowderCoatingDb;User Id=YOUR_USER;Password=YOUR_PASSWORD;MultipleActiveResultSets=true;TrustServerCertificate=true"
3. Apply Database Migrations
From the solution root directory:
# Set the startup project
cd src/PowderCoating.Web
# Add initial migration (if needed)
dotnet ef migrations add InitialCreate --project ../PowderCoating.Infrastructure --startup-project .
# Update database
dotnet ef database update --project ../PowderCoating.Infrastructure --startup-project .
4. Run the Applications
Web Application (MVC)
cd src/PowderCoating.Web
dotnet run
Navigate to: https://localhost:7001 (or the port shown in console)
Default admin login:
- Email:
admin@powdercoating.com - Password:
Admin123!
API (for Mobile)
cd src/PowderCoating.Api
dotnet run
Navigate to: https://localhost:7002 (API documentation via Swagger)
5. Configure AI Features (Optional)
To enable AI-powered quoting features:
- Get an OpenAI API key from https://platform.openai.com
- Update
appsettings.json:
"AI": {
"OpenAI": {
"ApiKey": "your-api-key-here",
"Model": "gpt-4",
"Endpoint": "https://api.openai.com/v1"
}
}
📁 Project Structure
PowderCoatingApp/
├── src/
│ ├── PowderCoating.Core/ # Domain entities, enums, interfaces
│ ├── PowderCoating.Application/ # Business logic, DTOs, services
│ ├── PowderCoating.Infrastructure/ # Data access, repositories, DbContext
│ ├── PowderCoating.Web/ # MVC web application
│ ├── PowderCoating.Api/ # RESTful API for mobile
│ └── PowderCoating.Shared/ # Shared constants and utilities
├── tests/
│ ├── PowderCoating.UnitTests/
│ └── PowderCoating.IntegrationTests/
└── docs/
🏗️ Architecture
The application follows Clean Architecture principles:
- Domain Layer (Core): Contains enterprise business rules and entities
- Application Layer: Contains application business rules and use cases
- Infrastructure Layer: Contains data access and external service implementations
- Presentation Layer: Web (MVC) and API projects
Key Design Patterns
- Repository Pattern
- Unit of Work Pattern
- Dependency Injection
- Options Pattern for Configuration
- CQRS-lite (separate read/write operations where beneficial)
🔐 Security
- ASP.NET Core Identity for authentication
- JWT tokens for API authentication
- Role-based authorization
- Claims-based authorization for fine-grained permissions
- Password requirements enforced
- HTTPS enforced in production
Default Roles
- Administrator: Full system access
- Manager: Manage operations, approve quotes
- Employee: Create jobs, quotes, update inventory
- ShopFloor: View and update job status
- ReadOnly: View-only access
📱 Mobile API
The API provides endpoints for:
- Authentication (login, register, refresh token)
- Jobs (CRUD, status updates)
- Customers (CRUD)
- Inventory (view, transactions)
- Shop floor display data
API Documentation
When running the API, access Swagger documentation at the root URL (e.g., https://localhost:7002)
Sample API Request
# Login
curl -X POST https://localhost:7002/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "admin@powdercoating.com",
"password": "Admin123!"
}'
# Get Jobs (with token)
curl -X GET https://localhost:7002/api/jobs \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
🎨 Customization
User Preferences
Each user can customize:
- Theme (light/dark)
- Date format
- Time zone
- Dashboard layout
- Feature visibility
Application Settings
Configure in appsettings.json:
- Company information
- Default quote validity
- Payment terms
- Tax rates
- Labor rates
- AI settings
🧪 Testing
Run unit tests:
dotnet test tests/PowderCoating.UnitTests
Run integration tests:
dotnet test tests/PowderCoating.IntegrationTests
Run all tests:
dotnet test
📊 Database Schema
Key tables:
- Customers: Customer information and settings
- Jobs: Job tracking and management
- JobItems: Individual items within jobs
- Quotes: Quote generation and tracking
- QuoteItems: Line items in quotes
- InventoryItems: Material and supply inventory
- Equipment: Equipment tracking
- MaintenanceRecords: Maintenance history
- AspNetUsers: User accounts and preferences
🔄 Shop Floor Display
The shop floor display provides real-time job status updates using SignalR:
- Navigate to
/ShopFloor/Display - Jobs are automatically updated as status changes
- Color-coded by priority
- Filterable by status
🤖 AI Features
The system includes hooks for:
- ML.NET: Price prediction based on historical data
- Semantic Kernel: AI orchestration for complex workflows
- OpenAI Integration: Intelligent quoting suggestions and job complexity analysis
📈 Future Enhancements
Planned features:
- Barcode/QR code generation for job tracking
- Email notifications for quote approvals
- Mobile apps (iOS/Android)
- Advanced reporting and analytics
- Customer portal
- Photo upload for jobs
- Time tracking integration
- Integration with accounting systems
- Advanced AI pricing optimization
🐛 Troubleshooting
Database Connection Issues
- Verify SQL Server is running
- Check connection string format
- Ensure database exists or migrations have been applied
- Check firewall settings
Migration Issues
# Reset database (WARNING: deletes all data)
dotnet ef database drop --project src/PowderCoating.Infrastructure --startup-project src/PowderCoating.Web
dotnet ef database update --project src/PowderCoating.Infrastructure --startup-project src/PowderCoating.Web
Port Conflicts
Update ports in launchSettings.json files if default ports are in use.
📝 License
[Your License Here]
👥 Contributing
[Your contribution guidelines]
📧 Support
For support and questions: [Your contact information]
Built with ❤️ using ASP.NET Core 10.0