Skip to content

patch/threadの実装 - #3127

Open
kurao2924 wants to merge 6 commits into
feat/threadfrom
patch_thread_clean
Open

patch/threadの実装#3127
kurao2924 wants to merge 6 commits into
feat/threadfrom
patch_thread_clean

Conversation

@kurao2924

@kurao2924 kurao2924 commented Jul 10, 2026

Copy link
Copy Markdown

patch/threadの実装

Summary by CodeRabbit

  • New Features

    • Added an authenticated endpoint to edit thread channels: PATCH /v3/threads/:channelID, supporting optional renaming and archived/unarchived updates in one request.
    • Thread updates now flow through the channel manager via a dedicated update method.
  • Bug Fixes

    • Improved validation and error handling: invalid thread names (400), name conflicts and invalid channel types (409), with other failures returning 500.
    • Updates are rejected when the target channel is not a supported type.

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds thread channel editing through a new manager operation and authenticated PATCH /v3/threads/:channelID route, supporting optional name and archived updates with validation, conflict handling, persistence, tree updates, and event recording.

Changes

Thread channel editing

Layer / File(s) Summary
Thread update contract
repository/channel.go, service/channel/manager.go
Defines UpdateThreadArgs, adds Manager.UpdateThread, and introduces ErrInvalidChannelType.
Manager thread update behavior
service/channel/manager_impl.go, service/channel/mock_channel/mock_manager.go
Validates and updates thread names and visibility, persists repository changes, updates the channel tree, records events, restricts regular channel updates by type, and adds mock support.
Authenticated thread PATCH endpoint
router/v3/channels.go, router/v3/router.go
Binds optional name and archived fields, maps errors to HTTP responses, and registers the permission-protected PATCH route.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant EditThread
  participant ChannelManager
  participant Repository
  participant ChannelTree
  Client->>EditThread: PATCH thread with name or archived
  EditThread->>ChannelManager: UpdateThread(ctx, id, args)
  ChannelManager->>Repository: validate and persist thread update
  ChannelManager->>ChannelTree: update in-memory thread
  ChannelManager-->>EditThread: return result
  EditThread-->>Client: 204 or mapped error response
Loading

Suggested reviewers: sakura2-3

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: implementing the PATCH /thread update flow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch patch_thread_clean

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@router/v3/channels.go`:
- Around line 176-184: Add a case for channel.ErrInvalidChannelType in the error
switch within the thread update handler, returning herror.BadRequest with an
appropriate message; keep unexpected errors mapped to
herror.InternalServerError.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1ff24015-92cb-452d-bdc2-80e369f872e0

📥 Commits

Reviewing files that changed from the base of the PR and between cb1b013 and 2f64cfb.

📒 Files selected for processing (6)
  • repository/channel.go
  • router/v3/channels.go
  • router/v3/router.go
  • service/channel/manager.go
  • service/channel/manager_impl.go
  • service/channel/mock_channel/mock_manager.go

Comment thread router/v3/channels.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (2)
service/channel/manager_impl.go (2)

300-309: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Missing m.T.move on thread rename UpdateThread updates the node, but never recalculates ct.paths, so a renamed thread keeps the old tree path. Call m.T.move(id, optional.Of[uuid.UUID]{}, args.Name) when args.Name.Valid before m.T.updateSingle(...).

🤖 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 `@service/channel/manager_impl.go` around lines 300 - 309, Update the thread
rename flow around UpdateChannel and m.T.updateSingle to call m.T.move with the
thread id, an empty optional parent UUID, and args.Name when args.Name.Valid is
true. Perform this path recalculation before m.T.updateSingle, while preserving
the existing error handling and update behavior.

266-271: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Avoid calling m.GetChannel while holding m.T.Lock()

m.GetChannel first calls m.T.GetModel, which takes ct.RLock(). Re-entering m.T under the write lock will self-deadlock here; use m.T.isChannelPresent(ch.ParentID) like CreateThreadChannel does.

🤖 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 `@service/channel/manager_impl.go` around lines 266 - 271, In the thread update
flow, replace the m.GetChannel call made after acquiring m.T.Lock() with the
existing m.T.isChannelPresent(ch.ParentID) check, matching CreateThreadChannel’s
pattern. Preserve the current error return when the parent channel is absent
while avoiding re-entering m.T under its write lock.
🤖 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.

Outside diff comments:
In `@service/channel/manager_impl.go`:
- Around line 300-309: Update the thread rename flow around UpdateChannel and
m.T.updateSingle to call m.T.move with the thread id, an empty optional parent
UUID, and args.Name when args.Name.Valid is true. Perform this path
recalculation before m.T.updateSingle, while preserving the existing error
handling and update behavior.
- Around line 266-271: In the thread update flow, replace the m.GetChannel call
made after acquiring m.T.Lock() with the existing
m.T.isChannelPresent(ch.ParentID) check, matching CreateThreadChannel’s pattern.
Preserve the current error return when the parent channel is absent while
avoiding re-entering m.T under its write lock.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 583acb28-dc44-4936-a8d6-be11180d75e5

📥 Commits

Reviewing files that changed from the base of the PR and between 2f64cfb and d06269e.

📒 Files selected for processing (2)
  • router/v3/channels.go
  • service/channel/manager_impl.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • router/v3/channels.go

@ramdos0207 ramdos0207 removed their assignment Jul 15, 2026
@kurao2924 kurao2924 self-assigned this Jul 15, 2026
@ACF37
ACF37 self-requested a review July 21, 2026 09:52

@ACF37 ACF37 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.

遅くなってごめんなさい!気づいた箇所にコメントしたので、確認お願いします!

Comment thread router/v3/router.go Outdated
Comment thread service/channel/manager_impl.go
Comment thread service/channel/manager_impl.go Outdated
Comment thread service/channel/manager_impl.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (3)
service/channel/manager_impl.go (3)

313-315: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Propagate ctx into event recording.

The new thread-update path calls recordChannelEvent, which ultimately invokes RecordChannelEvent(context.Background()). This drops cancellation, deadlines, and tracing context. Pass ctx into the helper and through to the repository; if recording must outlive the request, use an explicitly documented detached-context policy instead.

As per path instructions, Go functions performing I/O or network requests must accept context.Context as their first parameter and pass the received context to subsequent calls.

🤖 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 `@service/channel/manager_impl.go` around lines 313 - 315, Update the
thread-update event loop and recordChannelEvent helper to accept ctx as the
first parameter, then pass that context through to the repository instead of
context.Background(). Preserve cancellation, deadlines, and tracing for the
event-recording I/O path.

Source: Path instructions


286-298: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Treat an unchanged name as a no-op.

isChildPresent(args.Name.V, ch.ParentID) cannot exclude the current thread, so submitting the existing name at Line 289 finds the thread itself and returns ErrChannelNameConflicts. It also records a spurious NameChanged event when the value is unchanged.

Proposed fix
-	if args.Name.Valid {
+	if args.Name.Valid && args.Name.V != ch.Name {
 		if m.T.isChildPresent(args.Name.V, ch.ParentID) {
 			return ErrChannelNameConflicts
 		}
 
 		eventRecords[model.ChannelEventNameChanged] = model.ChannelEventDetail{
🤖 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 `@service/channel/manager_impl.go` around lines 286 - 298, Update the
name-handling branch in the channel update method around isChildPresent to
return without conflict or event recording when args.Name.V equals the current
ch.Name. Only perform duplicate-name validation and add the
model.ChannelEventNameChanged event when the submitted name actually differs.

260-276: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Refresh the thread after acquiring the tree lock.

The lookup at Line 261 occurs before the lock at Line 275, so concurrent updates can make ch stale. Event comparisons and before values may then be incorrect, and concurrent writes can proceed without detecting the stale state. Re-read the thread with a lock-aware lookup after acquiring m.T.Lock().

🤖 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 `@service/channel/manager_impl.go` around lines 260 - 276, Update UpdateThread
so it re-reads the thread through the lock-aware lookup after acquiring
m.T.Lock(), handling lookup errors consistently. Use the refreshed ch for
subsequent parent validation, event comparisons, and before-state values, while
preserving the existing channel-type checks and lock scope.
🤖 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.

Outside diff comments:
In `@service/channel/manager_impl.go`:
- Around line 313-315: Update the thread-update event loop and
recordChannelEvent helper to accept ctx as the first parameter, then pass that
context through to the repository instead of context.Background(). Preserve
cancellation, deadlines, and tracing for the event-recording I/O path.
- Around line 286-298: Update the name-handling branch in the channel update
method around isChildPresent to return without conflict or event recording when
args.Name.V equals the current ch.Name. Only perform duplicate-name validation
and add the model.ChannelEventNameChanged event when the submitted name actually
differs.
- Around line 260-276: Update UpdateThread so it re-reads the thread through the
lock-aware lookup after acquiring m.T.Lock(), handling lookup errors
consistently. Use the refreshed ch for subsequent parent validation, event
comparisons, and before-state values, while preserving the existing channel-type
checks and lock scope.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 53f1236a-f290-46d4-91ea-a1cda7ebc101

📥 Commits

Reviewing files that changed from the base of the PR and between d06269e and 97bc824.

📒 Files selected for processing (2)
  • router/v3/router.go
  • service/channel/manager_impl.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • router/v3/router.go

@kurao2924
kurao2924 requested a review from ACF37 July 25, 2026 08:21
@ramdos0207 ramdos0207 moved this from Inbox to In review in traQ Server Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

4 participants