You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Backend de agendamento e publicação automática de posts no Telegram.
Sistema que permite criar, agendar e publicar posts em canais do Telegram de forma automatizada, com fila de processamento, retry com backoff exponencial, monitormaneto via Prometheus/Grafana e autenticação JWT.
src/
├── app/ # Configuração do Fastify
│ ├── app.ts # Build da aplicação (plugins, rotas, error handler)
│ └── server.ts # Entrypoint (listen)
├── config/
│ └── env.ts # Validação de variáveis de ambiente com Zod
├── database/prisma/
│ └── client.ts # Instância singleton do Prisma Client
├── infra/ # Infraestrutura (Docker, monitoramento)
│ ├── grafana/
│ │ ├── dashboards/ # Provisioning de dashboards
│ │ └── datasources/ # Provisioning de datasources
│ └── prometheus/
│ └── prometheus.yml # Configuração de scrape
├── modules/ # Módulos da aplicação (domain-driven)
│ ├── auth/ # Autenticação (register, login)
│ ├── metrics/ # Métricas Prometheus
│ ├── posts/ # CRUD de posts
│ ├── telegram/ # Gerenciamento de canais Telegram
│ └── users/ # Perfil do usuário
├── plugins/ # Plugins do Fastify
│ ├── jwt.ts # JWT sign/verify + middleware authenticate
│ └── redis.ts # Conexão Redis (ioredis)
├── queues/
│ └── index.ts # Definição das filas BullMQ (publish, retry, dead-letter)
├── repositories/ # Data access layer (Prisma)
│ ├── job.repository.ts
│ ├── post.repository.ts
│ ├── telegram-channel.repository.ts
│ └── user.repository.ts
├── services/
│ ├── storage.service.ts # Upload de imagens (placeholder)
│ └── telegram.service.ts # Integração com a API do Telegram (Telegraf)
├── shared/
│ ├── constants/ # Enums do sistema
│ │ ├── job-status.ts
│ │ ├── post-status.ts
│ │ └── queues.ts
│ ├── errors/ # Classes de erro customizadas
│ │ └── app-error.ts
│ └── types/
│ └── index.ts # Interfaces compartilhadas
└── workers/
└── publish-post.worker.ts # Worker BullMQ que publica no Telegram
Modelo de Dados
erDiagram
User ||--o{ TelegramChannel : has
User ||--o{ Post : creates
TelegramChannel ||--o{ Post : target
Post ||--o{ Job : tracks
User {
uuid id PK
string name
string email UK
string password_hash
datetime created_at
}
TelegramChannel {
uuid id PK
uuid user_id FK
text bot_token
text chat_id
datetime created_at
}
Post {
uuid id PK
uuid user_id FK
uuid channel_id FK
string title
text caption
text image_url
string status "DRAFT | SCHEDULED | PROCESSING | PUBLISHED | FAILED | RETRYING | CANCELLED"
datetime scheduled_at
datetime published_at NULL
datetime created_at
}
Job {
uuid id PK
uuid post_id FK
string queue_name
string status "PENDING | ACTIVE | COMPLETED | FAILED | DELAYED | CANCELLED"
int attempts
datetime created_at
}
Loading
Ciclo de Vida de um Post
DRAFT → SCHEDULED → PROCESSING → PUBLISHED
│
▼
FAILED → RETRYING → PROCESSING (nova tentativa)
│
▼
DEAD LETTER (após 5 tentativas)
Fluxo de Publicação
POST /posts
│
├─ Valida dados com Zod
├─ Verifica se o canal pertence ao usuário
├─ Cria o post no banco (status: DRAFT)
├─ Adiciona job na fila "publish-post" com delay = scheduledAt - now
├─ Atualiza status para SCHEDULED
└─ Retorna 201 + bullJobId
Worker (quando o delay expira)
│
├─ Busca o post no banco
├─ Se CANCELLED → descarta o job
├─ Atualiza status para PROCESSING
├─ Envia a foto + legenda para o Telegram
├─ Se sucesso → marca PUBLISHED, incrementa métrica
│
└─ Se falha →
├─ Marca FAILED
├─ Se ainda há tentativas → adiciona na "retry-post" com backoff exponencial (5s, 10s, 20s, 40s...)
└─ Se esgotou tentativas → não faz mais nada (dead letter implícita)