---
title: Arquivos
description: Envie, organize e recupere arquivos da organização.
sidebar:
  order: 2
---

Cada arquivo no Siglata pertence a uma organização. Os arquivos permanecem na organização quando seus membros mudam. A arquitetura de armazenamento incorpora pré-reservas de upload, particionamento fixo em partes de 8 MiB, operações atômicas de metadados e um ciclo de vida automatizado de recuperação na lixeira por 30 dias.

## Arquitetura da Cota de Armazenamento [#storage-quota]

Cada organização inicia com uma cota de armazenamento base de **10 GiB** (**10.737.418.240 bytes**).

O Siglata monitora o armazenamento por meio de um livro-razão transacional atômico que distingue entre dados retidos e capacidade pré-alocada de upload:

```
┌────────────────────────────────────────────────────────────────────────┐
│                   Cota Total da Organização (10 GiB)                   │
├──────────────────────────────────────┬──────────────────┬──────────────┤
│             Bytes Usados             │ Bytes Reservados │    Espaço    │
│  (Arquivos Ativos + Lixeira 30 Dias) │(Uploads Ativos)  │ Livre Dispon.│
└──────────────────────────────────────┴──────────────────┴──────────────┘
```

- **`limitBytes`**: Capacidade total de armazenamento alocada para a organização (`10.737.418.240` bytes).
- **`usedBytes`**: Armazenamento retido, somando tanto **arquivos ativos** quanto **arquivos na lixeira**. Mover um item para a lixeira não libera a cota imediatamente; os bytes permanecem contabilizados até que o período de recuperação de 30 dias expire e a limpeza purgue os dados.
- **`reservedBytes`**: Armazenamento bloqueado por uploads em partes em andamento. Ao iniciar um upload, o Siglata pré-aloca o tamanho total declarado do arquivo para evitar que uploads concorrentes colidam ou ultrapassem os limites da organização.
- **Espaço Disponível**: Calculado em tempo real como `limitBytes - usedBytes - reservedBytes`.

## Particionamento em Partes e Reservas de Upload [#chunking-reservations]

Para suportar arquivos volumosos com alta confiabilidade de transferência mesmo em conexões instáveis, o Siglata utiliza um pipeline com blocos fixos de 8 MiB:

| Parâmetro | Especificação | Valor |
| :-- | :-- | :-- |
| **Tamanho da Parte (`CHUNK_SIZE`)** | Tamanho fixo do bloco | `8.388.608` bytes (8 MiB) |
| **Contagem Máxima de Partes** | Máximo de blocos por upload | `10.000` partes |
| **Tamanho Máximo do Arquivo (`MAX_FILE_BYTES`)** | Limite superior para arquivo único | `83.886.080.000` bytes (~80 GB) |

### O Ciclo de Vida do Upload

```
1. upload_begin ──> Checa Cota ──> Pré-aloca reservedBytes ──> Retorna ID e URL do Upload
        │
        ▼
2. PUT /parts/{n} ──> Envia Blocos de 8 MiB (Paralelo ou Sequencial) ──> Registra receivedParts
        │
        ▼
3. upload_complete ──> Valida Contagem ──> Converte reservedBytes em usedBytes ──> Arquivo Ativo
        │
        └── (Se Abortado) ──> upload_cancel ──> Exclui Blocos ──> Libera reservedBytes
```

1. **Reserva de Upload (`upload_begin`)**:
   - O cliente fornece um `requestId` exclusivo (UUID), `name`, `mediaType` e `size`.
   - O Siglata valida se `size <= (limitBytes - usedBytes - reservedBytes)`.
   - Os bytes declarados são adicionados atomicamente a `reservedBytes`, e uma sessão de upload é criada com prazo de expiração.
   - O servidor retorna o identificador do upload e as instruções de transferência com o modelo de URL HTTP `PUT`.

2. **Transmissão das Partes (`PUT /v1/mcp/uploads/{uploadId}/parts/{partNumber}`)**:
   - O cliente envia partes numeradas sequencialmente de `1` a `N` (até 10.000).
   - Cada parte deve ter exatamente `8.388.608` bytes, com exceção da parte final, que envia os bytes restantes declarados.
   - As partes podem ser enviadas em paralelo. O servidor valida o tamanho de cada bloco e registra a chegada no manifesto do upload.

3. **Finalização e Ativação (`upload_complete`)**:
   - Quando todas as partes forem recebidas, o cliente invoca `upload_complete`.
   - O servidor confirma que todas as partes de `1` a `N` foram registradas e que o tamanho total coincide com a reserva.
   - O registro do upload transiciona para `completed`, o arquivo é marcado como `active` e a capacidade reservada é transferida de `reservedBytes` para `usedBytes`.
   - Essa operação é totalmente idempotente: repetir `upload_complete` com o mesmo ID retorna o arquivo ativo com segurança.

4. **Cancelamento e Expiração (`upload_cancel`)**:
   - Se o upload for cancelado pelo usuário ou cliente, `upload_cancel` aciona a exclusão dos blocos armazenados e libera imediatamente os `reservedBytes`.
   - Se o cliente desconectar inesperadamente, o reconciliador em segundo plano detecta sessões de upload expiradas, cancela a reserva e limpa os blocos órfãos.

## Ciclo de Vida de 30 Dias na Lixeira e Recuperação [#trash-recovery]

O Siglata adota um modelo de retenção com foco na segurança dos dados para proteger equipes contra exclusões acidentais:

### Mover para a Lixeira (`file_trash`)

Quando um membro exclui um arquivo ativo:

- O estado do arquivo transiciona de `active` para `trash`.
- A data e hora da exclusão são registradas (`trashed_at = clock_timestamp()`).
- O prazo limite de recuperação é estabelecido para exatamente 30 dias no futuro:
  ```sql
  recover_until = clock_timestamp() + interval '30 days'
  ```
- O arquivo deixa de aparecer na listagem padrão, mas passa a ser exibido na lixeira (`files_list` com `state: "trash"`).
- **Contabilização na Cota**: Os bytes do arquivo continuam sendo cobrados do `usedBytes` da organização. Isso assegura que os dados permaneçam preservados e que a restauração futura nunca falhe por esgotamento de cota.

### Restaurar Arquivos (`file_restore`)

Caso um arquivo tenha sido excluído por engano:

- Qualquer membro com permissão `files:write` pode chamar `file_restore` a qualquer momento antes de `recover_until`.
- O arquivo retorna atomicamente ao status `active`, limpando `trashed_at` e `recover_until`.
- Como os bytes do arquivo já estavam contabilizados em `usedBytes` durante a permanência na lixeira, a restauração não consome cota adicional.

### Limpeza Permanente Automatizada

- Após o encerramento do prazo de 30 dias (`recover_until <= clock_timestamp()`), a restauração é desabilitada permanentemente.
- O reconciliador em segundo plano do Siglata busca os itens expirados na lixeira em lotes:
  ```sql
  SELECT id FROM files_object
  WHERE state = 'trash' AND recover_until <= clock_timestamp()
  ```
- O processo marca o objeto para purga, remove os dados binários do armazenamento e limpa o registro correspondente no banco de dados.
- Somente após a confirmação da exclusão física os bytes são subtraídos do `usedBytes` da organização, liberando espaço para novos envios.

## Operações de Metadados [#metadata-operations]

### Renomear Arquivo (`file_rename`)

A renomeação de um arquivo no Siglata altera apenas o atributo `name` no registro do banco de dados. Como os objetos são endereçados por UUIDs imutáveis, a renomeação é uma operação instantânea de custo zero, sem cópia de dados ou recálculo de cota.

### Downloads Autenticados em Fluxo (`file_download`)

Membros autorizados podem baixar arquivos diretamente pelo endpoint de download autenticado (`GET /v1/mcp/files/{fileId}/download`). O endpoint valida a associação ativa do chamador na organização em tempo real antes de iniciar o fluxo de bytes, garantindo que ex-membros não acessem os ativos da organização.

## Pastas e Controle de Acesso [#folders-access]

Arquivos podem residir em pastas aninhadas, e cada arquivo e pasta carrega um atributo `visibility`:

- **`org`** (padrão): Todo membro da organização pode ler e gravar o objeto, sujeito aos seus escopos OAuth. Isso preserva o comportamento de todos os arquivos criados antes da existência de pastas.
- **`restricted`**: Somente o criador do objeto, membros `owner`/`admin` da organização e membros com concessão explícita podem acessar o objeto.

Uma pasta restrita restringe toda a sua subárvore: para ler ou gravar um objeto, o chamador precisa satisfazer cada pasta restrita na cadeia de ancestrais. Uma concessão em uma pasta se estende aos seus descendentes irrestritos, enquanto um objeto restrito dentro de uma pasta compartilhada ainda exige sua própria concessão.

- Operações negadas falham com o código de erro `forbidden`; objetos restritos que um membro não pode ler também são omitidos dos resultados de `files_list` e `folders_list`.
- `grant_create` e `grant_revoke` são limitados ao criador do objeto e a administradores da organização. Para alterar o nível ou o beneficiário de uma concessão, revogue e depois crie (não há operação de substituição separada).
- `file_set_visibility` e `folder_set_visibility` exigem acesso de escrita ao objeto; não alteram concessões existentes.
- `file_move` e `upload_begin` em uma pasta requerem acesso de escrita à pasta de destino.
- Mover uma pasta para a lixeira não move seu conteúdo; quando uma pasta na lixeira ultrapassa o prazo de recuperação, ela é excluída e seus filhos voltam para a raiz da organização.
