Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

Batch analytics events into an EventSink and compute stats from it

Aberta
#246 2 comentários 0 reações 1 responsável Ver no GitHub

Mantenedores costumam responder em até 1 dia

@srujankaleru2007 já está trabalhando nisso.

Desde 21/10/2026.

Avaliação

Dificuldade
3/5
Tempo estimado
1-2 dias
Facilidade para iniciantes
78/100
Tipo de issue
Funcionalidade
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
typescript
Domínio
analytics, backend

Direção de pesquisa

Read packages/core/src/analytics/collector.ts and packages/core/src/storage/memory.ts, then compare the existing stats shape and event query API. Implement the buffered sink and stats function in packages/core/src/analytics/sink.ts; use packages/core/tests/analytics/sink.test.ts to cover batching, timers, failures, concurrent flushes, and matching stats. Done when the module is exported, the tests pass, and a minor changeset is added.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

core enhancement hacktoberfest help wanted

Analytics live in an AnalyticsCollector in memory (packages/core/src/analytics/collector.ts), capped at 1000 events and per process, so on serverless the stats only describe one instance. @chatcops/core now has an EventSink interface (packages/core/src/storage/types.ts) that stores can back with Redis, Postgres or D1. Writing every event as its own database call would be slow, so this issue adds a small buffer in front of the sink and a function that turns the sink's counts back into today's stats shape.

What to do
Create packages/core/src/analytics/sink.ts:

export class BufferedEventSink {
  constructor(sink: EventSink, options?: { maxBatch?: number; flushMs?: number });
  /** Queues an event. Never throws and never waits. */
  track(type: string, data?: Record<string, unknown>): void;
  /** Writes everything queued. Safe to call any time, including concurrently. */
  flush(): Promise<void>;
}

/** The same shape as AnalyticsCollector.getStats(), from the sink's counts. */
export function statsFromSink(sink: EventSink, range: { from: number; to: number }): Promise<AnalyticsStats>;
  • maxBatch defaults to 50: reaching it starts a flush right away.
  • flushMs defaults to 2000: the first track after an empty buffer starts one setTimeout. Create the timer only inside track, never in the constructor, because Workers forbid timers at global scope. Call unref() on it when it exists (Node), so it doesn't keep a process alive.
  • A failed sink.write logs one line, [chatcops] analytics write failed: <message>, and drops that batch. Analytics must never break a chat.
  • Two flushes at the same time must not write the same event twice.
  • statsFromSink throws a clear error when the sink has no query. It counts conversation:started as conversations, message:sent plus message:received as messages, and lead:captured as leads. Keep the existing field names (including leadsCapture), since people already read them.

Where to look

  • packages/core/src/analytics/collector.ts and packages/core/tests/analytics/collector.test.ts
  • packages/core/src/storage/memory.ts (memoryStorage().events has query, use it in the tests)

Acceptance criteria

  • New packages/core/src/analytics/sink.ts and packages/core/tests/analytics/sink.test.ts, exported from @chatcops/core
  • Tests (fake timers): flush on maxBatch, flush on flushMs, no timer before the first track, a failing sink logs and drops, concurrent flush() calls write each event once
  • statsFromSink on memoryStorage().events matches what AnalyticsCollector.getStats() gives for the same events
  • Changeset for @chatcops/core (minor)
  • pnpm test:coverage and pnpm lint pass

Want to work on this? Comment below and I'll assign it to you. Please take one issue at a time, branch off dev, and open your PR against dev with Closes #<this issue number>. Setup notes (pnpm, build before test) are in CONTRIBUTING.md.

Linguagem predominante
TypeScript
Estrelas
13
Forks
7
Merge médio
3h 41min
PRs com merge (30d)
155

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de codercops/chatcops

Todas as issues de codercops/chatcops

Issues semelhantes

Mais issues de TypeScript

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.