# EasyPanel API - Service Configuration

**Verificado:** 12-03-2026 (engenharia reversa do backend.js)

---

## Actualizar Source (GitHub)

```bash
curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateSourceGithub" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"descomplicar",
    "serviceName":"minha-api",
    "owner":"ealmeida",
    "repo":"MeuRepo",
    "ref":"main",
    "path":"/"
  }}'
```

## Actualizar Source (Git Custom)

**IMPORTANTE:** Os parametros `repo`, `ref`, `path` devem estar no nivel RAIZ do JSON, NAO dentro de um objecto `source`.

```bash
curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateSourceGit" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"descomplicar",
    "serviceName":"minha-api",
    "repo":"https://ealmeida:TOKEN@git.descomplicar.pt/ealmeida/repo",
    "ref":"main",
    "path":"/"
  }}'
```

**Errado (causa zodErrors):**
```json
{"json":{"projectName":"x","serviceName":"y","source":{"type":"git","repo":"...","ref":"main","path":"/"}}}
```

**Correcto:**
```json
{"json":{"projectName":"x","serviceName":"y","repo":"...","ref":"main","path":"/"}}
```

## Actualizar Source (Docker Image)

```bash
curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateSourceImage" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"descomplicar",
    "serviceName":"minha-api",
    "image":"node:22-alpine"
  }}'
```

## Actualizar Environment Variables

```bash
curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateEnv" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"descomplicar",
    "serviceName":"minha-api",
    "env":"NODE_ENV=production\nPORT=3000\nDATABASE_URL=postgres://..."
  }}'
```

## Actualizar Build Config

```bash
curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateBuild" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"descomplicar",
    "serviceName":"minha-api",
    "build":{
      "type":"nixpacks",
      "buildCommand":"npm run build",
      "startCommand":"npm start"
    }
  }}'
```

## Actualizar Resources

```bash
curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateResources" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"descomplicar",
    "serviceName":"minha-api",
    "resources":{
      "memoryLimit":"512m",
      "memoryReservation":"256m",
      "cpuLimit":1,
      "cpuReservation":0.5
    }
  }}'
```

## Actualizar Deploy (Replicas, Command)

```bash
curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateAdvanced" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"descomplicar",
    "serviceName":"minha-api",
    "deploy":{
      "replicas":2,
      "command":"node dist/index.js",
      "zeroDowntime":true
    }
  }}'
```

## Actualizar Redirects

```bash
curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateRedirects" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"descomplicar",
    "serviceName":"minha-api",
    "redirects":[]
  }}'
```

## Actualizar Basic Auth

```bash
curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateBasicAuth" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"descomplicar",
    "serviceName":"minha-api",
    "basicAuth":{"enabled":false}
  }}'
```

## Actualizar Maintenance Mode

```bash
curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateMaintenance" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"descomplicar",
    "serviceName":"minha-api",
    "maintenance":{"enabled":false}
  }}'
```

## Database Backup Config

```bash
curl -s -X POST "http://localhost:3000/api/trpc/services.postgres.updateBackup" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"descomplicar",
    "serviceName":"minha-db",
    "backup":{
      "enabled":true,
      "schedule":"0 3 * * *",
      "destination":{
        "type":"s3",
        "bucket":"backups",
        "region":"eu-west-1",
        "accessKey":"...",
        "secretKey":"..."
      }
    }
  }}'
```

---

## Domains API (Namespace separado)

**IMPORTANTE:** Os dominios NAO sao geridos por `services.app.*` mas sim pelo namespace `domains.*`.

### Listar Dominios (GET)

```bash
INPUT='{"json":{"projectName":"descomplicar"}}'
ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$INPUT'))")
curl -s "http://localhost:3000/api/trpc/domains.listDomains?input=$ENCODED" \
  -H "Authorization: Bearer $TOKEN"
```

### Criar Dominio (POST)

```bash
curl -s -X POST "http://localhost:3000/api/trpc/domains.createDomain" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "id":"meu-dominio-id",
    "https":true,
    "host":"app.descomplicar.pt",
    "path":"/",
    "middlewares":[],
    "certificateResolver":"letsencrypt",
    "wildcard":false,
    "destinationType":"service",
    "serviceDestination":{
      "protocol":"http",
      "port":3000,
      "path":"/",
      "projectName":"descomplicar",
      "serviceName":"meu-servico"
    }
  }}'
```

**Notas:**
- O `id` pode ser qualquer string unica (cuid ou slug)
- `certificateResolver`: `"letsencrypt"` para HTTPS, `""` para dominios internos
- `destinationType`: `"service"` para servicos EasyPanel, `"custom"` para destinos externos

### Actualizar Dominio (POST)

```bash
curl -s -X POST "http://localhost:3000/api/trpc/domains.updateDomain" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{...mesmo schema de createDomain...}}'
```

### Remover Dominio (POST)

```bash
curl -s -X POST "http://localhost:3000/api/trpc/domains.deleteDomain" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{"id":"meu-dominio-id"}}'
```

---

## Resumo de Endpoints de Configuracao

| Endpoint | Tipo | Descricao | Verificado |
|----------|------|-----------|:----------:|
| `services.app.updateSourceGithub` | POST | Source GitHub (`owner`,`repo`,`ref`,`path`) | Sim |
| `services.app.updateSourceGit` | POST | Source Git custom (`repo`,`ref`,`path` RAIZ) | Sim |
| `services.app.updateSourceImage` | POST | Source Docker image (`image`) | Sim |
| `services.app.updateEnv` | POST | Variaveis de ambiente (`env` string) | Sim |
| `services.app.updateBuild` | POST | Build config (`type`,`buildCommand`,`startCommand`) | Sim |
| `services.app.updateResources` | POST | CPU/RAM limits | Sim |
| `services.app.updateAdvanced` | POST | Deploy avancado (replicas, command, zeroDowntime) | Sim |
| `services.app.updateRedirects` | POST | Redireccionamentos HTTP | Sim |
| `services.app.updateBasicAuth` | POST | Autenticacao basica | Sim |
| `services.app.updateMaintenance` | POST | Modo manutencao | Sim |
| `domains.listDomains` | GET | Listar dominios (`projectName`) | Sim |
| `domains.createDomain` | POST | Criar dominio | Sim |
| `domains.updateDomain` | POST | Actualizar dominio | Sim |
| `domains.deleteDomain` | POST | Remover dominio | Sim |

**Endpoints que NAO existem na versao instalada:**
- ~~`services.app.updateDomains`~~ — usar `domains.createDomain`
- ~~`services.app.updateMounts`~~ — nao encontrado
- ~~`services.app.updatePorts`~~ — nao encontrado
- ~~`services.app.saveDomains`~~ — nao existe
- ~~`services.app.saveGithubSource`~~ — usar `updateSourceGithub` ou `updateSourceGit`

---

*Actualizado: 12-03-2026*
