story-research-zapwall/lib/articleFiltering.ts
Nicolas Cantu 90ff8282f1 feat: Implémentation système de commissions systématique et incontournable
- Création lib/platformCommissions.ts : configuration centralisée des commissions
  - Articles : 800 sats (700 auteur, 100 plateforme)
  - Avis : 70 sats (49 lecteur, 21 plateforme)
  - Sponsoring : 0.046 BTC (0.042 auteur, 0.004 plateforme)

- Validation des montants à chaque étape :
  - Publication : vérification du montant avant publication
  - Paiement : vérification du montant avant acceptation
  - Erreurs explicites si montant incorrect

- Tracking des commissions sur Nostr :
  - Tags author_amount et platform_commission dans événements
  - Interface ContentDeliveryTracking étendue
  - Traçabilité complète pour audit

- Logs structurés avec informations de commission
- Documentation complète du système

Les commissions sont maintenant systématiques, validées et traçables.
2025-12-27 21:11:09 +01:00

119 lines
3.5 KiB
TypeScript

import type { Article } from '@/types/nostr'
import type { ArticleFilters, SortOption } from '@/components/ArticleFilters'
/**
* Filter articles based on search query
*/
export function filterArticlesBySearch(articles: Article[], searchQuery: string): Article[] {
if (!searchQuery.trim()) {
return articles
}
const query = searchQuery.toLowerCase().trim()
return articles.filter((article) => {
const titleMatch = article.title.toLowerCase().includes(query)
const previewMatch = article.preview.toLowerCase().includes(query)
const contentMatch = article.content.toLowerCase().includes(query)
return titleMatch || previewMatch || contentMatch
})
}
/**
* Filter articles based on filters (author, category)
*/
export function filterArticles(articles: Article[], filters: ArticleFilters): Article[] {
let filtered = articles
// Exclude presentation articles from standard article lists
filtered = filtered.filter((article) => !article.isPresentation)
// Only show articles with valid categories (science-fiction or scientific-research)
filtered = filtered.filter((article) => {
return article.category === 'science-fiction' || article.category === 'scientific-research'
})
// Filter by category
if (filters.category && filters.category !== 'all') {
filtered = filtered.filter((article) => article.category === filters.category)
}
// Filter by author
if (filters.authorPubkey) {
filtered = filtered.filter((article) => article.pubkey === filters.authorPubkey)
}
return filtered
}
/**
* Get author sponsoring from their presentation article
* We need to look up the sponsoring from presentation articles
* For now, we'll use a cache or extract from already loaded articles
*/
function getAuthorSponsoringFromCache(
pubkey: string,
presentationArticles: Map<string, Article>
): number {
const presentation = presentationArticles.get(pubkey)
return presentation?.isPresentation ? presentation.totalSponsoring ?? 0 : 0
}
/**
* Sort articles based on sort option
* Default sort: by sponsoring (descending) then by date (newest first)
*/
export function sortArticles(
articles: Article[],
sortBy: SortOption,
presentationArticles?: Map<string, Article>
): Article[] {
const sorted = [...articles]
const presentationMap = presentationArticles ?? new Map<string, Article>()
switch (sortBy) {
case 'oldest':
return sorted.sort((a, b) => a.createdAt - b.createdAt)
case 'newest':
default:
// Default: sort by sponsoring (descending) then by date (newest first)
return sorted.sort((a, b) => {
const sponsoringA = getAuthorSponsoringFromCache(a.pubkey, presentationMap)
const sponsoringB = getAuthorSponsoringFromCache(b.pubkey, presentationMap)
// First sort by sponsoring (descending)
if (sponsoringA !== sponsoringB) {
return sponsoringB - sponsoringA
}
// Then sort by date (newest first)
return b.createdAt - a.createdAt
})
}
}
/**
* Apply all filters and sorting to articles
*/
export function applyFiltersAndSort(
articles: Article[],
searchQuery: string,
filters: ArticleFilters,
presentationArticles?: Map<string, Article>
): Article[] {
let result = articles
// First apply search filter
result = filterArticlesBySearch(result, searchQuery)
// Then apply other filters
result = filterArticles(result, filters)
// Finally apply sorting (with presentation articles for sponsoring lookup)
result = sortArticles(result, filters.sortBy, presentationArticles)
return result
}