# QuantEngine - Testing & Deployment Guide **Status**: Phase 6 (Testing) & Phase 8 (Deployment) - Configuration & Documentation --- ## Phase 6: Testing & Optimization ### 6.1 Unit Testing (bUnit) #### Setup ```bash cd src/dotnet dotnet add package bunit dotnet add package bunit.web ``` #### Example Test: Dashboard Component ```csharp // Tests/Pages/DashboardTests.cs [TestFixture] public class DashboardTests { [Test] public void Dashboard_Renders_KPICards() { // Arrange var cut = new TestContext().RenderComponent(); // Act & Assert var kpiCards = cut.FindAll(".mud-card-kpi"); kpiCards.Count.Should().Be(4); } [Test] public async Task Dashboard_LoadsAssets_OnInitialize() { // Arrange var httpClient = new HttpClientStub(); var cut = new TestContext(); cut.Services.AddScoped(sp => httpClient); var dashboard = cut.RenderComponent(); // Act await Task.Delay(100); // Wait for async init // Assert httpClient.Requests.Should().Contain(r => r.Url.Contains("/api/portfolio")); } } ``` #### Test Coverage Targets - Dashboard rendering (4 KPI cards) - Users list (search, filter, pagination) - Portfolio components (asset table, categories) - Form fields (all input types) - Dialogs (confirm/cancel actions) #### Run Tests ```bash dotnet test src/dotnet/QuantEngine.Web.Client.Tests dotnet test src/dotnet/QuantEngine.Web.Tests ``` ### 6.2 Integration Tests #### Database Test Setup ```csharp [TestFixture] public class RepositoryIntegrationTests { private IDbConnectionFactory _connectionFactory; private ICollectionRepository _repository; [OneTimeSetUp] public void OneTimeSetUp() { _connectionFactory = new DbConnectionFactory( "Host=localhost;Database=quantengine_test;..." ); } [Test] public async Task SaveCollectionRun_Persists_ToDatabase() { // Arrange var run = new CollectionRun { RunId = Guid.NewGuid().ToString(), ... }; // Act await _repository.SaveRunAsync(run); // Assert var retrieved = await _repository.GetRunAsync(run.RunId); retrieved.Should().NotBeNull(); retrieved.RunId.Should().Be(run.RunId); } } ``` ### 6.3 Performance Optimization #### Bundle Size Optimization ```bash # Check bundle sizes dotnet publish -c Release --output ./publish du -sh publish/wwwroot/_framework/* ``` **Targets**: - dotnet.wasm: < 2MB - app.js: < 500KB - Total: < 5MB #### Loading Time Optimization ```csharp // Use lazy loading for pages [lazy: Dashboard] @rendermode InteractiveWebAssembly // Pre-load critical resources ``` ### 6.4 Accessibility Testing (WCAG 2.1 AA) #### Automated Checks ```bash dotnet add package Deque.AxeCore.Selenium ``` #### Manual Checklist - [ ] Keyboard navigation (Tab, Enter, Escape) - [ ] Screen reader support (NVDA, JAWS) - [ ] Color contrast (4.5:1 for text) - [ ] Form labels properly associated - [ ] Error messages clear and descriptive - [ ] Focus indicators visible - [ ] No automatic content changes --- ## Phase 8: Deployment & Operations ### 8.1 Production Build #### Release Build Configuration ```bash # Build Release configuration cd src/dotnet dotnet build -c Release # Publish for deployment dotnet publish -c Release -o ./publish/quantengine # Size check ls -lh publish/quantengine/ ``` #### Build Output - `publish/quantengine/` - Complete deployment package - `publish/quantengine/wwwroot/` - Static assets - `publish/quantengine/QuantEngine.Web.exe` - Server executable - `publish/quantengine/appsettings.production.json` - Configuration ### 8.2 Docker Deployment #### Dockerfile ```dockerfile FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base WORKDIR /app EXPOSE 80 443 FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build WORKDIR /src COPY ["src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj", "QuantEngine.Web/"] RUN dotnet restore "QuantEngine.Web/QuantEngine.Web.csproj" COPY src/dotnet/ . RUN dotnet build "QuantEngine.Web/QuantEngine.Web.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "QuantEngine.Web/QuantEngine.Web.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "QuantEngine.Web.dll"] ``` #### Docker Build & Run ```bash # Build image docker build -t quantengine:latest . # Run container docker run -d \ -p 5265:80 \ -e ConnectionStrings__DefaultConnection="Host=db;Database=quantenginedb;..." \ -e ASPNETCORE_ENVIRONMENT=Production \ quantengine:latest # Check logs docker logs -f ``` ### 8.3 Nginx Reverse Proxy #### Nginx Configuration ```nginx upstream quantengine { server 127.0.0.1:5000; server 127.0.0.1:5001; } server { listen 80; server_name quantengine.example.com; # Redirect to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name quantengine.example.com; ssl_certificate /etc/ssl/certs/cert.pem; ssl_certificate_key /etc/ssl/private/key.pem; location / { proxy_pass http://quantengine; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location ~* \.(js|css|wasm|svg|woff2)$ { expires 30d; add_header Cache-Control "public, immutable"; } } ``` ### 8.4 Environment Configuration #### appsettings.production.json ```json { "Logging": { "LogLevel": { "Default": "Information", "System": "Warning", "Microsoft": "Warning" } }, "ConnectionStrings": { "DefaultConnection": "Host=prod-db-host;Database=quantenginedb;Username=quantengine_app;Password=***;SslMode=Require;", "HangfireConnection": "Host=prod-db-host;Database=quantengine_hangfire;..." }, "AdminSettings": { "Username": "admin", "Password": "***" }, "Kestrel": { "Endpoints": { "Http": { "Url": "http://0.0.0.0:5000" } } } } ``` ### 8.5 Deployment Checklist #### Pre-Deployment - [ ] All tests pass (`dotnet test`) - [ ] Code reviewed and approved - [ ] Security vulnerabilities scanned (`dotnet package-search`) - [ ] Database migrations tested - [ ] Hangfire schedules configured - [ ] Secrets properly managed (not in code) - [ ] Environment variables documented #### Deployment Steps ```bash # 1. Create backup pg_dump -h prod-db-host -U quantengine_app quantenginedb > backup-$(date +%Y%m%d).sql # 2. Deploy application docker pull quantengine:latest docker stop quantengine docker run -d --name quantengine -p 5000:80 quantengine:latest # 3. Health check curl https://quantengine.example.com/health # 4. Monitor logs docker logs -f quantengine # 5. Verify features - [ ] Login works - [ ] Dashboard loads - [ ] Data collection runs - [ ] Hangfire jobs scheduled ``` #### Post-Deployment - [ ] Monitor error logs (Serilog, Telegram alerts) - [ ] Check Hangfire dashboard - [ ] Verify scheduled jobs running - [ ] Monitor database performance - [ ] Check API response times (< 200ms) ### 8.6 Monitoring & Observability #### Health Checks ```csharp app.MapHealthChecks("/health", new HealthCheckOptions { Predicate = _ => true, ResponseWriter = WriteResponse }); // Add health checks builder.Services.AddHealthChecks() .AddDbContextCheck() .AddCheck("Database", () => HealthCheckResult.Healthy()) .AddCheck("KIS API", () => CheckKisApiAsync()); ``` #### Logging (Serilog) ```csharp Log.Information("Collection run completed: {RunId}, {Count} items", runId, itemCount); Log.Warning("API rate limit warning: {Remaining}", remaining); Log.Error(ex, "Collection failed: {RunId}", runId); ``` #### Monitoring Metrics - Request rate (requests/sec) - Error rate (errors/requests) - Database query time (p50, p95, p99) - Hangfire job success rate - API response time by endpoint ### 8.7 Rollback Plan #### If Deployment Fails ```bash # 1. Stop current deployment docker stop quantengine # 2. Restore previous version docker run -d --name quantengine -p 5000:80 quantengine:v1.0.0 # 3. Restore database from backup psql -h prod-db-host -U quantengine_app -d quantenginedb < backup-20260705.sql # 4. Verify health curl https://quantengine.example.com/health ``` --- ## Deployment Timeline | Milestone | Target Date | Status | |-----------|-------------|--------| | Phase 6: Tests | 2026-07-06 | 📋 | | Phase 7: Hangfire | 2026-07-05 | ✅ | | Phase 8: Deploy | 2026-07-07 | 📋 | | Production Release | 2026-07-10 | 📅 | --- ## Success Criteria **Phase 6**: - [ ] 80%+ test coverage - [ ] All component tests passing - [ ] WCAG AA compliance verified - [ ] Bundle size < 5MB **Phase 8**: - [ ] Docker image builds successfully - [ ] Production config validated - [ ] Database backups automated - [ ] Rollback plan documented - [ ] Monitoring alerts configured - [ ] 99.5% uptime target established --- **Next**: Execute deployment pipeline and monitor production metrics.