Repository navigation
feat(slack): credit Slack entries to the reporter's WordPress user - #196
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Self-review summary — 3 rounds on this branch before handoff. Accepted:
Declined:
Suggestions deferred (not blocking)
|
There was a problem hiding this comment.
🟡 Changes recommended
Concurrent saves and double-unslashing can bypass mapping uniqueness and misattribute entries.
2 open findings
What changed in this PR
Credits Slack entries and uploaded images to mapped WordPress reporters, with the bot user as fallback.
Changes:
- Adds profile fields and member-ID-first author matching.
- Applies resolved ownership during ingestion and logs the match source.
- Documents the trust model and adds resolver and webhook tests.
| File | Description |
|---|---|
| tests/test-slack-webhook.php | Tests mapped entry and image ownership. |
| tests/test-slack-author-resolver.php | Tests matching, permissions, and profile validation. |
| src/admin/DEVELOPMENT.md | Documents author mapping and trust constraints. |
| includes/sources/class-entry-ingestion-service.php | Renames the author parameter for broader use. |
| includes/slack/class-slack-webhook-controller.php | Applies resolved authors and logs matching. |
| includes/slack/class-slack-author-resolver.php | Adds profile mapping and author resolution. |
| includes/class-slack.php | Registers profile hooks. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Hey @leogermani, good job getting this PR merged! 🎉 Now, the Please check if this PR needs to be included in the "Upcoming Changes" and "Release Notes" doc. If it doesn't, simply remove the label. If it does, please add an entry to our shared document, with screenshots and testing instructions if applicable, then remove the label. Thank you! ❤️ |

Every rolling coverage entry posted from Slack is credited to a generic Slack bot user. Readers never see who reported it, and editors have to reassign entries by hand. With this change, reporters can link their Slack account to their WordPress user, and what they post from Slack is credited to them.
What changes
The profile and user edit screens get a Rolling Coverage section with a "Slack handle" field. It takes a Slack handle or a Slack member ID, and its help text explains how to find a member ID in Slack. When a message arrives, the entry is credited to the user whose member ID or handle matches the person who posted it. Messages from anyone else still go to the Slack bot user.
With this change:
How to test
Technical details
Matching.
Slack_Author_Resolver::resolve_author()compares the message's member ID with stored member IDs, exactly. It then compares the author's Slack display name, full name (real_name) and username, in that order, with stored handles only, ignoring case through the database collation. Names are free text their owner can change, so a name shaped like a member ID never reaches a member-ID mapping. A stored value is a member ID when it starts withUorWand is uppercase letters with at least one digit. Only users who canedit_postsare credited, checked withuser_can()on the matching rows rather than theget_users()capabilityargument, which misses filtered capabilities and network super admins.Webhook budget. The member ID comes with the event, so it matches even when the 1s
users.infolookup fails. Each message runs at most four indexedget_users()meta lookups.Trust model. The field is self-service: anyone who can write entries can enter any value on their own profile, and nothing checks it against Slack. This is a deliberate choice. Restricting it to editors, or verifying member IDs through
users.lookupByEmail(a new Slack scope), were the alternatives.src/admin/DEVELOPMENT.md("Slack authors") documents the trust model.Other changes. The ingest log's success entry gains an
authorfield (member_id,display_name,real_name,nameorbot), so entries credited through a name can be found if one turns out to be wrong.Entry_Ingestion_Service::ingest()'s$bot_user_idparameter is now$author_id.Known gaps, left for follow-ups:
Tests.
tests/test-slack-author-resolver.php(new) covers matching order, the member-ID impersonation case, capability gating and the profile save rules;tests/test-slack-webhook.phpadds end-to-end cases for a mapped handle and member ID. The full PHPUnit suite passes (1009 tests), and PHPCS is clean on the changed files.Self-review: three rounds (Opus 5.5), one blocker fixed.
🤖 Generated with Claude Code