2026 Code Clean Up #512
No reviewers
Labels
No labels
blocked
duplicate
needs
approval
needs
criteria
needs
estimate
needs
tests
question
step
doing
step
review
step
testing
step
todo
step
uat
type
admin
type
alert
type
bug
type
change
type
defect
type
epic
type
idea
type
incident
type
investigation
type
spike
type
story
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
External/card-drop!512
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "cursor/487-2026-code-clean-up"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #487
Works through the Code cleanup section of the 2026 clean-up checklist, plus the highest-value items from the Testing gaps section. Not the whole story - see "Left for a follow-up" at the bottom.
Code cleanup (complete)
GuildMemebrUpdate->GuildMemberUpdateacrossEventExecutors,client.tsandutil.ts. The registrar was also renamed fromCoreClient.GuildMemebrUpdatetoCoreClient.RegisterGuildMemberUpdateEventso it matches the otherRegister*Eventmethods. Nothing registers a member-update handler today, so there are no callers to update, andGuildMemebrUpdatenow appears nowhere in the repo.RegisterChannelUpdateEvent, which pushed its handler ontoChannelCreateinstead ofChannelUpdate. Not on the checklist, but the same copy-paste bug in the same block.Button,ChatInputCommand,StringDropdown) and inEvents.onInteractionCreate, so a rejected handler now reaches the surroundingtry/catchinstead of becoming an unhandled rejection. Errors go throughAppLogger.CatchErrorrather than being cast withe as string. The error reply usesfollowUpwhen the interaction has already been replied to or deferred, which is the common case once a handler has calleddeferReply.throw new Error(...)instead of bare strings inbot.tsandappLogger.ts.SeriesHelperpagination usesslicerather thansplice. Worth being straight about this one: both helpers alreadycloneDeepbefore paging, sosplicewas only ever mutating a throwaway clone. This is a defensive cleanup, not a live bug fix.ImageHelperno longer swallows image errors - the emptycatchnow logs viaAppLogger.CatchError. A failing card is still skipped so one bad image cannot fail the whole grid.AppBaseEntity.FetchOneByIddefaultsrelationsto[]instead of{}, matchingFetchAlland what TypeORM expects.TimerHelperhardening - strict equality for the timer id lookup, and ticks now run through a sharedRunTickthat catches synchronous throws and attaches acatchto async ticks, so a failing timer logs instead of producing an unhandled rejection.POST /api/reload-db- see the operator note below.package.json-jest,ts-jestandjest-mock-extendedmoved fromdependenciestodevDependencies, and the malformedbugs.url(https//) fixed.Operator action needed for the reload webhook
POST /api/reload-dbnow requires anx-webhook-tokenheader matchingWEBHOOK_TOKEN, compared with a length check and thentimingSafeEqual. IfWEBHOOK_TOKENis not set the endpoint refuses every request with503and logs an error, rather than silently staying open.WEBHOOK_TOKENneeds adding to the deployed.envor the endpoint will stop working after this lands. It is deliberately not inrequiredConfigs, so the bot still starts without it..env.exampleanddocs/webhooks.mdcover it.Tests
26 suites / 159 tests, up from 16 / 90. Ten new suites:
tests/client/interactionCreate/{Button,ChatInputCommand,StringDropdown}.test.ts- dispatch, not-found, and the error path. These are real regression guards, not just coverage: with theawaitremoved from the dispatcher, the rejection escapes and crashes the jest run.tests/helpers/TimerHelper.test.ts-runOnStart, sync throw and async rejection both logged, start/stop by id.tests/helpers/ImageHelper.test.ts- first coverage this helper has had. Covers the error being logged rather than swallowed, and the greyscale rules for claimed / unclaimed / no-user-id. That last one closes the gap flagged during UAT on #355, where the greyscale skip could only be verified by reading the code.tests/helpers/SeriesHelper.test.ts- page boundaries and stable page contents when paging back and forth.tests/hooks/middleware/RequireWebhookToken.test.ts- unconfigured, missing, wrong, and prefix-of-correct tokens.tests/hooks/ReloadDB.test.ts,tests/timers/GiveCurrency.test.ts,tests/client/interactionCreate/middleware/NewUserDiscovery.test.ts.Documentation
docs/webhooks.mdcovering the API, the token header and the response codes.Left for a follow-up
These are written and verified locally but are not in this PR, because pushing them through the Forgejo contents API one file at a time was not viable in a single run:
eqeqeqESLint rule. Strict equality is applied in the files this PR already touches; roughly 26 further files still use==/!=. Pure mechanical churn that would have tripled the diff and buried the behavioural changes above.docs/cards.md,docs/google-drive-sync.mdanddocs/logger.mdto.env.exampleand the relevant tests.tests/stringDropdowns/Inventory.test.ts- coverage for the inventory dropdown handler, which this PR does not otherwise change.Separately, and worth its own issue: the
rulesblock ineslint.config.mjsis scoped tofiles: ["./src", "./tests"], which matches no files, socamelcase,comma-dangle,prefer-constand friends are not actually enforced today. Fixing the glob surfaces a large number of pre-existing violations, so it did not belong here.Verification
yarn build,yarn lintandyarn testare all clean on this branch: 26 suites, 159 tests, 8 snapshots.WIP: 2026 Code Clean Upto 2026 Code Clean UpView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.