Skip to content

fix(analytics): make follow logging idempotent and prevent duplicate follow events#532

Open
Ridanshi wants to merge 3 commits into
Dev-Card:mainfrom
Ridanshi:fix/follow-log-analytics-poisoning
Open

fix(analytics): make follow logging idempotent and prevent duplicate follow events#532
Ridanshi wants to merge 3 commits into
Dev-Card:mainfrom
Ridanshi:fix/follow-log-analytics-poisoning

Conversation

@Ridanshi

@Ridanshi Ridanshi commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Closes #484

Summary

This PR fixes an analytics integrity issue where repeated follow requests could generate duplicate follow log records and inflate engagement metrics.

The follow operation itself was effectively idempotent, but follow-event logging was not.

Changes

  • Added database-level uniqueness guarantees for follow logs
  • Introduced idempotent follow logging using upsert semantics
  • Prevented duplicate follow events from retries, refreshes, and double-click submissions
  • Added migration to safely handle existing duplicate records before applying uniqueness constraints
  • Preserved existing follow and unfollow functionality

Test Coverage

Added/updated tests covering:

  • Initial follow creation
  • Repeated follow requests
  • Retry scenarios
  • Double-click submissions
  • Concurrent follow attempts
  • Analytics count correctness
  • Different users following the same target
  • Different targets generating independent records

Result

Follow analytics now accurately represent real follow relationships and cannot be inflated through duplicate requests or retries.

Ridanshi added 3 commits June 10, 2026 01:05
… logs

POST /:platform/:targetUsername/log accepted free-form `status` and
`layer` values and wrote them directly to followLog without validation.
Both fields feed analytics counters (totalFollows) and the
follower-state dashboard via `status: 'success'` queries, so an
authenticated user could fabricate successful follow events, inflate
engagement metrics, and manipulate the dashboard.

Fix:
- Add `followLogSchema` (Zod) in validations/follow.validation.ts with
  strict enum allowlists:
    status  → 'success' | 'failed' | 'pending'
    layer   → 'foreground' | 'background'
- Validate request body with safeParse before any database write;
  invalid payloads return 400 without touching followLog.create()
- Remove unsafe free-form defaults ('success' / 'webview') that
  silently accepted omitted fields
- Response body on validation failure contains only { error } —
  no Zod internals, paths, or stack traces are exposed

Layer 1 (API follow) writes status/layer internally and is unaffected.

Tests: 22 cases covering all valid enum combinations, all rejection
paths, DB-not-called guarantee on failure, correct payload written to
DB, and opaque error responses.

Closes Dev-Card#301
FollowLog had no unique constraint, so repeated follow requests (retries,
double-taps, concurrent clicks) each appended a new row — inflating the
totalFollows counter displayed in the analytics dashboard.

Changes:
- schema: add @@unique([followerId, targetUsername, platform]) to FollowLog
- schema: add updatedAt field (required by Prisma upsert)
- migration: deduplicates existing rows (keeps most-recent per group) before
  creating the unique index — safe on a populated database
- routes/follow.ts: replace followLog.create() with followLog.upsert() in
  both the Layer-1 API path and the Layer-2/3/4 manual-log path
- tests: update mocks to upsert; add three idempotency tests verifying the
  correct composite where-key, update/create shape, and multi-target isolation
@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

@Ridanshi is attempting to deploy a commit to the Prashantkumar Khatri's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

Hi @Ridanshi,

Thanks for opening this pull request.

This PR has been automatically classified based on the files modified.

Applied Labels

  • backend

Primary Review Area

  • backend

Reviewer

@Harxhit has been identified as the primary reviewer for this pull request.

If you have any questions regarding the affected area or implementation details, feel free to reach out to the assigned reviewer.

Thank you for your contribution!

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

CI — All Checks Passed

Backend — PASS

Check Result
Lint PASS
Test PASS
Typecheck PASS

Mobile — SKIP

Check Result
Lint -
Test -

Web — SKIP

Check Result
Check -
Build -

Last updated: Tue, 09 Jun 2026 19:53:20 GMT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Follow logging is not idempotent and allows duplicate follow events to inflate analytics

1 participant