Skip to main content

repti-community Service

Engagement and community features
Service Type: Community & Engagement Service
Port: 8005
Database: repti_community_db
Status: Planned
Team Owner: Engagement Team

Purpose & Responsibilities

repti-community powers user engagement through intelligent search, multi-channel notifications, community interactions, and advertising features that connect breeders and buyers.

Core Responsibilities

Search & Discovery

  • Global search across animals, breeders, knowledge base
  • Advanced filtering and faceted search
  • Search result ranking and relevance
  • Auto-complete and suggestions
  • Search analytics and optimization

Notification System

  • Multi-channel delivery (email, SMS, push, in-app)
  • Event-driven notification triggers
  • Personalized notification preferences
  • Delivery tracking and analytics
  • Template management and A/B testing

Community Features

  • Forums and discussion boards
  • User-generated content and reviews
  • Q&A and knowledge sharing
  • Social interactions and following
  • Community moderation tools

Advertising Platform

  • Boosted listings and promotions
  • Targeted advertising campaigns
  • Ad credit system and billing
  • Performance tracking and analytics
  • Self-service ad management

API Endpoints

Search & Discovery

GET    /search                          # Global search endpoint
GET    /search/animals                  # Animal-specific search
GET    /search/breeders                 # Breeder directory search
GET    /search/knowledge                # Knowledge base search
GET    /search/suggestions              # Auto-complete suggestions
POST   /search/save                     # Save search query
GET    /search/saved                    # User's saved searches
POST   /search/analytics                # Track search events

Search Index Management

POST   /index/animals/{animal_id}       # Index animal for search
DELETE /index/animals/{animal_id}       # Remove from search index
POST   /index/breeders/{breeder_id}     # Index breeder profile
POST   /index/rebuild                   # Rebuild search index
GET    /index/status                    # Index health status
POST   /index/optimize                  # Optimize search performance

Notification Management

GET    /notifications                   # List user notifications
POST   /notifications/send              # Send notification
PUT    /notifications/{notification_id}/read  # Mark as read
DELETE /notifications/{notification_id} # Delete notification
GET    /notifications/preferences       # User notification settings
PUT    /notifications/preferences       # Update preferences
POST   /notifications/test              # Test notification delivery

Notification Templates & Campaigns

GET    /notifications/templates         # List templates
POST   /notifications/templates         # Create template
PUT    /notifications/templates/{id}    # Update template
POST   /notifications/campaigns         # Create campaign
GET    /notifications/campaigns/{id}/stats # Campaign analytics
POST   /notifications/bulk              # Bulk notification sending

Community Features

GET    /community/forums                # List forums
GET    /community/forums/{forum_id}/posts # Forum posts
POST   /community/forums/{forum_id}/posts # Create post
GET    /community/posts/{post_id}       # Post details
POST   /community/posts/{post_id}/replies # Reply to post
POST   /community/posts/{post_id}/vote  # Vote on post
GET    /community/users/{user_id}/activity # User activity
POST   /community/follow                # Follow user/topic

Advertising Platform

GET    /ads/campaigns                   # List ad campaigns
POST   /ads/campaigns                   # Create campaign
GET    /ads/campaigns/{campaign_id}     # Campaign details
PUT    /ads/campaigns/{campaign_id}     # Update campaign
POST   /ads/campaigns/{campaign_id}/start # Start campaign
POST   /ads/campaigns/{campaign_id}/pause # Pause campaign
GET    /ads/analytics                   # Advertising analytics
POST   /ads/credits/purchase            # Buy ad credits

Database Schema

Core Tables

-- Search index for fast searching
CREATE TABLE search_index (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    entity_type VARCHAR(50) NOT NULL, -- 'animal', 'breeder', 'article'
    entity_id UUID NOT NULL,
    organization_id UUID,
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    tags VARCHAR(255)[] DEFAULT '{}',
    metadata JSONB DEFAULT '{}',
    visibility VARCHAR(20) DEFAULT 'public',
    search_vector tsvector,
    boost_score DECIMAL(3,2) DEFAULT 1.0,
    indexed_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(entity_type, entity_id)
);

-- Search analytics
CREATE TABLE search_analytics (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID,
    query TEXT NOT NULL,
    entity_type VARCHAR(50),
    filters JSONB DEFAULT '{}',
    results_count INTEGER,
    clicked_result_id UUID,
    click_position INTEGER,
    search_duration_ms INTEGER,
    performed_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Saved searches
CREATE TABLE saved_searches (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    name VARCHAR(255) NOT NULL,
    query_params JSONB NOT NULL,
    alert_enabled BOOLEAN DEFAULT FALSE,
    alert_frequency VARCHAR(20) DEFAULT 'daily',
    last_alerted_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Notification preferences
CREATE TABLE notification_preferences (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID UNIQUE NOT NULL,
    email_enabled BOOLEAN DEFAULT TRUE,
    sms_enabled BOOLEAN DEFAULT FALSE,
    push_enabled BOOLEAN DEFAULT TRUE,
    in_app_enabled BOOLEAN DEFAULT TRUE,
    preferences JSONB DEFAULT '{}', -- Specific notification type preferences
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Notification templates
CREATE TABLE notification_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(100) UNIQUE NOT NULL,
    template_type VARCHAR(50) NOT NULL, -- 'email', 'sms', 'push', 'in_app'
    subject_template VARCHAR(255),
    body_template TEXT NOT NULL,
    variables JSONB DEFAULT '{}',
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Notification queue
CREATE TABLE notification_queue (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    template_id UUID REFERENCES notification_templates(id),
    channel VARCHAR(20) NOT NULL, -- 'email', 'sms', 'push', 'in_app'
    recipient VARCHAR(255) NOT NULL,
    subject VARCHAR(255),
    content TEXT NOT NULL,
    priority INTEGER DEFAULT 5,
    status VARCHAR(20) DEFAULT 'pending',
    scheduled_for TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    sent_at TIMESTAMP WITH TIME ZONE,
    delivered_at TIMESTAMP WITH TIME ZONE,
    error_message TEXT,
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Notification delivery logs
CREATE TABLE notification_delivery_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    notification_id UUID REFERENCES notification_queue(id) ON DELETE CASCADE,
    event_type VARCHAR(50) NOT NULL, -- 'sent', 'delivered', 'opened', 'clicked', 'bounced'
    event_data JSONB DEFAULT '{}',
    occurred_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Forums and categories
CREATE TABLE forums (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    description TEXT,
    category VARCHAR(100),
    is_active BOOLEAN DEFAULT TRUE,
    post_count INTEGER DEFAULT 0,
    last_post_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Forum posts
CREATE TABLE forum_posts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    forum_id UUID REFERENCES forums(id) ON DELETE CASCADE,
    parent_post_id UUID REFERENCES forum_posts(id), -- For replies
    author_id UUID NOT NULL,
    title VARCHAR(255),
    content TEXT NOT NULL,
    post_type VARCHAR(20) DEFAULT 'post', -- 'post', 'reply', 'question'
    status VARCHAR(20) DEFAULT 'active',
    is_pinned BOOLEAN DEFAULT FALSE,
    is_locked BOOLEAN DEFAULT FALSE,
    vote_score INTEGER DEFAULT 0,
    reply_count INTEGER DEFAULT 0,
    view_count INTEGER DEFAULT 0,
    last_activity_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Consider creating comments table

-- Post votes and reactions
CREATE TABLE post_votes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    post_id UUID REFERENCES forum_posts(id) ON DELETE CASCADE,
    user_id UUID NOT NULL,
    vote_type VARCHAR(10) CHECK (vote_type IN ('up', 'down')),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(post_id, user_id)
);

-- User following relationships
CREATE TABLE user_follows (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    follower_id UUID NOT NULL,
    followed_id UUID NOT NULL,
    follow_type VARCHAR(20) DEFAULT 'user', -- 'user', 'forum', 'topic'
    followed_entity_id UUID,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(follower_id, followed_id, follow_type, followed_entity_id)
);
-- Ad campaigns
CREATE TABLE ad_campaigns (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id UUID NOT NULL,
    campaign_name VARCHAR(255) NOT NULL,
    campaign_type VARCHAR(50) NOT NULL, -- 'listing_boost', 'banner_ad', 'sponsored_content'
    target_entity_id UUID, -- listing_id, content_id, etc.
    targeting_criteria JSONB DEFAULT '{}',
    budget_cents INTEGER,
    daily_budget_cents INTEGER,
    bid_strategy VARCHAR(50) DEFAULT 'cpc',
    status VARCHAR(20) DEFAULT 'draft',
    start_date TIMESTAMP WITH TIME ZONE,
    end_date TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Ad creative content
CREATE TABLE ad_creatives (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    campaign_id UUID REFERENCES ad_campaigns(id) ON DELETE CASCADE,
    creative_type VARCHAR(50) NOT NULL,
    headline VARCHAR(255),
    description TEXT,
    image_urls JSONB DEFAULT '[]',
    call_to_action VARCHAR(100),
    landing_url VARCHAR(500),
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Ad performance tracking
CREATE TABLE ad_impressions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    campaign_id UUID REFERENCES ad_campaigns(id) ON DELETE CASCADE,
    creative_id UUID REFERENCES ad_creatives(id),
    user_id UUID,
    placement VARCHAR(100),
    event_type VARCHAR(20) NOT NULL, -- 'impression', 'click', 'conversion'
    cost_cents INTEGER DEFAULT 0,
    metadata JSONB DEFAULT '{}',
    occurred_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Ad credits and billing
CREATE TABLE ad_credits (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id UUID NOT NULL,
    credit_amount_cents INTEGER NOT NULL,
    purchase_type VARCHAR(50) NOT NULL, -- 'purchase', 'bonus', 'refund'
    transaction_id VARCHAR(255),
    expires_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

Event Publishing & Subscriptions

Published Events

Search Events:
  • search.query.performed - Search executed by user
  • search.result.clicked - Search result clicked
  • search.index.updated - Search index refreshed
  • search.saved - User saved search query
  • search.alert.triggered - Saved search alert fired
Notification Events:
  • notification.sent - Notification delivered
  • notification.delivered - Delivery confirmed
  • notification.opened - User opened notification
  • notification.clicked - User clicked notification link
  • notification.failed - Delivery failed
Community Events:
  • community.post.created - New forum post
  • community.post.replied - Reply added to post
  • community.post.voted - Post received vote
  • community.user.followed - User followed another user
  • community.activity.recorded - User activity logged
Advertising Events:
  • advertising.campaign.started - Campaign activated
  • advertising.impression.served - Ad displayed
  • advertising.click.recorded - Ad clicked
  • advertising.conversion.tracked - Goal conversion
  • advertising.budget.exhausted - Campaign budget depleted

Event Subscriptions

  • animal.created - Index new animal for search
  • animal.updated - Update search index
  • marketplace.listing.created - Index listing for discovery
  • profile.updated - Update breeder search data
  • breeding.clutch.created - Community notifications
  • sales.inquiry.received - Notify seller
  • payment.completed - Purchase confirmation notifications

Search Implementation

Full-Text Search Engine

async def perform_search(query: str, filters: Dict, user_context: Dict):
    """
    Advanced search with faceted filtering and personalization
    """
    # Parse and clean search query
    parsed_query = parse_search_query(query)
    
    # Build search vector query
    search_conditions = []
    
    # Full-text search on indexed content
    if parsed_query.text:
        search_conditions.append(
            "search_vector @@ plainto_tsquery('english', %s)",
            [parsed_query.text]
        )
    
    # Apply filters
    for filter_name, filter_value in filters.items():
        if filter_name == "species":
            search_conditions.append("metadata->>'species' = ANY(%s)", [filter_value])
        elif filter_name == "location":
            search_conditions.append("metadata->>'location' <-> %s < 50", [filter_value])
        elif filter_name == "price_range":
            search_conditions.append(
                "CAST(metadata->>'price' AS INTEGER) BETWEEN %s AND %s",
                [filter_value["min"], filter_value["max"]]
            )
    
    # Apply personalization based on user context
    boost_conditions = []
    if user_context.get("preferred_species"):
        boost_conditions.append(
            "CASE WHEN metadata->>'species' = ANY(%s) THEN 1.5 ELSE 1.0 END",
            [user_context["preferred_species"]]
        )
    
    # Execute search with ranking
    results = await execute_search_query(
        search_conditions, 
        boost_conditions,
        limit=filters.get("limit", 20),
        offset=filters.get("offset", 0)
    )
    
    # Track search analytics
    await track_search_event(user_context.get("user_id"), query, filters, len(results))
    
    return {
        "results": results,
        "total_count": await count_search_results(search_conditions),
        "facets": await get_search_facets(search_conditions),
        "suggestions": await get_search_suggestions(query)
    }

Smart Notification Engine

async def process_notification_trigger(event_type: str, event_data: Dict):
    """
    Intelligent notification processing with user preferences
    """
    # Determine notification template
    template = await get_notification_template(event_type)
    if not template:
        return
    
    # Find users to notify
    recipients = await find_notification_recipients(event_type, event_data)
    
    for recipient in recipients:
        # Check user preferences
        preferences = await get_user_notification_preferences(recipient.user_id)
        
        # Determine optimal delivery channel
        channels = await select_delivery_channels(preferences, event_type, recipient)
        
        for channel in channels:
            # Personalize notification content
            content = await personalize_notification(
                template, 
                event_data, 
                recipient, 
                channel
            )
            
            # Check rate limiting and frequency caps
            if await should_send_notification(recipient.user_id, event_type, channel):
                # Queue for delivery
                await queue_notification(
                    user_id=recipient.user_id,
                    channel=channel,
                    content=content,
                    priority=calculate_priority(event_type, recipient)
                )
    
    # Track notification metrics
    await track_notification_campaign(event_type, len(recipients), channels)

Performance & Scaling

Search Optimization

  • PostgreSQL Full-Text Search: Optimized with GIN indexes
  • Search Result Caching: Popular queries cached with Redis
  • Index Optimization: Automated index maintenance and optimization
  • Query Analysis: Slow query detection and optimization

Notification Delivery

  • Queue Processing: Async notification delivery with prioritization
  • Rate Limiting: Prevent spam and respect user preferences
  • Delivery Tracking: Complete delivery analytics and optimization
  • Channel Failover: Automatic fallback to alternative channels

Integration Points

Internal Dependencies

  • repti-core: Authentication, user preferences, configuration
  • repti-animal: Animal data for search indexing
  • repti-commerce: Marketplace listings and transaction notifications
  • repti-media: Media content for community features

External Services

  • Email Providers: SendGrid, AWS SES for email delivery
  • SMS Gateway: Twilio for SMS notifications
  • Push Notifications: Firebase, Apple Push for mobile notifications
  • Analytics: Custom analytics pipeline for search and engagement

Monitoring & Key Metrics

Search Metrics

  • Search Success Rate: Queries returning relevant results
  • Search Performance: Query response times and index health
  • Click-Through Rate: Search result relevance measurement
  • Search Abandonment: Queries with no clicks or interactions

Notification Metrics

  • Delivery Rate: Successful notification delivery percentage
  • Open Rate: Notification open and engagement rates
  • Conversion Rate: Notifications leading to desired actions
  • Unsubscribe Rate: User preference changes and opt-outs

Community Engagement

  • Active Users: Daily/monthly active community participants
  • Content Creation: Posts, replies, and user-generated content
  • Social Interactions: Follows, votes, and community engagement
  • Retention Rate: User return and continued participation

Advertising Performance

  • Campaign ROI: Return on advertising investment
  • Click-Through Rate: Ad engagement and effectiveness
  • Conversion Rate: Ad clicks leading to desired outcomes
  • Revenue per User: Advertising revenue optimization

repti-community creates the engagement layer that connects ReptiDex users, enabling discovery, communication, and community building around shared interests in reptile breeding and care.