📝

API de Submissão de Programação

API de Submissão de Programação

Visão Geral

API com que um admin (adminRole: admin) submete a programação (EPG - Electronic Program Guide) de uma rádio, em nome dela, quando não está disponível automaticamente via MyTuner Radio.

Autenticação

Requerida: Sim: JWT Bearer Token de um admin com escrita (adminRole: admin). Um usuário da app ou um viewer recebe 403.

Authorization: Bearer <token_jwt_de_admin>

Endpoint: Submeter Programação

Request

POST /api/radios/:id/schedule
Content-Type: application/json
Authorization: Bearer <token>

Parâmetros

Body

{
  "schedule": [
    [
      {
        "time": "06:00",
        "end_time": "10:00",
        "title": "Manhã de Domingo",
        "subtitle": "Com Maria Santos",
        "description": "Música e conversas para começar o domingo",
        "duration": 240,
        "sunday": true
      }
    ],
    [
      {
        "time": "07:00",
        "end_time": "10:00",
        "title": "Despertador",
        "subtitle": "Com João Silva",
        "monday": true,
        "tuesday": true,
        "wednesday": true,
        "thursday": true,
        "friday": true
      },
      {
        "time": "10:00",
        "end_time": "13:00",
        "title": "Manhã Livre",
        "subtitle": "Com Ana Costa",
        "monday": true,
        "tuesday": true,
        "wednesday": true,
        "thursday": true,
        "friday": true
      }
    ],
    [],
    [],
    [],
    [],
    []
  ]
}

Estrutura do Schedule

O array schedule deve conter exatamente 7 elementos, um para cada dia da semana:

Cada dia contém um array de programas. Dias sem programação podem ter array vazio [].

Campos do Programa

Campo Tipo Obrigatório Descrição
time string ✅ Hora de início (formato HH:MM 24h)
end_time string ❌ Hora de fim (formato HH:MM 24h)
title string ✅ Título do programa
subtitle string ❌ Apresentador ou subtítulo
description string ❌ Descrição detalhada
duration number ❌ Duração em minutos (1-1440)
monday boolean ❌ Transmitido às segundas
tuesday boolean ❌ Transmitido às terças
wednesday boolean ❌ Transmitido às quartas
thursday boolean ❌ Transmitido às quintas
friday boolean ❌ Transmitido às sextas
saturday boolean ❌ Transmitido aos sábados
sunday boolean ❌ Transmitido aos domingos

Validações

✅ Formato de Horários: Deve seguir padrão HH:MM (00:00 a 23:59)

✅ Número de Dias: Exatamente 7 dias obrigatórios

✅ Campos Obrigatórios: time e title são sempre necessários

Response Success

{
  "message": "Programação submetida com sucesso",
  "scheduleId": "675a1234567890abcdef1234"
}

Status: 201 Created

Response Errors

400 Bad Request

{
  "statusCode": 400,
  "message": ["time must be in format HH:MM", "title must be a string"],
  "error": "Bad Request"
}

Erros comuns:

403 Forbidden

{
  "statusCode": 403,
  "message": "Schedule deve conter exatamente 7 dias de programação",
  "error": "Forbidden"
}

Causas:

404 Not Found

{
  "statusCode": 404,
  "message": "Rádio com ID 123 não encontrada",
  "error": "Not Found"
}

401 Unauthorized

{
  "statusCode": 401,
  "message": "Unauthorized"
}

Causa: Token JWT inválido ou ausente

Endpoint: Consultar Programação

Request

GET /api/radios/:id/schedule

Parâmetros

Response Success

{
  "_id": "675a1234567890abcdef1234",
  "radio_id": "694830c00e1febe2e0cbfe38",
  "radio_name": "Rádio Exemplo",
  "mytuner_id": null,
  "schedule": [
    [
      {
        "time": "06:00",
        "end_time": "10:00",
        "title": "Manhã de Domingo",
        "subtitle": "Com Maria Santos",
        "description": "Música e conversas",
        "duration": 240,
        "sunday": true
      }
    ],
    [...],
    ...
  ],
  "fetched_at": "2025-12-24T01:00:00.000Z",
  "expires_at": "2025-12-31T01:00:00.000Z",
  "source": "user-submitted",
  "createdAt": "2025-12-24T01:00:00.000Z",
  "updatedAt": "2025-12-24T01:00:00.000Z"
}

Status: 200 OK

Response Error

404 Not Found

{
  "statusCode": 404,
  "message": "Rádio com ID 123 não encontrada",
  "error": "Not Found"
}

Causa: Rádio não existe ou não tem programação disponível

Fontes de Programação

O sistema suporta múltiplas fontes de EPG, identificadas pelo campo source:

1. MyTuner Radio API (`source: "mytuner"`)

2. Submissão Manual (`source: "user-submitted"`)

Prioridade de Fontes

Quando existem múltiplas fontes para mesma rádio:

  1. User-submitted (mais recente)
  2. MyTuner (se user-submitted expirou)

Expiração e Atualização

Validade

Atualização

Para atualizar programação existente:

  1. Submeta novamente via POST /api/radios/:id/schedule
  2. Sistema remove automaticamente programação anterior com source: "user-submitted"
  3. Nova programação fica válida por mais 7 dias

Nota: Programação de outras fontes (MyTuner) não é afetada.

Exemplos de Uso

Exemplo 1: Programação Simples (Segunda a Sexta)

{
  "schedule": [
    [],
    [
      {
        "time": "08:00",
        "end_time": "12:00",
        "title": "Manhã na Rádio",
        "monday": true,
        "tuesday": true,
        "wednesday": true,
        "thursday": true,
        "friday": true
      },
      {
        "time": "14:00",
        "end_time": "18:00",
        "title": "Tarde Musical",
        "monday": true,
        "tuesday": true,
        "wednesday": true,
        "thursday": true,
        "friday": true
      }
    ],
    [],
    [],
    [],
    [],
    []
  ]
}

Exemplo 2: Programação Completa com Detalhes

{
  "schedule": [
    [
      {
        "time": "10:00",
        "end_time": "14:00",
        "title": "Domingão na Rádio",
        "subtitle": "Com Pedro Santos",
        "description": "Músicas e entrevistas para o domingo",
        "duration": 240,
        "sunday": true
      }
    ],
    [
      {
        "time": "06:00",
        "end_time": "10:00",
        "title": "Despertador",
        "subtitle": "Com Ana Silva",
        "description": "Notícias, música e clima",
        "duration": 240,
        "monday": true,
        "tuesday": true,
        "wednesday": true,
        "thursday": true,
        "friday": true
      },
      {
        "time": "10:00",
        "end_time": "14:00",
        "title": "Tarde Livre",
        "subtitle": "Com João Costa",
        "duration": 240,
        "monday": true,
        "tuesday": true,
        "wednesday": true,
        "thursday": true,
        "friday": true
      }
    ],
    [],
    [],
    [],
    [],
    [
      {
        "time": "12:00",
        "end_time": "18:00",
        "title": "Sábado Total",
        "subtitle": "Com Maria Oliveira",
        "description": "Música e pedidos especiais",
        "duration": 360,
        "saturday": true
      }
    ]
  ]
}

Exemplo 3: Usando cURL

# Obter token JWT de um admin com escrita (adminRole: admin) primeiro
TOKEN="token_jwt_de_admin_aqui"

# Submeter programação
curl -X POST "http://localhost:3000/api/radios/694830c00e1febe2e0cbfe38/schedule" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "schedule": [
      [],
      [
        {
          "time": "08:00",
          "title": "Programa Matinal",
          "monday": true,
          "tuesday": true,
          "wednesday": true,
          "thursday": true,
          "friday": true
        }
      ],
      [],
      [],
      [],
      [],
      []
    ]
  }'

# Consultar programação
curl "http://localhost:3000/api/radios/694830c00e1febe2e0cbfe38/schedule"

Melhores Práticas

1. Estruture por Dia da Semana

Organize programas por dia real de transmissão, não por padrões de repetição:

✅ Correto:

{
  "schedule": [
    [], // Domingo
    [{"time": "08:00", "title": "Manhã", "monday": true}], // Segunda
    [{"time": "08:00", "title": "Manhã", "tuesday": true}], // Terça
    ...
  ]
}

❌ Evite:

{
  "schedule": [
    [], // Domingo
    [{"time": "08:00", "title": "Manhã", "monday": true, "tuesday": true, ...}], // Todos os dias no índice de segunda
    ...
  ]
}

2. Inclua Horários de Fim

Facilita visualização de grade:

✅ Recomendado:

{
  "time": "08:00",
  "end_time": "12:00",
  "title": "Manhã"
}

3. Use Subtítulos para Apresentadores

{
  "title": "Café da Manhã",
  "subtitle": "Com João Silva e Maria Santos"
}

4. Descrições Detalhadas

Ajudam usuários a decidirem ouvir:

{
  "title": "Jazz à Noite",
  "subtitle": "Com Pedro Costa",
  "description": "As melhores músicas de jazz de todos os tempos, com foco em artistas brasileiros e portugueses"
}

5. Valide Antes de Submeter

Use ferramenta online ou script para validar JSON antes de enviar.

Limitações e Considerações

Permissões (Atual)

⚠️ Implementação Atual: Só admins com escrita (adminRole: admin) podem submeter programação, para qualquer rádio; um usuário da app ou um viewer recebe 403.

🚧 Futuro: Apenas proprietários da rádio poderão submeter (campo owner_id será adicionado).

Validação de Horários

✅ Sistema valida formato mas não verifica:

Responsabilidade do cliente garantir consistência.

Performance

Cache

Programação é cacheada por 5 minutos após primeira consulta para melhor performance.

Troubleshooting

Erro: "time must be in format HH:MM"

✅ Solução: Use formato 24 horas com zero à esquerda:

Erro: "Schedule deve conter exatamente 7 dias"

✅ Solução: Array deve ter 7 elementos, mesmo dias vazios:

{
  "schedule": [[], [], [], [], [], [], []] // 7 dias vazios
}

Programação não aparece

Possíveis causas:

  1. Schedule expirou (> 7 dias)
  2. ID da rádio incorreto
  3. Programação de outra fonte tem prioridade

Solução: Consulte endpoint GET para verificar source e expires_at.

Token JWT inválido

Causas comuns:

Solução: Obtenha novo token via /api/auth/login.

Recursos Relacionados

Suporte

Para questões sobre esta API, consulte a documentação técnica ou abra issue no repositório.