Skip to content

Feat: user message tracking#380

Merged
TatevikGr merged 4 commits intodevfrom
feat/user-message-tracking
Feb 13, 2026
Merged

Feat: user message tracking#380
TatevikGr merged 4 commits intodevfrom
feat/user-message-tracking

Conversation

@TatevikGr
Copy link
Contributor

@TatevikGr TatevikGr commented Feb 12, 2026

Summary by CodeRabbit

  • New Features

    • Message view tracking: records when subscribers view messages and captures metadata (IP, User-Agent, referer).
  • Enhancements

    • Quick actions to mark messages as viewed and to check viewed status.
    • Message view counters now increment when viewed.
  • Refactor

    • Repository lookup renamed for consistency and callers updated.
  • Chores

    • Switched REST API parameter to a base URL and updated tracking image path.
  • Tests

    • Added tests for view tracking and updated placeholder expectations.

Thanks for contributing to phpList!

@TatevikGr TatevikGr changed the base branch from main to dev February 12, 2026 07:58
@phpList phpList deleted a comment from coderabbitai bot Feb 12, 2026
@TatevikGr
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Feb 12, 2026

✅ Actions performed

Review triggered.

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.

@coderabbitai
Copy link

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

Adds a new UserMessageService to record subscriber message views with sanitized metadata and persistence; adds convenience view methods and metadata incrementing; renames a repository method and updates call sites; switches REST API parameter to a base URL and updates related placeholders and tests.

Changes

Cohort / File(s) Summary
View Tracking Service
config/services/services.yml, src/Domain/Analytics/Service/UserMessageService.php, src/Domain/Analytics/Model/UserMessageView.php
New UserMessageService registered; trackUserMessageView() added and persists UserMessageView; UserMessageView::setViewedNow() convenience method added.
Message Model Enhancements
src/Domain/Messaging/Model/UserMessage.php, src/Domain/Messaging/Model/Message/MessageMetadata.php
Added UserMessage::isViewed() and UserMessage::setViewedNow(); added MessageMetadata::incrementViews() to bump view count.
Repository Rename & Callsites
src/Domain/Messaging/Repository/UserMessageRepository.php, src/Domain/Messaging/Service/ForwardingGuard.php, src/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandler.php, tests/Unit/Domain/Messaging/Service/ForwardingGuardTest.php
Renamed findOneByUserAndMessage()findByUserAndMessage() in repository and updated all call sites; semantics unchanged.
REST API / Placeholder Updates
config/parameters.yml.dist, src/Domain/Configuration/Service/Placeholder/UserTrackValueResolver.php, src/Domain/Messaging/Service/Builder/HttpReceivedStampBuilder.php
Replaced rest_api_domain param with rest_api_base_url; constructors/autowire updated; tracking image path changed to /t/open.gif?u=.
Message Repository
src/Domain/Messaging/Repository/MessageRepository.php
Added findById(int $id): ?Message to fetch Message by ID.
Tests
tests/Unit/Domain/Analytics/Service/UserMessageServiceTest.php, tests/Unit/Domain/Configuration/Service/Placeholder/UserTrackValueResolverTest.php, tests/Unit/Domain/Messaging/Service/ForwardingGuardTest.php
Adds comprehensive unit tests for UserMessageService; updates placeholder image expectations; updates forwarding guard test to use renamed repository method.

Sequence Diagram

sequenceDiagram
    participant Client as Client
    participant Service as UserMessageService
    participant SubRepo as SubscriberRepository
    participant MsgRepo as MessageRepository
    participant UMRepo as UserMessageRepository
    participant EM as EntityManager

    Client->>Service: trackUserMessageView(uid, messageId, metadata)
    Service->>SubRepo: findOneByUid(uid)
    SubRepo-->>Service: Subscriber / null
    alt Subscriber not found
        Service-->>Client: return
    end
    Service->>MsgRepo: findById(messageId)
    MsgRepo-->>Service: Message / null
    alt Message not found
        Service-->>Client: return
    end
    Service->>UMRepo: findByUserAndMessage(subscriber, message)
    UMRepo-->>Service: UserMessage / null
    Service->>Service: mark viewed, MessageMetadata.incrementViews(), sanitize metadata
    Service->>EM: persist(UserMessageView)
    EM-->>Service: queued
    Service-->>Client: done
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Feat/check max mail size #373 — touches the messaging pipeline and the same repository method rename (findOneByUserAndMessagefindByUserAndMessage), closely related to handler updates here.
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat: user message tracking' accurately describes the main feature added in the changeset—a new user message tracking service with view tracking functionality.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/user-message-tracking

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
src/Domain/Messaging/Repository/MessageRepository.php (1)

40-47: findById duplicates Doctrine's built-in find() method.

AbstractRepository (via Doctrine's EntityRepository) already provides $this->find($id), which does the exact same primary-key lookup and returns ?Message. The custom query builder version adds DQL parsing overhead for no benefit.

♻️ Suggested simplification

You can either:

  1. Drop findById entirely and have callers use $repository->find($id) directly, or
  2. Delegate to find() if you want to keep the explicit method for readability:
 public function findById(int $id): ?Message
 {
-    return $this->createQueryBuilder('m')
-        ->where('m.id = :id')
-        ->setParameter('id', $id)
-        ->getQuery()
-        ->getOneOrNullResult();
+    return $this->find($id);
 }

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.

@TatevikGr TatevikGr force-pushed the feat/user-message-tracking branch from e487b23 to 4785567 Compare February 12, 2026 08:52
Copy link

@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

🤖 Fix all issues with AI agents
In `@src/Domain/Configuration/Service/Placeholder/UserTrackValueResolver.php`:
- Line 16: The Autowire parameter name is inconsistent:
UserTrackValueResolver.php uses #[Autowire('%rest_api_base_url%')] while
HttpReceivedStampBuilder.php uses #[Autowire('%app.rest_api_base_url%')]; pick
one canonical container parameter (e.g., %app.rest_api_base_url%) and update the
Autowire attribute in UserTrackValueResolver::__construct (or update
HttpReceivedStampBuilder if you prefer the other name) so both classes reference
the exact same parameter name, or alternatively add a parameter alias in your
service config to map the two names; ensure the class names
UserTrackValueResolver and HttpReceivedStampBuilder and their Autowire
attributes are updated consistently.

In `@src/Domain/Messaging/Service/Builder/HttpReceivedStampBuilder.php`:
- Line 43: The Received header builder in HttpReceivedStampBuilder currently
uses $this->restApiBaseUrl directly in the sprintf, which may include a URL
scheme and produce a non-standard "by" field; modify the builder that constructs
the header (the method returning sprintf('from %s by %s with HTTP; %s', ...)) to
normalize restApiBaseUrl by stripping any scheme (http:// or https://) and
retain only the host (and optional port) before inserting it into the sprintf so
the "by" token is a hostname like api.example.com rather than
https://api.example.com.

@TatevikGr TatevikGr force-pushed the feat/user-message-tracking branch from 05e8f68 to 7c07bd2 Compare February 12, 2026 09:42
@TatevikGr TatevikGr merged commit 1770948 into dev Feb 13, 2026
6 checks passed
@TatevikGr TatevikGr deleted the feat/user-message-tracking branch February 13, 2026 08:24
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