Skip to content

[codex] Close lost Discord gig posts#303

Open
michaelmwu wants to merge 2 commits into
mainfrom
michaelmwu/close-lost-posts
Open

[codex] Close lost Discord gig posts#303
michaelmwu wants to merge 2 commits into
mainfrom
michaelmwu/close-lost-posts

Conversation

@michaelmwu
Copy link
Copy Markdown
Member

@michaelmwu michaelmwu commented May 23, 2026

Summary

  • Close Discord forum gig posts when their status is changed to lost.
  • Applies to both dashboard-driven status sync and the /update-gig-status lost command path.
  • Keeps existing title marker behavior, then locks and archives the thread for lost gigs.

Why

A gig marked as lost should no longer remain open for replies or look active in Discord. Previously, status updates only renamed the thread marker, leaving lost gig posts open.

Validation

  • uv run pytest tests/unit/test_internal_api.py tests/unit/test_jobs.py
  • uv run ruff check apps/discord_bot/src/five08/discord_bot/utils/internal_api.py apps/discord_bot/src/five08/discord_bot/cogs/jobs.py tests/unit/test_internal_api.py tests/unit/test_jobs.py
  • uv run ruff format --check apps/discord_bot/src/five08/discord_bot/utils/internal_api.py apps/discord_bot/src/five08/discord_bot/cogs/jobs.py tests/unit/test_internal_api.py tests/unit/test_jobs.py
  • Commit hook: ruff, ruff format, mypy

Summary by CodeRabbit

  • New Features

    • Discord threads now automatically close and lock when a gig engagement status is changed to "LOST", ensuring consistent state management and preventing orphaned open threads
    • Updated confirmation messages to clearly indicate when threads are closed as part of status update operations
  • Bug Fixes

    • Enhanced thread synchronization reliability to correctly handle all edge cases during status transitions

Review Change Stack

Copilot AI review requested due to automatic review settings May 23, 2026 14:10
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

Warning

Review limit reached

@michaelmwu, we couldn't start this review because you've used your available PR reviews for now.

Your plan currently allows 1 review/hour. Refill in 50 minutes and 55 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

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

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7ce3aff5-71de-4e43-9d69-0b19f5c31d9c

📥 Commits

Reviewing files that changed from the base of the PR and between 009970f and 01276af.

📒 Files selected for processing (4)
  • apps/discord_bot/src/five08/discord_bot/cogs/jobs.py
  • apps/discord_bot/src/five08/discord_bot/utils/internal_api.py
  • tests/unit/test_internal_api.py
  • tests/unit/test_jobs.py
📝 Walkthrough

Walkthrough

This PR extends Discord gig-thread status synchronization to explicitly handle the LOST state. The API route now detects when a thread should be closed (locked and archived) based on the normalized engagement status, the cog performs a sequence of idempotent Discord edits (unarchive if needed, rename, then lock/archive), and the user-facing confirmation message reflects both the rename and close actions for LOST transitions.

Changes

Thread LOST Status and Close Handling

Layer / File(s) Summary
API and cog thread close logic with tests
apps/discord_bot/src/five08/discord_bot/utils/internal_api.py, apps/discord_bot/src/five08/discord_bot/cogs/jobs.py, tests/unit/test_internal_api.py, tests/unit/test_jobs.py
Internal API derives should_close_thread from LOST status and returns a closed boolean. Cog _rename_gig_thread_for_status independently computes needs_rename and needs_close, conditionally unarchives before edits, renames when required, and applies locked=True/archived=True when closing. Tests assert the closed flag, title marker, and the expected edit call sequence for LOST status transitions.
User-facing close confirmation
apps/discord_bot/src/five08/discord_bot/cogs/jobs.py
The /update-gig-status success message now appends "and closed this thread" when the new status is EngagementStatus.LOST.

Sequence Diagram

sequenceDiagram
  participant Client
  participant InternalAPI as Internal API Route
  participant Cog as Jobs Cog
  participant Discord as Discord Thread
  Client->>InternalAPI: POST gig thread status to LOST
  InternalAPI->>InternalAPI: Compute should_close_thread=true for LOST
  InternalAPI->>InternalAPI: Compute needs_close=true if not locked/archived
  InternalAPI->>Cog: Pass should_close_thread, status, title
  Cog->>Cog: Compute needs_rename, needs_close
  Note over Cog: Edit sequence if needed:<br/>1. Unarchive if already archived<br/>2. Rename thread<br/>3. Lock + Archive
  Cog->>Discord: thread.edit(name="[LOST] ...")
  Discord->>Discord: Update thread name
  Cog->>Discord: thread.edit(locked=true, archived=true)
  Discord->>Discord: Lock and archive thread
  Cog->>InternalAPI: Return closed=true, updated status
  InternalAPI->>Client: 200 OK with closed=true
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • 508-dev/508-workflows#301: Both PRs touch the Discord gig status update flow—specifically the gig-thread title marker logic in apps/discord_bot/src/five08/discord_bot/cogs/jobs.py (and the same /update-gig-status behavior)—with the main PR extending it to handle the LOST state by locking/archiving/closing.

Poem

🐰 A thread marked LOST finds its rest,
Now locked and archived with the best,
The cog unarchives when it must,
Then renames, closes—earning our trust.
Idempotent edits, clean and tight,
Discord threads sleeping through the night!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Close lost Discord gig posts' clearly and concisely describes the main change: adding functionality to close Discord forum posts when a gig status becomes 'lost'.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/close-lost-posts

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 and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Discord bot’s gig-thread status syncing so that when a gig becomes LOST, the associated Discord forum thread is not only renamed with the [LOST] marker but also locked and archived. This applies both to the dashboard-driven internal API sync and the /update-gig-status lost slash-command path.

Changes:

  • Lock + archive Discord gig threads when the engagement status becomes lost (dashboard sync + slash command).
  • Extend internal API responses to include whether the thread was “closed”.
  • Add unit tests covering the new lost-thread closing behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
apps/discord_bot/src/five08/discord_bot/utils/internal_api.py Update dashboard status sync to lock/archive threads for LOST gigs and return closed state.
apps/discord_bot/src/five08/discord_bot/cogs/jobs.py Update /update-gig-status rename helper to lock/archive for LOST gigs and tweak user confirmation messaging.
tests/unit/test_internal_api.py Add test asserting LOST dashboard updates lock/archive the thread and report closed=True.
tests/unit/test_jobs.py Add test asserting LOST slash-command path locks/archives the thread after renaming.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/discord_bot/src/five08/discord_bot/utils/internal_api.py Outdated
Comment thread apps/discord_bot/src/five08/discord_bot/utils/internal_api.py Outdated
Comment thread apps/discord_bot/src/five08/discord_bot/utils/internal_api.py Outdated
Comment thread apps/discord_bot/src/five08/discord_bot/cogs/jobs.py Outdated
Comment thread apps/discord_bot/src/five08/discord_bot/cogs/jobs.py Outdated
Copy link
Copy Markdown

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

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: 009970f38d

ℹ️ 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".

Comment thread apps/discord_bot/src/five08/discord_bot/cogs/jobs.py Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/discord_bot/src/five08/discord_bot/cogs/jobs.py (1)

2376-2397: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Non-LOST status changes do not reopen previously closed threads.

Once a thread is closed for LOST, switching to another status does not clear locked/archived, so the thread can remain closed unexpectedly.

Suggested fix
         should_close_thread = status is EngagementStatus.LOST
+        should_reopen_thread = not should_close_thread and (
+            not not getattr(thread, "locked", False)
+            or not not getattr(thread, "archived", False)
+        )
         needs_rename = thread.name != next_name
         needs_close = should_close_thread and (
             not getattr(thread, "locked", False)
             or not getattr(thread, "archived", False)
         )
-        if not needs_rename and not needs_close:
+        if not needs_rename and not needs_close and not should_reopen_thread:
             return next_name
@@
-        if getattr(thread, "archived", False) and (needs_rename or needs_close):
+        if getattr(thread, "archived", False) and (
+            needs_rename or needs_close or should_reopen_thread
+        ):
             await thread.edit(archived=False, reason=reason)
         if needs_rename:
             await thread.edit(name=next_name, reason=reason)
         if should_close_thread:
             await thread.edit(locked=True, archived=True, reason=reason)
+        elif should_reopen_thread:
+            await thread.edit(locked=False, archived=False, reason=reason)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/discord_bot/src/five08/discord_bot/cogs/jobs.py` around lines 2376 -
2397, The code only reopens threads when should_close_thread is True, so
switching from LOST to another status leaves threads archived/locked; update the
logic in the block around should_close_thread / getattr(thread, "archived",
False) so that when should_close_thread is False but the thread is currently
archived or locked you call await thread.edit(archived=False, locked=False,
reason=reason) before any rename; specifically adjust the flow where you compute
needs_close and where you call thread.edit so that non-LOST transitions clear
archived and locked on the thread (use EngagementStatus.LOST, thread,
needs_rename, needs_close, and thread.edit) to ensure the thread is reopened
prior to renaming or further edits.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/discord_bot/src/five08/discord_bot/utils/internal_api.py`:
- Around line 376-377: Replace the narrow "thread_rename_forbidden" error key in
the except discord.Forbidden handler with a generic update-scoped forbidden key
(e.g. "thread_update_forbidden") to cover rename/unarchive/lock/archive
failures; update the except discord.Forbidden block in internal_api.py so it
returns {"error": "thread_update_forbidden"}, 403 (keeping the 403 status)
instead of the current "thread_rename_forbidden".
- Around line 345-387: The code never re-opens threads moved away from LOST:
compute a needs_open flag (e.g. needs_open = not should_close_thread and
(getattr(channel, "locked", False) or getattr(channel, "archived", False)))
alongside needs_rename/needs_close, and include it in the early-return check;
then in the update block, if needs_open await channel.edit(archived=False,
locked=False, reason="Dashboard gig status update") (before renaming) so threads
are unarchived/unlocked when status transitions off EngagementStatus.LOST; keep
existing exception handling and ordering (unarchive/unlock before rename, and
only lock+archive when should_close_thread).

---

Outside diff comments:
In `@apps/discord_bot/src/five08/discord_bot/cogs/jobs.py`:
- Around line 2376-2397: The code only reopens threads when should_close_thread
is True, so switching from LOST to another status leaves threads
archived/locked; update the logic in the block around should_close_thread /
getattr(thread, "archived", False) so that when should_close_thread is False but
the thread is currently archived or locked you call await
thread.edit(archived=False, locked=False, reason=reason) before any rename;
specifically adjust the flow where you compute needs_close and where you call
thread.edit so that non-LOST transitions clear archived and locked on the thread
(use EngagementStatus.LOST, thread, needs_rename, needs_close, and thread.edit)
to ensure the thread is reopened prior to renaming or further edits.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1af4f7c5-10e0-4c1b-8394-23df4443b2a4

📥 Commits

Reviewing files that changed from the base of the PR and between 73c34dc and 009970f.

📒 Files selected for processing (4)
  • apps/discord_bot/src/five08/discord_bot/cogs/jobs.py
  • apps/discord_bot/src/five08/discord_bot/utils/internal_api.py
  • tests/unit/test_internal_api.py
  • tests/unit/test_jobs.py

Comment thread apps/discord_bot/src/five08/discord_bot/utils/internal_api.py
Comment thread apps/discord_bot/src/five08/discord_bot/utils/internal_api.py Outdated
Copy link
Copy Markdown

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

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: 01276af05d

ℹ️ 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".

is_locked = bool(getattr(thread, "locked", False))
is_archived = bool(getattr(thread, "archived", False))
needs_rename = thread.name != next_name
needs_reopen = not should_close_thread and (is_locked or is_archived)
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 Avoid unlocking non-LOST threads unconditionally

This condition reopens any non-LOST thread whenever it is locked or archived, even if it was manually moderated rather than closed by the lost-status flow. In Discord, threads can be locked without being lost/closed, so a normal status sync (e.g., recruiting→filled, or even reapplying the same status) will silently clear moderator locks and unarchive the post. That is a behavioral regression introduced here and can override intentional moderation state; the reopen logic should be limited to threads that were previously closed due to LOST status.

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.

2 participants