Ir para o conteúdo

Sincronizar atividades ​

Objetivo: levar o calendário de uma turma (aulas, plantões, práticas) do seu sistema para o Presente. Há duas formas: importação CSV (várias atividades de uma vez, idempotente) e cadastro unitário (uma atividade, com todos os campos).

Você precisa de: CADASTRAR na turma (veja Permissões) e o id da turma.

Importar por CSV (recomendado para calendários) ​

csv
data,inicio,fim,descricao,local
10/03/2026,08:00,12:00,Plantão no pronto atendimento,Hospital Exemplo
11/03/2026,14:00,16:00,Aula de técnicas básicas,Laboratório 2
ColunaObrigatóriaFormato
datasimAAAA-MM-DD ou DD/MM/AAAA (apelidos: date, fecha).
inicio e fimnão, mas juntasHH:MM ou HH:MM:SS; fim depois de inicio. Só uma das duas preenchida é erro.
descricaonãoAté 2000 caracteres.
localnãoAté 500 caracteres.

Limites e separadores: os mesmos de Sincronizar alunos (500 linhas, 90 000 caracteres, vírgula, ponto e vírgula ou tabulação).

O uso é igual ao da importação de alunos: POST /turmas/{turmaId}/importacoes/atividades com { "csv": "...", "modo": "simular" }, conferir o relatório e repetir com "modo": "aplicar" (tudo ou nada; parcial com hashConteudo como descrito lá).

bash
curl -X POST "$API/turmas/$TURMA/importacoes/atividades" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile csv atividades.csv '{csv: $csv, modo: "aplicar"}')"

Idempotência: uma atividade é reconhecida pela combinação data + hora de início + descrição (sem diferenciar maiúsculas). Reaplicar o mesmo arquivo dá JA_EXISTE nas que já existem e CRIADA nas novas. Mas:

  • A importação só cria: não altera nem apaga atividades. Se você muda a hora ou a descrição no seu sistema, a importação trata como uma atividade nova.
  • Duas linhas iguais no arquivo: a segunda é ERRO (duplicate).
  • O texto de descricao vira (ou reaproveita, pelo nome) um item do catálogo de atividades da disciplina; use sempre a mesma grafia para a mesma atividade. Os campos que o CSV não tem (obrigatória, cerca de localização etc.) ficam com os valores padrão; ajuste pelo cadastro unitário.

Cadastro unitário ​

Para controlar todos os campos, ou para alterar e cancelar:

bash
curl -X POST "$API/turmas/$TURMA/atividades" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"data":"2026-03-10","horaInicio":"08:00","horaFim":"12:00","descricao":"Plantão no pronto atendimento","local":"Hospital Exemplo","obrigatoria":true}'

Só data é obrigatória. Outros campos: atividadeProfissionalId (item do catálogo da disciplina), observacoes, obrigatoria, cancelada, cercaAtiva, cercaRaioM (10 a 5000 m), lat e lng. Veja o modelo completo em AtividadeCriar.

Cuidado: POST /turmas/{turmaId}/atividades não é idempotente. Se a chamada falhar por rede depois de o servidor processar, repetir cria uma atividade duplicada. Antes de repetir depois de uma falha incerta, liste as atividades do dia (GET /turmas/{turmaId}/atividades?de=2026-03-10&ate=2026-03-10) e confira.

Ler, alterar e remover ​

OperaçãoRota
Listar (com filtro de datas de e ate)GET /turmas/{turmaId}/atividades
Ler umaGET /turmas/{turmaId}/atividades/{atividadeId}
AlterarPATCH /turmas/{turmaId}/atividades/{atividadeId}
Cancelar (mantém no calendário)PATCH com {"cancelada": true}
RemoverDELETE /turmas/{turmaId}/atividades/{atividadeId}

Remover só é possível enquanto não há presença registrada na atividade; depois disso a resposta é 409 CONFLICT. Nesse caso, cancele em vez de remover.

Um fluxo de sincronização do calendário ​

  1. Leia as atividades atuais da turma (todas as páginas) e monte um mapa data|inicio|descrição → id.
  2. Para cada atividade do seu sistema: se está no mapa, compare os campos e use PATCH se mudaram; se não está, crie (CSV ou unitário).
  3. Para atividades que o seu sistema removeu e que existem no Presente: cancele (PATCH com cancelada: true) ou remova (DELETE, se não tiver presença).

Esse fluxo evita a limitação do CSV (que só cria) e não duplica nada.

Exemplo (Python): criar as que faltam ​

python
def chave(a):
    return (a["data"], (a["horaInicio"] or "")[:5], (a["descricao"] or "").lower())

existentes = {chave(a) for a in todos(f"/turmas/{TURMA}/atividades", token)}  # veja "Paginação e limites"

for a in calendario_do_meu_sistema:
    if chave(a) in existentes:
        continue
    r = requests.post(f"{API}/turmas/{TURMA}/atividades",
                      headers={"Authorization": f"Bearer {token}"}, json=a)
    r.raise_for_status()

contato@presente.app.br