# Apps Laravel

Além dos hotsites e dos sites WordPress, o servidor roda **apps Laravel**.
O primeiro é o **`suite`**, o site da comunidade PHP com Rapadura, em
<https://phpcomrapadura.org> (o antigo site WordPress continua em
`legacy.phpcomrapadura.org`, e `novo.phpcomrapadura.org` redireciona para o
domínio principal).

O `rapadura artisan` dá a você e ao seu agente o `artisan` do app, do mesmo
jeito que o `rapadura wp` dá o `wp-cli`: sem SSH, sem senha do servidor, com
uma política que deixa inspecionar e operar o app sem mexer no código, no
banco ou nos segredos dele, e com cada comando no log de auditoria.

Não é deploy. Mudança de código passa pelo repositório do app
([PHPcomRapadura/suite](https://github.com/PHPcomRapadura/suite)): um merge
na `main` publica sozinho, e é esse deploy que roda as migrations, logo
depois de um dump do banco. O `rapadura artisan` serve para olhar o app
rodando e cuidar dele.

## Quem pode usar

- O **owner** usa todos os apps.
- As demais pessoas usam os apps que o owner liberou para elas
  (`rapadura admin artisan-access suite --grant <login>`; veja
  [Administração](admin.md#apps-laravel)).

```sh
rapadura artisan apps
```

```text
APP    URL                         ALSO                    MEMBERS
suite  https://phpcomrapadura.org  www.phpcomrapadura.org  -
```

Um app ao qual você não tem acesso responde `not_found`, igual a um que não
existe.

## Rodar o artisan

Tudo depois de `--` vai para o `artisan`. Ele roda no servidor como o
usuário do app, na versão que está no ar, sem perguntas
(`--no-interaction`), por no máximo 3 minutos.

```sh
rapadura artisan suite -- about
rapadura artisan suite -- route:list --path=cfp
rapadura artisan suite -- migrate:status
rapadura artisan suite -- db:show --counts
rapadura artisan suite -- config:cache
rapadura artisan suite -- cache:clear
rapadura artisan suite -- down --retry=60 --secret=pode-entrar
rapadura artisan suite -- up
```

```sh
rapadura artisan suite -- about --only=environment
```

```text
  Environment ................................................................
  Application Name .......................................... PHP com Rapadura
  Laravel Version .................................................... 13.34.0
  PHP Version ......................................................... 8.4.23
  Composer Version .................................................... 2.10.2
  Environment ..................................................... production
  Debug Mode ............................................................. OFF
  URL ..................................................... phpcomrapadura.org
  Maintenance Mode ....................................................... OFF
  Timezone ............................................................... UTC
  Locale ............................................................... pt_BR
```

Dá para chamar o app por qualquer um dos endereços dele também
(`rapadura artisan phpcomrapadura.org -- about`). O nome `suite` não muda
mesmo que os endereços mudem, então use ele em scripts e prompts.

A saída e o código de saída são os do artisan. Com `--json` você recebe
`stdout`, `stderr` e `exit_code` separados. Pelo MCP as ferramentas são
`list_apps` e `artisan` (`{"app": "suite", "args": ["route:list", "--json"]}`).

### O que é permitido

| para | comandos |
|---|---|
| olhar o app | `about`, `env`, `list`, `help`, `inspire`, `route:list`, `migrate:status`, `schedule:list`, `event:list`, `db:show`, `db:table` |
| caches | `optimize`, `optimize:clear`, `config:cache`, `config:clear`, `route:cache`, `route:clear`, `view:cache`, `view:clear`, `event:cache`, `event:clear`, `clear-compiled`, `cache:clear`, `cache:forget` |
| modo de manutenção | `down` (com `--retry=`, `--refresh=`, `--secret=`, `--with-secret` e `--redirect=/um-caminho-do-site`), `up` |
| limpeza | `auth:clear-resets`, `sanctum:prune-expired` |

Escreva o nome do comando inteiro: o artisan aceita abreviações (`tink` roda
o `tinker`), o rapadura não.

Recusados sempre, com o motivo no erro:

| comandos | por quê |
|---|---|
| `tinker`, `invoke-serialized-closure` | rodam PHP arbitrário |
| `migrate` e `migrate:*` (menos `migrate:status`), `db:seed`, `db:wipe`, `model:prune` | mexem no banco fora de um deploy; o deploy roda as migrations depois de um dump |
| `db` | shell interativo do banco; `db:show` e `db:table` descrevem o banco |
| `config:show`, `key:generate`, `env:encrypt`, `env:decrypt` | leem ou trocam segredos (o `config:show` mostra senhas) |
| `make:*`, `install:*`, `vendor:publish` e os outros `*:publish`, `storage:link`, `schema:dump`, `package:discover` | escrevem código ou arquivos na versão; mudança passa pelo repositório |
| `serve`, `dev`, `queue:*`, `schedule:*` (menos `schedule:list`) | processos longos; quem roda o app é o servidor, e ele não tem workers de fila nem agendador |
| `model:show` | instancia qualquer classe pelo nome |
| qualquer argumento que comece com `--env` (`--env=local`, `schedule:list --environment=…`) | o Laravel lê como o ambiente, que o servidor define |
| `migrate:status --path`, `--realpath` | leem migrations de outro diretório |
| `down --redirect=<outro site>`, `down --refresh=<o que não for segundos>`, `down --render`, `down --status` | o site mandaria todo visitante para outro lugar; as opções vão com `=` |
| `cache:clear <store>`, `cache:clear --locks` | só o cache padrão; o `--locks` também esvazia o banco que guarda as sessões (todo mundo sai da conta) |

Comando que não está em nenhuma das listas é recusado até o owner liberar
(`artisan_refused`, com a lista na dica). A política vale para o owner
também: o que passar dela é feito no servidor.

## Bom saber

- **Mudar o `.env`.** Segredo não passa pelo rapadura: o administrador
  edita o `.env` no servidor. Depois, quem tem acesso aplica com
  `rapadura artisan suite -- config:cache`.
- **Modo de manutenção.** O `down` tira o site do ar para todo mundo, com
  503. Com `--secret=<palavra>`, visitar `https://<endereço>/<palavra>` uma
  vez libera o seu navegador. Todo deploy termina com `up`, então um merge na
  `main` traz o site de volta mesmo que alguém tenha tirado do ar à mão.
- **Sem segredos na saída.** `about`, `db:show` e `db:table` mostram
  drivers, nome do banco, host, usuário e tamanho das tabelas, não senhas.
- **Auditoria.** Todo comando, recusado ou não, vai para o log de auditoria
  como `artisan.run`, com os valores de `--secret=` e parecidos escondidos.

## Prompts para testar

```prompt
O site da comunidade está saudável? Com o rapadura artisan no suite, me mostre o ambiente, se o modo de manutenção está ligado e se tem alguma migration pendente.
```

```prompt
O administrador mudou o .env do site da comunidade. Aplique com o rapadura artisan (config:cache no suite) e confirme que https://phpcomrapadura.org continua respondendo.
```

```prompt
Coloque o suite em modo de manutenção com uma palavra secreta para passar, me dê o endereço de acesso e só tire do modo de manutenção quando eu pedir.
```

## Erros

| código | quando |
|---|---|
| `artisan_refused` | o comando está fora da política; a mensagem diz por quê, a dica o que fazer |
| `not_found` | o app não existe, ou você não tem acesso a ele; `rapadura artisan apps` |
| `forbidden` | seu token é só de leitura |
| `artisan_unavailable` | a trilha Laravel está desligada neste gateway, ou a lista de apps do servidor está quebrada; avise o administrador |

Todos os códigos: [códigos de erro](../errors.md).
