Selfie Time Server: Main Backend API & Admin Dashboard
Client
Selfie Time (PT Intinya Technology)
My Role
Fullstack Engineer
Duration
July 2025 - Present
Tech Stack
Laravel 11, PHP 8.3, MySQL, Redis, Spatie Permissions, Livewire, jQuery DataTables
Quality
Unit + Feature tests
Project Overview
This is the main backend server powering the entire Selfie Time ecosystem. It serves:
- Website selfietime.id - Public marketing website with product showcases
- Public API - RESTful endpoints for mobile app (React Native) and kiosk server
- Admin Dashboard - Internal operations dashboard for managing all features
- Webhook/Integration endpoints - Payment gateway callbacks, Instagram integration
The kiosk-server (separate Electron edge backend) proxies requests to this server while caching operational data locally for offline resilience.
System Architecture
Mobile App (React Native)
└── REST API ──► selfy-time-server (Laravel)
│ ├── Admin Dashboard (Livewire)
│ ├── Public Website (Blade)
│ ├── Webhook Handlers
│ └── MySQL + Redis
Kiosk Server (Electron)
└── Proxy + Cache ──► selfy-time-server (Laravel)THR Catcher Analytics Dashboard
Admin dashboard for monitoring and analyzing the THR Catcher mini-game performance. The mini-game is a gamified campaign where users play a 3-level catching game to win daily rewards.
Database Models
ThrCatcherSessionNew- Session tracking (user_id, playtime_seconds, final_score, is_winner)MiniGamesDailyClaim- Daily reward claims with unique constraint (user_id + game_key + claim_date)
API Endpoints
- POST /api/new/thr-catcher/session/start - Create game session
- POST /api/new/thr-catcher/session/end - End session with playtime + score
- POST /api/new/thr-catcher/claim-reward - Claim 1000 points (throttled 100/min)
Dashboard Metrics
- Active Players - Unique users who started sessions in date range
- Total Playtime - Sum of playtime_seconds from all sessions
- Users with Points - Unique winners who claimed rewards
DataTables with per-user breakdown: sessions, playtime, wins, points. CSV export available.
Affiliate/Referral System
Full-featured referral system where users share codes to invite others, earning points and vouchers as rewards. Features fraud prevention and pending rewards activation on first paid transaction.
Database Models
AffiliateProgram- Program definitions (name, points_reward, validity, vouchers)AffiliateCode- Individual codes (owner, usage limits, daily_usage_limit)- User: pending_affiliate_points, pending_affiliate_code_id, device_id
API Endpoints
- POST /api/affiliate/check - Validate code, return benefits (public, 30/min rate limit)
- GET /api/user/affiliate-code - Get user's own referral code
- POST /api/affiliate/retry-apply - Safety net for failed applications
Reward Activation Flow
- User registers with referral code → rewards held as "pending"
- User makes first PAID transaction → OnTransactionPaid event fires
- ActivatePendingAffiliateReward listener activates vouchers + awards points
Fraud Prevention
- Self-referral block - users cannot use their own code
- Device cooldown - 3 uses from same device → 30-day ban
- Duplicate phone block - same phone cannot use codes twice
- Usage limits - max_usage (total) and daily_usage_limit enforced
Admin Dashboard
- /admin/affiliate/programs - CRUD programs with voucher assignment
- /admin/affiliate/codes - CRUD individual codes with owner assignment
- /admin/affiliate/reports - Usage analytics per code (registered_count, transacted_count, voucher_created_count)
Product Catalog Admin Dashboard
Major refactor from hardcoded product data to dynamic server-driven catalog. Admin team can now manage products without developer intervention.
Database Schema
catalog_products- UUID pk, name, category, price_display, info, variant_text, people, display_ordercatalog_product_features- Feature attributes (take_photo, digital_copy, printed_sheet, duration, etc.)catalog_product_photos- Gallery photoscatalog_product_packets- Packet options for professionalFotocatalog_locations- Outlet display names for thematic productscatalog_product_locations- Pivot table for product-location mapping
API Endpoint
- GET /api/catalog-products - Public, 5-min cache
- Eager loaded (products + features + packets + locations = 4 queries)
- Returns grouped by category: photobooth, thematic, studioPro, highAngle, wideAngle, professionalFoto, additional, retailProduct
- Retail products sub-grouped: album, bingkai, merchandise, gift_decor
- Thematic products include available_in array for location filtering
Admin Dashboard Features
- Livewire CRUD - CreateCatalogProduct, CreateCatalogLocation components
- Feature management - Add/remove features with deferred deletion
- Packet management - Configure packet options per product
- Location mapping - Link thematic products to available outlets
- Double cache invalidation - Pattern on save for reliability
- OwenIt Auditing - Change tracking on catalog_products
- Auto-slug generation - From location names
Core Backend Features
Authentication & Users
- JWT-based API authentication
- Spatie Permissions for role-based access
- Device tracking for fraud prevention
- Profile completion flow with referral code
Transactions & Wallet
- Points system with wallet balance
- Voucher marketplace and redemption
- Transaction history with photo/video gallery
- OnTransactionPaid event for integrations
Queue Management
- Real-time queue status per outlet
- User session tracking
- Turn notification triggers
Integrations
- Xendit payment gateway webhooks
- Instagram OAuth for feed content
- Firebase Cloud Messaging
Technical Stack
- Laravel 11 - PHP framework with modern features
- PHP 8.3 - Latest PHP with JIT, attributes, typed properties
- MySQL - Primary database
- Redis - Caching (5-min catalog cache) and session storage
- Spatie Permissions - Role and permission management
- Livewire - Admin dashboard reactive components
- jQuery DataTables - Server-side tables with export
- Laravel Events & Listeners - Decoupled business logic (OnTransactionPaid, AffiliateCodeUsed)