Skip to content

Consolidate module system before module development - #212

Draft
RedsTom wants to merge 14 commits into
masterfrom
chore/consolidate-core
Draft

RedsTom wants to merge 14 commits into
masterfrom
chore/consolidate-core

Conversation

@RedsTom

@RedsTom RedsTom commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Consolidates the existing module system (core + lib + tooling + docs) before new module development (e.g. Autopin). Stacked per-feature commits, all green (tsc, 144 unit, 36 integration).

Silent killers fixed

  • Command registration failures no longer flip the DB to enabled; failed version updates retry next boot
  • Missing activatedVersion tolerated instead of throwing; downgrades resync
  • Install hooks run before the DB flip (no more “already installed” deadlocks)
  • Autocomplete receives the module config, not the core one
  • Vanished entities are dropped from config lists instead of crashing consumers
  • Explicit guild-id extraction for listeners; commands/autocomplete wrapped in try/catch with DM guards

Boot resilience

  • Broken imports and throwing onLoad skip the module instead of aborting boot; onLoad supports async
  • Lifecycle hooks optional (example modules de-boilerplated)

Author tooling

  • Shared test helpers (#lib/testing.js) + pnpm new-module scaffold (verified end to end)
  • Prisma consolidator fails fast on duplicate model names
  • requiresAdmin on commands, duplicate customId rejection, publishing checklist, LOG_LEVEL, TS env validator with one shared dev constant

🤖 Generated with Claude Code

RedsTom and others added 14 commits September 16, 2026 22:26
Add a global core guildCreate listener: explicit config init on first
join, reinstall of enabled modules guild commands on rejoin (Discord
purges them on kick), and a Components V2 welcome message in the system
channel with owner DM fallback. Nothing is deleted on leave so a rejoin
restores history. updateModuleActivation is now an upsert.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Rethrow Discord failures from install/uninstall so the DB state only
flips on success; skip the activatedVersion bump on failed updates so
they retry next boot. Tolerate missing activatedVersion (""/null) as
0.0.0 instead of throwing. Resync downgraded guilds instead of leaving
them behind. Fetch dev-guild module states in parallel and share one
bulk-PUT helper between the dev and prod paths.

Co-Authored-By: Claude Code <noreply@anthropic.com>
A throwing onInstall/onUninstall no longer leaves the guild marked
enabled/disabled, which used to deadlock the next install with
"already installed".

Co-Authored-By: Claude Code <noreply@anthropic.com>
References to deleted channels/roles/users deserialized to null and
crashed consumers (e.g. channel.id). Lists now filter them out with a
structured warning instead of console.warn.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The old heuristic could return a member user id or a whole event object
as guildId. Only real string ids resolve now; guild-less events run
without config.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Autocomplete now receives the command module config instead of the
core one. Command execution is wrapped in try/catch with an ephemeral
error reply (followUp when already answered) and guild-less
interactions are ignored. New requiresAdmin flag on commands, enforced
centrally and set on both core commands. Duplicate interaction
customIds warn at dispatch; rejected interaction checks log at debug.

Co-Authored-By: Claude Code <noreply@anthropic.com>
A broken module import or a throwing onLoad no longer aborts the whole
boot: the module is skipped with an error log. onLoad supports async
and all three lifecycle hooks are optional, dropping the log-only
boilerplate from the example modules.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Also drops the declared-but-never-propagated configType field from
event listeners.

Co-Authored-By: Claude Code <noreply@anthropic.com>
New #lib/testing.js: makeTestConfig, fakeGuild/fakeChannel/fakeMessage,
initTestI18n and silenceLogs, so module tests stop reinventing mocks
(and stop accidentally booting the bot). The guild-create listener
test is migrated onto them as proof.

Co-Authored-By: Claude Code <noreply@anthropic.com>
validate-env-vars runs under tsx so it imports the single dev-mode
definition from #lib/env.js instead of duplicating the development
literal. dev/start scripts updated to match.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Generates a compiling, tested module skeleton (definition, config
schema, namespaced example command, guarded example listener,
en/fr i18n, commented Prisma model, test on the shared helpers).

Co-Authored-By: Claude Code <noreply@anthropic.com>
The consolidator now reports the model and both files instead of
failing late at generate time. Covered by a unit test; scripts tests
join the unit project.

Co-Authored-By: Claude Code <noreply@anthropic.com>
LOG_LEVEL accepts fatal/error/warn/info/debug/trace/silent and falls
back to debug otherwise. Documented in AGENTS.md.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Document pnpm new-module and the shared test helpers, plus a
pre-production checklist (version bump, prefixed names, DM guards,
requiresAdmin, prisma order).

Co-Authored-By: Claude Code <noreply@anthropic.com>
@RedsTom
RedsTom requested a review from AntoineJT September 16, 2026 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant