Automation

Discord book club bot for suggesting and voting on books

Discord bot where members suggest books, vote via select menu, and the bot announces the winner using JSON file storage.

typescriptdiscord.jsnodejsvitestdotenv

Built 1 time, downloaded 0 times.

Install from your terminal

Run this in your project folder. It signs you in, shows what changes and asks before it overwrites a file.

npx claude-lab add discord-book-club-bot-for-suggesting-and-voting-on-books-075f80
CLAUDE.md
# the app

## Purpose

A Discord bot for one book club server. Members suggest books with `/suggest`. An admin opens a vote with `/vote-start`. Members vote in a select menu. `/vote-close` announces the winner.

Read these before starting work:
- `SPEC.md` holds the requirements.
- `PLAN.md` holds the phases, each ending in a `/goal` prompt.
- `REVIEW.md` holds the review checklist.

## Stack

- Node 22 LTS, TypeScript in strict mode
- discord.js v14
- vitest for tests
- dotenv for config
- Storage: a JSON file at `data/state.json`, written atomically (write a temp file, then rename it)

## Commands

- `npm install`: install dependencies
- `npm run build`: compile TypeScript
- `npm test`: run vitest
- `npm run dev`: run the bot with `tsx watch`
- `npm run dry-run`: simulated 3-person vote with a mock client (after Phase 4)

A task is done only when `npm run build` and `npm test` both exit 0.

## Layout

- `src/index.ts`: entry point, loads `.env`, logs in
- `src/commands/`: one file per slash command
- `src/vote.ts`: pure tally logic, no Discord imports
- `src/store.ts`: JSON persistence
- `tests/`: mirrors `src/`

## Gotchas

- `DISCORD_TOKEN` lives only in `.env`. Never commit it. Never print it.
- Slash commands register on startup. Guild commands update instantly. Global commands can take up to an hour.
- For development, register commands to the guild in `DISCORD_GUILD_ID`.
- A select menu allows at most 25 options.
- Interactions must be acknowledged within 3 seconds. Use `deferReply` for slow work.

## Conventions

- One vote per user per poll. A later click replaces the earlier vote.
- Ties are broken by a random pick among the tied titles. The announcement says so.
- Only one poll can be open at a time.
- Keep `vote.ts` pure and unit tested. Tests must not call the Discord API or need a network.

## Rules

- Ask before adding a dependency.
- Ask before deleting `data/state.json`.
- Never run `git push`, `git reset --hard`, or `rm -rf` without asking.

## Context habits

- Use `/clear` between unrelated tasks.
- Use `/compact` at natural breaks.
Use for my project