مدل محتوای اجتماعی

یک مدل برای هر موجودیت (پست، نظر، حساب) و مبدل‌هایی که داده‌های API را یک بار به آن تبدیل می‌کنند

معرفی

همهٔ محصولات پرتو با سه موجودیت کار می‌کنند: پست، نظر و حساب. تا امروز هر محصول شکل دادهٔ API خودش را مستقیم به کامپوننت‌ها می‌داد؛ نتیجه این بود که مقدار نامعلوم با صفر پر می‌شد و «0 بازدید» روی پست عکس نمایش داده می‌شد، و نرخ تعامل در یک جا کسر بود و در جای دیگر درصد.

مدل محتوای اجتماعی داده را در یک نقطه یکسان می‌کند و برای هر موجودیت یک کامپوننت دارد که همین مدل را می‌گیرد: Post، Comment و Account، و برای فهرست همهٔ آن‌ها EntityCollection. جدول «از چه چیزی استفاده کنید» در پایین همین بخش راه درست را نشان می‌دهد.

  • SocialPost، SocialComment و SocialAccount انواع نمایشی سیستم طراحی‌اند، نه شکل API. اجزای @partodata/ui/social هیچ فیلد API را نمی‌خوانند و فقط همین مدل را می‌گیرند.
  • هر محصول دادهٔ خودش را یک بار در یک مبدل به این مدل تبدیل می‌کند. مبدل‌های آماده در @partodata/ui/social/adapters هستند: برای PostData، برای ردیف خام API جست‌وجوی محتوا و برای نظرهای کشوی جزئیات.
  • همین مدل خبر و مقالهٔ وب، بخش رونوشت تلویزیون و رادیو و فایل بارگذاری‌شده را هم نمایش می‌دهد؛ این‌ها پست اجتماعی نیستند ولی در همان فهرست‌ها کنار پست‌ها می‌آیند.

از چه چیزی استفاده کنید

کارکامپوننت (@partodata/ui/social)داده
فهرست پست‌ها (نتایج جست‌وجو، خبرخوان)EntityCollection entity="post" با Post (پیش‌فرض card؛ row و tile انتخابی) در ستون فیدSocialPost[] (با fromPostData یا مبدل محصول)
جزئیات پست همراه با نظرها (صفحه یا پنل)Post layout="details" و زیر آن EntityCollection entity="comment" از Comment (thread)SocialPost و SocialComment[]
پستی که یک صفحهٔ تحلیل دربارهٔ آن استPost layout="summary"SocialPost
نظرها (بحث، شبکهٔ تحلیل نظرها)Comment (thread، card، row)، فهرستشان با EntityCollection entity="comment"SocialComment (با fromPostComment)
حساب (ردیف منشن، کارت، سربرگ صفحهٔ حساب)Account (row، card، header)SocialAccount
یک جزء تنها: منبع، شناسه، شاخص‌ها، رسانه، زمان، متناجزای پایه (PlatformMark، Handle، MetricGroup، …)بخشی از SocialPost

کارت یا ردیف پست را خودتان از اجزای پایه نسازید: Post همان اجزا را با قاعده‌های چیدمان (رسانهٔ بدون برش، طول خط خوانا، ارتفاع ثابت ردیف، اقدامات قابل‌دسترس با لمس و کیبورد) کنار هم می‌گذارد. داده را یک بار تبدیل کنید، در لایهٔ دادهٔ محصول:

'use client'

import type { PostData } from '@partodata/ui'
import { EntityCollection, Post, type SocialPost } from '@partodata/ui/social'
import { fromPostData } from '@partodata/ui/social/adapters'
import { useMemo } from 'react'

interface SearchResultsProps {
  rows: PostData[]
  loading: boolean
  onOpen: (post: SocialPost) => void
}

export function SearchResults({ rows, loading, onOpen }: SearchResultsProps) {
  const posts = useMemo(() => rows.map((row) => fromPostData(row)), [rows])
  return (
    <EntityCollection
      entity="post"
      items={posts}
      getId={(post) => post.id}
      loading={loading}
      label="نتایج جست‌وجو"
      renderItem={(post, item) => <Post post={post} {...item} onOpen={onOpen} />}
    />
  )
}

کامپوننت‌های اجتماعی نسخهٔ 3 (PostList، PostCard، CommentCard، ProfileCard، PageCard و PostDetailsDrawer) و پیش‌تنظیم‌هایشان (@partodata/ui/social/presets) در 5.0 حذف شدند؛ کد آن‌ها به همین کامپوننت‌ها می‌رود.

سه قاعده

مقدار نامعلوم صفر نیست

هر شمارنده از نوع Count است، یعنی number | null. سه حالت از هم جدا هستند:

مقدار در مدلمعنانمایش
عدد (از جمله 0)مقدار جمع‌آوری‌شده؛ صفر هم مقدار واقعی استعدد
nullاین شاخص برای این مورد وجود دارد ولی مقدارش را نمی‌دانیم«—»
کلید حذف‌شده (undefined)این شاخص برای این مورد معنا ندارد (بازدید رادیو، پسندِ کانال تلگرام)هیچ‌چیز

هرگز مقدار نامعلوم را با 0 پر نکنید. اگر API شما برای مقدارِ جمع‌آوری‌نشده صفر می‌فرستد، مبدل باید آن را به null تبدیل کند (toCount(value, { zeroMeansUnknown: true })). آمار حساب هم همین‌طور است: وب‌سایت خبری دنبال‌کننده ندارد، پس کلید followers آن حذف می‌شود، نه null.

نسبت‌ها کسرند

Ratio همیشه کسر است، هرگز درصد: 0.034 یعنی 3.4 درصد و 1 یعنی 100 درصد. واحد ورودی در مبدل اعلام می‌شود، نه حدس زده: toRatio(6.8, { unit: 'percent' }). امتیازها (اطمینان، سمی بودن) بین 0 و 1 می‌مانند و سقفشان را اعلام می‌کنند (toRatio(value, { max: 1 }))؛ مقدار بالاتر نشانهٔ واحد اشتباه است، نامعلوم (null) می‌شود و در محیط توسعه هشدار می‌دهد. نرخ‌ها سقف ندارند: نرخ تعامل پست پربازدیدِ یک حساب کوچک می‌تواند 1.8 (180 درصد) باشد.

وضعیت‌ها داده‌اند

پست حذف‌شده در منبع، حساب خصوصی، موردی که در حال پردازش است یا در حال بارگذاری، همان موجودیت با یک state است: 'ready' | 'loading' | 'processing' | 'failed' | 'unavailable' | 'private' | 'deleted'. برای هیچ‌کدام کامپوننت جدا نسازید و پرچم جدا هم نگذارید: حساب خصوصی state: 'private' است.

نمونه بصری

یک پست اینستاگرام، یک خبر وب و یک بخش رونوشت تلویزیون، هر سه از همان نوع SocialPost:

فروشگاه نمونه
@sample_shop
جشنوارهٔ تخفیف فصلی از امروز شروع شد و تا پایان هفته ادامه دارد. برای دیدن فهرست محصولات و شرایط ارسال به صفحهٔ فروشگاه سر بزنید. #تخفیف #پاییز
  • لایک12,400
  • نظر0
  • بازدیدنامعلوم
  • نرخ تعامل3.4٪
news.example.com

رونمایی محصول جدید در نمایشگاه با استقبال مشتری‌ها همراه شد

سارا محمدی
بازدیدکننده‌ها دربارهٔ بسته‌بندی، قیمت و پشتیبانی پس از فروش نظر دادند و بیشترین گفت‌وگو به همکاری برند با اینفلوئنسرها مربوط بود.
اقتصادی
شبکهٔ نمونه
گزارش اقتصادی2:05–2:50
… در ادامهٔ برنامه دربارهٔ کمپین تخفیف فصلی و بازخورد بسته‌بندی گفت‌وگو شد و کارشناس برنامه گفت که …
رسانه منقضی شده است0:45
گفتاراطمینان 86٪گوینده: کارشناس برنامه

هر سه همان Post در چیدمان پیش‌فرض کارت است؛ تفاوت‌ها (تیتر و نویسندهٔ خبر، برنامه و زمان پخش، شاخص‌های اجتماعی) فقط از رکورد می‌آید.

پیاده‌سازی

مبدل‌ها

مبدل‌ها در مسیر جداگانهٔ @partodata/ui/social/adapters هستند. این ماژول نه React دارد و نه 'use client'، پس در کامپوننت سرور، route handler و worker هم قابل استفاده است.

کدام مبدل

داده‌ای که داریدمبدل
هر چیزی از نوع PostDatafromPostData
ردیف خام API جست‌وجوی محتوا (همان 20 فیلد، بدون افزونه)fromSearchContent
نظرهای کشوی جزئیات (PostComment)fromPostComment
برچسب‌های نظر (احتمال 0 تا 100)fromCommentTag
حساب پشت یک پست (ردیف خام یا PostData؛ یک مبدل برای هر دو)accountFromPost
API خود محصولمبدل خودتان، روی toCount، toRatio، toTimestamp

fromSearchContent نوع PostData را نمی‌پذیرد (خطای نوع می‌دهد) و اگر PostData بدون نوع به آن برسد، در محیط توسعه هشدار می‌دهد؛ چون افزونه‌های پرتو (محتوا، پرچم حذف، شاخص‌های افزونه، خروجی تحلیل) را دور می‌ریزد. برای ردیف ساده هر دو مبدل یک نتیجه می‌دهند.

مسیر import

چه چیزیاز کجا
کامپوننت‌ها (SocialText، MetricGroup، MediaFrame، PlatformMark، …)@partodata/ui/social
همهٔ تابع‌ها: مبدل‌ها، نرمال‌کننده‌ها، توابع مدل (metricPresence، toSocialSource، SOURCE_KEYS) و نام‌ها (metricLabel، sourceLabel)@partodata/ui/social/adapters
انواع مدل (SocialPost، SocialMedia، …)هر دو مسیر (همان انواع‌اند)؛ از همان مسیری بگیرید که کامپوننت یا تابع را می‌گیرید

@partodata/ui/social نشانهٔ 'use client' دارد و برای همین فقط کامپوننت و نوع صادر می‌کند و هیچ تابعی ندارد؛ کامپوننت سرور نمی‌تواند تابعی را از چنین مسیری فراخوانی کند. همهٔ تابع‌ها، از جمله نام شاخص (metricLabel) و نام منبع (sourceLabel) برای سرستون جدول یا فیلتر، در @partodata/ui/social/adapters هستند که در کامپوننت سرور و کلاینت هر دو کار می‌کند. قالب‌بندی عدد و زمان کار خود اجزاست: عدد را با MetricGroup و زمان را با RelativeTime نمایش دهید.

fromSearchContent

یک ردیف خام API جست‌وجوی محتوا را به SocialPost تبدیل می‌کند:

فیلد APIدر مدلقاعده
platformsource1 اینستاگرام، 2 فیسبوک، 3 وب‌سایت، 4 تلگرام؛ کد دیگر { key: 'unknown', code }
ididرشته می‌شود؛ اگر نباشد یا null یا خالی باشد، شناسهٔ پایدار از منبع، دامنه، نشانی و زمان
domainactor.handle@ (و @ تمام‌عرض) و نشانه‌های جهت حذف می‌شوند؛ از آن نامی ساخته نمی‌شود
dateCreatedpublishedAtثانیه به میلی‌ثانیه تبدیل می‌شود؛ 0 یعنی زمانی وجود ندارد
hashtagshashtags# و نشانه‌های جهت حذف می‌شوند و هر هشتگ یک بار می‌آید
thumbnailUrlmediasrc تصویر یا poster ویدئو؛ API ابعاد نمی‌فرستد، پس width/height فقط از گزینهٔ mediaSize
likeCount، commentCountlikes، commentsصفر، صفر واقعی است؛ در منبعی که این شمارنده را ندارد (تلگرام) حذف می‌شود
viewCount، videoPlayCountviews، playsصفر یعنی نامعلوم؛ پخش فقط برای ویدئو؛ بازدید اینستاگرام فقط برای ویدئو
engagementRateengagementکسر (واحد درصد را در گزینه‌ها اعلام کنید)؛ صفر یعنی نامعلوم؛ ممکن است از 1 بیشتر شود
followerCount، followingCount، domainRankactor.metricsصفر یعنی نامعلوم؛ فقط شمارنده‌هایی که منبع دارد (وب‌سایت فقط رتبه، کانال تلگرام بدون دنبال‌شده)
ردیف وب‌سایتkind: 'article'title، summary ← excerpt، body ← text؛ بدون شمارندهٔ اجتماعی

گزینه‌ها: engagementRateUnit ('fraction' یا 'percent')، zeroMeansUnknown (پیش‌فرض true؛ فقط برای تولیدکننده‌ای خاموشش کنید که همهٔ شمارنده‌ها را تضمین می‌کند)، missingMedia ('unavailable' یا 'pending'، برای پست اینستاگرامی که تصویرش هنوز نرسیده است) و mediaSize (ابعاد رسانهٔ ردیف؛ پایین‌تر).

ابعاد رسانه در ردیف API

ردیف API جست‌وجوی محتوا فقط thumbnailUrl دارد و عرض و ارتفاع ندارد. بدون ابعاد، MediaFrame کادر جایگزین مربع می‌گیرد: در کارتِ ستون خبرخوان قابی به عرض ستون و ارتفاع 500 پیکسل که رسانه کامل در آن است (تصویر افقی بالا و پایین نوار محو می‌گیرد) و در جزئیات یک مربع. چیزی بریده یا جابه‌جا نمی‌شود، ولی تصویر عرض کارت را پر نمی‌کند. برای کادر درست، ابعاد را با mediaSize بدهید؛ این تابع برای هر ردیفی که thumbnailUrl دارد یک بار فراخوانی می‌شود و فقط نسبت عرض به ارتفاع مهم است:

import { fromSearchContent, type MediaSize, type SearchContentPost } from '@partodata/ui/social/adapters'

// Sizes your media proxy reports for each thumbnail URL (or the API's fields, once it sends them).
declare const thumbnailSizes: Map<string, MediaSize>

export function toSocialPost(row: SearchContentPost) {
  return fromSearchContent(row, { mediaSize: (r) => thumbnailSizes.get(r.thumbnailUrl) })
}

اگر ابعادی ندارید چیزی برنگردانید (undefined)؛ عدد صفر یا منفی هم نادیده گرفته می‌شود و در محیط توسعه یک هشدار می‌دهد. همین گزینه در fromPostData برای ردیفی که content ندارد کار می‌کند؛ رسانه‌های content ابعادشان را از aspectRatio هر مورد می‌گیرند. درخواست به تیم API: ابعاد تصویر بندانگشتی (thumbnailWidth و thumbnailHeight) در ردیف فرستاده شود تا این گام برای همهٔ محصولات یکی شود.

fromPostData

PostData فعلی سیستم طراحی (همان ردیف API به‌علاوهٔ افزونه‌های پرتو) را با همان قاعده‌های fromSearchContent به مدل تبدیل می‌کند و افزونه‌ها را هم نگه می‌دارد: content (متن، رسانه با نسبت و وضعیت، مقاله، کلیپ پخش با رونوشت کامل، استوری)، platformMeta (نمایش تلویزیون، رادیو، مطبوعات، وب و استوری)، channel/program/reporterName، verified/authorKind/postCount، شاخص‌های افزونه (صفرِ صریح حفظ می‌شود)، خروجی تحلیل، برچسب‌ها، پرچم‌ها (محتوای حساس؛ حذف در منبع ← state: 'deleted')، پست نقل‌شده، پست والد و بازنشر.

نام رسانه از channel می‌آید. وب‌سایتی که channel ندارد نامی نمی‌گیرد و دامنه‌اش شناسهٔ آن است، تا دامنه دو بار نمایش داده نشود. ایستگاه تلویزیون و رادیو شناسه ندارد؛ اگر channel نباشد، domain نام آن می‌شود.

fromPostComment

نظری را که کشوی جزئیات می‌گیرد (PostComment در details.comments) به SocialComment تبدیل می‌کند:

فیلد PostCommentدر مدلقاعده
authorauthor@ حذف می‌شود؛ نامی که با شناسه یکی است تکرار نمی‌شود؛ بدون آن ناشناس
timestamppublishedAtثانیه به میلی‌ثانیه؛ هرگز 1970
likes، replyCountmetrics.likes، metrics.repliesنبودن یعنی معنا ندارد؛ عدد (از جمله صفر) خودش
sentiment، toxicityScore (0 تا 1)signals.sentiment، signals.toxicityامتیاز بالاتر از 1 نامعلوم می‌شود
pinned، edited، authorReply، hiddenByModeratorflags (hidden برای پنهان‌شده)
language، translatedText، replieslang، translation، repliesپاسخ‌ها به همین شکل تبدیل می‌شوند

fromCommentTag احتمال برچسب نظر (0 تا 100) را به confidence مدل (0 تا 1) تبدیل می‌کند.

نرمال‌کننده‌ها برای مبدل محصول

مبدلِ دادهٔ خود محصول را روی همین توابع بنویسید تا تصمیم واحد و مقدار نامعلوم در همه‌جا یکسان باشد:

تابعکار
toCount(value, { zeroMeansUnknown })عدد نامنفی یا رشتهٔ فقط‌رقمی (لاتین، فارسی یا عربی) را به عدد صحیح گرد می‌کند و هر چیز دیگر را null می‌کند
toRatio(value, { unit, max, field })کسر یا null؛ واحد اعلام می‌شود، حدس زده نمی‌شود؛ max برای امتیازهای سقف‌دار؛ field نام فیلد API در هشدار محیط توسعه (وقتی واحد را خود مبدل ثابت کرده است)
toTimestamp(value)ثانیه را به میلی‌ثانیه تبدیل می‌کند؛ 0، عدد کوچک (مثل سال 2026) و مقدار نامعتبر یعنی بدون زمان
searchContentSource(code)کد پلتفرم API به SocialSource

شکل قدیمی پست

شکل تودرتوی { source, author, timestamp, body, metrics } در نسخهٔ 3.0.2 حذف شد. کدی که هنوز آن را می‌سازد قبلاً با پیام نامفهوم post.hashtags is not iterable از کار می‌افتاد. حالا مبدل‌ها خطای LegacyPostShapeError می‌دهند که کلیدهای قدیمی را در legacyKeys نام می‌برد و راه اصلاح را می‌گوید.

انواع

SocialPost

فیلدتوضیح
idشناسهٔ پایدار (کلید React، انتخاب، وضعیت خوانده‌شده)
sourceمنبع: { key, label?, code? }؛ کد ناشناختهٔ API داده است و با key: 'unknown' می‌ماند
kindنوع مورد: text، photo، video، carousel، reel، story، article، transcript، file
actorحساب، سایت، رسانه، شبکه یا ایستگاهی که منتشر کرده (name، handle بدون @، avatarUrl، …)
publishedAtزمان انتشار؛ برای بخش رونوشت، زمان پخش
urlنشانی مورد در منبع؛ همیشه یک اقدام جدا («مشاهده در منبع»)، نه کلیک اصلی
title، text، excerptعنوان، متن کامل، و لید خبر یا پنجرهٔ رونوشت
highlightsعبارت‌هایی که در متن علامت می‌خورند (نتیجهٔ جست‌وجو، کلیدواژهٔ رونوشت)
mediaفهرست رسانه‌ها با ابعاد و وضعیت (پایین‌تر)
metricsشاخص‌های پست؛ هر کلید Count است و engagement یک Ratio
broadcastویژگی‌های پخش: program، segment، textSource (گفتار یا متن روی تصویر)، speaker، confidence
byline، category، hashtags، labels، signalsنویسنده، بخش، هشتگ‌ها، برچسب‌ها با اطمینان، خروجی تحلیل
flagssensitive (true یا دلیل: nsfw، graphic، spoiler)، ad، partnership، pinned، edited، archiveUrl
quoted، replyTo، repostپست نقل‌شده، پستی که به آن پاسخ داده شده، و بازنشر
stateوضعیت مورد

آمار حساب (دنبال‌کننده، دنبال‌شده، تعداد پست، رتبه) مال حساب است، نه مال هر پست؛ اگر همراه داده بیاید در actor.metrics قرار می‌گیرد و جای نمایشش کارت یا ردیف حساب است.

signals خروجی تحلیل است و فقط برای موردی پر می‌شود که واقعاً تحلیل شده است (برای پست: پستی که در یک خوشه قرار گرفته). برای پست خامِ جمع‌آوری‌شده آن را خالی بگذارید؛ پر کردنش یعنی ساختن تحلیلی که انجام نشده است.

SocialMedia

فیلدتوضیح
kindimage، video یا audio
srcفایل رسانه
posterپیش‌نمایش: پوستر ویدئو، جلد صوت یا نسخهٔ کوچک تصویر (ردیف و کاشی همین را بارگذاری می‌کنند)
width، heightابعاد واقعی به پیکسل؛ قاب رسانه از روی همین‌ها ساخته می‌شود و صفحه بعد از بارگذاری جابه‌جا نمی‌شود؛ بدون آن‌ها قاب مربع است (ردیف API ابعاد ندارد: mediaSize)
durationSecطول ویدئو یا صوت
statusready، pending (هنوز نرسیده)، failed، expired (منقضی شده)، unavailable (ذخیره نشده)
sensitiveرسانهٔ حساس تا وقتی کاربر نخواهد محو می‌ماند؛ پستی که flags.sensitive دارد همهٔ رسانه‌هایش را همین‌طور نمایش می‌دهد

SocialComment و SocialAccount

نظر: author (بدون آن ناشناس است)، text، lang، translation، publishedAt، metrics (likes، replies)، labels با اطمینان 0 تا 1، signals (sentiment، toxicity، authorGender)، flags (pinned، edited، authorReply، hidden) و replies.

حساب: همهٔ فیلدهای actor به‌علاوهٔ id، source، bio، category، metrics (followers، following، posts، engagement، rank)، flags (business) و state. حساب خصوصی state: 'private' است. نشان تأییدشده فقط وقتی verified: true باشد نمایش داده می‌شود؛ هرگز آن را پیش‌فرض true نگذارید.

الگوهای رایج

سه مورد غیراجتماعی که محصولات پایش کنار پست‌ها نمایش می‌دهند، با همین مدل ساخته می‌شوند.

خبر و مقالهٔ وب

import type { SocialPost } from '@partodata/ui/social/adapters'

export const article: SocialPost = {
  id: 'news-42',
  source: { key: 'web' },
  kind: 'article',
  actor: { handle: 'news.example.com', kind: 'organization' },
  publishedAt: '2026-09-20T08:30:00Z',
  title: 'رونمایی محصول جدید در نمایشگاه',
  excerpt: 'محصول جدید امروز در نمایشگاه معرفی شد.',
  byline: 'سارا محمدی',
  category: 'اقتصادی',
  url: 'https://news.example.com/a/42',
}

مقاله شاخص تعامل اجتماعی ندارد، پس metrics را نمی‌نویسید (نه صفر، نه null). برای نشریهٔ چاپی از source.key: 'press' استفاده کنید.

بخش رونوشت تلویزیون و رادیو

import type { SocialPost } from '@partodata/ui/social/adapters'

export const segment: SocialPost = {
  id: 'passage:7f3a',
  source: { key: 'tv' },
  kind: 'transcript',
  actor: { name: 'شبکهٔ خبر نمونه', kind: 'organization' },
  publishedAt: '2026-09-20T18:05:00Z',
  broadcast: { program: 'گفت‌وگوی اقتصادی', segment: { startSec: 318, endSec: 342 }, textSource: 'speech' },
  excerpt: 'در ادامهٔ برنامه دربارهٔ رونمایی محصول جدید صحبت شد.',
  highlights: ['رونمایی محصول'],
  lang: 'fa',
  media: [{ kind: 'video', status: 'expired', durationSec: 24 }],
}

شبکه یا ایستگاه actor است و زمان پخش publishedAt. کلیپی که از بازهٔ نگه‌داری خارج شده status: 'expired' دارد و فقط رونوشت باقی می‌ماند.

فایل بارگذاری‌شده

import type { SocialPost } from '@partodata/ui/social/adapters'

export const uploaded: SocialPost = {
  id: 'upload-3',
  source: { key: 'file', label: 'فایل اکسل' },
  kind: 'file',
  title: 'نظرات-کمپین-تخفیف.xlsx',
}

بهترین روش‌ها و دام‌های رایج

بکنید

  • هر چیزی از نوع PostData را با fromPostData تبدیل کنید و fromSearchContent را فقط برای ردیف خام API نگه دارید.
  • برای API خودتان یک مبدل بنویسید و آن را روی toCount، toRatio و toTimestamp بسازید.
  • width و height رسانه را هر جا معلوم است در مبدل پر کنید تا قاب رسانه از ابتدا درست باشد؛ برای ردیف API جست‌وجوی محتوا، که ابعاد ندارد، با گزینهٔ mediaSize.
  • خبر، رونوشت و فایل را با همان SocialPost و kind درست بسازید، نه با نوع جدا.

نکنید

  • مقدار نامعلوم را با 0 پر نکنید؛ null بگذارید، یا اگر شاخص برای این مورد معنا ندارد کلیدش را ننویسید.
  • نسبت را درصد ذخیره نکنید و در کامپوننت در 100 ضرب یا بر 100 تقسیم نکنید؛ تبدیل واحد فقط در مبدل است.
  • شکل API را مستقیم به اجزای @partodata/ui/social ندهید و نام نمایشی را از روی شناسه نسازید.
  • کارت یا ردیف پست را خودتان از اجزای پایه نسازید؛ Post، Comment و Account را به کار ببرید.
  • آمار حساب را جزو شاخص‌های هر پست نیاورید.
  • برای پست حذف‌شده، خصوصی یا در حال پردازش کامپوننت یا پرچم جدا نسازید؛ state را تنظیم کنید.

صفحات مرتبط

  • Post، Comment و Account — یک کامپوننت برای هر موجودیت.
  • EntityCollection — فهرست و شبکهٔ آن‌ها، با اسکلت، حالت‌ها، انتخاب و کیبورد.
  • PlatformMark — نشان منبع برای هر SocialSource، از جمله وب، تلویزیون، رادیو و منبع ناشناخته.
  • چیدمان صفحه — فهرست پست‌ها در ستون خبرخوان صفحه قرار می‌گیرد، نه در تمام عرض آن.