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)
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| Coluna | Obrigatória | Formato |
|---|---|---|
data | sim | AAAA-MM-DD ou DD/MM/AAAA (apelidos: date, fecha). |
inicio e fim | não, mas juntas | HH:MM ou HH:MM:SS; fim depois de inicio. Só uma das duas preenchida é erro. |
descricao | não | Até 2000 caracteres. |
local | não | Até 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á).
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
descricaovira (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:
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}/atividadesnã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ção | Rota |
|---|---|
Listar (com filtro de datas de e ate) | GET /turmas/{turmaId}/atividades |
| Ler uma | GET /turmas/{turmaId}/atividades/{atividadeId} |
| Alterar | PATCH /turmas/{turmaId}/atividades/{atividadeId} |
| Cancelar (mantém no calendário) | PATCH com {"cancelada": true} |
| Remover | DELETE /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
- Leia as atividades atuais da turma (todas as páginas) e monte um mapa
data|inicio|descrição → id. - Para cada atividade do seu sistema: se está no mapa, compare os campos e use
PATCHse mudaram; se não está, crie (CSV ou unitário). - Para atividades que o seu sistema removeu e que existem no Presente: cancele (
PATCHcomcancelada: 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
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()