Skip to content

[codex] Add admin job channel management#377

Merged
michaelmwu merged 2 commits into
mainfrom
michaelmwu/admin-job-channels
Jul 9, 2026
Merged

[codex] Add admin job channel management#377
michaelmwu merged 2 commits into
mainfrom
michaelmwu/admin-job-channels

Conversation

@michaelmwu

@michaelmwu michaelmwu commented Jul 9, 2026

Copy link
Copy Markdown
Member

Summary

Adds job channel management to the admin dashboard Configure view. Admins can now inspect registered Discord job forums, register a new forum from the live Discord channel list, change posting type between part-time/full-time/both/unknown, and deregister a channel.

Also adds a duplicate gig status. Updating a gig to duplicate from the dashboard or Discord command marks the thread title and closes/locks the Discord forum post, matching the existing close behavior for lost.

Impact

  • Configure now has hash-backed tabs, including #job-channels, so refreshes preserve the selected tab.
  • Dashboard job channel writes are audited and protected by the existing configuration write permission and same-origin checks.
  • The bot internal channel metadata response now includes all available guild forum channels for dashboard registration.
  • Existing registered-channel reads remain compatible with the sourced lead posting workflow.
  • The bundled admin dashboard static assets were rebuilt.

Validation

  • bun run typecheck
  • bun run test -- configuration-view.test.tsx
  • bun run biome check src/views/configuration-view.tsx src/configuration-view.test.tsx src/main.tsx
  • uv run ruff check packages/shared/src/five08/engagements.py apps/api/src/five08/backend/api.py apps/api/src/five08/backend/routes.py apps/api/src/five08/backend/schemas.py apps/discord_bot/src/five08/discord_bot/cogs/jobs.py apps/discord_bot/src/five08/discord_bot/utils/internal_api.py
  • uv run python3 -m compileall packages/shared/src/five08/engagements.py apps/api/src/five08/backend/api.py apps/api/src/five08/backend/routes.py apps/api/src/five08/backend/schemas.py apps/discord_bot/src/five08/discord_bot/cogs/jobs.py apps/discord_bot/src/five08/discord_bot/utils/internal_api.py
  • bun run build

Note

Medium Risk
New configuration-write endpoints change which Discord forums accept job posts; mistakes could misroute leads, though auditing and permission checks mitigate operator error.

Overview
Adds a Job channels tab to the admin Configuration view (hash-backed, including #job-channels) so operators can list registered Discord job forums, pick from live guild forum channels, set posting type, register/update, and deregister channels. The dashboard loads channels with include_available=true and wires PUT/DELETE on /dashboard/api/job-channels/{channel_id} through main.tsx.

The API extends job-channel listing with optional available_channels, stricter read permission when including available forums, and register_defaults=false when talking to the bot so registration stays explicit. Register/update/delete persist via register_job_post_channel / unregister_job_post_channel, return refreshed payloads, and are audited under configuration:write with same-origin checks.

The gigs UI treats duplicate like lost for failed-style badges. Tests cover the new configuration tab and channel actions; static dashboard assets are rebuilt.

Reviewed by Cursor Bugbot for commit 960a8ef. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@michaelmwu, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 58 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 291f9cca-ff54-47fb-b206-b245b915bf06

📥 Commits

Reviewing files that changed from the base of the PR and between 4ecbb3d and 960a8ef.

📒 Files selected for processing (16)
  • apps/admin_dashboard/src/configuration-view.test.tsx
  • apps/admin_dashboard/src/main.tsx
  • apps/admin_dashboard/src/views/configuration-view.tsx
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/routes.py
  • apps/api/src/five08/backend/schemas.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-2UypYUrJ.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-C7nSMvGG.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPdZbvv_.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CV7QH8Ei.js
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/jobs.py
  • apps/discord_bot/src/five08/discord_bot/utils/internal_api.py
  • apps/worker/src/five08/worker/migrations/versions/20260709_0100_add_duplicate_engagement_status.py
  • packages/shared/src/five08/engagements.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/admin-job-channels

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_0a07b3d5-0b9b-4716-9af8-6b4d4fa92ac3)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7ff8a79549

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

UNKNOWN = "unknown"
LOST = "lost"
OUTDATED = "outdated"
DUPLICATE = "duplicate"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Add a migration before exposing duplicate status

Adding this enum value makes the dashboard and Discord commands accept duplicate, but the current Alembic status constraint still only allows lead, recruiting, filled, unknown, lost, and outdated in apps/worker/src/five08/worker/migrations/versions/20260708_0100_add_lead_engagement_status.py. In a migrated Postgres database, choosing Duplicate causes update_engagement_status to run UPDATE engagements SET status = 'duplicate', which violates ck_engagements_status; the dashboard request will 500 and the Discord command will report that the status update failed. Add a migration that updates the check constraint before exposing this status.

Useful? React with 👍 / 👎.

</Select>
<Select
aria-label="New job channel posting type"
value={selectedPostingType}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Sync update form with the selected channel type

When this top form is pointed at an already registered channel, selectedPostingType stays at its initial or previous value instead of the selected channel's current posting_type. For example, if there are no unregistered forums left and the first registered channel is full_time, the form still shows/sends part_time, so clicking “Update channel” silently rewrites that channel to the wrong posting type. Initialize or update this state from selectedChannel.posting_type, or restrict this form to unregistered channels.

Useful? React with 👍 / 👎.

Comment on lines +4328 to 4330
return JSONResponse(
await _dashboard_job_channels_payload(request, include_available=True)
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Prevent deregister from re-adding default forums

When deleting a forum whose name matches DISCORD_DEFAULT_JOB_FORUM_CHANNELS (the defaults include gigs and fulltime-roles) and the bot internal endpoint is configured, this follow-up payload call asks the bot for channel metadata; JobsCog.list_registered_job_post_forums() refreshes the cache and calls _register_default_job_forum_channels(), which inserts missing default forums back into job_post_channels. The DELETE can therefore return success while the channel immediately reappears as registered, so explicit deregistration does not work for default forums.

Useful? React with 👍 / 👎.

@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_38587155-1905-457d-b39c-e442e2a091d4)

@michaelmwu
michaelmwu added this pull request to the merge queue Jul 9, 2026
Merged via the queue into main with commit 6fda8ef Jul 9, 2026
13 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/admin-job-channels branch July 9, 2026 07:19

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 960a8efb13

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


try:
removed = await asyncio.to_thread(
unregister_job_post_channel,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Persist opt-outs for deleted default forums

When an admin deregisters a forum whose name matches DISCORD_DEFAULT_JOB_FORUM_CHANNELS, this only deletes the job_post_channels row. The bot still auto-registers those defaults during later normal channel loads/posts (list_registered_job_post_forums() with defaults enabled and _resolve_job_lead_post_channel()), so after this delete the next Gigs-page channel load or lead post recreates the row and the forum resumes receiving job leads. The fresh evidence in the current tree is that the delete response avoids immediate default registration, but this delete path still records no opt-out for the later auto-registration calls.

Useful? React with 👍 / 👎.

Comment on lines +4233 to +4234
created = await asyncio.to_thread(
register_job_post_channel,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Trigger forum backfill after dashboard registration

When this dashboard path creates a new registration or changes a forum's posting type, it only writes job_post_channels and refreshes the channel list; unlike the Discord /register-jobs-channel command, it never calls the bot's _start_forum_backfill_task. If an admin registers a forum that already has posts, or changes an existing forum's posting type, those existing threads keep missing/stale dashboard engagement rows until a bot restart or a separate Discord registration triggers backfill, so the new Configure action does not fully enable matching for already-posted jobs.

Useful? React with 👍 / 👎.

if isinstance(available_channels, list)
else channels
)
return payload

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include unresolved registered channels in management view

When the bot is reachable, this returns the bot's live channels list as authoritative for the new management tab, but the bot skips registered IDs it can no longer fetch with 403/404. If a registered forum was deleted or the bot lost access, the row remains in job_post_channels and can still make lead posting fall through to no_registered_job_forum, yet it disappears from the dashboard so admins cannot see or deregister it without calling the API manually. Merge in the DB rows (or have the bot return unresolved registered IDs) for the configuration view.

Useful? React with 👍 / 👎.

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