# Local Development with Azure Resources

> **Scope:** blazor-azure
> **Layer:** 2
> **Keywords:** local, development, azure, sql, key vault, storage, defaultazurecredential, azure cli
> **Load When:** Local development setup, Azure resource access, development environment

> Como rodar o projeto localmente e acessar recursos Azure do Staging

---

## 📋 Conceito

Developers **não precisam de ambiente próprio**. Ao invés disso:

- ✅ **Rodam o projeto LOCAL** (Visual Studio, Rider, VS Code)
- ✅ **Acessam recursos REMOTOS** do ambiente Staging (SQL, Storage, Key Vault)
- ✅ **Testam localmente** antes de commitar
- ✅ **Criam PRs** para Staging quando pronto

**Vantagens:**
- 💰 **Custo zero** para ambiente dev
- ⚡ **Desenvolvimento mais rápido** (hot reload, debug local)
- 🔄 **Dados compartilhados** (todos testam com mesmos dados)
- 🎯 **Ambiente staging sempre atualizado**

---

## ⚙️ Setup Inicial (Uma vez)

### 1. Instalar Ferramentas

```bash
# .NET SDK
winget install Microsoft.DotNet.SDK.8

# Azure CLI
winget install Microsoft.AzureCLI

# Git
winget install Git.Git

# Visual Studio ou VS Code
winget install Microsoft.VisualStudio.2022.Community
# ou
winget install Microsoft.VisualStudioCode
```

### 2. Login no Azure

```bash
# Login com sua conta corporativa
az login

# Verificar subscription
az account show

# Se necessário, trocar subscription
az account set --subscription "<SUBSCRIPTION_ID>"
```

### 3. Obter Permissões Staging

Solicite ao tech lead para adicionar você ao ambiente staging:

```bash
# Tech lead executa:
az role assignment create \
  --assignee <developer-email> \
  --role "Contributor" \
  --scope "/subscriptions/<SUB_ID>/resourceGroups/rg-myapp-staging"

# Permissão SQL Database
az sql server ad-admin set \
  --resource-group rg-myapp-staging \
  --server-name sql-myapp-staging \
  --display-name "<developer-name>" \
  --object-id <developer-object-id>
```

---

## 🔧 Configuração do Projeto

### 1. Clonar Repositório

```bash
git clone https://dev.azure.com/org/project/_git/repo
cd repo
```

### 2. Criar appsettings.Development.json

```json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=sql-myapp-staging.database.windows.net;Database=myapp;Authentication=Active Directory Default;"
  },
  "Azure": {
    "KeyVault": "https://kv-myapp-staging.vault.azure.net/",
    "Storage": {
      "AccountName": "stmyappstaging",
      "BlobEndpoint": "https://stmyappstaging.blob.core.windows.net"
    }
  },
  "ApplicationInsights": {
    "ConnectionString": "<copiar-do-azure-portal-staging>"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}
```

**⚠️ IMPORTANTE:**
- ❌ **NUNCA commitar** `appsettings.Development.json`
- ✅ Já está no `.gitignore`
- ✅ Cada developer tem seu próprio arquivo local

### 3. Configurar DefaultAzureCredential

No `Program.cs`:

```csharp
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
    var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
    options.UseSqlServer(connectionString, sqlOptions =>
    {
        sqlOptions.EnableRetryOnFailure(
            maxRetryCount: 3,
            maxRetryDelay: TimeSpan.FromSeconds(30),
            errorNumbersToAdd: null);
    });
});

// Azure Key Vault
if (!builder.Environment.IsDevelopment())
{
    var keyVaultUrl = builder.Configuration["Azure:KeyVault"];
    builder.Configuration.AddAzureKeyVault(
        new Uri(keyVaultUrl),
        new DefaultAzureCredential());
}

// Azure Storage
builder.Services.AddSingleton(x =>
{
    var accountName = builder.Configuration["Azure:Storage:AccountName"];
    var blobServiceClient = new BlobServiceClient(
        new Uri($"https://{accountName}.blob.core.windows.net"),
        new DefaultAzureCredential());
    return blobServiceClient;
});
```

**DefaultAzureCredential** tenta autenticar nesta ordem:
1. Environment variables (CI/CD)
2. Managed Identity (Azure)
3. **Azure CLI** (← usado localmente)
4. Visual Studio
5. VS Code

---

## 🚀 Rodando Localmente

### Opção 1: Visual Studio

1. Abrir `.sln`
2. F5 (Debug) ou Ctrl+F5 (Run)
3. Projeto abrirá em `https://localhost:7001`

### Opção 2: Rider

1. Abrir `.sln`
2. Shift+F10 (Run) ou Shift+F9 (Debug)

### Opção 3: VS Code

```bash
# Restaurar dependências
dotnet restore

# Rodar projeto
dotnet run --project src/YourApp/YourApp.csproj

# Ou com watch (hot reload)
dotnet watch --project src/YourApp/YourApp.csproj
```

### Opção 4: CLI direto

```bash
cd src/YourApp
dotnet run
```

---

## 🗄️ Acesso ao Banco de Dados

### Via Azure Data Studio

1. Download: https://aka.ms/azuredatastudio
2. Conectar:
   - **Server**: `sql-myapp-staging.database.windows.net`
   - **Database**: `myapp`
   - **Authentication**: `Azure Active Directory - Universal with MFA`
   - **Account**: Sua conta corporativa

### Via SQL Server Management Studio (SSMS)

1. Download: https://aka.ms/ssmsfullsetup
2. Conectar:
   - **Server**: `sql-myapp-staging.database.windows.net`
   - **Authentication**: `Azure Active Directory - Universal with MFA`
   - **Login**: Sua conta

### Via Entity Framework Migrations

```bash
# Criar migration
dotnet ef migrations add NomeDaMigration

# Aplicar migration no staging (CUIDADO!)
dotnet ef database update

# Reverter migration
dotnet ef database update PreviousMigration
```

⚠️ **ATENÇÃO**: Migrations aplicadas localmente afetam **TODOS** os developers!

**Melhor prática:**
- Criar migration localmente
- Commitar migration
- Deixar pipeline aplicar automaticamente

---

## 📦 Acesso ao Azure Storage

### Via Azure Storage Explorer

1. Download: https://aka.ms/storageexplorer
2. Login com sua conta
3. Navegue até: `stmyappstaging`
4. Pode fazer upload/download de blobs

### Via Código

```csharp
// Upload blob
var blobClient = blobServiceClient
    .GetBlobContainerClient("uploads")
    .GetBlobClient("test.txt");

await blobClient.UploadAsync(
    BinaryData.FromString("Hello from local!"),
    overwrite: true);

// Download blob
var downloadedData = await blobClient.DownloadContentAsync();
Console.WriteLine(downloadedData.Value.Content.ToString());
```

---

## 🔐 Acesso ao Key Vault

### Via Azure CLI

```bash
# Listar secrets
az keyvault secret list \
  --vault-name kv-myapp-staging

# Obter secret
az keyvault secret show \
  --vault-name kv-myapp-staging \
  --name "ConnectionStrings--DefaultConnection"
```

### Via Código

```csharp
// Program.cs já configurou automaticamente
// Acesse via IConfiguration normalmente:

var secret = builder.Configuration["MySecretKey"];
```

---

## 🧪 Testes Locais

### Unit Tests

```bash
# Rodar todos os testes
dotnet test

# Rodar com cobertura
dotnet test --collect:"XPlat Code Coverage"

# Apenas testes de uma classe
dotnet test --filter "FullyQualifiedName~MyTests"
```

### Integration Tests

```bash
# Integration tests usam staging database
dotnet test --filter "Category=Integration"
```

⚠️ **Cuidado**: Integration tests modificam dados staging!

**Melhor prática:**
- Use transações que fazem rollback
- Ou crie/delete dados de teste
- Ou use database separado para testes

---

## 🔄 Workflow Diário

### 1. Começar Nova Feature

```bash
# Atualizar staging
git checkout staging
git pull origin staging

# Criar feature branch
git checkout -b feature/minha-funcionalidade

# Rodar projeto local
dotnet run
```

### 2. Desenvolver

```bash
# Fazer mudanças
# Testar localmente (conecta em staging resources)
# Commitar frequentemente

git add .
git commit -m "feat: adiciona funcionalidade X"
```

### 3. Testar

```bash
# Unit tests
dotnet test

# Teste manual no browser
# http://localhost:5000
```

### 4. Push e PR

```bash
# Push da feature branch
git push origin feature/minha-funcionalidade

# Criar PR para staging no Azure DevOps
# 1. Vá em Repos → Pull Requests → New Pull Request
# 2. Source: feature/minha-funcionalidade
# 3. Target: staging
# 4. Adicionar reviewers
# 5. Create
```

### 5. Code Review e Merge

```
# Reviewer faz code review
# Após aprovação, merge
# Pipeline staging triggará automaticamente
```

### 6. Testar em Staging Deployado

```bash
# Acessar URL staging
https://ca-myapp-staging.<region>.azurecontainerapps.io

# Validar funcionalidade
# Se OK, criar PR staging → main para prod
```

---

## 🆘 Troubleshooting

### Erro: "Login failed for user"

**Causa**: Azure CLI não autenticado ou token expirado.

**Solução**:
```bash
az logout
az login
az account show
```

### Erro: "Cannot connect to SQL Server"

**Causa**: Firewall SQL bloqueando seu IP.

**Solução**:
```bash
# Adicionar seu IP ao firewall
az sql server firewall-rule create \
  --resource-group rg-myapp-staging \
  --server sql-myapp-staging \
  --name "DevIP-$(whoami)" \
  --start-ip-address <SEU_IP> \
  --end-ip-address <SEU_IP>

# Obter seu IP público
curl https://api.ipify.org
```

### Erro: "Access denied to Key Vault"

**Causa**: Sem permissão no Key Vault.

**Solução** (Tech lead):
```bash
az keyvault set-policy \
  --name kv-myapp-staging \
  --upn <developer-email> \
  --secret-permissions get list
```

### Erro: "Blob not found"

**Causa**: Container não existe ou sem permissão.

**Solução** (Tech lead):
```bash
# Dar permissão Storage Blob Data Contributor
az role assignment create \
  --assignee <developer-email> \
  --role "Storage Blob Data Contributor" \
  --scope "/subscriptions/<SUB_ID>/resourceGroups/rg-myapp-staging/providers/Microsoft.Storage/storageAccounts/stmyappstaging"
```

### Erro: "DefaultAzureCredential failed"

**Causa**: Nenhum método de autenticação funcionou.

**Solução**:
1. Feche Visual Studio/Rider/VS Code
2. `az logout && az login`
3. Reabra IDE
4. Rode novamente

### Migration falhou

**Causa**: Conflito com migration de outro developer.

**Solução**:
```bash
# Pull latest
git pull origin staging

# Deletar sua migration
dotnet ef migrations remove

# Aplicar migrations remotas
dotnet ef database update

# Recriar sua migration
dotnet ef migrations add SuaMigration
```

---

## ✅ Checklist de Setup

Para novos developers:

- [ ] Instalar .NET SDK 8
- [ ] Instalar Azure CLI
- [ ] Instalar Git
- [ ] Instalar IDE (VS/Rider/VS Code)
- [ ] `az login` com conta corporativa
- [ ] Solicitar permissões staging (tech lead)
- [ ] Clonar repositório
- [ ] Criar `appsettings.Development.json`
- [ ] Testar conexão SQL (Azure Data Studio)
- [ ] Rodar projeto local (`dotnet run`)
- [ ] Acessar `https://localhost:7001`
- [ ] Rodar testes (`dotnet test`)
- [ ] Criar feature branch de teste
- [ ] Fazer commit de teste
- [ ] Criar PR de teste
- [ ] Deletar PR/branch de teste

---

## 📚 Referências

- [DefaultAzureCredential](https://learn.microsoft.com/dotnet/api/azure.identity.defaultazurecredential)
- [Azure SQL with Azure AD](https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure)
- [Azure Storage SDK](https://learn.microsoft.com/azure/storage/blobs/storage-quickstart-blobs-dotnet)
- [Entity Framework Migrations](https://learn.microsoft.com/ef/core/managing-schemas/migrations/)

---

*MORPH-SPEC by Polymorphism Tech*
