MNO (Music Network One) is a referral-focused networking organization made up of business professionals and musicians. Members meet weekly — via Zoom or in person — to pass referrals, stay visible, and support one another by “Playing It Forward”. This philosophy means promoting others without expecting anything in return, primarily through online visibility and real-world referrals.
MNO members are expected to remain top-of-mind by showing up weekly in meetings and posting three times per week on social media. These posts are distributed through the MNO Member App and published to whichever social media platforms the member has specified in their Feature Link (FL) preferences.
This toolkit automates the chapter performance chair reports that get sent out at various times throughout the week.
- Overview
- What this tool does
- How it works
- Prerequisites
- Setup
- Running reports
- Testing
- Code Quality
- Operational notes
- Troubleshooting
- Project structure (high level)
- Extending with new reports
- Security
- Logs into the MNO portal with your credentials
- Scrapes report pages using a headless browser
- Parses HTML into strongly-typed data
- Generates clean, paste-ready report outputs to stdout
Current reports:
- Chapter Performance Report
- Members (totals, zero/low activity, lists)
- Social media (total posts, averages, rounds)
- Sessions (type breakdowns, submitted-by details)
- Events (type breakdowns, submitted-by details)
- Referrals and Business Bucks
- Weekly Checklist Report
- Member checklists within a date range
- Puppeteer launches a single shared browser with a persistent profile under
.session/chrome-profile.- A single login happens once per run (guarded by a shared promise); each processor gets its own tab (Page) in parallel.
- Cheerio parses HTML tables into typed objects.
- Each report has a dedicated processor; generators render the final report text to stdout.
- Node 20+
- pnpm
- An MNO account with access to the report pages
- Install dependencies:
pnpm install- Copy the example environment file and fill in your values (recommended):
cp .env.example .env
# then edit .env- Chapter performance:
pnpm gen-chapter-report- Weekly checklist:
pnpm gen-checklist-reportThis project includes comprehensive testing with Vitest:
# Run all tests
pnpm test
# Run tests with coverage
pnpm test:coverage
# Run tests in watch mode (development)
pnpm test:watchTests use a dedicated .env.test file for consistent, isolated testing:
# Create test environment file
cp .env.example .env.test
# Edit .env.test with test values
# Tests will automatically use this file via dotenv-cliKey benefits:
- Isolated testing - test environment separate from development
- Consistent results - same environment variables every test run
- No conflicts - won't interfere with your development
.env - Easy maintenance - update test config in one place
This project maintains high code quality through automated tools:
- ESLint v9 with flat config for modern JavaScript/TypeScript
- Prettier for consistent code formatting
- Import sorting and destructuring rules
- TypeScript-specific linting rules
- Pre-commit hooks automatically run formatting and linting
- Ensures code quality before commits
- Consistent code style across the project
- Pre-push hook runs tests
- Ensures tests pass before pushing
# Format code
pnpm format
# Lint and auto-fix
pnpm lint
# Clean dependencies and session data
pnpm clean- A single Chromium instance is launched per run and shared across processors; session persists in
.session/chrome-profile/. - Processors run in parallel using separate tabs; login occurs once and is reused.
- The tool waits for pages to reach network idle before scraping for stability.
- Keep runs reasonable to avoid hammering the MNO site; prefer
PUPPETEER_HEADLESS_MODE=true.
- Login failed or timed out
- Verify
.envcredentials and all URLs/paths - Remove the
.session/chrome-profile/directory to reset the browser session
- Verify
- Report table not found
- The MNO page structure may have changed; update selectors in the corresponding processor
- Date input issues (weekly checklist)
- Ensure dates are valid and parseable (e.g.,
YYYY-MM-DD)
- Ensure dates are valid and parseable (e.g.,
- Test failures due to environment variables
- Ensure
.env.testfile exists and contains all required variables - Run
cp .env.example .env.testand update with test values
- Ensure
src/index.ts— CLI entrypoint and report routingsrc/interfaces/— Strongly-typed data contractssrc/lib/Scraper.ts— Shared browser/session/auth managementsrc/lib/processors/*.ts— Report processors for each report typesrc/lib/reportGenerators/*.ts— Report generators for each report type (text output)src/utils/— Utility functions (number formatting, string processing, etc.)tests/— Comprehensive test suite
- Add a processor under
src/lib/processors/YourNewProcessor.tsusing the established pattern:init()→parse()→ optional validate/aggregate → typed getter
- Add a report generator in
src/lib/reportGenerators/YourReportGenerator.ts. - Wire it up in
src/index.tsand add a script inpackage.json:
{
"scripts": {
"gen-new-report": "tsx --env-file=./.env -r dotenv/config src/index.ts yourReportType"
}
}- Add tests for your new functionality in the
tests/directory
- Credentials live only in your local
.envand never leave your machine. - Everything runs locally; nothing is deployed or shared.
- Avoid committing
.envor.sessiondata to version control.
This project is licensed under the MIT License. See LICENSE for details.