Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b19b1a3
fix(db): add missing reminders fk and afk_statuses index
LucasSantana-Dev Aug 10, 2026
808af79
chore: remove the download feature for top.gg compliance
LucasSantana-Dev Aug 10, 2026
3ad19d0
fix(db): clear orphaned reminders before adding the guild fk
LucasSantana-Dev Aug 10, 2026
d042f0f
Merge remote-tracking branch 'origin/main' into chore/remove-download…
LucasSantana-Dev Aug 11, 2026
02e36d2
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 11, 2026
1d8d3d7
Merge remote-tracking branch 'origin/main' into chore/remove-download…
LucasSantana-Dev Aug 11, 2026
0faf3ed
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
1ee6c6a
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
0ab0611
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
e0f57b5
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
238bb75
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
76b1584
fix(bot): make new-feature-removal migrations idempotent for re-apply
LucasSantana-Dev Aug 12, 2026
c69ad1d
docs(bot): fix stale command-category list; drop removed settings fie…
LucasSantana-Dev Aug 12, 2026
ceb09ff
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
9ba2ae0
fix(bot): scope migration guards to their table; cover commandCategory
LucasSantana-Dev Aug 12, 2026
dbf188e
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
0369e00
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
472a86a
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
bc56747
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
52cf7d6
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
b1e57d7
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
00b8baa
chore: trigger fresh CI run (not a rerun) to test if a clean workflow…
LucasSantana-Dev Aug 12, 2026
15dfc05
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
c8e93d0
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
3a26dc3
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 12, 2026
e60ebaa
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 14, 2026
63d7197
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 14, 2026
4b26495
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 14, 2026
7ea8269
Merge branch 'main' into chore/remove-download-feature
LucasSantana-Dev Aug 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ SENTRY_DSN=...
| `/ping` | Check latency |
| `/help` | Command list and syntax |
| `/version` | Current bot version |
| `/download` | Get Lucky for your own server |

---

Expand Down
39 changes: 39 additions & 0 deletions decisions/2026-08-09-remove-download-feature-topgg-compliance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ADR 2026-08-09 — Remove the `/download` feature for Top.gg compliance

**Status:** Accepted
**Deciders:** Lucas Santana

## Context

Lucky's Top.gg listing (bot id `962198089161134131`) has been in the verification queue since 2026-07-11 (see `docs/TOP_GG_SUBMISSION.md`, handoff `~/.claude/handoffs/lucky/latest.md`). Before resubmitting, reviewed Top.gg's published bot guidelines (support.top.gg "Bot Guidelines" article, via search — the article itself 403s to automated fetches):

> Bots must not provide or distribute downloads of copyrighted material without proper licensing. Bots must abide by top.gg's Terms of Service, Discord's Terms of Service, API rate limits and Developer terms.

Lucky's `/download` command (`packages/bot/src/functions/download/`) shelled out to `yt-dlp` to rip audio/video from YouTube, Spotify, and SoundCloud URLs and hand the file back to the user — no licensing, no rights check, exactly the pattern the guideline names. Discord's own Developer ToS separately prohibits facilitating unauthorized access to copyrighted media. This is a known risk class: Top.gg lists rejections/removals of YouTube-downloader bots for this reason, though some downloader bots do exist on the platform (inconsistently enforced, not something to rely on).

## Decision

**Remove the download subsystem entirely** — not feature-flag it off, not gate it per-guild:

- Bot: `functions/download/**` (commands, processor, service, validator, yt-dlp wrapper, path manager — ~30 files), `utils/download/downloadHelpers.ts`, the `download` command-category registration, the `download` feature toggle.
- Shared: `Download` Prisma model + its FK to `Guild`, `GuildSettings.allowDownloads` / `downloadCooldown` columns, the `download` entry in `FeatureToggleService`/`featureToggles.ts`/`featureToggle.ts` types.
- Frontend: the `download` feature-toggle option in the features store/page + its e2e fixtures.
- DB: migration `prisma/migrations/20260810014436_remove_download_feature/` drops the `downloads` table and the two `guild_settings` columns.

While generating that migration, `prisma migrate diff` also surfaced pre-existing unrelated drift (`reminders` table had no FK to `guilds` at all; `afk_statuses` was missing its `guildId` index) — split into its own migration (`20260810014435_fix_schema_drift/`) and tracked separately in issue #1955, not folded into this decision.

## Alternatives considered

- **Per-guild opt-in toggle (keep `allowDownloads`).** Rejected — the guideline prohibits the capability outright; it isn't a usage or consent question, so gating it off by default doesn't clear a listing review that can still inspect the code/command surface.
- **Restrict to sources with clear licensing (e.g. Creative Commons only).** Rejected — `yt-dlp` has no reliable way to verify license status per-URL at request time; scope would collapse to near-nothing and still can't be verified.
- **Keep it, accept listing risk.** Rejected — a rejected/pulled listing resets the review queue (already 4 weeks in) for a feature with no measured demand signal driving the resubmission.

## Consequences

**Positive:** removes the single clearest Top.gg guideline violation before resubmission; drops a real dependency surface (`yt-dlp` binary, `youtube-dl-exec`, download-path filesystem management) that has caused prior CI/postinstall breakage (#874, #1827, #1486).
**Negative:** users who relied on `/download` lose it with no replacement — no migration path, since the capability itself is the compliance problem.
**Neutral:** this is independent of the vote webhook / `/voterewards` work (already shipped, #729/#730) and of the pending Top.gg ad campaign (#1784, still blocked on listing approval).

## Revisit when

- Top.gg's guidelines change to explicitly permit licensed-source downloading, or Lucky adds a real rights-checked content pipeline (not `yt-dlp` scraping) — no timeline, not planned.
14 changes: 7 additions & 7 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ Each package can be developed independently:

### Package layouts

| Package | Layout | Where to add |
| ------------ | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **shared** | `src/config/`, `src/services/`, `src/types/`, `src/utils/` | New config in config/; new services in services/; shared types in types/; composables and helpers in utils/. |
| **bot** | `src/functions/{general,music,download}/commands/`, `src/handlers/`, `src/utils/`, `src/services/`, `src/events/` | New slash command: add file under `functions/<category>/commands/` or folder + re-export (see command loading below). Handlers, utils, and services by domain. |
| **backend** | `src/routes/`, `src/services/`, `src/middleware/` | New API: route in routes/, logic in services/. |
| **frontend** | `src/components/`, `src/pages/`, `src/hooks/`, `src/stores/`, `src/services/` | New page in pages/; shared UI in components/; API client in services/. |
| Package | Layout | Where to add |
| ------------ | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **shared** | `src/config/`, `src/services/`, `src/types/`, `src/utils/` | New config in config/; new services in services/; shared types in types/; composables and helpers in utils/. |
| **bot** | `src/functions/{automod,general,management,moderation,music}/commands/`, `src/handlers/`, `src/utils/`, `src/services/`, `src/events/` | New slash command: add file under `functions/<category>/commands/` or folder + re-export (see command loading below). Handlers, utils, and services by domain. |
| **backend** | `src/routes/`, `src/services/`, `src/middleware/` | New API: route in routes/, logic in services/. |
| **frontend** | `src/components/`, `src/pages/`, `src/hooks/`, `src/stores/`, `src/services/` | New page in pages/; shared UI in components/; API client in services/. |

### Command loading (bot)

Expand All @@ -106,7 +106,7 @@ Keep one re-export per folder command; name the re-export file to match the comm
### Principles for maintainability

1. **Consistency over perfection** – Follow the same pattern in each area (e.g. all music commands either single-file or folder + re-export). Document the rule; don’t mix styles without reason.
2. **Shallow where possible** – Prefer flat or one level of nesting for new code. Deeper trees (e.g. `play/`, `queue/`, download utils) exist where the feature needs many files; don’t add layers (e.g. extra “domain” folders) unless there’s a clear benefit.
2. **Shallow where possible** – Prefer flat or one level of nesting for new code. Deeper trees (e.g. `play/`, `queue/`) exist where the feature needs many files; don’t add layers (e.g. extra “domain” folders) unless there’s a clear benefit.
3. **One place for cross-cutting concerns** – DB, Redis, config, and shared types live in `@lucky/shared`. Bot-only helpers stay in `packages/bot/src/utils/` or under the feature.
4. **Avoid big restructures** – Prefer small, incremental improvements when touching code. Don’t rename large trees or split packages for structure alone.
5. **Path aliases** – `packages/bot/tsconfig.json` already has `@/*` → `./src/*`, so you can use `@/utils/...`, `@/handlers/...` etc. Use them in new code if you prefer; migrate old relative imports gradually.
Expand Down
Loading
Loading