# aalejandrofer/grubdrops architecture

> Architecture diagram of the GitHub repository aalejandrofer/grubdrops, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/aalejandrofer/grubdrops
- Repository: https://github.com/aalejandrofer/grubdrops

## Overview

GrubDrops is a self-hosted Twitch and Kick drops miner. Admins configure accounts and game whitelists in the web console; the runtime discovers eligible campaigns, watches streams to accrue progress, claims rewards, and exposes status/history. The README documents platform-specific login and watch paths, including Kick’s WebSocket-to-Chrome fallback, plus notifications and SSO. The map uses documented capabilities where implementation excerpts are absent; links for those subsystems are limited to supported paths and avoid implying unverified calls.

Main entry points: [`internal/store/db.go`](https://github.com/aalejandrofer/grubdrops/blob/master/internal/store/db.go) (SQLite Store), [`internal/watcher/watcher.go`](https://github.com/aalejandrofer/grubdrops/blob/master/internal/watcher/watcher.go) (Drop Watcher), [`internal/api/server.go`](https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/server.go) (Web Console), [`internal/scheduler/scheduler.go`](https://github.com/aalejandrofer/grubdrops/blob/master/internal/scheduler/scheduler.go) (Account Scheduler)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_console["Admin Console"]
  node_web["Web Console<br/>[server.go]"]
  node_account_config["Accounts and Games"]
  node_drops_view["Drops Catalog<br/>[handlers_drops.go]"]
  node_dashboard["Dashboard and History"]
  node_settings["Runtime Settings"]
end

subgraph group_mining["Mining Runtime"]
  node_scheduler["Account Scheduler<br/>[scheduler.go]"]
  node_watcher["Drop Watcher<br/>[watcher.go]"]
  node_discovery["Campaign Discovery<br/>[discovery.go]"]
  node_canary["Accrual Canary<br/>[canary.go]"]
end

subgraph group_platforms["Platform Access"]
  node_twitch["Twitch Backend<br/>[backend.go]"]
  node_kick["Kick Backend<br/>[backend.go]"]
  node_browser_client["Browser RPC Client<br/>[client.go]"]
  node_sidecar["Browser Sidecar<br/>[server.go]"]
end

subgraph group_identity["Identity and Alerts"]
  node_login["Platform Login"]
  node_oidc["SSO<br/>[oidc.go]"]
  node_authcheck["Session Health<br/>[authcheck.go]"]
  node_notifications["Discord Alerts<br/>[router.go]"]
  node_updates["Update Checks<br/>[checker.go]"]
end

subgraph group_persistence["Persistence"]
  node_store[("SQLite Store<br/>[db.go]")]
  node_sessions["Encrypted Sessions<br/>[sessions.go]"]
  node_campaign_persist["Campaign Persistence"]
  node_claims["Claim History<br/>[claim_recorder.go]"]
end

node_admin(("Administrator"))
node_platform_services(("Twitch and Kick"))

node_admin -->|"uses console"| node_web
node_web -->|"routes requests"| node_account_config
node_web -->|"routes requests"| node_drops_view
node_web -->|"routes requests"| node_dashboard
node_web -->|"routes requests"| node_settings
node_account_config -->|"reads and writes"| node_store
node_account_config -->|"reloads accounts"| node_scheduler
node_drops_view -->|"reads and writes"| node_store
node_dashboard -->|"reads status"| node_store
node_settings -->|"reads and writes"| node_store
node_settings -->|"tests alerts"| node_notifications
node_scheduler -->|"loads account state"| node_store
node_scheduler -->|"loads sessions"| node_sessions
node_scheduler -->|"runs accounts"| node_watcher
node_watcher -->|"uses campaigns"| node_discovery
node_discovery -->|"persists campaigns"| node_campaign_persist
node_watcher -->|"watches and claims"| node_twitch
node_watcher -->|"watches and claims"| node_kick
node_twitch -->|"calls Twitch API"| node_platform_services
node_kick -->|"calls Kick API"| node_platform_services
node_kick -.->|"uses fallback"| node_browser_client
node_browser_client -.->|"calls gRPC"| node_sidecar
node_sidecar -.->|"drives browser"| node_platform_services
node_watcher -->|"records claims"| node_claims
node_watcher -->|"emits events"| node_notifications
node_login -->|"persists sessions"| node_sessions
node_login -->|"authenticates"| node_platform_services
node_oidc -.->|"federates identity"| node_platform_services
node_authcheck -->|"checks sessions"| node_sessions
node_authcheck -->|"reports auth state"| node_notifications
node_canary -->|"probes accrual"| node_twitch
node_canary -->|"probes accrual"| node_kick
node_updates -.->|"checks releases"| node_platform_services
node_sessions -->|"encrypted storage"| node_store
node_campaign_persist -->|"writes campaigns"| node_store
node_claims -->|"writes history"| node_store

click node_web "https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/server.go"
click node_account_config "https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/handlers_accounts.go"
click node_drops_view "https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/handlers_drops.go"
click node_dashboard "https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/handlers_dashboard.go"
click node_settings "https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/handlers_settings.go"
click node_scheduler "https://github.com/aalejandrofer/grubdrops/blob/master/internal/scheduler/scheduler.go"
click node_watcher "https://github.com/aalejandrofer/grubdrops/blob/master/internal/watcher/watcher.go"
click node_discovery "https://github.com/aalejandrofer/grubdrops/blob/master/internal/discovery/discovery.go"
click node_canary "https://github.com/aalejandrofer/grubdrops/blob/master/internal/canary/canary.go"
click node_twitch "https://github.com/aalejandrofer/grubdrops/blob/master/internal/platform/twitch/backend.go"
click node_kick "https://github.com/aalejandrofer/grubdrops/blob/master/internal/platform/kick/backend.go"
click node_browser_client "https://github.com/aalejandrofer/grubdrops/blob/master/internal/auth/browser/client.go"
click node_sidecar "https://github.com/aalejandrofer/grubdrops/blob/master/internal/auth/browser/sidecar/server.go"
click node_login "https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/handlers_login_twitch.go"
click node_oidc "https://github.com/aalejandrofer/grubdrops/blob/master/internal/auth/oidc/oidc.go"
click node_authcheck "https://github.com/aalejandrofer/grubdrops/blob/master/internal/authcheck/authcheck.go"
click node_notifications "https://github.com/aalejandrofer/grubdrops/blob/master/internal/notify/router.go"
click node_updates "https://github.com/aalejandrofer/grubdrops/blob/master/internal/update/checker.go"
click node_store "https://github.com/aalejandrofer/grubdrops/blob/master/internal/store/db.go"
click node_sessions "https://github.com/aalejandrofer/grubdrops/blob/master/internal/store/sessions.go"
click node_campaign_persist "https://github.com/aalejandrofer/grubdrops/blob/master/internal/store/campaign_persister.go"
click node_claims "https://github.com/aalejandrofer/grubdrops/blob/master/internal/store/claim_recorder.go"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_web,node_account_config,node_drops_view,node_dashboard,node_settings toneBlue
class node_scheduler,node_watcher,node_discovery,node_canary toneAmber
class node_twitch,node_kick,node_browser_client,node_sidecar toneMint
class node_login,node_oidc,node_authcheck,node_notifications,node_updates toneRose
class node_store,node_sessions,node_campaign_persist,node_claims,node_admin,node_platform_services toneIndigo
```

## Components

### Admin Console

- [Web Console](https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/server.go): `internal/api/server.go`
- [Accounts and Games](https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/handlers_accounts.go): `internal/api/handlers_accounts.go`
- [Drops Catalog](https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/handlers_drops.go): `internal/api/handlers_drops.go`
- [Dashboard and History](https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/handlers_dashboard.go): `internal/api/handlers_dashboard.go`
- [Runtime Settings](https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/handlers_settings.go): `internal/api/handlers_settings.go`

### Mining Runtime

- [Account Scheduler](https://github.com/aalejandrofer/grubdrops/blob/master/internal/scheduler/scheduler.go): `internal/scheduler/scheduler.go`
- [Drop Watcher](https://github.com/aalejandrofer/grubdrops/blob/master/internal/watcher/watcher.go): `internal/watcher/watcher.go`
- [Campaign Discovery](https://github.com/aalejandrofer/grubdrops/blob/master/internal/discovery/discovery.go): `internal/discovery/discovery.go`
- [Accrual Canary](https://github.com/aalejandrofer/grubdrops/blob/master/internal/canary/canary.go): `internal/canary/canary.go`

### Platform Access

- [Twitch Backend](https://github.com/aalejandrofer/grubdrops/blob/master/internal/platform/twitch/backend.go): `internal/platform/twitch/backend.go`
- [Kick Backend](https://github.com/aalejandrofer/grubdrops/blob/master/internal/platform/kick/backend.go): `internal/platform/kick/backend.go`
- [Browser RPC Client](https://github.com/aalejandrofer/grubdrops/blob/master/internal/auth/browser/client.go): `internal/auth/browser/client.go`
- [Browser Sidecar](https://github.com/aalejandrofer/grubdrops/blob/master/internal/auth/browser/sidecar/server.go): `internal/auth/browser/sidecar/server.go`

### Identity and Alerts

- [Platform Login](https://github.com/aalejandrofer/grubdrops/blob/master/internal/api/handlers_login_twitch.go): `internal/api/handlers_login_twitch.go`
- [SSO](https://github.com/aalejandrofer/grubdrops/blob/master/internal/auth/oidc/oidc.go): `internal/auth/oidc/oidc.go`
- [Session Health](https://github.com/aalejandrofer/grubdrops/blob/master/internal/authcheck/authcheck.go): `internal/authcheck/authcheck.go`
- [Discord Alerts](https://github.com/aalejandrofer/grubdrops/blob/master/internal/notify/router.go): `internal/notify/router.go`
- [Update Checks](https://github.com/aalejandrofer/grubdrops/blob/master/internal/update/checker.go): `internal/update/checker.go`

### Persistence

- [SQLite Store](https://github.com/aalejandrofer/grubdrops/blob/master/internal/store/db.go): `internal/store/db.go`
- [Encrypted Sessions](https://github.com/aalejandrofer/grubdrops/blob/master/internal/store/sessions.go): `internal/store/sessions.go`
- [Campaign Persistence](https://github.com/aalejandrofer/grubdrops/blob/master/internal/store/campaign_persister.go): `internal/store/campaign_persister.go`
- [Claim History](https://github.com/aalejandrofer/grubdrops/blob/master/internal/store/claim_recorder.go): `internal/store/claim_recorder.go`

### Other components

- **Administrator**
- **Twitch and Kick**

## Connections

- Administrator → Web Console: uses console
- Web Console → Accounts and Games: routes requests
- Web Console → Drops Catalog: routes requests
- Web Console → Dashboard and History: routes requests
- Web Console → Runtime Settings: routes requests
- Accounts and Games → SQLite Store: reads and writes
- Accounts and Games → Account Scheduler: reloads accounts
- Drops Catalog → SQLite Store: reads and writes
- Dashboard and History → SQLite Store: reads status
- Runtime Settings → SQLite Store: reads and writes
- Runtime Settings → Discord Alerts: tests alerts
- Account Scheduler → SQLite Store: loads account state
- Account Scheduler → Encrypted Sessions: loads sessions
- Account Scheduler → Drop Watcher: runs accounts
- Drop Watcher → Campaign Discovery: uses campaigns
- Campaign Discovery → Campaign Persistence: persists campaigns
- Drop Watcher → Twitch Backend: watches and claims
- Drop Watcher → Kick Backend: watches and claims
- Twitch Backend → Twitch and Kick: calls Twitch API
- Kick Backend → Twitch and Kick: calls Kick API
- Kick Backend → Browser RPC Client: uses fallback
- Browser RPC Client → Browser Sidecar: calls gRPC
- Browser Sidecar → Twitch and Kick: drives browser
- Drop Watcher → Claim History: records claims
- Drop Watcher → Discord Alerts: emits events
- Platform Login → Encrypted Sessions: persists sessions
- Platform Login → Twitch and Kick: authenticates
- SSO → Twitch and Kick: federates identity
- Session Health → Encrypted Sessions: checks sessions
- Session Health → Discord Alerts: reports auth state
- Accrual Canary → Twitch Backend: probes accrual
- Accrual Canary → Kick Backend: probes accrual
- Update Checks → Twitch and Kick: checks releases
- Encrypted Sessions → SQLite Store: encrypted storage
- Campaign Persistence → SQLite Store: writes campaigns
- Claim History → SQLite Store: writes history
