This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
A Slack bot for managing a queue of reviewers for HackerRank coding assessments. The bot connects reviewers with candidates by maintaining a queue of available reviewers, matching them by language preference, and managing the request/acceptance workflow through Slack interactions and direct messages.
pnpm install # Install dependencies
pnpm verify # Run all checks: lint, format, compile, build, and test
pnpm test # Run tests
pnpm test:watch # Run tests in watch mode
pnpm lint # Lint and fix
pnpm format # Format code
pnpm compile # Type check without emitting files
pnpm build # Build for productiondev # Sign into AWS dev (requires sai-aws-auth setup)
pnpm deploy # Deploy to dev (can run from any directory)The application uses Google Spreadsheets as its database. The database module (src/database/database.ts) manages connections to Google Sheets using service account authentication. Each "table" is a separate sheet within the spreadsheet:
- users sheet: Stores reviewers in the queue with their language preferences and last review date
- activeReviews sheet: Tracks ongoing review requests and their state
- languages sheet: Defines available programming languages
Repositories (src/database/repos/) provide CRUD operations on these sheets, mapping rows to TypeScript models.
- User (
src/database/models/User.ts): Queue members withid,name,languages[], andlastReviewedDate - ActiveReview (
src/database/models/ActiveReview.ts): Ongoing reviews with thread info, requestor, candidate identifier, and arrays trackingacceptedReviewers,pendingReviewers, anddeclinedReviewers
- Someone requests a review via Slack shortcut (
requestReview) QueueServicefinds best reviewers by language match and last review timeRequestServicesends DMs to selected reviewers with accept/decline buttons- Reviewers respond, transitioning from
pendingReviewerstoacceptedReviewersordeclinedReviewers - Requests expire after
REQUEST_EXPIRATION_MINif not accepted (handled byexpireRequestscron) - Once enough reviewers accept, the review is complete and closed via
ReviewCloser
Services (src/services/) contain business logic:
- QueueService: Finds and ranks available reviewers
- RequestService: Manages sending review requests to users
- ChatService: Slack messaging utilities
- ReviewActionService: Processes accept/decline actions
Bot commands (src/bot/) handle Slack shortcuts and interactions:
joinQueue: Add/update user in reviewer queueleaveQueue: Remove user from queuerequestReview: Initiate a new review requestacceptReviewRequest: Handle reviewer acceptancedeclineReviewRequest: Handle reviewer declinerequestPosition: Show user their position in queuetriggerCron: Dev-only manual cron trigger
Each bot command exports a setup(app) function that registers Slack event handlers.
Scheduled jobs (src/cron/index.ts) run on node-cron in America/Chicago timezone:
- healthCheck: Daily at midnight
- checkAllUsersActive: Daily at 12:05 AM (verifies users still exist in Slack)
- expireRequests: Every 15 minutes during work hours
Work hours are configured via WORKDAY_START_HOUR and WORKDAY_END_HOUR environment variables.
The project uses path aliases (configured in tsconfig.json):
@/*→src/*@bot/*→src/bot/*@cron/@cron/*→src/cron@database→src/database/database@models/*→src/database/models/*@repos/*→src/database/repos/*@services→src/services@utils/*→src/utils/*
- Jest with ts-jest preset
- Tests colocated in
__tests__directories next to source - Coverage thresholds enforced: 80% lines, 75% functions/statements, 55% branches
@utils/logis mocked globally viamoduleNameMapper- Timezone set to
America/Chicagofor tests
IMPORTANT: Before considering any task complete, ALWAYS run pnpm verify to ensure:
- Linting passes
- Code formatting is correct
- TypeScript compilation succeeds
- Build completes successfully
- All tests pass
This helps catch issues early and maintains code quality.
This repo uses Conventional Commits:
feat:- New featurefix:- Bug fixchore:- Refactor, lint fixes, formattingci:- CI updatesdocs:- Documentation changesBREAKING CHANGE:- Breaking changes
PRs are squash-merged, so commit messages on feature branches don't need to follow the convention—just name the PR correctly.