You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[#648] Add Career Discord settings in Blade - #665
Officers need a way to change the Career channels and reminder roles when the Discord server gets reorganized. This puts them on Blade's existing Discord config page.
Internship and new-grad posting channels (digests post there too)
Internship and new-grad digest roles
An optional channel for job source failure alerts
The channels and roles use the supplied production IDs. The failure channel starts empty ("Not configured") until an officer sets it. Every other setting still requires a production ID.
Permissions, audit logs and caching didn't change. The new getOptionalDiscordConfigId returns null for the empty failure channel, so alert code can skip it.
These show as "Unused" until #651, #653 and #654 read them. The names follow #633's internship/new-grad split, not #648's three keys, so downstream owners please confirm them.
About the size: the migration is 21 lines. Almost everything else is meta/0064_snapshot.json, Drizzle's full-schema snapshot, which you can skip.
Test Plan
pnpm db:generate finds no schema drift.
A fresh database migrates cleanly twice. All five rows are seeded, and re-running the seed keeps officer edits.
All @forge/db tests (167) and the API config tests (50) pass against real Postgres. They cover upgrades, required IDs, setting and clearing the failure channel, audit records and cache refresh.
pnpm verify:precommit passes.
In Chromium I saved, reloaded and cleared the failure channel, and checked desktop and 320px mobile layouts.
The full workspace tests and build passed earlier. Since then only the migration files and their tests changed.
Screenshots
Career posting channels
Digest roles
Empty failure channel
Officer editor
Rollout
Deploy this code before running the migration. Old Blade can't show the new rows or an empty production ID. The CI migrate job doesn't wait for the deploy, so please confirm the order.
Development IDs are empty, so dev falls back to the production IDs. Set dev channels before testing real delivery outside production.
Checklist
Database: No schema changes, OR I ran pnpm db:generate and committed the generated files in packages/db/drizzle/
Environment Variables: No environment variables changed, OR I have contacted the Development Lead to modify them on Coolify BEFORE merging.
The change adds five Career Discord settings: three channels and two digest roles. It seeds the settings and allows the source-health channel to remain unset. Validation and configuration readers distinguish optional destinations from required ones. The Blade editor supports configuring or clearing the optional destination and displays unset values separately from production fallback values. Tests cover migration, validation, reads, updates, auditing, and the editor.
Pre-merge checks: 8
Check name
Status
Explanation
Title check
Title is "[#648] Add Career Discord settings in Blade", which contains the issue number in brackets, is under 72 characters, and describes the main change: five Career Discord settings added to Blade'…
Description check
The description explains why (officers need to change Career channels and reminder roles after a Discord reorganization), what changed (five new settings, optional failure channel, getOptionalDiscordC…
Linked Issues check
[#648] Scope items are implemented at head. CONFIG_KEYS in packages/consts/src/discord.ts adds the three Career channel keys and two digest role keys. CONFIG_KEY_CONSUMERS gives each new key an …
Out of Scope Changes check
The changes support [#648]. They include the Career keys, the seed migration and journal entry, the nullable production_id with its check constraint, the optional-ID reader and validator, the Blade …
Docstring Coverage
Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentati…
No Hardcoded Secrets
No changed file adds a hardcoded API key, password, access token, or secret literal. The new long numeric values are Discord channel and role IDs or test fixtures. Token-related additions in the gener…
Validated Env Access
The pull request adds no direct process.env usage. The authoritative diff has no added process.env lines, and pickaxe inspection finds no changes containing that reference. Existing repository usa…
No Typescript Escape Hatches
No TypeScript escape hatch was introduced. The pull-request additions contain no any type, @ts-ignore, @ts-expect-error, or non-null assertion (!.).
Full details: Title check
Explanation
Title is "[#648] Add Career Discord settings in Blade", which contains the issue number in brackets, is under 72 characters, and describes the main change: five Career Discord settings added to Blade's Discord config page. The title meets the configured requirement.
Full details: Description check
Explanation
The description explains why (officers need to change Career channels and reminder roles after a Discord reorganization), what changed (five new settings, optional failure channel, getOptionalDiscordConfigId), test plan, rollout order, and screenshots. It is directly related to the changeset.
Full details: Linked Issues check
Explanation
[#648] Scope items are implemented at head. CONFIG_KEYS in packages/consts/src/discord.ts adds the three Career channel keys and two digest role keys. CONFIG_KEY_CONSUMERS gives each new key an empty consumer list, which the PR states is intentional until #651, #653, and #654 land. Migration packages/db/drizzle/0064_career_discord_config.sql seeds all five rows with production IDs. It leaves career_source_health_channel unset, and it uses ON CONFLICT DO NOTHING so replays keep officer edits. Blade's config page lists and edits these rows, including the empty optional channel. The API validates, lists, updates, audits, and caches them. The generic readers in packages/utils/src/discord-config.ts resolve the registered keys. getOptionalDiscordConfigId returns null for an unset optional row. The 'Cron and the API can read them' criterion holds at the reader level. No cron consumer reads the keys yet, and the PR defers that work to the blocked issues. Non-coding checklist items do not apply.
Full details: Out of Scope Changes check
Explanation
The changes support [#648]. They include the Career keys, the seed migration and journal entry, the nullable production_id with its check constraint, the optional-ID reader and validator, the Blade dialog and section display, API and cache behavior, seed_devdb.ts (its guildIds now requires a production ID, which follows from the nullable column), resolveDiscordConfigId return type, documentation, and tests. The .forge/features/career-discord-config files are feature documentation for this change. No delivery consumer or unrelated runtime behavior was added.
Full details: Docstring Coverage
Explanation
Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 12 functions across 17 files. (7 skipped: 7 unsupported.)
Full details: No Hardcoded Secrets
Explanation
No changed file adds a hardcoded API key, password, access token, or secret literal. The new long numeric values are Discord channel and role IDs or test fixtures. Token-related additions in the generated snapshot are schema column names and constraints, not credential values.
Full details: Validated Env Access
Explanation
The pull request adds no direct process.env usage. The authoritative diff has no added process.env lines, and pickaxe inspection finds no changes containing that reference. Existing repository usages are pre-existing and do not cause a pull-request violation.
Finishing Touches
Generate unit tests (beta)
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Warning
Some tools did not complete. Review the errors below.
ESLint
If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.
This status still says the squashed change is unpublished and requires approval to open a PR. Record the current PR and remove the obsolete publication instruction. Align the stale status lines in spec.md and srd.md at the same time.
set -u
printf'%s\n''--- current Blade section ---'
nl -ba apps/blade/src/app/_components/admin/roles/discord-config-section.tsx | sed -n '1,380p'printf'%s\n''--- current Blade dialog ---'
nl -ba apps/blade/src/app/_components/admin/roles/discord-config-dialog.tsx | sed -n '1,240p'printf'%s\n''--- API router ---'
nl -ba packages/api/src/routers/discord-config.ts | sed -n '1,230p'printf'%s\n''--- current constants and utils ---'
nl -ba packages/consts/src/discord.ts | sed -n '1,130p'
nl -ba packages/utils/src/discord-config.ts | sed -n '1,180p'printf'%s\n''--- base versions of relevant files ---'forfin apps/blade/src/app/_components/admin/roles/discord-config-section.tsx apps/blade/src/app/_components/admin/roles/discord-config-dialog.tsx packages/api/src/routers/discord-config.ts packages/consts/src/discord.ts;doprintf'\\n--- %s at base ---\\n'\"$f\"
git show b88d4de35ac47f7cb1555658741778a792351c90:\"$f\"2>/dev/null | nl -ba | sed -n '1,380p'||truedoneprintf'%s\n''--- migration execution and deployment docs ---'
rg -n -i --glob '*.{ts,tsx,md,yml,yaml,json,toml,sql}' -e 'db:migrate' -e 'drizzle.*migrat' -e 'migrate_prod' -e 'deployment gate' -e 'deploy.*before' -e 'before.*deploy' packages apps docs .github 2>/dev/null | sed -n '1,260p'
Repository: KnightHacks/forge
Length of output: 42464
Script executed:
set -u
printf'%s\n''--- revision availability ---'
git rev-parse --verify b88d4de35ac47f7cb1555658741778a792351c90^{commit} 2>&1||true
git rev-parse --verify 9b0c9847bdd6278aec9e1c03e13b9a65131b67c9^{commit} 2>&1||true
git status --short --branch
printf'%s\n''--- base tree candidates ---'
git ls-tree -r --name-only b88d4de35ac47f7cb1555658741778a792351c90 -- apps/blade/src/app/_components/admin/roles packages/api/src/routers packages/consts/src/discord.ts 2>&1| sed -n '1,120p'printf'%s\n''--- base file existence and source ---'forfin apps/blade/src/app/_components/admin/roles/discord-config-section.tsx apps/blade/src/app/_components/admin/roles/discord-config-dialog.tsx packages/api/src/routers/discord-config.ts packages/consts/src/discord.ts;doprintf'\\n--- %s ---\\n'\"$f\"
git cat-file -e \"b88d4de35ac47f7cb1555658741778a792351c90:$f\"2>&1||true
git show \"b88d4de35ac47f7cb1555658741778a792351c90:$f\"2>&1| sed -n '1,360p'doneprintf'%s\n''--- production migration job ---'
nl -ba .github/workflows/ci.yml | sed -n '250,315p'printf'%s\n''--- explicit migration gate ---'
nl -ba packages/db/drizzle/0034_dry_shriek.sql | sed -n '112,145p'printf'%s\n''--- db README ---'
nl -ba packages/db/README.md | sed -n '1,42p'
Repository: KnightHacks/forge
Length of output: 9211
Script executed:
printf'%s\n''--- base discord section ---'
git show b88d4de35ac47f7cb1555658741778a792351c90:apps/blade/src/app/_components/admin/roles/discord-config-section.tsx | nl -ba | sed -n '1,380p'printf'%s\n''--- base discord dialog ---'
git show b88d4de35ac47f7cb1555658741778a792351c90:apps/blade/src/app/_components/admin/roles/discord-config-dialog.tsx | nl -ba | sed -n '1,260p'printf'%s\n''--- base API router ---'
git show b88d4de35ac47f7cb1555658741778a792351c90:packages/api/src/routers/discord-config.ts | nl -ba | sed -n '1,230p'printf'%s\n''--- base constants ---'
git show b88d4de35ac47f7cb1555658741778a792351c90:packages/consts/src/discord.ts | nl -ba | sed -n '1,130p'printf'%s\n''--- diff for these consumers ---'
git diff --unified=25 b88d4de35ac47f7cb1555658741778a792351c90 9b0c9847bdd6278aec9e1c03e13b9a65131b67c9 -- apps/blade/src/app/_components/admin/roles/discord-config-section.tsx apps/blade/src/app/_components/admin/roles/discord-config-dialog.tsx packages/api/src/routers/discord-config.ts packages/consts/src/discord.ts | sed -n '1,500p'
Repository: KnightHacks/forge
Length of output: 42476
Script executed:
printf'%s\n''--- head API list and view transformation ---'
nl -ba packages/api/src/routers/discord-config.ts | sed -n '1,115p'printf'%s\n''--- base API list and view transformation ---'
git show b88d4de35ac47f7cb1555658741778a792351c90:packages/api/src/routers/discord-config.ts | nl -ba | sed -n '1,115p'printf'%s\n''--- API diff ---'
git diff --stat b88d4de35ac47f7cb1555658741778a792351c90 9b0c9847bdd6278aec9e1c03e13b9a65131b67c9 -- packages/api/src/routers/discord-config.ts
Repository: KnightHacks/forge
Length of output: 9864
Script executed:
git show b88d4de35ac47f7cb1555658741778a792351c90:packages/consts/src/discord.ts | nl -ba | sed -n '60,120p'
Repository: KnightHacks/forge
Length of output: 2971
Deploy compatible Blade instances before applying migration 0064.
Old Blade does not define consumer metadata for the five new keys. It then evaluates row.readBy.length and can fail while rendering the Discord configuration page. Enforce the compatible deployment and old-instance drain before this migration runs.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
StevScripts
added
Feature
New Feature or Request
Blade
Change modifies code in Blade app
Database
Change modifies code in the DB package
API
Change modifies code in the global API/tRPC package
Major
Big change - 2+ reviewers required
labels
Nov 4, 2026
The reason will be displayed to describe this comment to others. Learn more.
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
Other comments: 1
.forge/features/career-discord-config/spec.md: 1
3-3: Minor · Maintainability & Code Quality · Quick win
Update the publication status.
This revision is under PR #665, but this line says the work was not republished. Update this line and the matching statement in .forge/features/career-discord-config/status.md (Line 3). Keep the account of PR #664 as history.
Files not fully reviewed because their changes were unavailable: 1
packages/db/drizzle/meta/0064_snapshot.json
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.
The reason will be displayed to describe this comment to others. Learn more.
Code rabbit fix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
APIChange modifies code in the global API/tRPC packageBladeChange modifies code in Blade appDatabaseChange modifies code in the DB packageFeatureNew Feature or RequestMajorBig change - 2+ reviewers required
1 participant
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Officers need a way to change the Career channels and reminder roles when the Discord server gets reorganized. This puts them on Blade's existing Discord config page.
What
Closes: #648
Five new settings:
The channels and roles use the supplied production IDs. The failure channel starts empty ("Not configured") until an officer sets it. Every other setting still requires a production ID.
Permissions, audit logs and caching didn't change. The new
getOptionalDiscordConfigIdreturnsnullfor the empty failure channel, so alert code can skip it.These show as "Unused" until #651, #653 and #654 read them. The names follow #633's internship/new-grad split, not #648's three keys, so downstream owners please confirm them.
About the size: the migration is 21 lines. Almost everything else is
meta/0064_snapshot.json, Drizzle's full-schema snapshot, which you can skip.Test Plan
pnpm db:generatefinds no schema drift.@forge/dbtests (167) and the API config tests (50) pass against real Postgres. They cover upgrades, required IDs, setting and clearing the failure channel, audit records and cache refresh.pnpm verify:precommitpasses.The full workspace tests and build passed earlier. Since then only the migration files and their tests changed.
Screenshots
Career posting channels
Digest roles
Empty failure channel
Officer editor
Rollout
Checklist
pnpm db:generateand committed the generated files inpackages/db/drizzle/