Skip to main content

Sponsor Ad Type Definitions

Source: lib/types/sponsor-ad.ts

The sponsor ad module defines types for the sponsorship and advertising system. Sponsors can promote items through weekly or monthly advertising slots with a full lifecycle from payment through approval, activation, and expiration.

Type Aliases

SponsorAdStatus

Lifecycle states for a sponsor advertisement:

type SponsorAdStatus =
| 'pending_payment'
| 'pending'
| 'rejected'
| 'active'
| 'expired'
| 'cancelled';
StatusDescription
pending_paymentAd created, awaiting payment completion
pendingPayment received, awaiting admin approval
rejectedAdmin rejected the sponsorship request
activeApproved and currently displayed
expiredActive period has ended
cancelledCancelled by the sponsor or admin

SponsorAdIntervalType

Billing interval options:

type SponsorAdIntervalType = 'weekly' | 'monthly';

Display Types

SponsorWithItem

A sponsor ad with its associated item data for UI display. The item field may be null if the linked item no longer exists.

import type { SponsorAd } from '@/lib/db/schema';
import type { ItemData } from '@/lib/content';

interface SponsorWithItem {
sponsor: SponsorAd;
item: ItemData | null;
}

Request Types

CreateSponsorAdRequest

Payload for creating a new sponsor ad.

interface CreateSponsorAdRequest {
itemSlug: string;
interval: SponsorAdIntervalType;
paymentProvider: string;
}

UpdateSponsorAdRequest

Payload for updating an existing sponsor ad. Used primarily by admin operations.

interface UpdateSponsorAdRequest {
id: string;
status?: SponsorAdStatus;
startDate?: Date;
endDate?: Date;
subscriptionId?: string;
customerId?: string;
}

ApproveSponsorAdRequest

Payload for approving a pending sponsor ad.

interface ApproveSponsorAdRequest {
id: string;
}

RejectSponsorAdRequest

Payload for rejecting a sponsor ad with a reason.

interface RejectSponsorAdRequest {
id: string;
rejectionReason: string;
}

CancelSponsorAdRequest

Payload for cancelling an active or pending sponsor ad.

interface CancelSponsorAdRequest {
id: string;
cancelReason?: string;
}

Response Types

SponsorAdResponse

Discriminated union response for single sponsor ad operations:

type SponsorAdResponse =
| {
success: true;
data: SponsorAd;
message?: string;
}
| { success: false; error: string };

SponsorAdListResponse

Discriminated union response for paginated sponsor ad lists:

type SponsorAdListResponse =
| {
success: true;
data: { sponsorAds: SponsorAd[] };
meta: {
page: number;
totalPages: number;
total: number;
limit: number;
};
}
| { success: false; error: string };

Query Options

SponsorAdListOptions

Query parameters for filtering and paginating sponsor ad lists.

interface SponsorAdListOptions {
status?: SponsorAdStatus;
interval?: SponsorAdIntervalType;
userId?: string;
page?: number;
limit?: number;
search?: string;
sortBy?: 'createdAt' | 'updatedAt' | 'startDate' | 'endDate' | 'status';
sortOrder?: 'asc' | 'desc';
}

Stats Types

SponsorAdStats

Aggregate statistics for the sponsor ad dashboard.

interface SponsorAdStats {
overview: {
total: number;
pendingPayment: number;
pending: number;
active: number;
rejected: number;
expired: number;
cancelled: number;
};
byInterval: {
weekly: number;
monthly: number;
};
revenue: {
totalRevenue: number;
weeklyRevenue: number;
monthlyRevenue: number;
};
}

Dashboard Types

SponsorAdDashboardResponse

Combined response for the admin sponsor dashboard, including the list, pagination, and statistics.

interface SponsorAdDashboardResponse {
success: boolean;
data: {
sponsorAds: SponsorAd[];
pagination: {
page: number;
totalPages: number;
total: number;
limit: number;
};
stats: SponsorAdStats;
};
error?: string;
}

Extended Types

SponsorAdWithUser

Sponsor ad enriched with user and reviewer data, used in admin detail views.

interface SponsorAdWithUser extends SponsorAd {
user?: {
id: string;
email: string | null;
image: string | null;
};
reviewer?: {
id: string;
email: string | null;
} | null;
}

Usage Examples

Creating a sponsor ad

import type { CreateSponsorAdRequest } from '@/lib/types/sponsor-ad';

const request: CreateSponsorAdRequest = {
itemSlug: 'my-awesome-tool',
interval: 'monthly',
paymentProvider: 'stripe',
};

Filtering sponsor ads

import type { SponsorAdListOptions } from '@/lib/types/sponsor-ad';

const options: SponsorAdListOptions = {
status: 'active',
interval: 'monthly',
sortBy: 'startDate',
sortOrder: 'desc',
page: 1,
limit: 20,
};

Handling discriminated union responses

import type { SponsorAdResponse } from '@/lib/types/sponsor-ad';

async function approveSponsor(id: string): Promise<void> {
const res = await fetch(`/api/admin/sponsor-ads/${id}/approve`, {
method: 'POST',
});
const data: SponsorAdResponse = await res.json();

if (data.success) {
console.log('Approved:', data.data.id);
if (data.message) {
console.log('Message:', data.message);
}
} else {
console.error('Failed:', data.error);
}
}

Displaying dashboard statistics

import type { SponsorAdStats } from '@/lib/types/sponsor-ad';

function renderStats(stats: SponsorAdStats) {
const activeRate = stats.overview.total > 0
? (stats.overview.active / stats.overview.total * 100).toFixed(1)
: '0';

return {
totalAds: stats.overview.total,
activePercentage: `${activeRate}%`,
weeklyRevenue: `$${stats.revenue.weeklyRevenue.toFixed(2)}`,
monthlyRevenue: `$${stats.revenue.monthlyRevenue.toFixed(2)}`,
};
}

Design Notes

pending_payment -> pending -> active -> expired
\-> rejected
active -> cancelled
  1. Sponsor creates ad and initiates payment (pending_payment)
  2. After payment completes, ad moves to pending for admin review
  3. Admin approves (active) or rejects (rejected)
  4. Active ads expire automatically when endDate passes
  5. Sponsors or admins can cancel at any time

Discriminated Union Responses

The SponsorAdResponse and SponsorAdListResponse types use discriminated unions based on the success field. This enables type-safe error handling in TypeScript:

// TypeScript narrows the type based on success check
if (response.success) {
// TypeScript knows response.data exists here
console.log(response.data);
} else {
// TypeScript knows response.error exists here
console.error(response.error);
}
  • ItemData - The item being sponsored (referenced by itemSlug)
  • SponsorAd - Database schema type from lib/db/schema