L’Oréal Beauty Creator Club Competition Analytics
A queued social-profile enrichment and auditable preselection workflow for GCC competition applicants.
Role: Backend Developer
Overview
A Laravel workflow that captures an applicant’s primary Instagram or TikTok profile, enriches eligible GCC applications through Influencers Club, and presents a ranked preselection snapshot to authorized competition administrators. It includes lifecycle tracking, review actions and comments, and private XLSX exports.
Tech Stack
backend
frontend
data
The Problem
Competition administrators need a controlled way to assess eligible content creator and makeup artist applications using social-profile analytics while preserving a reviewable shortlist.
- The two legacy applicant tables reuse numeric IDs, requiring applicant type to resolve the correct source record.
- Full enrichment is a paid synchronous provider request with no report-retrieval endpoint, making duplicate dispatches and automatic retries costly.
- Provider responses require normalization into consistent engagement, audience geography, credibility, performance, and profile fields.
- Preselection results must remain stable even if live analytics change later.
The Solution
- 1Register event-scoped primary social identities alongside application records.
- 2Use scheduled, bounded queue dispatch to claim eligible profiles atomically before enrichment.
- 3Normalize Influencers Club full-enrichment responses into a dedicated social analytics read model.
- 4Create a ranked, immutable preselection snapshot only after eligible analytics records have settled.
Primary-profile registration
Validates and canonicalizes Instagram and TikTok handles or public profile URLs, then records one scoped primary profile per application.
Queued analytics lifecycle
Dispatches eligible GCC Instagram and TikTok profiles to an analytics queue and records queued, processing, completed, insufficient-data, unsupported, failed, and retry-required states.
Provider normalization
Maps full-enrichment responses into persisted follower, engagement, GCC audience, credibility, performance, median-view, and profile fields.
Auditable preselection
Ranks completed profiles meeting configured country, engagement, and GCC-audience thresholds and saves copied result data as an immutable run.
Admin review and exports
Allows authorized administrators to review shortlisted results, add comments, and request private XLSX exports that are invalidated when reviews change.
Architecture
Laravel modular monolith with scheduled queue-based enrichment


- 1An applicant submits a validated primary Instagram or TikTok account with a GCC country declaration.
- 2The scheduler finds locally eligible profiles without analytics records, claims them in a transaction, and queues bounded analytics jobs.
- 3A unique job calls Influencers Club, normalizes the full response, and persists lifecycle status and analytics fields.
- 4Once every eligible profile is settled, the system creates a ranked immutable preselection run from completed analytics that meet configured thresholds.
- 5Authorized administrators review the saved shortlist and can request private XLSX exports.
Components
Application and admin interface
Laravel Blade, JavaScript, Tailwind CSSProvides localized application routes and authenticated competition dashboard routes for filtering, review, comments, and export requests.
Backend workflow
Laravel 8, PHPValidates submissions, persists application and identity claims transactionally, dispatches analytics jobs, and builds preselection snapshots.
Analytics integration
Influencers Club HTTP APIPerforms server-side full handle enrichment with bearer authentication and normalizes provider data.
Data
MySQL, Laravel Eloquent migrationsStores scoped social profiles, analytics lifecycle data, immutable preselection runs and results, reviews, and export records.
Asynchronous processing
Laravel Queues, Laravel SchedulerSchedules bounded analytics dispatches, isolates provider calls in workers, and generates private exports asynchronously.
- Analytics dispatch refuses a synchronous queue connection outside dry runs.
- Application email claims and scoped social-profile indexes provide database-level uniqueness across legacy applicant tables.
- Competition dashboard routes require authentication and competition-admin authorization.
- Generated XLSX files use a private storage disk and can be downloaded only by the requesting administrator before expiry.
Queues
Scheduled Maintenance
- Analytics dispatch runs every minute after the configured start time, with server-wide and overlap guards.
- Preselection-export cleanup runs hourly.
Key Decisions
Persist an analytics lifecycle row before dispatching each job.
Why: The dispatcher uses transactional locking so simultaneous scheduler processes cannot queue the same profile twice.
Trade-off: A failed dispatch must remove the unclaimed queued row before it can be reconsidered.
Disable automatic retry for transient full-enrichment failures.
Why: The provider has no report-retrieval endpoint, so a repeated request may consume another credit when a response was lost.
Trade-off: Transient failures require explicit operator review.
Store preselection output as an immutable snapshot.
Why: Dashboard rows and exports must not silently change when underlying social analytics are later updated.
Trade-off: The snapshot is intentionally separate from live analytics.
Limit enrichment eligibility to declared GCC applicants with Instagram or TikTok primary profiles.
Why: The workflow targets the configured GCC countries and supported analytics platforms.
Trade-off: Other platforms and non-GCC declared applications are outside the analytics population.
Technical Challenges
Preventing duplicate paid enrichment requests under concurrent dispatch.
Solution: The dispatcher locks profile and analytics records in database transactions, while the enrichment job is unique for 30 minutes.
Outcome: A profile is claimed before queue dispatch and duplicate work is guarded at both dispatch and job levels.
Handling incomplete, private, invalid, rate-limited, and transient provider responses.
Solution: The normalizer classifies unavailable required KPIs and unsupported profiles, while the job records provider, authorization, network, and transient-provider failure classifications.
Outcome: Analytics records retain an explicit lifecycle state and error classification.
Maintaining explainable preselection decisions.
Solution: Configured thresholds, ordering version, rank, and copied analytics fields are stored with each preselection run and result.
Outcome: The dashboard and exports are based on the saved run rather than mutable live data.
Outcomes
- Delivered a scheduled, queue-backed analytics pipeline for eligible GCC competition profiles.
- Delivered an authorized competition dashboard with immutable shortlist review, comments, filtering, and private XLSX exports.
- Delivered persisted analytics statuses and error classifications for operational visibility.
Engineering Practices
- Uses transactions and row-level locks for profile, analytics, application, review, and export state changes.
- Applies platform-specific normalization and validation for public Instagram and TikTok identities.
- Converts provider audience-country fractional weights into persisted percentage values.
- Uses a single analytics worker with a 250 ms delay between outbound requests to stay below the documented 240-requests-per-minute rate.
- Caps analytics batches and preselection runs at 500 records.
- Escapes formula-like XLSX cell values before writing exports.
- Includes unit and feature tests for provider normalization, API client behavior, analytics dispatch, retry review, preselection, dashboard access, reviews, exports, and cleanup.
Known Limitations
- Analytics eligibility is limited to declared GCC applicants with Instagram or TikTok primary profiles.
- Automatic re-enrichment is intentionally disabled for transient provider failures.
- A completed analytics record is configured to expire after 30 days.
- The repository contains no project-specific deployment configuration files beyond Laravel environment and application configuration.