Skip to main content

Profile & Settings PRD for Marketplace Features

Date: March 2026 Author: Product Team Status: Draft Version: 1.0 Related: Marketplace Strategy Analysis v2

Executive Summary

This PRD defines the Profile and Settings features required to support Avala’s data marketplace. Based on comprehensive analysis of the existing codebase, ~60% of the foundation exists but critical marketplace-specific features are missing.

Key Gaps Identified

CategoryCurrent StateGap
Creator ProfilesBasic user profileNo earnings, analytics, portfolio, verification
Payment IntegrationCoworker payouts onlyNo Stripe Connect, no marketplace transactions
Reputation SystemNoneNo ratings, reviews, or quality scores
Analytics DashboardNoneNo creator metrics, downloads, revenue tracking
Notification PreferencesPlaceholderNo granular controls or delivery preferences
API Key ManagementBasic CRUDNo scopes, rate limits, usage tracking

Implementation Scope

  • Backend: 12 new models, 8 new API endpoint groups
  • Frontend: 6 new pages, 15+ new components
  • Estimated Effort: 8-12 weeks (2 senior engineers)

Part 1: Current State Analysis

1.1 Existing Profile Infrastructure

Backend Models (Django)

ModelLocationPurposeMarketplace Ready?
Useraccount/models.pyCore user with type, bio, picturePartial
CoworkerProfileaccount/models.pyAnnotator details, payout method, hourly ratePartial
CustomerProfileaccount/models.pyBuyer company info, industry, urgencyPartial
CoworkerPayoutaccount/models.pyHistorical payout recordsYes
Scoreaccount/models.pyPer-task performance scoresNo (task-scoped)
UserCreditaccount/models.pyCredit balance systemPartial
ApiKeyapikey/models.pyAPI authenticationPartial

Frontend Pages (Flutter)

PageRouteStatus
Profile Overview/@{username}Implemented
Profile Settings/@{username}/settingsPlaceholder only
Coworker Payouts/@{username}/payoutsImplemented (staff-only)
Coworker Wallet/@{username}/walletImplemented (staff-only)
Personal Settings/settingsPartial (account, security, storage)

1.2 Existing Organization Infrastructure

Backend Models

ModelLocationPurpose
Organizationorganization/models.pyOrg with plan, visibility, verification
OrganizationMembershiporganization/models.pyUser-org relationship with roles
OrganizationInvitationorganization/models.pyInvite flow with token
Teamorganization/models.pySub-teams within org
TeamMembershiporganization/models.pyTeam member roles
OrganizationBillingorganization/models.pyStripe customer/subscription IDs
OrganizationAllowedDomainorganization/models.pyEmail domain auto-enrollment

Frontend Pages

PageRouteStatus
Org Overview/{slug}Implemented
Org Settings/{slug}/settingsImplemented (account, members, invites)
Org Teams/{slug}/teamsImplemented
Org Members/{slug}/membersImplemented
URL Design: Uses GitHub-style root-level slugs. Both organizations and users share the /{slug}/... namespace. Reserved system routes (/settings, /admin, /api, /search, etc.) are protected.

Part 2: Gap Analysis by Feature Area

2.1 Creator Profile Features

Required for: Marketplace sellers to showcase their work and build trust

What’s Missing

FeatureBackend GapFrontend GapPriority
Creator verification statusNo is_verified_creator fieldNo badge UIP0
Creator display nameUses username onlyNo separate display fieldP1
Portfolio/showcaseNo relation to featured datasetsNo showcase sectionP1
Social linksNo fieldsNo UIP2
Response time metricsNo trackingNo displayP2
Creator tier/levelNo tier systemNo visual indicatorP1

Required Models

# New fields on User model
class User(AbstractUser):
    # Existing fields...

    # NEW: Creator-specific fields
    creator_display_name = models.CharField(max_length=100, blank=True)
    creator_bio = models.TextField(max_length=2000, blank=True)  # Longer than user bio
    is_verified_creator = models.BooleanField(default=False)
    creator_tier = models.CharField(
        max_length=20,
        choices=[('STARTER', 'Starter'), ('PRO', 'Pro'), ('VERIFIED', 'Verified')],
        default='STARTER'
    )
    social_links = models.JSONField(default=dict)  # {"github": "...", "linkedin": "..."}
    portfolio_datasets = models.ManyToManyField('dataset.Dataset', blank=True)

2.2 Payment Integration (Stripe Connect)

Required for: Creators to receive earnings from dataset sales

What’s Missing

FeatureBackend GapFrontend GapPriority
Stripe Connect accountNo stripe_connect_account_idNo onboarding flowP0
Payout settingsNo payout schedule configNo settings UIP0
Bank account managementNo modelNo UIP0
Tax informationNo fieldsNo W-9/tax form UIP0
Earnings balanceNo available_balance fieldNo balance displayP0
Transaction historyNo marketplace transaction modelNo transaction listP0

Required Models

# server/apps/account/models.py - Extend or create new

class CreatorPaymentProfile(models.Model):
    """Stripe Connect integration for marketplace creators"""
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='payment_profile')

    # Stripe Connect
    stripe_connect_account_id = models.CharField(max_length=255, blank=True)
    stripe_connect_onboarding_complete = models.BooleanField(default=False)
    stripe_connect_payouts_enabled = models.BooleanField(default=False)

    # Payout configuration
    payout_schedule = models.CharField(
        max_length=20,
        choices=[('DAILY', 'Daily'), ('WEEKLY', 'Weekly'), ('MONTHLY', 'Monthly')],
        default='WEEKLY'
    )
    payout_minimum_threshold = MoneyField(
        max_digits=10, decimal_places=2,
        default_currency='USD', default=Money(50, 'USD')
    )

    # Tax information
    tax_form_submitted = models.BooleanField(default=False)
    tax_form_type = models.CharField(max_length=20, blank=True)  # W-9, W-8BEN, etc.

    # Balance (cached, synced from Stripe)
    available_balance = MoneyField(max_digits=12, decimal_places=2, default_currency='USD', default=0)
    pending_balance = MoneyField(max_digits=12, decimal_places=2, default_currency='USD', default=0)

    class Meta:
        db_table = 'account_creator_payment_profile'


class MarketplaceTransaction(models.Model):
    """Individual marketplace sale/purchase record"""
    uid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)

    # Participants
    seller = models.ForeignKey(User, on_delete=models.PROTECT, related_name='sales')
    buyer = models.ForeignKey(User, on_delete=models.PROTECT, related_name='purchases')

    # What was sold
    dataset = models.ForeignKey('dataset.Dataset', on_delete=models.PROTECT)

    # Pricing
    sale_price = MoneyField(max_digits=10, decimal_places=2, default_currency='USD')
    platform_commission = MoneyField(max_digits=10, decimal_places=2, default_currency='USD')
    seller_earnings = MoneyField(max_digits=10, decimal_places=2, default_currency='USD')

    # Stripe
    stripe_payment_intent_id = models.CharField(max_length=255)
    stripe_transfer_id = models.CharField(max_length=255, blank=True)

    # Status
    status = models.CharField(
        max_length=20,
        choices=[
            ('PENDING', 'Pending'),
            ('COMPLETED', 'Completed'),
            ('REFUNDED', 'Refunded'),
            ('FAILED', 'Failed'),
        ],
        default='PENDING'
    )

    # Timestamps
    created_at = models.DateTimeField(auto_now_add=True)
    completed_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'marketplace_transaction'
        indexes = [
            models.Index(fields=['seller', 'created_at']),
            models.Index(fields=['buyer', 'created_at']),
            models.Index(fields=['status']),
        ]

2.3 Reputation & Rating System

Required for: Building trust and quality signals in the marketplace

What’s Missing

FeatureBackend GapFrontend GapPriority
Dataset ratingsNo modelNo star rating UIP0
Dataset reviewsNo modelNo review display/formP0
Creator reputation scoreNo aggregationNo score displayP1
Quality badgesNo badge systemNo badge componentsP1
Review moderationNo modelNo moderation UIP2

Required Models

# server/apps/marketplace/models.py (NEW APP)

class DatasetReview(models.Model):
    """User review of a dataset"""
    uid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)

    dataset = models.ForeignKey('dataset.Dataset', on_delete=models.CASCADE, related_name='reviews')
    reviewer = models.ForeignKey(User, on_delete=models.CASCADE, related_name='written_reviews')
    transaction = models.ForeignKey(MarketplaceTransaction, on_delete=models.SET_NULL, null=True)

    # Rating
    rating = models.PositiveSmallIntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
    title = models.CharField(max_length=200, blank=True)
    body = models.TextField(max_length=5000, blank=True)

    # Quality dimensions (optional detailed ratings)
    quality_score = models.PositiveSmallIntegerField(null=True, validators=[MinValueValidator(1), MaxValueValidator(5)])
    documentation_score = models.PositiveSmallIntegerField(null=True, validators=[MinValueValidator(1), MaxValueValidator(5)])
    value_score = models.PositiveSmallIntegerField(null=True, validators=[MinValueValidator(1), MaxValueValidator(5)])

    # Moderation
    is_verified_purchase = models.BooleanField(default=False)
    is_visible = models.BooleanField(default=True)
    moderation_status = models.CharField(
        max_length=20,
        choices=[('PENDING', 'Pending'), ('APPROVED', 'Approved'), ('REJECTED', 'Rejected')],
        default='APPROVED'
    )

    # Helpfulness
    helpful_count = models.PositiveIntegerField(default=0)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = 'marketplace_dataset_review'
        unique_together = [['dataset', 'reviewer']]
        indexes = [
            models.Index(fields=['dataset', '-created_at']),
            models.Index(fields=['reviewer']),
        ]


class CreatorReputation(models.Model):
    """Aggregated reputation metrics for a creator"""
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='reputation')

    # Aggregated scores (updated via Celery task)
    overall_rating = models.DecimalField(max_digits=3, decimal_places=2, default=0)
    total_reviews = models.PositiveIntegerField(default=0)
    total_sales = models.PositiveIntegerField(default=0)
    total_downloads = models.PositiveIntegerField(default=0)

    # Quality metrics
    average_quality_score = models.DecimalField(max_digits=3, decimal_places=2, default=0)
    response_time_hours = models.PositiveIntegerField(null=True)  # Average response time

    # Badges (stored as list of badge IDs)
    badges = ArrayField(models.CharField(max_length=50), default=list)

    # Timestamps
    last_calculated_at = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = 'marketplace_creator_reputation'


class Badge(models.Model):
    """Badge definitions"""
    code = models.CharField(max_length=50, unique=True, primary_key=True)
    name = models.CharField(max_length=100)
    description = models.TextField()
    icon = models.CharField(max_length=100)  # Icon name or URL
    category = models.CharField(
        max_length=20,
        choices=[
            ('ACHIEVEMENT', 'Achievement'),
            ('QUALITY', 'Quality'),
            ('SALES', 'Sales'),
            ('VERIFICATION', 'Verification'),
        ]
    )
    criteria = models.JSONField()  # {"type": "sales_count", "threshold": 100}

    class Meta:
        db_table = 'marketplace_badge'

2.4 Creator Analytics Dashboard

Required for: Creators to understand their performance and optimize

What’s Missing

FeatureBackend GapFrontend GapPriority
Revenue analyticsNo aggregation queriesNo chartsP0
Download trackingNo download event modelNo download statsP0
View/engagement metricsNo view trackingNo engagement displayP1
Top performersNo ranking queriesNo top datasets listP1
Time-series dataNo time-bucketed storageNo trend chartsP1
Export analyticsNo export endpointNo export buttonP2

Required Models

# server/apps/analytics/models.py

class DatasetEngagement(models.Model):
    """Track dataset views and engagement"""
    dataset = models.ForeignKey('dataset.Dataset', on_delete=models.CASCADE)
    date = models.DateField()

    # Metrics
    views = models.PositiveIntegerField(default=0)
    unique_viewers = models.PositiveIntegerField(default=0)
    preview_downloads = models.PositiveIntegerField(default=0)
    full_downloads = models.PositiveIntegerField(default=0)
    favorites = models.PositiveIntegerField(default=0)

    class Meta:
        db_table = 'analytics_dataset_engagement'
        unique_together = [['dataset', 'date']]
        indexes = [
            models.Index(fields=['dataset', 'date']),
        ]


class CreatorEarnings(models.Model):
    """Daily earnings aggregation per creator"""
    creator = models.ForeignKey(User, on_delete=models.CASCADE)
    date = models.DateField()

    # Revenue
    gross_revenue = MoneyField(max_digits=12, decimal_places=2, default_currency='USD', default=0)
    net_earnings = MoneyField(max_digits=12, decimal_places=2, default_currency='USD', default=0)
    commission_paid = MoneyField(max_digits=12, decimal_places=2, default_currency='USD', default=0)

    # Volume
    transaction_count = models.PositiveIntegerField(default=0)
    units_sold = models.PositiveIntegerField(default=0)

    class Meta:
        db_table = 'analytics_creator_earnings'
        unique_together = [['creator', 'date']]
        indexes = [
            models.Index(fields=['creator', 'date']),
        ]

Required API Endpoints

# GET /api/v1/users/{uid}/analytics/overview/
# Returns: total_earnings, total_downloads, total_sales, avg_rating

# GET /api/v1/users/{uid}/analytics/earnings/?period=30d
# Returns: time-series earnings data

# GET /api/v1/users/{uid}/analytics/downloads/?period=30d
# Returns: time-series download data

# GET /api/v1/users/{uid}/analytics/top-datasets/?limit=10
# Returns: top performing datasets by revenue/downloads

# GET /api/v1/users/{uid}/analytics/export/?format=csv
# Returns: CSV download of all analytics

2.5 Notification Preferences

Required for: Users to control how they receive updates

What’s Missing

FeatureBackend GapFrontend GapPriority
Email preferencesNo modelNo togglesP1
In-app preferencesNo modelNo togglesP1
Notification categoriesNo categorizationNo category UIP1
Digest settingsNo digest configNo digest optionsP2
Quiet hoursNo quiet hours modelNo time pickerP3

Required Models

# server/apps/notifications/models.py (NEW APP)

class NotificationPreference(models.Model):
    """User notification preferences"""
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='notification_preferences')

    # Global settings
    email_enabled = models.BooleanField(default=True)
    push_enabled = models.BooleanField(default=True)

    # Category settings (JSON for flexibility)
    # Format: {"sales": {"email": true, "push": true}, "reviews": {"email": false, "push": true}}
    category_settings = models.JSONField(default=dict)

    # Digest settings
    digest_frequency = models.CharField(
        max_length=20,
        choices=[('NONE', 'None'), ('DAILY', 'Daily'), ('WEEKLY', 'Weekly')],
        default='NONE'
    )
    digest_day = models.PositiveSmallIntegerField(default=1)  # 1-7 for weekly
    digest_hour = models.PositiveSmallIntegerField(default=9)  # 0-23

    # Quiet hours
    quiet_hours_enabled = models.BooleanField(default=False)
    quiet_hours_start = models.TimeField(default='22:00')
    quiet_hours_end = models.TimeField(default='08:00')

    class Meta:
        db_table = 'notifications_preference'


NOTIFICATION_CATEGORIES = [
    ('SALES', 'Sales & Purchases'),
    ('REVIEWS', 'Reviews & Ratings'),
    ('FOLLOWERS', 'Followers & Social'),
    ('UPDATES', 'Product Updates'),
    ('MARKETING', 'Marketing & Promotions'),
    ('SECURITY', 'Security Alerts'),
    ('PAYOUTS', 'Payouts & Earnings'),
]

2.6 Enhanced API Key Management

Required for: SDK users to manage access with granular permissions

What’s Missing

FeatureBackend GapFrontend GapPriority
Key scopesField exists but unusedNo scope selectorP1
Rate limit displayNo trackingNo rate limit UIP2
Usage statisticsNo trackingNo usage chartsP2
Key expirationField existsNo expiration pickerP2
IP whitelistingNo fieldNo IP inputP3

Required Model Updates

# server/apps/apikey/models.py - Extend existing

class ApiKey(models.Model):
    # Existing fields...

    # NEW: Enhanced management
    rate_limit_per_minute = models.PositiveIntegerField(default=60)
    rate_limit_per_day = models.PositiveIntegerField(default=10000)

    # Usage tracking
    total_requests = models.PositiveIntegerField(default=0)
    last_used_at = models.DateTimeField(null=True, blank=True)
    last_used_ip = models.GenericIPAddressField(null=True, blank=True)

    # IP restrictions
    allowed_ips = ArrayField(models.GenericIPAddressField(), default=list, blank=True)


class ApiKeyUsageLog(models.Model):
    """Hourly usage aggregation per API key"""
    api_key = models.ForeignKey(ApiKey, on_delete=models.CASCADE)
    hour = models.DateTimeField()  # Truncated to hour

    request_count = models.PositiveIntegerField(default=0)
    error_count = models.PositiveIntegerField(default=0)

    class Meta:
        db_table = 'apikey_usage_log'
        unique_together = [['api_key', 'hour']]

2.7 Privacy & Visibility Settings

Required for: Users to control their public presence

What’s Missing

FeatureBackend GapFrontend GapPriority
Profile visibility toggleField existsNo toggleP1
Default dataset visibilityNo fieldNo selectorP1
Hide statisticsNo fieldNo toggleP2
Hide reviewsNo fieldNo toggleP2
Block usersNo modelNo block UIP3

Required Model Updates

# server/apps/account/models.py - Extend User

class User(AbstractUser):
    # Existing fields...

    # NEW: Privacy settings
    profile_visibility = models.CharField(...)  # EXISTS
    default_dataset_visibility = models.CharField(
        max_length=20,
        choices=[('PUBLIC', 'Public'), ('PRIVATE', 'Private'), ('ORG_ONLY', 'Organization Only')],
        default='PRIVATE'
    )
    show_statistics_publicly = models.BooleanField(default=True)
    show_reviews_publicly = models.BooleanField(default=True)
    allow_messages = models.BooleanField(default=True)


class UserBlock(models.Model):
    """User blocking for safety"""
    blocker = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blocking')
    blocked = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blocked_by')
    reason = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'account_user_block'
        unique_together = [['blocker', 'blocked']]

Part 3: Frontend Requirements

3.1 New Pages Required

PageRouteComponentsPriority
Creator Analytics/{username}/analyticsCharts, stats cards, date pickerP0
Payment Settings/settings/paymentStripe Connect button, bank form, tax formP0
Privacy Settings/settings/privacyToggle groups, visibility selectorsP1
Notification Settings/settings/notificationsCategory toggles, digest optionsP1
Purchase History/{username}/purchasesTransaction list, filtersP1
Reviews Written/{username}/reviewsReview cards, edit/deleteP2

3.2 New Components Required

ComponentLocationPurpose
CreatorBadgelib/common/widgets/Display verification/achievement badges
ReputationScorelib/common/widgets/Star rating display with count
StatsCardlib/common/widgets/Analytics metric card (value, trend, label)
AnalyticsChartlib/common/widgets/Time-series line/bar chart
StripeConnectButtonlib/settings/Stripe Connect onboarding button
PayoutScheduleSelectorlib/settings/Payout frequency dropdown
NotificationToggleGrouplib/settings/Category toggle group
DatasetRatingInputlib/datasets/5-star rating selector
ReviewCardlib/datasets/Review display with rating, text, author
ReviewFormlib/datasets/Review submission form
TransactionCardlib/profile/Purchase/sale transaction display
EarningsChartlib/profile/Revenue over time chart
DownloadsChartlib/profile/Downloads over time chart
VisibilityTogglelib/settings/Public/Private/Org toggle
DateRangePickerlib/common/widgets/Analytics date range selection

3.3 State Management (Cubits/BLoCs)

Cubit/BLoCPurpose
CreatorAnalyticsCubitLoad and cache analytics data
PaymentSettingsCubitManage Stripe Connect state
NotificationPreferencesCubitLoad/save notification settings
PrivacySettingsCubitLoad/save privacy settings
DatasetReviewsCubitLoad reviews for a dataset
WriteReviewCubitSubmit/edit review
PurchaseHistoryCubitLoad purchase transactions
TransactionsCubitLoad all transactions (sales + purchases)

Part 4: API Endpoints Required

4.1 Creator Profile & Analytics

GET    /api/v1/users/{uid}/creator-profile/
PATCH  /api/v1/users/{uid}/creator-profile/
GET    /api/v1/users/{uid}/analytics/overview/
GET    /api/v1/users/{uid}/analytics/earnings/
GET    /api/v1/users/{uid}/analytics/downloads/
GET    /api/v1/users/{uid}/analytics/top-datasets/
GET    /api/v1/users/{uid}/analytics/export/

4.2 Payment Integration

GET    /api/v1/users/{uid}/payment-profile/
POST   /api/v1/users/{uid}/payment-profile/stripe-connect/onboard/
GET    /api/v1/users/{uid}/payment-profile/stripe-connect/status/
PATCH  /api/v1/users/{uid}/payment-profile/payout-settings/
GET    /api/v1/users/{uid}/transactions/
GET    /api/v1/users/{uid}/transactions/{uid}/
GET    /api/v1/users/{uid}/payouts/
POST   /api/v1/users/{uid}/payouts/request/

4.3 Reviews & Ratings

GET    /api/v1/datasets/{slug}/reviews/
POST   /api/v1/datasets/{slug}/reviews/
GET    /api/v1/datasets/{slug}/reviews/{uid}/
PATCH  /api/v1/datasets/{slug}/reviews/{uid}/
DELETE /api/v1/datasets/{slug}/reviews/{uid}/
POST   /api/v1/datasets/{slug}/reviews/{uid}/helpful/
GET    /api/v1/users/{uid}/reviews/
GET    /api/v1/users/{uid}/reputation/

4.4 Notifications

GET    /api/v1/users/{uid}/notification-preferences/
PATCH  /api/v1/users/{uid}/notification-preferences/
GET    /api/v1/users/{uid}/notifications/
POST   /api/v1/users/{uid}/notifications/mark-read/

4.5 Privacy & Blocking

GET    /api/v1/users/{uid}/privacy-settings/
PATCH  /api/v1/users/{uid}/privacy-settings/
GET    /api/v1/users/{uid}/blocked-users/
POST   /api/v1/users/{uid}/blocked-users/
DELETE /api/v1/users/{uid}/blocked-users/{blocked_uid}/

Part 5: Implementation Roadmap

Phase 1: Creator Foundation (Weeks 1-3)

Goal: Enable creators to set up profiles and connect payments
TaskBackendFrontendOwner
Creator profile fieldsAdd fields to User modelProfile settings formBE/FE
Stripe Connect integrationCreatorPaymentProfile model + APIOnboarding flowBE/FE
Payment settings pagePayout settings APISettings UIBE/FE
Basic analytics overviewOverview endpointStats cardsBE/FE
Deliverables:
  • Creator can add display name, bio, social links
  • Creator can connect Stripe account
  • Creator can see basic earnings overview

Phase 2: Reputation & Reviews (Weeks 4-6)

Goal: Build trust signals through ratings and reviews
TaskBackendFrontendOwner
Review model + APIDatasetReview modelReview form/displayBE/FE
Reputation aggregationCreatorReputation + Celery taskReputation displayBE
Badge systemBadge model + assignment logicBadge componentsBE/FE
Review moderationModeration status + admin UIAdmin panelBE
Deliverables:
  • Users can rate/review purchased datasets
  • Creators have aggregated reputation scores
  • Verification and achievement badges display

Phase 3: Analytics Dashboard (Weeks 7-9)

Goal: Give creators insights into their performance
TaskBackendFrontendOwner
Engagement trackingDatasetEngagement model-BE
Earnings aggregationCreatorEarnings + Celery-BE
Analytics pageTime-series APIsCharts, filtersFE
Export functionalityCSV export endpointExport buttonBE/FE
Deliverables:
  • Creators see revenue, downloads, views over time
  • Top performing datasets highlighted
  • Analytics exportable as CSV

Phase 4: Settings & Privacy (Weeks 10-12)

Goal: Complete user control over their experience
TaskBackendFrontendOwner
Notification preferencesNotificationPreference modelSettings togglesBE/FE
Privacy settingsPrivacy fields + APIPrivacy togglesBE/FE
Enhanced API keysUsage tracking + rate limitsKey management UIBE/FE
User blockingUserBlock model + enforcementBlock UIBE/FE
Deliverables:
  • Users control notification delivery
  • Users control profile/data visibility
  • API keys show usage and have granular scopes

Part 6: Success Metrics

MetricTarget (Month 3)Target (Month 6)
Creators with Stripe Connected50200
Datasets with ratings100500
Average creator rating4.0+4.2+
Analytics page DAU20% of creators40% of creators
Notification opt-in rate70%75%
API keys with scopes configured30%50%

Part 7: Open Questions

  1. Commission structure: Is 12% platform commission final? Need to confirm for transaction model.
  2. Tax handling: Do we collect W-9 ourselves or use Stripe’s tax form collection?
  3. Review moderation: Auto-approve all reviews or require moderation queue?
  4. Badge criteria: What are the specific thresholds for each badge type?
  5. Analytics retention: How long do we keep daily analytics data? (Suggest: 2 years)
  6. Notification channels: Do we support SMS notifications or just email + in-app?

Appendix A: Database Migration Plan

New Tables

  • account_creator_payment_profile
  • marketplace_transaction
  • marketplace_dataset_review
  • marketplace_creator_reputation
  • marketplace_badge
  • analytics_dataset_engagement
  • analytics_creator_earnings
  • notifications_preference
  • apikey_usage_log
  • account_user_block

Modified Tables

  • account_user - Add creator fields, privacy settings
  • apikey_apikey - Add rate limits, usage tracking

Migration Order

  1. Core user fields (no dependencies)
  2. Payment profile (depends on user)
  3. Transaction/review models (depends on user + dataset)
  4. Analytics tables (depends on user + dataset)
  5. Notification preferences (depends on user)

Appendix B: Third-Party Integrations

ServicePurposeAPI Docs
Stripe ConnectCreator payoutshttps://stripe.com/docs/connect
Stripe TaxTax form collectionhttps://stripe.com/docs/tax
SendGridEmail notificationshttps://docs.sendgrid.com/
FirebasePush notificationshttps://firebase.google.com/docs/cloud-messaging

Last Updated: March 2026