Batch analytics events into an EventSink and compute stats from it
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
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
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>;
maxBatchdefaults to 50: reaching it starts a flush right away.flushMsdefaults to 2000: the firsttrackafter an empty buffer starts onesetTimeout. Create the timer only insidetrack, never in the constructor, because Workers forbid timers at global scope. Callunref()on it when it exists (Node), so it doesn't keep a process alive.- A failed
sink.writelogs 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.
statsFromSinkthrows a clear error when the sink has noquery. It countsconversation:startedas conversations,message:sentplusmessage:receivedas messages, andlead:capturedas leads. Keep the existing field names (includingleadsCapture), since people already read them.
Where to look
packages/core/src/analytics/collector.tsandpackages/core/tests/analytics/collector.test.tspackages/core/src/storage/memory.ts(memoryStorage().eventshasquery, use it in the tests)
Acceptance criteria
- New
packages/core/src/analytics/sink.tsandpackages/core/tests/analytics/sink.test.ts, exported from@chatcops/core - Tests (fake timers): flush on
maxBatch, flush onflushMs, no timer before the firsttrack, a failing sink logs and drops, concurrentflush()calls write each event once -
statsFromSinkonmemoryStorage().eventsmatches whatAnalyticsCollector.getStats()gives for the same events - Changeset for
@chatcops/core(minor) -
pnpm test:coverageandpnpm lintpass
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
- Sem Dockerfile nem arquivo Docker Compose
- Tem um modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de codercops/chatcops
-
Document the pre-chat formTalvez já em andamento @masyarakatai assumiu há 5 dias. Abertadocumentation good first issue hacktoberfest widget
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 88/100
codercops/chatcops#70 · 5 comentários ·
Mantenedores costumam responder em até 1 dia
-
docs: update the providers page for openai-compatible, registerProvider and provider importsTalvez já em andamento @prakashNalla assumiu hoje. Abertadocumentation good first issue hacktoberfest website
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 76/100
codercops/chatcops#291 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
docs: add a protocol reference page for custom clientsTalvez já em andamento @kachamsiddarth assumiu hoje. Abertadocumentation good first issue hacktoberfest website
codercops/chatcops#286 · 2 comentários · 1 responsável ·
Mantenedores costumam responder em até 1 dia
-
Create @chatcops/store-cloudflare (D1, KV and a Durable Object counter)Talvez já em andamento @bhushan4work assumiu hoje. Abertaenhancement hacktoberfest help wanted server
Dificuldade 5/5 Mais de uma semana Facilidade para iniciantes 25/100
codercops/chatcops#249 · 2 comentários · 1 responsável ·
Mantenedores costumam responder em até 1 dia
-
Create @chatcops/store-sqlite, a store for single-server setupsTalvez já em andamento @srikar-naidu assumiu hoje. Abertaenhancement hacktoberfest help wanted server
Dificuldade 5/5 Mais de uma semana Facilidade para iniciantes 35/100
codercops/chatcops#247 · 3 comentários · 1 responsável ·
Mantenedores costumam responder em até 1 dia
Todas as issues de codercops/chatcops
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 74/100
paperclipai/paperclip#17151 ·
Mantenedores costumam responder em até 1 dia
-
needs-triage
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 83/100
AgoraIO-Extensions/agent-infra#3159 ·
Mantenedores costumam responder em até 1 dia
-
blocklist addition
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 66/100
MetaMask/eth-phishing-detect#304596 ·
Mantenedores costumam responder em até 1 dia
-
friction
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 70/100
kentcdodds/kody#4142 ·
-
[Bug] Statistics | Task statistics are always empty on MikroORM with MySQL or SQLiteTalvez já em andamento @NdekoCode assumiu hoje. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
ever-co/ever-gauzy#11214 ·
Mantenedores costumam responder em até 1 dia