# Deployment Configuration Guide

This guide explains how to configure the Powder Coating App for different environments (Development, Staging, Production).

## Overview

The application uses environment-specific configuration files and supports multiple secure configuration methods:

- **Development**: `appsettings.Development.json` (included in repo)
- **Production**: Environment variables, User Secrets, or Azure Key Vault

## Configuration Files

### Development Environment

**File**: `src/PowderCoating.Web/appsettings.Development.json`
- Contains actual development values
- Safe to commit to source control (dev-only credentials)
- Used automatically when `ASPNETCORE_ENVIRONMENT=Development`

**File**: `src/PowderCoating.Api/appsettings.Development.json`
- API-specific development settings
- Contains dev JWT secret and CORS origins

### Production Environment

**File**: `src/PowderCoating.Web/appsettings.json`
- Contains placeholders only (`USE_USER_SECRETS_OR_ENVIRONMENT_VARIABLE`)
- NEVER contains actual secrets
- Safe to commit to source control

**File**: `src/PowderCoating.Api/appsettings.json`
- Same approach - placeholders only
- Production secrets configured via environment variables or Key Vault

---

## Required Configuration Values

### 1. Database Connection String

**Development**:
```json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=.\\SQLEXPRESS;Database=PowderCoatingDb;Trusted_Connection=true;MultipleActiveResultSets=true;TrustServerCertificate=true"
  }
}
```

**Production** (Windows Server with SQL Server):
```bash
# Environment Variable
set ConnectionStrings__DefaultConnection="Server=PROD_SERVER;Database=PowderCoatingDb;User Id=app_user;Password=SecurePassword123!;MultipleActiveResultSets=true;Encrypt=true"
```

**Production** (Linux/Docker):
```bash
export ConnectionStrings__DefaultConnection="Server=PROD_SERVER;Database=PowderCoatingDb;User Id=app_user;Password=SecurePassword123!;MultipleActiveResultSets=true;Encrypt=true"
```

**Production** (Azure Web App):
- Navigate to: Configuration > Connection strings
- Name: `DefaultConnection`
- Value: Your production connection string
- Type: `SQLServer`

---

### 2. JWT Settings (API Only)

**Development**:
```json
{
  "JwtSettings": {
    "SecretKey": "DEV-ONLY-SecretKey-MinimumLength32CharactersRequired!@#$",
    "Issuer": "PowderCoatingAPI",
    "Audience": "PowderCoatingMobileApp",
    "ExpirationMinutes": 15,
    "RefreshTokenExpirationDays": 7
  }
}
```

**Production**:

Generate a strong secret key (minimum 32 characters):
```powershell
# PowerShell - Generate random secret
-join ((48..57) + (65..90) + (97..122) | Get-Random -Count 64 | ForEach-Object {[char]$_})
```

```bash
# Linux - Generate random secret
openssl rand -base64 64
```

Set as environment variable:
```bash
# Windows
set JwtSettings__SecretKey="YOUR_GENERATED_SECRET_HERE"

# Linux
export JwtSettings__SecretKey="YOUR_GENERATED_SECRET_HERE"

# Azure Web App - Application Settings
JwtSettings__SecretKey = YOUR_GENERATED_SECRET_HERE
```

---

### 3. CORS Origins (API Only)

**Development**:
```json
{
  "CorsSettings": {
    "AllowedOrigins": [
      "http://localhost:3000",
      "http://localhost:5173",
      "http://localhost:58461",
      "https://localhost:58461"
    ]
  }
}
```

**Production**:
```json
{
  "CorsSettings": {
    "AllowedOrigins": [
      "https://yourapp.com",
      "https://www.yourapp.com",
      "https://app.yourdomain.com"
    ]
  }
}
```

⚠️ **NEVER use `*` (wildcard) in production!**

---

### 4. Allowed Hosts

**Development**:
```json
{
  "AllowedHosts": "localhost;127.0.0.1"
}
```

**Production**:
```json
{
  "AllowedHosts": "yourapp.com;www.yourapp.com;app.yourdomain.com"
}
```

---

### 5. Logging Configuration

**Development** (detailed logging):
```json
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft.AspNetCore": "Information",
      "Microsoft.EntityFrameworkCore": "Information"
    }
  }
}
```

**Production** (reduced logging):
```json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.EntityFrameworkCore": "Warning"
    }
  }
}
```

---

## Security Checklist

### ✅ Development Environment

- [x] Use `appsettings.Development.json` for local development
- [x] Development secrets can be simple (e.g., "Dev123!")
- [x] CORS can allow `localhost` origins
- [x] Detailed logging enabled for debugging
- [x] Database uses Trusted Connection (Windows Auth) or simple password

### ✅ Production Environment

- [ ] **CRITICAL**: Never use development secrets in production
- [ ] **CRITICAL**: Use strong, randomly generated secrets (64+ characters)
- [ ] **CRITICAL**: Store secrets in environment variables, User Secrets, or Azure Key Vault
- [ ] **CRITICAL**: Enable HTTPS with valid SSL certificate
- [ ] **CRITICAL**: Configure CORS with specific allowed origins (NO wildcards)
- [ ] Configure AllowedHosts with actual production domain(s)
- [ ] Use encrypted database connection with strong password
- [ ] Reduce logging verbosity (Warning/Error only)
- [ ] Set `ASPNETCORE_ENVIRONMENT=Production`
- [ ] Enable HSTS (Strict-Transport-Security headers)
- [ ] Configure rate limiting and DDoS protection
- [ ] Set up monitoring and alerting
- [ ] Regular security patches and updates

---

## Configuration Methods by Environment

### Method 1: Environment Variables (Recommended for Production)

**Advantages**:
- Secure (not stored in files)
- Easy to manage in cloud platforms
- Platform-agnostic

**Windows**:
```powershell
# Set for current session
$env:ConnectionStrings__DefaultConnection="Server=...;Database=...;User Id=...;Password=..."
$env:JwtSettings__SecretKey="YourSecretKey"

# Set permanently (System-wide)
[Environment]::SetEnvironmentVariable("ConnectionStrings__DefaultConnection", "Server=...;", "Machine")
```

**Linux**:
```bash
# Add to ~/.bashrc or /etc/environment
export ConnectionStrings__DefaultConnection="Server=...;Database=...;User Id=...;Password=..."
export JwtSettings__SecretKey="YourSecretKey"
```

**Docker**:
```yaml
# docker-compose.yml
services:
  powdercoating-web:
    environment:
      - ConnectionStrings__DefaultConnection=Server=db;Database=PowderCoatingDb;User Id=sa;Password=YourPassword
      - ASPNETCORE_ENVIRONMENT=Production
```

---

### Method 2: User Secrets (Development Only)

**Setup**:
```bash
cd src/PowderCoating.Web
dotnet user-secrets init
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=...;Database=...;"
dotnet user-secrets set "JwtSettings:SecretKey" "YourSecretKey"
```

**View secrets**:
```bash
dotnet user-secrets list
```

⚠️ **User Secrets are for development only** - they are stored locally on your machine and won't deploy to production.

---

### Method 3: Azure Key Vault (Production)

**Setup**:
1. Create Azure Key Vault
2. Add secrets to Key Vault:
   - `ConnectionStrings--DefaultConnection`
   - `JwtSettings--SecretKey`
3. Grant App Service Managed Identity access to Key Vault

**Code** (add to `Program.cs`):
```csharp
if (builder.Environment.IsProduction())
{
    var keyVaultUri = new Uri($"https://{builder.Configuration["KeyVaultName"]}.vault.azure.net/");
    builder.Configuration.AddAzureKeyVault(keyVaultUri, new DefaultAzureCredential());
}
```

---

## Deployment Steps

### Local Development

1. Clone repository
2. Ensure `ASPNETCORE_ENVIRONMENT=Development`
3. Verify `appsettings.Development.json` has correct local SQL Server connection
4. Run migrations:
   ```bash
   cd src/PowderCoating.Web
   dotnet ef database update --project ../PowderCoating.Infrastructure
   ```
5. Run application:
   ```bash
   dotnet run
   ```

---

### Production Deployment (Windows Server/IIS)

1. **Publish Application**:
   ```bash
   cd src/PowderCoating.Web
   dotnet publish -c Release -o C:\Publish\PowderCoatingApp
   ```

2. **Configure Environment Variables** (IIS):
   - Open IIS Manager
   - Select Application Pool > Advanced Settings
   - Under Environment Variables, add:
     - `ASPNETCORE_ENVIRONMENT = Production`
     - `ConnectionStrings__DefaultConnection = <your connection string>`

3. **Install SQL Server Database**:
   ```bash
   # Run migrations on production database
   dotnet ef database update --project ../PowderCoating.Infrastructure --configuration Release
   ```

4. **Configure IIS**:
   - Enable HTTPS binding with valid SSL certificate
   - Set Application Pool to "No Managed Code"
   - Install ASP.NET Core Hosting Bundle

5. **Security Hardening**:
   - Disable directory browsing
   - Remove unnecessary HTTP headers
   - Configure IP restrictions if needed
   - Enable request filtering

---

### Production Deployment (Azure App Service)

1. **Create Azure Resources**:
   - Azure SQL Database
   - Azure App Service (Windows or Linux)
   - Azure Key Vault (optional, but recommended)

2. **Configure App Service**:
   - **Configuration > General Settings**:
     - Stack: .NET 8
     - Platform: 64-bit
     - HTTPS Only: On

   - **Configuration > Application Settings**:
     ```
     ASPNETCORE_ENVIRONMENT = Production
     JwtSettings__SecretKey = <your secret>
     JwtSettings__ExpirationMinutes = 15
     CorsSettings__AllowedOrigins__0 = https://yourapp.com
     AllowedHosts = yourapp.com;www.yourapp.com
     ```

   - **Configuration > Connection Strings**:
     ```
     Name: DefaultConnection
     Value: Server=tcp:yourserver.database.windows.net,1433;Database=PowderCoatingDb;User ID=sqladmin;Password=...;Encrypt=True;
     Type: SQLServer
     ```

3. **Deploy Code**:
   ```bash
   # Via Azure CLI
   az webapp deployment source config-zip --resource-group YourRG --name YourAppName --src publish.zip
   ```

4. **Run Database Migrations**:
   - Option 1: Use Azure Cloud Shell or local machine with connection to Azure SQL
   - Option 2: Enable migrations on startup (NOT recommended for production)

---

## Password Requirements

**Development**: Minimum 8 characters

**Production** (enforced by application):
- Minimum 12 characters
- At least 1 uppercase letter
- At least 1 lowercase letter
- At least 1 digit
- At least 1 special character (!@#$%^&*)
- At least 4 unique characters
- Account lockout after 5 failed attempts (15-minute lockout)

---

## Security Headers (Automatically Applied)

The application automatically adds these security headers in production:

- `X-Frame-Options: DENY` - Prevent clickjacking
- `X-Content-Type-Options: nosniff` - Prevent MIME sniffing
- `X-XSS-Protection: 1; mode=block` - XSS protection
- `Strict-Transport-Security: max-age=31536000; includeSubDomains` - Force HTTPS
- `Content-Security-Policy` - Restrict resource loading
- `Referrer-Policy: strict-origin-when-cross-origin` - Control referrer info
- `Permissions-Policy` - Disable unnecessary browser features

---

## Troubleshooting

### Issue: "Connection string not found"

**Solution**: Ensure environment variable is set with double underscores (`__`):
```bash
ConnectionStrings__DefaultConnection  # Correct
ConnectionStrings:DefaultConnection   # Wrong (this is for User Secrets only)
```

### Issue: "JWT secret key is too short"

**Solution**: Generate a new secret with minimum 32 characters (64+ recommended)

### Issue: "CORS policy blocked"

**Solution**: Add your frontend domain to `CorsSettings:AllowedOrigins` array

### Issue: "Cookies not working"

**Solution**:
- Ensure HTTPS is enabled in production
- Check that `CookieSecurePolicy.Always` is compatible with your hosting
- For development over HTTP, set `SecurePolicy = CookieSecurePolicy.SameAsRequest`

---

## Monitoring and Logs

**Development**:
- Console output
- Files in `/logs/` directory
  - `powdercoating-{date}.txt` - All logs
  - `errors-{date}.txt` - Errors only

**Production**:
- Configure Azure Application Insights (recommended)
- Or use Serilog sinks (Seq, Elasticsearch, etc.)
- Set up alerts for errors and performance issues

---

## Summary

| Configuration | Development | Production |
|---------------|-------------|------------|
| **Secrets** | appsettings.Development.json | Environment Variables / Key Vault |
| **HTTPS** | Optional | **Required** |
| **CORS** | localhost:* | Specific domains only |
| **Logging** | Debug/Information | Warning/Error |
| **AllowedHosts** | localhost;127.0.0.1 | yourdomain.com |
| **JWT Expiration** | 15 minutes | 15 minutes |
| **Password Policy** | Strong (12 chars) | Strong (12 chars) |
| **Session Cookies** | Secure, HttpOnly, SameSite=Strict | Same + SecurePolicy=Always |

---

## Questions?

If you encounter any issues with deployment or configuration, check:
1. This guide
2. Application logs (Diagnostics > View Logs in the app)
3. Environment-specific appsettings files
4. Environment variables are correctly set

**Security Tip**: Regularly rotate secrets (JWT keys, database passwords) every 90 days in production.
