All input validation runs server-side in apps/backend/validators/ before any database or manager call. Errors are thrown as UserInputError with translated messages via the translation service.
User fields
| Field | Rule |
|---|
username | 3–50 chars, regex /^[a-zA-Z0-9_-]+$/ |
email | Standard email regex, max 255 chars |
password | 8–128 chars, must contain uppercase, lowercase, digit, and one of @$!%*?& |
bio | Optional, max 100 chars |
dateOfBirth | Min age 13, max age 120 |
gender | male / female / other / prefer_not_to_say |
accountType | personal / creator / business |
phone | 7–15 digits (E.164 format, strips spaces/dashes/parentheses) |
countryCode | + followed by 1–3 digits |
otp | 4–6 digits |
Post fields
| Field | Rule |
|---|
text | Max 5,000 chars; required unless media is present |
visibility | public (default) / followers / private / subscribers |
limit (pagination) | 1–100, default 20 |
offset (pagination) | ≥ 0, default 0 |
| Field | Rule |
|---|
text | Max 2,000 chars |
limit | 1–100, default 20 |
Message fields
| Field | Rule |
|---|
messageText | Max 10,000 chars |
messageType | text (default) / image / video / audio / file / voice / gif / sticker / location / poll / coin_transfer |
coinPrice | ≥ 0; only allowed on image or video messages |
limit | 1–100, default 50 |
before (cursor) | Timestamp-based cursor for keyset pagination |
Hashtag fields
| Field | Rule |
|---|
name | Max 100 chars, alphanumeric + underscores only, lowercased, leading # stripped |
Live stream fields
| Field | Rule |
|---|
title | 3–255 chars |
description | Optional, max 5,000 chars |
visibility | public (default) / private / followers_only / close_friends |
scheduledStartTime | Must be a future date |
commentText | Max 500 chars |
interactionType | like / love / wow / haha / sad / angry |
status (update) | scheduled / live / ended / cancelled |
Coin package fields
| Field | Rule |
|---|
name | 3–100 chars |
coinAmount | Integer, 1–1,000,000 |
bonusCoins | Integer, ≥ 0, max 1,000,000 |
price | Float, > 0, max $10,000, max 2 decimal places |
currency | USD / EUR / GBP / JPY / MXN (defaults to USD) |
Subscription tier fields
| Field | Rule |
|---|
name | 1–100 chars |
description | Optional, max 500 chars |
coinPrice | Integer, 0–1,000,000; null = free tier |
benefits | Array of strings |
Content report fields
| Field | Allowed values |
|---|
contentType | post / comment / message / user |
reason | spam / nudity / hate_speech / violence / harassment / false_information / scam / intellectual_property / self_harm / terrorism / other |
details | Optional, max 1,000 chars |
status (lifecycle) | pending → reviewing → resolved / dismissed |
Validation errors are returned as GraphQL UserInputError with a message string. All messages are internationalized via the translation service and respect the user's locale in the GraphQL context.