Add initial project structure, including README, CONTRIBUTING, and documentation files
- Created .gitignore to exclude unnecessary files - Added README.md with project description and core features - Introduced CONTRIBUTING.md for development guidelines - Established documentation files for architecture, quality requirements, and technical risks
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
|||||||
|
# agents
|
||||||
|
.agents/
|
||||||
|
.clinerules/
|
||||||
|
.cursor/
|
||||||
|
.github/instructions/
|
||||||
|
.github/copilot-instructions.md
|
||||||
|
.opencode/
|
||||||
|
.windsurf/
|
||||||
|
AGENTS.md
|
||||||
|
skills-lock.json
|
||||||
|
|
||||||
|
# environment files
|
||||||
|
.env
|
||||||
|
|
||||||
|
# node modules
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# build and test outputs
|
||||||
|
dist/
|
||||||
|
coverage/
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
Internal development only. PRs reviewed by @directors.
|
||||||
|
|
||||||
|
## Code Standards
|
||||||
|
|
||||||
|
- **Language:** TypeScript (Node.js) per ADR-001
|
||||||
|
- **Commands:** kebab-case (`/sign-up`, not `/signup`)
|
||||||
|
- **Events:** `on<EventName>` handler pattern
|
||||||
|
- **DB:** snake_case table names, plural
|
||||||
|
- **Commits:** [Conventional Commits](https://www.conventionalcommits.org/) (`feat:`, `fix:`, `chore:`, `docs:`)
|
||||||
|
- **Env vars:** Required vars documented in `.env.example`. Never commit `.env`.
|
||||||
|
|
||||||
|
## PR Process
|
||||||
|
|
||||||
|
1. Branch from `main`. Name: `feat/`, `fix/`, `chore/` prefix.
|
||||||
|
2. Lint + tests pass before push.
|
||||||
|
3. PR description links to any related issue.
|
||||||
|
4. At least 1 approval from @directors required.
|
||||||
|
5. Squash-merge to `main`.
|
||||||
|
|
||||||
|
## Reporting Issues
|
||||||
|
|
||||||
|
Open GitHub issue with:
|
||||||
|
|
||||||
|
- Steps to reproduce
|
||||||
|
- Expected vs actual behavior
|
||||||
|
- Bot logs (redact tokens)
|
||||||
|
- Discord command and response if relevant
|
||||||
|
|
||||||
|
## Architecture Reference
|
||||||
|
|
||||||
|
See [arc42 docs](/docs/01_introduction_and_goals.md) for full architecture context.
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
# Discord Bot for Open Mic Odyssey
|
||||||
|
|
||||||
|
A custom Discord bot and web integration layer designed to bridge the [openmicodyssey.com](https://openmicodyssey.com) experience with our community server. This application gamifies community engagement, automates content syndication, and provides a suite of event management tools centered around the themes of stand-up comedy, indie filmmaking, and a cross-country road trip.
|
||||||
|
|
||||||
|
## Core Features
|
||||||
|
|
||||||
|
### The Call Sheet (User & Role Management)
|
||||||
|
|
||||||
|
- **The Experience:** New members are greeted with a customized onboarding menu to declare their interests (e.g., `@ComedyFan`, `@Filmmaker`). Active users progress through community ranks, leveling up from **"Extra"** to **"Roadie"** and eventually **"Executive Producer"**.
|
||||||
|
- **Technical Implementation:** Utilizes Discord's Reaction Role payloads and interaction webhooks for automated Role-Based Access Control (RBAC). Implements dynamic permission bitfield assignment and role hierarchy state management based on user activity telemetry.
|
||||||
|
|
||||||
|
### The Tour Schedule (Event Management)
|
||||||
|
|
||||||
|
- **The Experience:** Organizes virtual **"Tour Stops"** (screenings) and digital open mics. Users can utilize the `/sign-up` command to enter the stage queue, while attendees receive temporary **"VIP Backstage"** passes for live Q&As.
|
||||||
|
- **Technical Implementation:** Wraps the Discord Scheduled Events API. Implements a FIFO (First-In-First-Out) queue data structure for managing Voice/Stage channel speaker states. Handles automated role assignment/revocation for temporary event permissions.
|
||||||
|
|
||||||
|
### The Dailies (Content Webhooks & Syndication)
|
||||||
|
|
||||||
|
- **The Experience:** Automatically delivers fresh behind-the-scenes content directly from the crew's socials to dedicated server channels:
|
||||||
|
- `#polaroids-from-the-van`: Instagram drops.
|
||||||
|
- `#outtakes`: TikTok crowd work and detours.
|
||||||
|
- `#screenings`: YouTube trailers and vlogs.
|
||||||
|
|
||||||
|
- **Technical Implementation:** Event-driven architecture utilizing incoming Discord Webhooks. Integrates external API polling (YouTube Data API, TikTok/IG endpoints) to fetch, parse, and format multimedia payloads into rich Discord Embeds.
|
||||||
|
|
||||||
|
### Mileage & The Hidden Map (Gamified Progression)
|
||||||
|
|
||||||
|
- **The Experience:** Every interaction earns users **"Mileage"**. Accumulating miles unlocks secure passwords and GPS coordinates for the hidden `/map` route on the main website, granting access to deleted scenes and exclusive scripts.
|
||||||
|
- **Technical Implementation:** Requires Discord OAuth2 integration with the main web application. Message and event telemetry are captured, scored, and stored in a database (e.g., PostgreSQL/MongoDB), continuously syncing the user's Discord state with their authenticated web session.
|
||||||
|
|
||||||
|
### The Control Room (Admin Web Interface)
|
||||||
|
|
||||||
|
- **The Experience:** A dedicated dashboard for the **"Producers"** and **"Directors"** to manage the server, schedule content drops, and view engagement without touching Discord commands.
|
||||||
|
- **Technical Implementation:** A standalone web portal (intended for `admin.openmicodyssey.com`). Exposes secure RESTful/GraphQL endpoints for bot configuration, CRON job scheduling for content drops, and data visualization for external link click-through rates.
|
||||||
|
|
||||||
|
## Architecture Documentation (arc42)
|
||||||
|
|
||||||
|
This project uses the [arc42](https://arc42.org) architecture documentation template.
|
||||||
|
All chapters are in `docs/`:
|
||||||
|
|
||||||
|
| # | Chapter | File |
|
||||||
|
| --- | ------------------------ | ---------------------------------------------------------------------------- |
|
||||||
|
| 1 | Introduction & Goals | [`docs/01_introduction_and_goals.md`](docs/01_introduction_and_goals.md) |
|
||||||
|
| 2 | Architecture Constraints | [`docs/02_architecture_constraints.md`](docs/02_architecture_constraints.md) |
|
||||||
|
| 3 | Context & Scope | [`docs/03_context_and_scope.md`](docs/03_context_and_scope.md) |
|
||||||
|
| 4 | Solution Strategy | [`docs/04_solution_strategy.md`](docs/04_solution_strategy.md) |
|
||||||
|
| 5 | Building Block View | [`docs/05_building_block_view.md`](docs/05_building_block_view.md) |
|
||||||
|
| 6 | Runtime View | [`docs/06_runtime_view.md`](docs/06_runtime_view.md) |
|
||||||
|
| 7 | Deployment View | [`docs/07_deployment_view.md`](docs/07_deployment_view.md) |
|
||||||
|
| 8 | Cross-cutting Concepts | [`docs/08_concepts.md`](docs/08_concepts.md) |
|
||||||
|
| 9 | Architecture Decisions | [`docs/09_architecture_decisions.md`](docs/09_architecture_decisions.md) |
|
||||||
|
| 10 | Quality Requirements | [`docs/10_quality_requirements.md`](docs/10_quality_requirements.md) |
|
||||||
|
| 11 | Risks & Technical Debt | [`docs/11_technical_risks.md`](docs/11_technical_risks.md) |
|
||||||
|
| 12 | Glossary | [`docs/12_glossary.md`](docs/12_glossary.md) |
|
||||||
|
|
||||||
|
## Architecture & Tech Stack
|
||||||
|
|
||||||
|
| Layer | Choice |
|
||||||
|
| --------------- | -------------------- |
|
||||||
|
| Runtime | Node.js (Discord.js) |
|
||||||
|
| Database | PostgreSQL |
|
||||||
|
| Admin Dashboard | React |
|
||||||
|
| Auth | Discord OAuth2 |
|
||||||
|
| Hosting | Coolify + Nixpacks |
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Node.js v16+ (or Python 3.9+)
|
||||||
|
- A Discord Developer Application with Bot Token
|
||||||
|
- Access to `openmicodyssey.com` backend for OAuth syncing
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
1. Clone the repository:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/your-org/open-mic-odyssey-bot.git
|
||||||
|
cd open-mic-odyssey-bot
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Install dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Configure environment variables. Duplicate `.env.example` to `.env` and add your specific keys:
|
||||||
|
|
||||||
|
```env
|
||||||
|
DISCORD_TOKEN=your_bot_token
|
||||||
|
CLIENT_ID=your_client_id
|
||||||
|
GUILD_ID=your_server_id
|
||||||
|
DB_CONNECTION_STRING=your_db_uri
|
||||||
|
YOUTUBE_API_KEY=your_yt_key
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Deploy Slash Commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run deploy-commands
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Start the bot:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm start
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
For internal development only. Please refer to [CONTRIBUTING.md](CONTRIBUTING.md) for styling guidelines and PR review processes for "The Control Room" dashboard updates.
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Introduction and Goals
|
||||||
|
|
||||||
|
## Business Goals
|
||||||
|
|
||||||
|
- **Community engagement gamification** — Drive member participation through mileage-based progression system
|
||||||
|
- **Content syndication automation** — Auto-deliver YouTube, Instagram, TikTok content to Discord channels
|
||||||
|
- **Event management simplification** — Streamline virtual "Tour Stop" screenings and open mic scheduling
|
||||||
|
- **Cross-platform bridge** — Connect Discord community with openmicodyssey.com via OAuth2
|
||||||
|
|
||||||
|
## Essential Features
|
||||||
|
|
||||||
|
- Reaction-role onboarding ("The Call Sheet")
|
||||||
|
- Event queue management with `/sign-up` command
|
||||||
|
- Automated webhook syndication ("The Dailies")
|
||||||
|
- Mileage-based progression system
|
||||||
|
- Admin web dashboard ("The Control Room")
|
||||||
|
|
||||||
|
## Quality Goals
|
||||||
|
|
||||||
|
| Priority | Goal | Scenario |
|
||||||
|
| -------- | ---------------- | ------------------------------------------------------------------------------------- |
|
||||||
|
| 1 | Availability | Bot responds within 2s during peak events (100+ concurrent users) |
|
||||||
|
| 2 | Data consistency | Mileage and role state survive bot restarts without drift |
|
||||||
|
| 3 | Extensibility | New content sources (Twitter, RSS) addable via adapter without core changes |
|
||||||
|
| 4 | Security | OAuth2 tokens never exposed; role assignments authorized via Discord permission model |
|
||||||
|
|
||||||
|
## Stakeholders
|
||||||
|
|
||||||
|
| Role | Contact | Expectation |
|
||||||
|
| ----------------- | ------------------ | ------------------------------------------------------- |
|
||||||
|
| Community Manager | @producers | Easy event scheduling, content automation |
|
||||||
|
| Developer | @directors | Clean codebase, documented APIs, testable |
|
||||||
|
| End User | @community | Fun onboarding, seamless XP tracking, reliable commands |
|
||||||
|
| Site Owner | openmicodyssey.com | Secure OAuth2 bridge, accurate mileage sync |
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Architecture Constraints
|
||||||
|
|
||||||
|
## Technical Constraints
|
||||||
|
|
||||||
|
| Constraint | Description |
|
||||||
|
| ---------- | --------------------------------------------------------------------------------------------------- |
|
||||||
|
| Runtime | Discord Bot must run on Node.js (Discord.js) or Python (Discord.py) per existing proposal |
|
||||||
|
| Hosting | Bot process must run 24/7 — planned deployment to Coolify |
|
||||||
|
| API Limits | Discord rate limits (50 req/s per route); webhook pollers must respect YouTube/IG/TikTok quota caps |
|
||||||
|
| OAuth2 | Web app auth must use Discord OAuth2 — no custom auth service |
|
||||||
|
| Database | PostgreSQL or MongoDB required for mileage and state persistence |
|
||||||
|
|
||||||
|
## Organizational Constraints
|
||||||
|
|
||||||
|
| Constraint | Description |
|
||||||
|
| ----------- | ----------------------------------------------------------------------------------------- |
|
||||||
|
| Development | Internal team only; no open-source contributions from outside |
|
||||||
|
| Deployment | Admin dashboard hosted at `admin.openmicodyssey.com` — CORS and subdomain config required |
|
||||||
|
| Branding | All documentation, embeds, and UI must reflect "Open Mic Odyssey" road-trip theme |
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Git commit messages follow Conventional Commits format
|
||||||
|
- Environment variables stored in `.env`, never committed
|
||||||
|
- Slash commands registered via `deploy-commands` script, not manual guild config
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# Context and Scope
|
||||||
|
|
||||||
|
## Business Context
|
||||||
|
|
||||||
|
```txt
|
||||||
|
┌─────────────────┐ Discord API ┌──────────────────┐
|
||||||
|
│ Discord Users │◄───────────────────────► │ omo-bot │
|
||||||
|
│ (Community) │ slash cmds, embeds │ (Discord Bot) │
|
||||||
|
└─────────────────┘ └────────┬─────────┘
|
||||||
|
│
|
||||||
|
OAuth2 + REST │
|
||||||
|
▼
|
||||||
|
┌────────────────┐
|
||||||
|
│ openmicodyssey │
|
||||||
|
│ .com (Web App) │
|
||||||
|
└────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Technical Context
|
||||||
|
|
||||||
|
| Partner | Protocol | Data | Description |
|
||||||
|
| ------------------ | -------------------------- | --------------------------------------- | ------------------------------------ |
|
||||||
|
| Discord API | WebSocket (Gateway) + REST | Messages, roles, events, voice states | Bot core communication |
|
||||||
|
| YouTube Data API | HTTPS (REST + polling) | Video metadata, thumbnails | Auto-post new uploads to #screenings |
|
||||||
|
| Instagram API | HTTPS (REST + polling) | Image URLs, captions | Auto-post to #polaroids-from-the-van |
|
||||||
|
| TikTok API | HTTPS (REST + polling) | Video metadata | Auto-post to #outtakes |
|
||||||
|
| openmicodyssey.com | HTTPS (OAuth2 + REST) | User profiles, mileage data, map routes | Web session sync |
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
**In scope:** Discord bot commands, reaction-role management, event queue, content webhook syndication, mileage tracking, admin dashboard API.
|
||||||
|
|
||||||
|
**Out of scope:** The main `openmicodyssey.com` website frontend, native mobile apps, third-party content moderation.
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# Solution Strategy
|
||||||
|
|
||||||
|
## Technology Decisions
|
||||||
|
|
||||||
|
| Decision | Choice | Rationale |
|
||||||
|
| ---------------- | -------------------- | --------------------------------------------------------------------------------------- |
|
||||||
|
| Bot framework | Discord.js (Node.js) | Mature library, strong type support, rich event model |
|
||||||
|
| Database | PostgreSQL | Reliable, supports JSONB for flexible user state, well-suited for mileage/role tracking |
|
||||||
|
| Frontend (Admin) | React | Team familiarity, rich ecosystem for dashboards |
|
||||||
|
| Hosting | Coolify | Easy deployment for Node.js with Nixpacks. |
|
||||||
|
| Auth | Discord OAuth2 | No custom auth needed, seamless web/bot integration |
|
||||||
|
|
||||||
|
## Top-Level Decomposition
|
||||||
|
|
||||||
|
The system follows a **modular monolith** pattern with clear separation:
|
||||||
|
|
||||||
|
- **Core Bot** — command handlers, event listeners, Discord Gateway logic
|
||||||
|
- **Content Syndicator** — polling adapters for YouTube/IG/TikTok, webhook dispatch
|
||||||
|
- **Event Manager** — FIFO queue for stage/speaker management
|
||||||
|
- **Mileage Engine** — scoring logic, persistence, state sync with web app
|
||||||
|
- **Admin API** — RESTful endpoints for bot config, content scheduling, analytics
|
||||||
|
|
||||||
|
## Key Quality Goals
|
||||||
|
|
||||||
|
- **Availability** — Stateless bot instances scale horizontally behind load balancer
|
||||||
|
- **Consistency** — Write-ahead logging for mileage transactions; periodic state reconciliation with web app
|
||||||
|
- **Extensibility** — Adapter pattern for content sources: implement interface, register, deploy
|
||||||
|
|
||||||
|
## Organizational Decisions
|
||||||
|
|
||||||
|
- One-person or small-team development per project scope
|
||||||
|
- CI/CD via Gitea Actions: lint → test → deploy
|
||||||
|
- Feature toggles for admin dashboard rollout
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# Building Block View
|
||||||
|
|
||||||
|
## Whitebox Overall System (Level 1)
|
||||||
|
|
||||||
|
```txt
|
||||||
|
┌──────────────────────────────────────────────────────┐
|
||||||
|
│ omo-bot │
|
||||||
|
├──────────────────────────────────────────────────────┤
|
||||||
|
│ ┌──────────────────┐ ┌─────────────────────────┐ │
|
||||||
|
│ │ Command Layer │ │ Event Listener Layer │ │
|
||||||
|
│ │ /sign-up, /map │ │ member_join, reaction │ │
|
||||||
|
│ └────────┬─────────┘ └───────────┬─────────────┘ │
|
||||||
|
│ │ │ │
|
||||||
|
│ ▼ ▼ │
|
||||||
|
│ ┌──────────────────────────────────────────────┐ │
|
||||||
|
│ │ Service Layer │ │
|
||||||
|
│ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │
|
||||||
|
│ │ │ Event │ │ Mileage │ │ Content │ │ │
|
||||||
|
│ │ │ Manager │ │ Engine │ │ Syndicator │ │ │
|
||||||
|
│ │ └──────────┘ └──────────┘ └──────────────┘ │ │
|
||||||
|
│ └───────────────────┬──────────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌──────────────────────────────────────────────┐ │
|
||||||
|
│ │ Data / Persistence Layer │ │
|
||||||
|
│ │ PostgreSQL DB + Discord API Wrapper │ │
|
||||||
|
│ └──────────────────────────────────────────────┘ │
|
||||||
|
└──────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Black Box Descriptions
|
||||||
|
|
||||||
|
| Building Block | Responsibility |
|
||||||
|
| ------------------ | ------------------------------------------------------------------------------------------ |
|
||||||
|
| Command Layer | Register and handle slash commands (`/sign-up`, `/map`, `/help`); validate permissions |
|
||||||
|
| Event Listener | Subscribe to Discord Gateway events (member join, reaction add, voice state change) |
|
||||||
|
| Event Manager | Manage FIFO queue for voice/stage speakers; schedule "Tour Stop" events via Discord API |
|
||||||
|
| Mileage Engine | Score user interactions, persist to DB, trigger role upgrades, sync with web app |
|
||||||
|
| Content Syndicator | Poll YouTube/IG/TikTok APIs; format rich embeds; dispatch to Discord channels via webhooks |
|
||||||
|
| Admin API | Expose REST endpoints for dashboard (configuration, content schedule, engagement stats) |
|
||||||
|
| DB Layer | PostgreSQL connection pool, migrations, query builders |
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Runtime View
|
||||||
|
|
||||||
|
## Scenario: User Signs Up for Open Mic
|
||||||
|
|
||||||
|
1. User runs `/sign-up` in voice channel
|
||||||
|
2. Command Layer validates user has `@ComedyFan` role
|
||||||
|
3. Event Manager adds user to FIFO queue
|
||||||
|
4. When previous speaker leaves stage (voice state change), Event Manager pops queue
|
||||||
|
5. Bot grants temporary speaker permission via voice channel API
|
||||||
|
6. Announcement sent to `#stage-door` channel
|
||||||
|
7. Mileage Engine awards +50 miles for participation
|
||||||
|
|
||||||
|
## Scenario: Content Auto-Post
|
||||||
|
|
||||||
|
1. CRON job triggers Content Syndicator every 15 min
|
||||||
|
2. Syndicator polls YouTube Data API for new uploads on channel
|
||||||
|
3. New video detected → fetches metadata + thumbnail
|
||||||
|
4. Syndicator builds rich embed (title, description, thumbnail, link)
|
||||||
|
5. Embed posted to `#screenings` channel via Discord webhook
|
||||||
|
6. Mileage Engine awards +10 miles to channel subscribers
|
||||||
|
|
||||||
|
## Scenario: Admin Updates Bot Restart
|
||||||
|
|
||||||
|
1. Bot receives SIGTERM from hosting platform
|
||||||
|
2. Graceful shutdown initiated: close Gateway connection, flush pending DB writes
|
||||||
|
3. Bot process restarts
|
||||||
|
4. On startup: reconnect to Discord Gateway, rehydrate in-memory state from DB
|
||||||
|
5. Mileage state is consistent — no data loss
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# Deployment View
|
||||||
|
|
||||||
|
## Infrastructure Overview
|
||||||
|
|
||||||
|
```txt
|
||||||
|
┌─────────────┐ ┌──────────────────────────────────────┐
|
||||||
|
│ Discord │◄─────►│ Coolify │
|
||||||
|
│ Gateway │ WSS │ │
|
||||||
|
│ + REST API │ │ ┌──────────────────────────────┐ │
|
||||||
|
└─────────────┘ │ │ omo-bot (Node.js process) │ │
|
||||||
|
│ │ - Command handlers │ │
|
||||||
|
│ │ - Event listeners │ │
|
||||||
|
│ │ - Mileage engine │ │
|
||||||
|
│ └──────────┬───────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌──────────────────────────────┐ │
|
||||||
|
│ │ PostgreSQL (local) │ │
|
||||||
|
│ │ - User profiles │ │
|
||||||
|
│ │ - Mileage scores │ │
|
||||||
|
│ │ - Event schedules │ │
|
||||||
|
│ │ - Content cache │ │
|
||||||
|
│ └──────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────────────────────┐ │
|
||||||
|
│ │ Admin API / Dashboard │ │
|
||||||
|
│ │ (React SPA) │ │
|
||||||
|
│ │ admin.openmicodyssey.com │ │
|
||||||
|
│ └──────────────────────────────┘ │
|
||||||
|
└──────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
OAuth2 │
|
||||||
|
▼
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ openmicodyssey.com │
|
||||||
|
│ (Web Application) │
|
||||||
|
└─────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environments
|
||||||
|
|
||||||
|
| Environment | Host | Bot Instance | DB | Purpose |
|
||||||
|
| ----------- | ---------------- | ------------ | ---------------- | ---------------------------- | ---------------------- |
|
||||||
|
| Development | Local machine | 1 process | Local Postgres | Feature development, testing |
|
||||||
|
| Staging | Coolify | 1 instance | Staging Postgres | Integration | Pre-release validation |
|
||||||
|
| Production | Coolify (scaled) | 2+ instances | Production (HA) | Live community server |
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Cross-cutting Concepts
|
||||||
|
|
||||||
|
## Logging & Monitoring
|
||||||
|
|
||||||
|
- Structured logging (JSON) to stdout — visible in Coolify logs and via `docker logs`
|
||||||
|
- Log levels: DEBUG (dev), INFO (prod), ERROR (alert-worthy)
|
||||||
|
- Key metrics exposed via Prometheus endpoint: commands/sec, webhook latency, active users
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
- Command handlers: try/catch → ephemeral error reply to user + logged
|
||||||
|
- Content pollers: exponential backoff on API failures, alert after 3 consecutive failures
|
||||||
|
- Mileage writes: retry (3x, 50ms backoff) before logging as failed
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
- Environment variables via `.env` file (dev) or Coolify secrets (prod), keep example in `.env.example`
|
||||||
|
- Config schema validated on startup — bot exits on missing required vars
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
- Bot token stored in env variable, never logged
|
||||||
|
- OAuth2 tokens short-lived; refresh flow managed by web app
|
||||||
|
- Admin dashboard routes guarded by Discord OAuth2 role check (`@Producer` or `@Director`)
|
||||||
|
- All external API calls over HTTPS
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Slash command names: kebab-case
|
||||||
|
- Event handler naming: `on<EventName>` pattern
|
||||||
|
- Database table names: snake_case, plural
|
||||||
|
- PRs require passing lint + tests before merge
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Architecture Decisions
|
||||||
|
|
||||||
|
## ADR-001: Discord.js over Discord.py
|
||||||
|
|
||||||
|
**Status:** Accepted
|
||||||
|
**Context:** Node.js and Python both viable. Team has stronger Node.js experience.
|
||||||
|
**Decision:** Use Discord.js for the bot runtime.
|
||||||
|
**Consequences:** Faster development velocity; ecosystem rich with community plugins (command handling, modals, components).
|
||||||
|
|
||||||
|
## ADR-002: PostgreSQL over MongoDB
|
||||||
|
|
||||||
|
**Status:** Accepted
|
||||||
|
**Context:** Mileage data is relational (user → role → event → score). MongoDB adds flexibility but sacrifices query power.
|
||||||
|
**Decision:** Use PostgreSQL with JSONB columns for extensible user metadata.
|
||||||
|
**Consequences:** Schema migrations needed for new features; joins straightforward.
|
||||||
|
|
||||||
|
## ADR-003: Polling over Webhooks for Content Sources
|
||||||
|
|
||||||
|
**Status:** Accepted
|
||||||
|
**Context:** YouTube, Instagram, TikTok do not provide push webhooks to arbitrary third parties without approval.
|
||||||
|
**Decision:** Poll public APIs on a CRON schedule (15-min interval).
|
||||||
|
**Consequences:** ~5 min delay between publish and Discord post; API quota management required.
|
||||||
|
|
||||||
|
## ADR-004: Modular Monolith over Microservices
|
||||||
|
|
||||||
|
**Status:** Accepted
|
||||||
|
**Context:** Single-developer or small team; deployment complexity of microservices not justified.
|
||||||
|
**Decision:** Single process with internal module boundaries (commands, events, mileage, syndication).
|
||||||
|
**Consequences:** Simpler deploy, debug, and develop; can extract services later if needed.
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
# Quality Requirements
|
||||||
|
|
||||||
|
Content
|
||||||
|
|
||||||
|
This section contains all relevant quality requirements.
|
||||||
|
|
||||||
|
The most important of these requirements have already been described in
|
||||||
|
section 1.2. (quality goals), therefore they should only be referenced
|
||||||
|
here. In this section 10 you should also capture quality requirements
|
||||||
|
with lesser importance, which will not create high risks when they are
|
||||||
|
not fully achieved (but might be _nice-to-have_).
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
|
||||||
|
Since quality requirements will have a lot of influence on architectural
|
||||||
|
decisions you should know what qualities are really important for your
|
||||||
|
stakeholders, in a specific and measurable way.
|
||||||
|
|
||||||
|
Further Information
|
||||||
|
|
||||||
|
- See [Quality Requirements](10_quality_requirements.md) in the
|
||||||
|
arc42 documentation.
|
||||||
|
|
||||||
|
- See the extensive [Q42 quality model on
|
||||||
|
<https://quality.arc42.org>](https://quality.arc42.org).
|
||||||
|
|
||||||
|
## Quality Requirements Overview
|
||||||
|
|
||||||
|
Content
|
||||||
|
|
||||||
|
An overview or summary of quality requirements.
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
|
||||||
|
Often we encounter dozens (or even hundreds) of detailed quality
|
||||||
|
requirements. In this overview section you should try to summarize, e.g.
|
||||||
|
by describing categories or topics (as suggested by [ISO
|
||||||
|
25010:2023](https://www.iso.org/obp/ui/#iso:std:iso-iec:25010:ed-2:v1:en)
|
||||||
|
or [Q42](https://quality.arc42.org))
|
||||||
|
|
||||||
|
If these summary descriptions are already precise, specific enough and
|
||||||
|
measurable, you may skip section 10.2.
|
||||||
|
|
||||||
|
Form
|
||||||
|
|
||||||
|
Use a simple table in which each line contains a category or topic and a
|
||||||
|
short description of the quality requirement. Alternatively, you may use
|
||||||
|
a mindmap to structure these quality requirements. In literature, the
|
||||||
|
idea of a _quality attribute tree_ has also been described, which puts
|
||||||
|
the generic term "quality" as the root and uses a tree-like refinement
|
||||||
|
of the term "quality". \[Bass+21\] introduced the term "Quality
|
||||||
|
Attribute Utility Tree" for this purpose.
|
||||||
|
|
||||||
|
## Quality Scenarios
|
||||||
|
|
||||||
|
Content
|
||||||
|
|
||||||
|
Quality scenarios make quality requirements concrete and allow to decide
|
||||||
|
whether they are fulfilled (in the sense of acceptance criteria). Ensure
|
||||||
|
that your scenarios are specific and measurable.
|
||||||
|
|
||||||
|
Two kinds of scenarios are especially useful:
|
||||||
|
|
||||||
|
- _Usage scenarios_ (also called application scenarios or use case
|
||||||
|
scenarios) describe the system’s runtime reaction to a certain
|
||||||
|
stimulus. This also includes scenarios that describe the system’s
|
||||||
|
efficiency or performance. Example: The system reacts to a user’s
|
||||||
|
request within one second.
|
||||||
|
|
||||||
|
- _Change scenarios_ describe the desired effect of a modification or
|
||||||
|
extension of the system or of its immediate environment. Example:
|
||||||
|
Additional functionality is implemented or requirements for a quality
|
||||||
|
attribute change, and the effort or duration of the change is
|
||||||
|
measured.
|
||||||
|
|
||||||
|
Form
|
||||||
|
|
||||||
|
Typical information for detailed scenarios include the following:
|
||||||
|
|
||||||
|
In short form (favoured in the Q42 model):
|
||||||
|
|
||||||
|
- **Context/Background**: What kind of system or component, what is the
|
||||||
|
envirionment or situation?
|
||||||
|
|
||||||
|
- **Source/Stimulus**: Who or what initiates or triggers a behaviour,
|
||||||
|
reaction or action.
|
||||||
|
|
||||||
|
- **Metric/Acceptance Criteria**: A response including a _measure_ or
|
||||||
|
_metric_
|
||||||
|
|
||||||
|
The long form of scenarios (favoured by the SEI and \[Bass+21\]) is more
|
||||||
|
detailed and includes the following information:
|
||||||
|
|
||||||
|
- **Scenario ID**: A unique identifier for the scenario.
|
||||||
|
|
||||||
|
- **Scenario Name**: A short, descriptive name for the scenario.
|
||||||
|
|
||||||
|
- **Source**: The entity (user, system, or event) that initiates the
|
||||||
|
scenario.
|
||||||
|
|
||||||
|
- **Stimulus**: The triggering event or condition the system must
|
||||||
|
address.
|
||||||
|
|
||||||
|
- **Environment**: The operational context or condition under which the
|
||||||
|
system experiences the stimulus.
|
||||||
|
|
||||||
|
- **Artifact**: The building-blocks or other elements of the system
|
||||||
|
affected by the stimulus.
|
||||||
|
|
||||||
|
- **Response**: The outcome or behavior the system exhibits in reaction
|
||||||
|
to the stimulus.
|
||||||
|
|
||||||
|
- **Response Measure**: The criteria or metric by which the system’s
|
||||||
|
response is evaluated.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
|
||||||
|
See [the Q42 quality model website](https://quality.arc42.org) for
|
||||||
|
detailed examples of quality requirements.
|
||||||
|
|
||||||
|
Further Information
|
||||||
|
|
||||||
|
- Len Bass, Paul Clements, Rick Kazman: "Software Architecture in
|
||||||
|
Practice", 4th Edition, Addison-Wesley, 2021.
|
||||||
|
|
||||||
|
## Project-Specific Scenarios
|
||||||
|
|
||||||
|
| Quality | Scenario | Priority | Current Gap |
|
||||||
|
| ---------------- | --------------------------------------------------- | -------- | ----------------------------------------- |
|
||||||
|
| Availability | Bot must handle 100+ concurrent users during events | High | Not yet load-tested |
|
||||||
|
| Responsiveness | Slash commands respond within 2s | High | Baseline OK; need perf testing under load |
|
||||||
|
| Data consistency | Mileage not lost on crash or restart | High | Write-ahead logging not yet implemented |
|
||||||
|
| Security | No token leakage via logs or error messages | Critical | Pass — tokens env-only |
|
||||||
|
| Extensibility | Add new content source in ≤2 days work | Medium | Adapter pattern defined, not yet coded |
|
||||||
|
|
||||||
|
## Nice-to-Have
|
||||||
|
|
||||||
|
| Quality | Scenario |
|
||||||
|
| ------------------ | -------------------------------------------- |
|
||||||
|
| Localization | Embeds and messages in multiple languages |
|
||||||
|
| Accessibility | Dashboard UI meets WCAG 2.1 AA |
|
||||||
|
| Offline resilience | Bot caches last hour of events on local disk |
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# Risks and Technical Debts
|
||||||
|
|
||||||
|
## Identified Risks
|
||||||
|
|
||||||
|
| Priority | Risk | Likelihood | Impact | Mitigation |
|
||||||
|
| -------- | ------------------------------------------------ | ---------- | -------- | --------------------------------------------------------------- |
|
||||||
|
| High | API quota exhaustion (YouTube/TikTok) | Medium | High | Cache aggressively; add quota alerts; stagger poll intervals |
|
||||||
|
| High | Discord rate limit bans if polling misconfigured | Low | Critical | Implement proper backoff; respect `Retry-After` headers |
|
||||||
|
| Medium | OAuth2 token expiry during web session | Medium | Medium | Implement refresh token rotation; warn user before expiry |
|
||||||
|
| Medium | Single-process bot: any crash = total downtime | Medium | High | Use process manager (PM2); deploy to platform with auto-restart |
|
||||||
|
| Low | Mileage database drift between bot and web app | Low | Medium | Periodic reconciliation job (nightly) |
|
||||||
|
|
||||||
|
## Technical Debts
|
||||||
|
|
||||||
|
| Item | Area | Description | Priority |
|
||||||
|
| ---------------- | ------ | -------------------------------------- | -------- |
|
||||||
|
| No test coverage | All | Tests not implemented for any module | High |
|
||||||
|
| No CI pipeline | DevOps | Lint + test not automated in PRs | High |
|
||||||
|
| Inline config | Bot | Some settings hardcoded instead of env | Medium |
|
||||||
|
| Manual deploy | DevOps | No deployment script / IaC yet | Medium |
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Glossary
|
||||||
|
|
||||||
|
| Term | Definition |
|
||||||
|
| ------------------ | -------------------------------------------------------------- |
|
||||||
|
| Call Sheet | Onboarding system for role assignment via reaction roles |
|
||||||
|
| Mileage | Gamified XP earned through community interactions |
|
||||||
|
| Tour Stop | A scheduled virtual event (screening or open mic) |
|
||||||
|
| The Dailies | Auto-syndicated content feeds from YouTube/IG/TikTok |
|
||||||
|
| The Control Room | Admin web dashboard for bot management |
|
||||||
|
| VIP Backstage | Temporary role granting Q&A access during events |
|
||||||
|
| Executive Producer | Highest community rank, reached via mileage progression |
|
||||||
|
| OAuth2 | Discord-based authentication for web app session sync |
|
||||||
|
| FIFO Queue | First-In-First-Out data structure for stage speaker management |
|
||||||
|
| Adapter | Pluggable module for adding new content sources |
|
||||||
Vendored
+44
@@ -0,0 +1,44 @@
|
|||||||
|
# Architectural Decision Record (ADR)
|
||||||
|
|
||||||
|
This template document outlines the format for recording architectural decisions made during the development of the Open Mic Odyssey Bot. Each decision should be documented in a separate ADR file within the `docs/architecture_decisions` directory, following the structure below.
|
||||||
|
|
||||||
|
## ADR Template
|
||||||
|
|
||||||
|
### Title
|
||||||
|
|
||||||
|
A concise title for the architectural decision.
|
||||||
|
|
||||||
|
### Status
|
||||||
|
|
||||||
|
The current status of the decision (e.g., Proposed, Accepted, Rejected, Deprecated).
|
||||||
|
|
||||||
|
### Context
|
||||||
|
|
||||||
|
A detailed description of the context in which the decision is being made. This should include any relevant background information, constraints, and considerations that influenced the decision.
|
||||||
|
|
||||||
|
### Decision
|
||||||
|
|
||||||
|
A clear statement of the architectural decision that has been made. This should be specific and actionable.
|
||||||
|
|
||||||
|
### Consequences
|
||||||
|
|
||||||
|
An analysis of the consequences of the decision, including any trade-offs, benefits, and potential drawbacks. This section should also discuss how the decision impacts other parts of the system and any future implications.
|
||||||
|
|
||||||
|
### Example ADR
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# ADR-001: Discord.js over Discord.py
|
||||||
|
|
||||||
|
**Status:** Accepted
|
||||||
|
**Context:** Node.js and Python both viable. Team has stronger Node.js experience.
|
||||||
|
**Decision:** Use Discord.js for the bot runtime.
|
||||||
|
**Consequences:** Faster development velocity; ecosystem rich with community plugins (command handling, modals, components).
|
||||||
|
```
|
||||||
|
|
||||||
|
### Guidelines for Writing ADRs
|
||||||
|
|
||||||
|
- Be clear and concise in your writing.
|
||||||
|
- Ensure that the context and consequences are well thought out and provide enough detail for future reference.
|
||||||
|
- Use a consistent format for all ADRs to maintain readability and organization.
|
||||||
|
- Regularly review and update ADRs as the project evolves and new information becomes available.
|
||||||
|
- Encourage team members to contribute to ADRs and discuss architectural decisions openly to foster collaboration and shared understanding.
|
||||||
Reference in New Issue
Block a user