Duplicate Detection Service
Component Detail
Description
Business logic layer that invokes the Supabase RPC before the final activity insert to check for conflicts based on the triple constraint: same peer_mentor_id, same activity_type_id, and same date with status not 'cancelled'. Returns matched candidates to the caller so the UI can surface the warning.
duplicate-detection-service
Summaries
The Duplicate Detection Service is the intelligence layer that prevents bad data from entering the system in the first place. By automatically checking every activity submission against existing records before it is saved, this service ensures that peer mentors cannot accidentally double-count sessions — a problem that, if undetected, would inflate programme metrics, mislead funders, and undermine trust in the organisation's reporting. The service enforces a precise business rule: same peer mentor, same activity type, and same date equals a conflict requiring review. This automated gatekeeping reduces the manual burden on coordinators who would otherwise need to audit records retrospectively, freeing their time for higher-value programme support work.
It is the foundational engine that makes the entire duplicate management workflow function.
The Duplicate Detection Service is a medium-complexity backend service with a single dependency on the Duplicate Check Repository, which in turn wraps the Supabase RPC. The RPC must be defined, tested, and deployed to the database before this service layer can be validated end-to-end, so database team coordination is required early in the sprint. The service is consumed by the Duplicate Warning Bottom Sheet (real-time submission checking) and the Deduplication Queue (batch queue management), meaning its interface stability is critical — breaking changes ripple across both consumer components. The duplicate_reviewed flag attachment via markAsReviewed(activityId) must be designed with the activity wizard flow in mind to ensure it is set atomically with the final insert.
Testing must cover the three-parameter constraint edge cases: same mentor and date but different activity type (should not flag), and cancelled activities (must be excluded from conflict detection).
The Duplicate Detection Service wraps the Supabase RPC call behind a typed business logic layer, exposing four methods: checkForDuplicates(peerId, activityTypeId, date) which invokes the RPC and returns a boolean conflict signal, getDuplicateCandidates() which returns the full candidate Activity array from the most recent check, markAsReviewed(activityId) which sets the duplicate_reviewed flag on the activity record, and buildDuplicateCheckPayload(draftActivity) which constructs the RPC parameter object from a draft Activity. The service is stateful within a single submission session — it holds the candidate list in memory between checkForDuplicates and getDuplicateCandidates calls, which the Bottom Sheet reads to populate the Comparison Panel. The underlying Supabase RPC applies the triple constraint (peer_mentor_id, activity_type_id, date) with a status != 'cancelled' filter at the database level for performance. Error handling must distinguish between no-duplicate (empty array), duplicate-found (populated array), and RPC failure (throw), each triggering different UI paths.
Unit tests should stub the Duplicate Check Repository to cover all three outcomes without hitting the database.
Responsibilities
- Call Supabase RPC with peer_mentor_id, activity_type_id, and date parameters
- Parse and return candidate duplicate records
- Determine whether to block submission and trigger warning UI
- Attach duplicate_reviewed flag when user confirms intentional submission
Interfaces
checkForDuplicates(peerId, activityTypeId, date)
getDuplicateCandidates()
markAsReviewed(activityId)
buildDuplicateCheckPayload(draftActivity)
Relationships
Dependents (3)
Components that depend on this component