Skip to content

Consolidate module system before module development - #212

Merged
AntoineJT merged 16 commits into
masterfrom
chore/consolidate-core
Oct 3, 2026
Merged

AntoineJT merged 16 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
RedsTom requested a review from AntoineJT September 16, 2026 21:28
@RedsTom

RedsTom commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor Author

Review clanker :

Pas mergeable en l-etat, pour raisons process + conflits :

  • Draft = true
  • mergeable = CONFLICTING (mergeStateStatus DIRTY)
  • reviewDecision = REVIEW_REQUIRED (0 review, 1 requise sur master)
  • statusCheckRollup vide : aucun check visible sur la PR

Cause racine : la branche est basee sur d0c40fe et origin/master a ~19 commits d-avance, dont du fonctionnel qui touche les memes fichiers. Un rebase sur origin/master est requis, avec au moins ces resolutions :

  1. src/core/loaders/listener-loader.ts : conflit extractGuildId (cette PR, exportee + testee) vs findGuildId (master, f680ac8). Suggestion : garder extractGuildId, supprimer findGuildId.
  2. src/core/listeners/interaction-create.listener.ts : le hunk handleInteraction lit encore handler.handler.requiresAdmin, qui n-existe plus depuis ad0fce6 (access: InteractionAccess requis) — migrer vers access == admin, sinon ca ne compilera pas apres rebase.
  3. src/core/loaders/command-loader.ts : reporter Client -> Client (c52788a) sur les fonctions refactorisees.
  4. config.command.ts / module.command.ts : requiresAdmin: true (cette PR) vs check inline requireAdmin (master, 292e028) — le flag central rend l-inline redondant, suggerer de ne garder que le flag.
  5. guild-create.listener.ts : guild.client (type Client) passe a installModuleCommandsIn — a ajuster pour Client.

Deux remarques design pour le rebase :

  • Cette PR ajoute requiresAdmin optionnel sur Command, alors que les interactions exigent desormais access (requis) depuis ad0fce6 — deux conventions paralleles. Ca vaudrait le coup d-aligner Command sur access.
  • onInstall/onUninstall tournent maintenant avant le flip DB : a noter dans la doc du scaffold si un module supposait la ligne d-activation existante.

Cote ordre de merge avec #217 (zones differentes, auto-merge probable dans les deux sens), je recommande de faire passer celle-ci d-abord puisque c-est la fondation annoncee.

Process suggere : rebase -> pnpm build && pnpm test -> sortir du draft -> review. Je ne merge donc pas.

@RedsTom
RedsTom force-pushed the chore/consolidate-core branch from 3006243 to 780fb44 Compare October 2, 2026 14:11
@RedsTom
RedsTom marked this pull request as ready for review October 2, 2026 14:11
@RedsTom
RedsTom enabled auto-merge (squash) October 2, 2026 14:16
@RedsTom

RedsTom commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

Rebase done, PR is now ready and all green. Summary of what changed since the review:

  • Rebased onto origin/master (was 19 commits behind). Resolved 2 conflicts:
    • command-loader.ts: kept the shared bulk-PUT helper against the new Client signatures.
    • listener-loader.ts: kept extractGuildId (exported and tested), removed the duplicate findGuildId from master.
  • Removed the now-redundant inline requireAdmin checks in /config and /modules (the central dispatcher enforces requiresAdmin; the inline code was unreachable). New fixup commit: 780fb44.
  • Fixed the integration test mock (ambient client gains isReady) for the upstream readyClient guard in module-installer.ts.

Verified locally: tsc clean, oxlint clean, 180/180 tests pass. CI is green too (lint, build, docker, CodeQL).

Remaining step: 1 approving review is still required by the master branch policy (auto-merge is enabled, so the PR will merge automatically once approved). Note the pre-existing oxfmt drift across the repo (142 files fail oxfmt --check even on master) — I only formatted the 3 files touched here so the diff stays minimal.

@RedsTom
RedsTom disabled auto-merge October 2, 2026 14:26
@RedsTom
RedsTom enabled auto-merge (rebase) October 2, 2026 14:26
RedsTom and others added 15 commits October 2, 2026 16:30
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 force-pushed the chore/consolidate-core branch from 780fb44 to 7f9198f Compare October 2, 2026 14:34

@AntoineJT AntoineJT left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

regardé vite fait, pas en détail, ça a l'air pas mal, je merge pour pouvoir regarder la #220 de loic

@AntoineJT
AntoineJT disabled auto-merge October 3, 2026 16:27
@AntoineJT
AntoineJT merged commit 5136540 into master Oct 3, 2026
10 checks passed
@AntoineJT
AntoineJT deleted the chore/consolidate-core branch October 3, 2026 16:27
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.

2 participants