Item Type Definitions
Source: lib/types/item.ts
Items are the core content entities in the template. This module defines the data structures for creating, reading, updating, and listing items, along with validation constants and status management types.
Interfaces
ItemLocationData
Location data for items that can be geocoded. Stored in YAML and indexed in item_location_index for fast geo queries.
import type { MapProvider } from './location';
interface ItemLocationData {
address?: string; // Full address string for geocoding
city?: string;
state?: string;
country?: string;
postal_code?: string;
latitude?: number; // Pre-geocoded latitude
longitude?: number; // Pre-geocoded longitude
service_area?: string; // e.g., "Nationwide", "New York Metro"
is_remote?: boolean; // Whether this item operates remotely
geocoded_by?: MapProvider; // Which geocoding provider was used
}
ItemData
The primary item data structure returned by read operations.
interface ItemData {
id: string;
name: string;
slug: string;
description: string;
source_url: string;
category: string | string[];
tags: string[];
collections?: string[];
featured?: boolean;
icon_url?: string;
updated_at: string;
status: 'draft' | 'pending' | 'approved' | 'rejected';
submitted_by?: string;
submitted_at?: string;
reviewed_by?: string;
reviewed_at?: string;
review_notes?: string;
deleted_at?: string; // ISO timestamp for soft delete
action?: 'visit-website' | 'start-survey' | 'buy';
showSurveys?: boolean; // Whether to show surveys section
publisher?: string; // Publisher name for display
location?: ItemLocationData;
}
Key details:
categorysupports both a single string and an array for multi-category itemsstatususes a four-state approval flow: draft, pending, approved, rejecteddeleted_atenables soft deletion without removing dataactiondefines the CTA button type on the item detail page
CreateItemRequest
Input payload for creating a new item (POST endpoint).
interface CreateItemRequest {
id: string;
name: string;
slug: string;
description: string;
source_url: string;
category: string | string[];
tags: string[];
collections?: string[];
brand?: string;
featured?: boolean;
icon_url?: string;
status?: 'draft' | 'pending' | 'approved' | 'rejected';
submitted_by?: string;
location?: ItemLocationData;
}
UpdateItemRequest
Input payload for updating an existing item. Extends Partial<CreateItemRequest> so all fields except id are optional.
interface UpdateItemRequest extends Partial<CreateItemRequest> {
id: string;
status?: 'draft' | 'pending' | 'approved' | 'rejected';
review_notes?: string;
deleted_at?: string; // For soft delete operations
}
ItemListOptions
Query parameters for filtering and paginating item lists.
interface ItemListOptions {
status?: 'draft' | 'pending' | 'approved' | 'rejected';
categories?: string[]; // Multi-category filtering
tags?: string[]; // Multi-tag filtering
page?: number;
limit?: number;
sortBy?: SortField;
sortOrder?: SortOrder;
includeDeleted?: boolean; // Include soft-deleted items (default: false)
submittedBy?: string; // Filter by submitting user
search?: string; // Search by name or description
city?: string; // Filter by city
country?: string; // Filter by country
includeRemote?: boolean; // Include remote items in location queries
}
ItemListResponse
Paginated response for item list queries.
interface ItemListResponse {
items: ItemData[];
total: number;
page: number;
limit: number;
totalPages: number;
}
ItemResponse
Response envelope for single-item operations.
interface ItemResponse {
success: boolean;
item?: ItemData;
error?: string;
message?: string;
}
ReviewRequest
Payload for approving or rejecting an item during the review process.
interface ReviewRequest {
status: 'approved' | 'rejected';
review_notes?: string;
}
Type Aliases
SortField
Valid fields for sorting item lists:
type SortField = 'name' | 'updated_at' | 'status' | 'submitted_at';
SortOrder
Sort direction:
type SortOrder = 'asc' | 'desc';
ItemStatus
A union type derived from ITEM_STATUSES:
type ItemStatus = (typeof ITEM_STATUSES)[keyof typeof ITEM_STATUSES];
// Resolves to: 'draft' | 'pending' | 'approved' | 'rejected'
Constants
ITEM_VALIDATION
Validation constraints for item fields:
const ITEM_VALIDATION = {
NAME_MIN_LENGTH: 3,
NAME_MAX_LENGTH: 100,
DESCRIPTION_MIN_LENGTH: 10,
DESCRIPTION_MAX_LENGTH: 500,
SLUG_MIN_LENGTH: 3,
SLUG_MAX_LENGTH: 50,
} as const;
ITEM_STATUSES
Canonical status values for the item approval workflow:
const ITEM_STATUSES = {
DRAFT: 'draft',
PENDING: 'pending',
APPROVED: 'approved',
REJECTED: 'rejected',
} as const;
ITEM_STATUS_LABELS
Human-readable labels for each status:
const ITEM_STATUS_LABELS = {
draft: 'Draft',
pending: 'Pending Review',
approved: 'Approved',
rejected: 'Rejected',
} as const;
ITEM_STATUS_COLORS
UI color mappings for each status:
const ITEM_STATUS_COLORS = {
draft: 'gray',
pending: 'yellow',
approved: 'green',
rejected: 'red',
} as const;
Usage Examples
Creating an item
import type { CreateItemRequest } from '@/lib/types/item';
import { ITEM_VALIDATION } from '@/lib/types/item';
function validateItemName(name: string): boolean {
return (
name.length >= ITEM_VALIDATION.NAME_MIN_LENGTH &&
name.length <= ITEM_VALIDATION.NAME_MAX_LENGTH
);
}
const newItem: CreateItemRequest = {
id: 'unique-id-123',
name: 'My Tool',
slug: 'my-tool',
description: 'A description of my tool that is at least 10 characters.',
source_url: 'https://example.com',
category: ['productivity', 'developer-tools'],
tags: ['open-source', 'free'],
status: 'pending',
};
Filtering items
import type { ItemListOptions } from '@/lib/types/item';
const options: ItemListOptions = {
status: 'approved',
categories: ['productivity'],
tags: ['open-source'],
page: 1,
limit: 20,
sortBy: 'updated_at',
sortOrder: 'desc',
includeRemote: true,
};
Rendering status badges
import { ITEM_STATUS_LABELS, ITEM_STATUS_COLORS } from '@/lib/types/item';
import type { ItemStatus } from '@/lib/types/item';
function getStatusBadge(status: ItemStatus) {
return {
label: ITEM_STATUS_LABELS[status],
color: ITEM_STATUS_COLORS[status],
};
}
// getStatusBadge('pending')
// => { label: 'Pending Review', color: 'yellow' }
Related Types
ItemLocationDatareferencesMapProviderfrom the location moduleClientSubmissionDatainclient-item.tsextendsItemDatawith engagement metricsCategoryDatadefines the category values referenced inItemData.categoryTagDatadefines the tag values referenced inItemData.tags