Skip to main content

Posts Management API

Author: Josh, Lead Backend Team
Last Updated: 2025-12-11
Version: v1.0

Base URL: https://api.nexgate.com/api/v1

Short Description: The Posts Management API provides comprehensive social media posting functionality including creating posts, polls, quote posts, drafts management, media attachments, commerce integrations, collaboration features, and engagement interactions (likes, bookmarks, reposts, comments). This API enables users to create rich content with privacy controls and scheduled publishing.

Hints:

  • All endpoints require authentication via Bearer token unless specified
  • Draft posts follow a "one draft at a time" rule - publish or discard before creating new
  • Posts support text content, media (images/videos), polls, and commerce attachments
  • Privacy settings control visibility, comment permissions, and repost permissions
  • Collaborative posts require accepted invitations from collaborators
  • Pagination is 1-indexed (page=1 for first page), default size is 20 items
  • Poll votes can be changed if poll allows it (allowVoteChange setting)

Standard Response Format

All API responses follow a consistent structure using our Globe Response Builder pattern:

Success Response Structure

{
  "success": true,
  "httpStatus": "OK",
  "message": "Operation completed successfully",
  "action_time": "2025-09-23T10:30:45",
  "data": {
    // Actual response data goes here
  }
}

Error Response Structure

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Error description",
  "action_time": "2025-09-23T10:30:45",
  "data": "Error description"
}

Standard Response Fields

Field Type Description
success boolean Always true for successful operations, false for errors
httpStatus string HTTP status name (OK, BAD_REQUEST, NOT_FOUND, etc.)
message string Human-readable message describing the operation result
action_time string ISO 8601 timestamp of when the response was generated
data object/string Response payload for success, error details for failures

HTTP Method Badge Standards

For better visual clarity, all endpoints use colored badges for HTTP methods with the following standard colors:

  • GET - GET - Green (Safe, read-only operations)
  • POST - POST - Blue (Create new resources)
  • PUT - PUT - Yellow (Update/replace entire resource)
  • DELETE - DELETE - Red (Remove resources)

Common Response Structure for POST/PUT Operations

Most POST and PUT operations return a PostResponse object. For brevity, this documentation references the detailed PostResponse structure defined below instead of repeating it for each endpoint.

Standard Success Response for Post Creation/Update:

{
  "success": true,
  "httpStatus": "OK",
  "message": "[Operation-specific message]",
  "action_time": "2025-12-11T10:30:45",
  "data": {
    // PostResponse object - see "PostResponse Structure" section below
  }
}

PostResponse Structure

This is the standard response structure returned by most post-related endpoints:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "author": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "userName": "john_doe",
    "firstName": "John",
    "lastName": "Doe",
    "profilePictureUrl": "https://cdn.nexgate.com/profiles/john_doe.jpg",
    "isVerified": true
  },
  "content": "Check out this amazing product! @jane_doe #shopping",
  "contentParsed": {
    "text": "Check out this amazing product! @jane_doe #shopping",
    "entities": [
      {
        "type": "MENTION",
        "text": "@jane_doe",
        "startIndex": 33,
        "endIndex": 42,
        "user": {
          "id": "987e6543-e21b-12d3-a456-426614174999",
          "userName": "jane_doe",
          "firstName": "Jane",
          "lastName": "Doe",
          "profilePictureUrl": "https://cdn.nexgate.com/profiles/jane_doe.jpg"
        }
      },
      {
        "type": "HASHTAG",
        "text": "#shopping",
        "startIndex": 43,
        "endIndex": 52,
        "hashtag": "shopping"
      }
    ]
  },
  "postType": "REGULAR",
  "status": "PUBLISHED",
  "media": [
    {
      "id": "media-123",
      "mediaType": "IMAGE",
      "originalUrl": "https://cdn.nexgate.com/posts/image1.jpg",
      "thumbnailUrl": "https://cdn.nexgate.com/posts/image1_thumb.jpg",
      "placeholderBase64": "base64-string-here",
      "width": 1920,
      "height": 1080,
      "order": 1,
      "imageTags": []
    }
  ],
  "attachments": {
    "products": [],
    "shops": [],
    "events": [],
    "buyTogetherGroups": [],
    "installmentPlans": [],
    "externalLink": null
  },
  "collaboration": {
    "isCollaborative": false,
    "collaborators": [],
    "byline": null
  },
  "privacySettings": {
    "visibility": "PUBLIC",
    "whoCanComment": "EVERYONE",
    "whoCanRepost": "EVERYONE",
    "hideLikesCount": false,
    "hideCommentsCount": false
  },
  "engagement": {
    "likesCount": 0,
    "commentsCount": 0,
    "repostsCount": 0,
    "quotesCount": 0,
    "bookmarksCount": 0,
    "sharesCount": 0,
    "viewsCount": 0,
    "canLike": true,
    "canComment": true,
    "canRepost": true,
    "canShare": true
  },
  "userInteraction": {
    "hasLiked": false,
    "hasBookmarked": false,
    "hasReposted": false,
    "hasCommented": false,
    "hasViewed": false
  },
  "createdAt": "2025-12-11T10:30:45",
  "publishedAt": "2025-12-11T10:30:45",
  "scheduledAt": null
}

Endpoints

1. Create Post

Purpose: Create a new post (draft or scheduled) with optional content, media, poll, attachments, and collaboration

Endpoint: POST {base_url}/e-social/posts

Access Level: 🔒 Protected (Requires Bearer Token Authentication)

Authentication: Bearer Token

Behavior:

  • Creates a post with status DRAFT (unless scheduledAt is provided, then SCHEDULED)
  • Enforces "one draft at a time" rule - user must publish or discard existing draft first
  • Automatically parses @mentions, $shop tags, and #hashtags from content
  • Validates all attached products, shops, events exist and are active
  • Sends collaboration invitations to specified users via notifications
  • For scheduled posts, validates scheduledAt is at least 5 minutes in the future
  • Media files must already be uploaded to file service before creating post
  • Collaborative posts remain in PENDING status until all invitees accept/reject

Business Rules:

  1. Draft System: Only one draft allowed per user at a time
  2. Content Requirements: Either content text OR media OR poll must be provided (not all optional)
  3. Poll Requirements: If postType is POLL, poll object with 2-10 options is required
  4. Media Limits: Maximum 10 media items per post
  5. Commerce Limits: Max 10 products, 5 shops, 3 events per post
  6. Collaboration Limits: Maximum 5 collaborators per post
  7. Scheduling Rules: Scheduled time must be at least 5 minutes in future, max 6 months ahead
  8. Mention Extraction: System automatically detects and links @username and $shopname mentions
  9. Hashtag Indexing: All #hashtags automatically indexed for search and trending
  10. Privacy Inheritance: MENTIONED visibility requires at least one @mention in content

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication (format: Bearer <token>)
Content-Type string Yes Must be application/json

Request JSON Sample:

{
  "content": "Excited to share my latest project! @john_doe check this out #coding",
  "postType": "REGULAR",
  "media": [
    {
      "mediaType": "IMAGE",
      "mediaUrl": "https://cdn.nexgate.com/uploads/image1.jpg",
      "placeholderBase64": "base64-string",
      "width": 1920,
      "height": 1080
    }
  ],
  "privacySettings": {
    "visibility": "PUBLIC",
    "whoCanComment": "EVERYONE",
    "whoCanRepost": "EVERYONE",
    "hideLikesCount": false,
    "hideCommentsCount": false
  },
  "scheduledAt": null
}

Request Body Parameters:

Parameter Type Required Description Validation
content string No* Post text content Max: 5000 characters. *Required if no media/poll
postType string Yes Type of post enum: REGULAR, POLL
media array No Array of media objects (images/videos) Max: 10 items
media[].mediaType string Yes (if media provided) Type of media enum: IMAGE, VIDEO
media[].mediaUrl string Yes (if media provided) URL of the media file Valid URL format, must be from approved CDN
media[].placeholderBase64 string No BlurHash or base64 placeholder Used for progressive image loading
media[].width integer No Media width in pixels Min: 1, Max: 8000
media[].height integer No Media height in pixels Min: 1, Max: 8000
media[].duration integer No Video duration in seconds Required for videos, Max: 600 (10 minutes)
poll object No Poll configuration Required if postType is POLL
poll.title string Yes (if poll provided) Poll question/title Min: 5, Max: 500 characters
poll.description string No Additional poll description Max: 1000 characters
poll.options array Yes (if poll provided) Array of poll options Min: 2, Max: 10
poll.options[].optionText string Yes Text for the poll option Min: 1, Max: 200 characters
poll.options[].optionImageUrl string No Optional image for the option Valid URL format, must be from approved CDN
poll.allowMultipleVotes boolean No Allow selecting multiple options Default: false
poll.isAnonymous boolean No Hide voter identities Default: true. If false, voters visible to post author
poll.allowVoteChange boolean No Allow users to change their vote Default: true. If false, votes are final
poll.expiresAt string No Poll expiration datetime ISO 8601 format, must be future, max 30 days from now
attachments object No Commerce attachments
attachments.productIds array No Array of product UUIDs to attach Max: 10. Products must be ACTIVE status
attachments.shopIds array No Array of shop UUIDs to attach Max: 5. Shops must be VERIFIED
attachments.eventIds array No Array of event UUIDs to attach Max: 3. Events must be PUBLISHED
attachments.buyTogetherGroupIds array No Array of group purchase UUIDs Groups must be ACTIVE, not COMPLETED
attachments.installmentPlanIds array No Array of installment plan UUIDs Plans must be ACTIVE, not EXPIRED
attachments.externalLink object No External link object Only one external link allowed per post
attachments.externalLink.url string Yes (if externalLink provided) URL to attach Valid URL format, supports http/https only
collaboration object No Collaboration settings
collaboration.collaboratorIds array No Array of user UUIDs to invite Max: 5. Users must not be blocked by author
privacySettings object No Privacy configuration
privacySettings.visibility string No Post visibility level enum: PUBLIC, FOLLOWERS, MENTIONED, PRIVATE. Default: PUBLIC
privacySettings.whoCanComment string No Comment permission level enum: EVERYONE, FOLLOWERS, MENTIONED, DISABLED. Default: EVERYONE
privacySettings.whoCanRepost string No Repost permission level enum: EVERYONE, FOLLOWERS, DISABLED. Default: EVERYONE
privacySettings.hideLikesCount boolean No Hide like count from others Default: false. Author always sees true count
privacySettings.hideCommentsCount boolean No Hide comment count from others Default: false. Author always sees true count
scheduledAt string No Schedule post for future publication ISO 8601 format, must be 5+ minutes future, max 6 months ahead

Validation Notes:

  • At least one of: content, media, or poll must be provided
  • If postType is POLL, content is optional but poll object is required
  • Media files must be pre-uploaded to file service and URLs must be from approved CDN domains
  • All UUIDs (products, shops, events, users) are validated for existence and status
  • Mentions (@username, $shopname) and hashtags (#tag) are automatically extracted from content
  • MENTIONED visibility requires at least one @mention in content
  • Scheduled posts cannot be in the past; minimum 5 minutes buffer required
  • Collaborative posts send real-time notifications to all invited users
  • External links are validated for protocol (http/https only) and reachability

Success Response: Returns standard PostResponse structure (see "PostResponse Structure" section above)

Success Response Message: "Post created successfully"

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "You already have a draft post",
  "action_time": "2025-12-11T10:30:45",
  "data": "You already have a draft post. Please update or publish your existing draft before creating a new one."
}

Standard Error Types:

Application-Level Exceptions (400-499)

  • 400 BAD_REQUEST: Already have a draft post, invalid post data, or validation errors
  • 401 UNAUTHORIZED: Authentication issues (empty, invalid, expired, or malformed tokens)
  • 422 UNPROCESSABLE_ENTITY: Validation errors with detailed field information
  • 500 INTERNAL_SERVER_ERROR: Unexpected server errors

Error Response Examples:

Bad Request - Existing Draft (400):

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "You already have a draft post",
  "action_time": "2025-12-11T10:30:45",
  "data": "You already have a draft post. Please update or publish your existing draft before creating a new one."
}

Validation Error - Content Too Long (422):

{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Validation failed",
  "action_time": "2025-12-11T10:30:45",
  "data": {
    "content": "Content exceeds maximum length of 5000 characters"
  }
}

Validation Error - Invalid Poll (422):

{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Validation failed",
  "action_time": "2025-12-11T10:30:45",
  "data": {
    "poll.options": "Poll must have at least 2 options"
  }
}

Validation Error - Empty Post (422):

{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Post must have content, media, or poll",
  "action_time": "2025-12-11T10:30:45",
  "data": "At least one of content, media, or poll must be provided"
}

Validation Error - Invalid Product Attachment (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Product not found",
  "action_time": "2025-12-11T10:30:45",
  "data": "Product with ID 550e8400-e29b-41d4-a716-446655440000 not found or inactive"
}

Validation Error - Scheduled Time in Past (400):

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Invalid scheduled time",
  "action_time": "2025-12-11T10:30:45",
  "data": "Scheduled time must be at least 5 minutes in the future"
}

Validation Error - Blocked Collaborator (403):

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Cannot collaborate with blocked user",
  "action_time": "2025-12-11T10:30:45",
  "data": "User 770e8400-e29b-41d4-a716-446655440001 has blocked you or you have blocked them"
}

Use Case Examples:

Example 1: Simple Text Post

{
  "content": "Just launched my new product! Check it out at nexgate.com/myshop",
  "postType": "REGULAR"
}

Result: Creates a PUBLIC draft post with text only, no attachments.

Example 2: Product Showcase Post

{
  "content": "New arrivals! 🎉 Amazing deals on electronics. $TechWorld #shopping #deals",
  "postType": "REGULAR",
  "media": [
    {
      "mediaType": "IMAGE",
      "mediaUrl": "https://cdn.nexgate.com/uploads/product1.jpg",
      "width": 1920,
      "height": 1080
    }
  ],
  "attachments": {
    "productIds": ["550e8400-e29b-41d4-a716-446655440001", "550e8400-e29b-41d4-a716-446655440002"],
    "shopIds": ["660e8400-e29b-41d4-a716-446655440003"]
  }
}

Result: Creates draft with image, attaches 2 products and 1 shop, extracts $TechWorld mention and #shopping/#deals hashtags.

Example 3: Poll Post

{
  "content": "What feature should we build next? Vote below! 👇",
  "postType": "POLL",
  "poll": {
    "title": "Next Feature Priority",
    "description": "Help us decide what to build for Q1 2026",
    "options": [
      {"optionText": "Dark Mode"},
      {"optionText": "Video Upload"},
      {"optionText": "Live Streaming"},
      {"optionText": "Advanced Analytics"}
    ],
    "allowMultipleVotes": true,
    "isAnonymous": false,
    "allowVoteChange": true,
    "expiresAt": "2025-12-25T23:59:59Z"
  }
}

Result: Creates poll allowing multiple votes, non-anonymous (voters visible), votes can be changed, expires Dec 25.

Example 4: Scheduled Collaborative Event Post

{
  "content": "Excited to announce our tech conference! @john_doe and I are hosting. Join us! 🚀 #TechConf2026",
  "postType": "REGULAR",
  "attachments": {
    "eventIds": ["880e8400-e29b-41d4-a716-446655440004"]
  },
  "collaboration": {
    "collaboratorIds": ["770e8400-e29b-41d4-a716-446655440001"]
  },
  "scheduledAt": "2025-12-20T08:00:00Z"
}

Result: Creates scheduled post for Dec 20, attaches event, sends collaboration invite to john_doe, extracts @john_doe mention and #TechConf2026 hashtag.


2. Publish Draft Post

Purpose: Publish the current user's draft post

Endpoint: POST {base_url}/api/v1/e-social/posts/publish

Access Level: 🔒 Protected (Requires Bearer Token Authentication)

Authentication: Bearer Token

BehaviorRequest Headers:

  • Finds
  • user'scurrent
    HeaderTypeRequiredDescription
    AuthorizationstringYesBearer token for authentication
    Content-TypestringYesMust be application/json

    Content Validation Rules:

    The post must pass content validation before publishing. At minimum, a post must have meaningful content.

    ScenarioAllowed?Notes
    Text only✅ YesValid standalone post
    Text + Media✅ YesValid post with images/videos
    Media only (no text)❌ NoMedia posts must include text content
    Poll only✅ YesPoll title serves as content
    Poll + Text✅ YesEnhanced poll post
    Quote only✅ YesQuoted post provides context
    Quote + Text✅ YesQuote with commentary
    Attachment only (product/shop/event/link)✅ YesCommerce/social attachment
    Attachment + Text✅ YesEnhanced attachment post
    Attachment + Media (no text)❌ NoMedia requires text content
    Attachment + Media + Text✅ YesFull featured post
    Empty post❌ NoMust have at least one content type

    Validation Error Messages:

    (status
  • Changes
  • products/shops/events
  • Triggers
  • feed distribution to all followers
  • No request body required - system automatically finds the user's draft
  • ConditionError Message
    Media without text"Media posts must include text content"
    Empty post"Post must have at least one of: text content, poll, quote, or attachments"
    No draft postfound "No =draft DRAFT)found"
    Pending collaborators"Cannot publish collaborative post status- from DRAFT to PUBLISHED
  • Sets publishedAt timestamp to current time
  • Sends notifications to all mentioned users (@username, $shopname)
  • For collaborative posts, only publishes if all collaborators have accepted
  • Increments engagement counterswaiting for allcollaborator attachedacceptance"
  • Business Rules:

    1. Draft Requirement: User must have exactly one draft post
    2. Content Validation: Draft must pass all content validation rules (see table above)
    3. Media Rule: Posts with media (images/videos) must include text content
    4. Collaboration Status: All invited collaborators must have accepted (status = ACCEPTED)
    5. Content Validation: Draft must pass all content validation rules before publishing
    6. Attachment Validation: All attached products/shops/events must still be active/valid
    7. Scheduled Posts: Cannot publish a scheduled post (status = SCHEDULED) using this endpoint
    8. Feed Distribution: Published posts immediately appear in followers' feeds
    9. Notification Triggers: Sends notifications to @mentioned users and collaborators
    10. Engagement Initialization: All engagement counters (likes, comments, etc.) start at 0

    Validation Checks on Publish:

    • Draft exists and belongs to current user
    • Content validation passes (text, media, poll, quote, or attachments)
    • Media posts have accompanying text content
    • All collaborators have accepted (if collaborative post)
    • All attached products are still ACTIVE
    • All attached shops are still VERIFIED
    • All attached events are still PUBLISHED
    • Content still meets length requirements (max 5000 chars)
    • Media URLs stillare valid and accessible
    • Poll configuration is valid (if poll post)

    RequestSuccess HeadersResponse JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Post published successfully",
      "action_time": "2025-12-29T10:30:45",
      "data": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "author": {
          "id": "660e8400-e29b-41d4-a716-446655440001",
          "userName": "john_doe",
          "firstName": "John",
          "lastName": "Doe",
          "profilePictureUrl": "https://storage.example.com/profiles/john.jpg",
          "isVerified": true
        },
        "content": "Check out this amazing product! 🛍️",
        "postType": "REGULAR",
        "status": "PUBLISHED",
        "media": [
          {
            "id": "media-001",
            "mediaType": "IMAGE",
            "originalUrl": "https://storage.example.com/posts/image1.jpg",
            "thumbnailUrl": "https://storage.example.com/posts/image1_thumb.jpg",
            "width": 1080,
            "height": 1080,
            "order": 0
          }
        ],
        "attachments": {
          "products": [
            {
              "id": "770e8400-e29b-41d4-a716-446655440002",
              "name": "Wireless Headphones",
              "price": 150000.00,
              "imageUrl": "https://storage.example.com/products/headphones.jpg",
              "shopName": "TechStore TZ",
              "inStock": true
            }
          ],
          "shops": [],
          "events": [],
          "buyTogetherGroups": [],
          "installmentPlans": [],
          "externalLink": null
        },
        "privacySettings": {
          "visibility": "PUBLIC",
          "whoCanComment": "EVERYONE",
          "whoCanRepost": "EVERYONE",
          "hideLikesCount": false,
          "hideCommentsCount": false
        },
        "engagement": {
          "likesCount": 0,
          "commentsCount": 0,
          "repostsCount": 0,
          "quotesCount": 0,
          "bookmarksCount": 0,
          "sharesCount": 0,
          "viewsCount": 0,
          "canLike": true,
          "canComment": true,
          "canRepost": true,
          "canShare": true
        },
        "userInteraction": {
          "hasLiked": false,
          "hasBookmarked": false,
          "hasReposted": false,
          "hasCommented": false,
          "hasViewed": false,
          "hasShared": false
        },
        "createdAt": "2025-12-29T10:00:00",
        "publishedAt": "2025-12-29T10:30:45",
        "scheduledAt": null
      }
    }
    

    Success Response Fields:

    Uniqueidentifier
    HeaderTypeRequiredField Description
    Authorizationid string Yes Bearerof tokenthe forpublished authentication (format: Bearer <token>)post
    Content-Typeauthor stringInformation about the post author
    content YesText content of the post
    postType MustType beof application/jsonpost: REGULAR, POLL, QUOTE
    statusPost status (now PUBLISHED)
    mediaArray of media attachments (images/videos)
    attachmentsCommerce and social attachments
    privacySettingsPrivacy and interaction settings
    engagementEngagement counters (all start at 0)
    userInteractionCurrent user's interaction status
    publishedAtTimestamp when post was published

    SuccessError Response JSON Samples: Returns standard PostResponse structure with status changed to PUBLISHED

    SuccessMedia ResponseWithout MessageText Content:

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Media posts must include text content",
      "action_time": "2025-12-29T10:30:45",
      "data": null
    }
    

    Empty Post:

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Post publishedmust successfully"have at least one of: text content, poll, quote, or attachments",
      "action_time": "2025-12-29T10:30:45",
      "data": null
    }
    

    No Draft Found:

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "No draft found",
      "action_time": "2025-12-29T10:30:45",
      "data": null
    }
    

    Pending Collaborator Approval:

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Cannot publish collaborative post - waiting for collaborator acceptance",
      "action_time": "2025-12-29T10:30:45",
      "data": "2 of 3 collaborators have accepted"
    }
    

    Invalid Attached Product:

    {
      "success": false,
      "httpStatus": "UNPROCESSABLE_ENTITY",
      "message": "Invalid product attachment",
      "action_time": "2025-12-29T10:30:45",
      "data": "Product 550e8400-e29b-41d4-a716-446655440001 is no longer active"
    }
    

    Standard Error Types:

    Application-Level Exceptions (400-499)

    • 400 BAD_REQUEST: No draft found, draftcontent incomplete,validation failed, or onlymedia draftwithout posts can be publishedtext
    • 401 UNAUTHORIZED: AuthenticationMissing issuesor invalid authentication token
    • 403 FORBIDDEN: Collaborative post pending approval from collaborators
    • 404 NOT_FOUND: No draft post found for user
    • 422 UNPROCESSABLE_ENTITY: Draft validation failed (invalid attachments, expired poll, etc.)
    • 500 INTERNAL_SERVER_ERROR: Unexpected server errors

    Error Response Examples:

    No Draft Found (404):

    {
      "success": false,
      "httpStatus": "NOT_FOUND",
      "message": "No draft post found",
      "action_time": "2025-12-11T10:30:45",
      "data": "You don't have a draft post to publish"
    }
    

    Pending Collaborator Approval (403):

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Cannot publish collaborative post",
      "action_time": "2025-12-11T10:30:45",
      "data": "Waiting for collaborator acceptance. 2 of 3 collaborators have accepted."
    }
    

    Invalid Attached Product (422):

    {
      "success": false,
      "httpStatus": "UNPROCESSABLE_ENTITY",
      "message": "Invalid product attachment",
      "action_time": "2025-12-11T10:30:45",
      "data": "Product 550e8400-e29b-41d4-a716-446655440001 is no longer active and must be removed before publishing"
    }
    

    Use Case Examples:

    Example 1: SimpleText DraftOnly PublishPost

    POST /e-social/posts/publish
    
    User has draft:Draft: "Hello world! This is my first post"
    Result: Draft published,Published appears in followers' feeds, status = PUBLISHED, publishedAt set to current timesuccessfully
    

    Example 2: CollaborativeText Draft+ PublishMedia (All Accepted)Post

    POSTDraft: /e-social/posts/publish"Check Userout hasthis draftsunset! with🌅" 2+ collaborators
    Both collaborators have accepted (status = ACCEPTED)[image.jpg]
    Result: Draft published,Published all 3 authors credited, appears on all 3 profiles, notifications sentsuccessfully
    

    Example 3: CollaborativeMedia Draft PublishOnly (PendingNo Approval)Text)

    POSTDraft: /e-social/posts/publish[image.jpg] User(no hastext draft with 3 collaborators
    Only 2 have accepted, 1 still pendingcontent)
    Result: Error 403 - Cannot"Media publishposts untilmust allinclude collaboratorstext acceptcontent"
    

    Example 4: DraftPoll with Product AttachmentOnly

    POSTDraft: /e-social/posts/publishPoll User"What's hasyour draftfavorite color?" with attachedoptions product[Red, ProductBlue, validation checks:
    - Product exists? ✓
    - Product status ACTIVE? ✓
    - Product belongs to active shop? ✓Green]
    Result: Draft published,Published productsuccessfully card(poll appearstitle inserves post,as shop gets notificationcontent)
    

    Example 5: Product Attachment Only

    Draft: Attached product "Wireless Headphones" (no text)
    Result: ✅ Published successfully (attachment provides context)
    

    Example 6: Product + Media (No Text)

    Draft: Attached product + [product_photo.jpg] (no text)
    Result: ❌ Error - "Media posts must include text content"
    

    Example 7: Quote Post Only

    Draft: Quoting another post (no additional text)
    Result: ✅ Published successfully (quoted post provides context)
    

    Example 8: Empty Post

    Draft: No content, no media, no attachments
    Result: ❌ Error - "Post must have at least one of: text content, poll, quote, or attachments"
    

    3. Delete Post

    Purpose: Soft delete a post (marks as deleted, doesn't remove from database)

    Endpoint: DELETE {base_url}/e-social/posts/{postId}

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Performs soft delete: Sets isDeleted flag to true, doesn't remove from database
    • Removes post from all users' feeds immediately
    • Preserves post data for analytics and audit purposes
    • All comments, likes, bookmarks remain in database but are hidden
    • Decrements engagement counters for attached products/shops/events
    • Sends notification to collaborators (if collaborative post)
    • Post no longer appears in searches, hashtag feeds, or explore pages
    • Only post author can delete their own posts (not collaborators)

    Business Rules:

    1. Author Only: Only the original post author can delete (collaborators cannot)
    2. Soft Delete: Data retained in database with isDeleted = true
    3. Irreversible: Deleted posts cannot be undeleted (would need backend intervention)
    4. Cascade Hiding: Comments/likes/bookmarks hidden but not deleted
    5. Analytics Preservation: Engagement data preserved for historical analytics
    6. Feed Removal: Immediately removed from all feeds (home, explore, profile)
    7. Notification: Collaborators notified of deletion
    8. Attachment Impact: Products/shops/events lose post engagement stats

    What Gets Hidden:

    • Post itself (no longer visible to anyone)
    • All comments and replies on the post
    • All likes, bookmarks, reposts
    • Post no longer appears in:
      • User's profile
      • Followers' feeds
      • Hashtag pages
      • Search results
      • Product/shop/event pages (if attached)

    What Gets Preserved (in database for analytics):

    • Original post content and metadata
    • All engagement metrics (historical counts)
    • All comments and their content
    • All likes, bookmarks, and reposts
    • Author and timestamp information
    • Attachment relationships

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication (format: Bearer <token>)
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the post to delete Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Post deleted successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Success Response Fields:

    Field Description
    data Always null for this endpoint

    Standard Error Types:

    Application-Level Exceptions (400-499)

    • 400 BAD_REQUEST: Can only delete your own posts
    • 401 UNAUTHORIZED: Authentication issues
    • 403 FORBIDDEN: Not the post author (collaborators cannot delete)
    • 404 NOT_FOUND: Post not found or already deleted
    • 500 INTERNAL_SERVER_ERROR: Unexpected server errors

    Error Response Examples:

    Not Post Author (403):

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Cannot delete post",
      "action_time": "2025-12-11T10:30:45",
      "data": "Only the post author can delete this post. Collaborators cannot delete."
    }
    

    Post Not Found (404):

    {
      "success": false,
      "httpStatus": "NOT_FOUND",
      "message": "Post not found",
      "action_time": "2025-12-11T10:30:45",
      "data": "Post with ID 550e8400-e29b-41d4-a716-446655440000 not found or already deleted"
    }
    

    Use Case Examples:

    Example 1: Delete Regular Post

    DELETE /e-social/posts/550e8400-e29b-41d4-a716-446655440000
    
    Post has: 50 likes, 10 comments, 5 reposts
    Result: Post soft deleted, all engagement hidden, removed from feeds, data preserved in DB
    

    Example 2: Delete Post with Product Attachments

    DELETE /e-social/posts/660e8400-e29b-41d4-a716-446655440001
    
    Post attached to 2 products
    Result: Post deleted, product engagement counters decremented, post removed from product pages
    

    Example 3: Collaborator Tries to Delete (Fails)

    DELETE /e-social/posts/770e8400-e29b-41d4-a716-446655440002
    
    User is collaborator, not author
    Result: Error 403 - Only original author can delete collaborative posts
    

    4. Get Post by ID

    Purpose: Retrieve a single post by its ID with full details

    Endpoint: GET {base_url}/e-social/posts/{postId}

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Returns full post details including author info, content, media, attachments, engagement
    • Respects post visibility settings (PUBLIC, FOLLOWERS, MENTIONED, PRIVATE)
    • Checks if requesting user has permission to view based on privacy settings
    • Includes user interaction state (hasLiked, hasBookmarked, etc.)
    • For poll posts, includes user's voting status and results if visible
    • Increments view counter if this is first view by this user
    • Returns parsed content with @mentions, $shops, and #hashtags highlighted
    • Includes collaboration info if collaborative post

    Visibility Logic:

    • PUBLIC: Anyone can view
    • FOLLOWERS: Only followers of author can view
    • MENTIONED: Only users mentioned in post (@username) can view
    • PRIVATE: Only author can view

    Additional Access Rules:

    • Blocked users cannot view each other's posts (even if PUBLIC)
    • Deleted posts (isDeleted = true) return 404 NOT_FOUND
    • Scheduled posts (status = SCHEDULED) only visible to author before scheduled time
    • Draft posts (status = DRAFT) only visible to author
    • Collaborative posts visible to all collaborators regardless of visibility setting

    Response Includes:

    • Full post content with parsed entities (mentions, hashtags, shops)
    • Author information with profile picture and verification status
    • All media with URLs, dimensions, placeholders (BlurHash)
    • All commerce attachments (products, shops, events, groups, installments)
    • Collaboration details (if collaborative post)
    • Privacy settings
    • Engagement metrics (likes, comments, reposts counts)
    • User's interaction state (liked?, bookmarked?, reposted?, etc.)
    • Poll results (if poll post and user can see results)
    • Creation and publication timestamps

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication (format: Bearer <token>)
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the post to retrieve Must be valid UUID format

    Success Response: Returns standard PostResponse structure

    Success Response Message: "Post retrieved successfully"

    Standard Error Types:

    Application-Level Exceptions (400-499)

    • 401 UNAUTHORIZED: Authentication issues
    • 403 FORBIDDEN: User doesn't have permission to view this post (visibility restrictions)
    • 404 NOT_FOUND: Post not found, deleted, or not yet published (scheduled/draft)
    • 500 INTERNAL_SERVER_ERROR: Unexpected server errors

    Error Response Examples:

    Post Not Found (404):

    {
      "success": false,
      "httpStatus": "NOT_FOUND",
      "message": "Post not found",
      "action_time": "2025-12-11T10:30:45",
      "data": "Post with ID 550e8400-e29b-41d4-a716-446655440000 not found"
    }
    

    Insufficient Permissions - Followers Only (403):

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Cannot view this post",
      "action_time": "2025-12-11T10:30:45",
      "data": "This post is visible to followers only. Follow the author to view."
    }
    

    Blocked User (403):

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Cannot view this post",
      "action_time": "2025-12-11T10:30:45",
      "data": "You cannot view posts from this user"
    }
    

    Use Case Examples:

    Example 1: View Public Post

    GET /e-social/posts/550e8400-e29b-41d4-a716-446655440000
    
    Post visibility: PUBLIC
    Result: Full post details returned, view counter incremented, engagement visible
    

    Example 2: View Followers-Only Post (Not Following)

    GET /e-social/posts/660e8400-e29b-41d4-a716-446655440001
    
    Post visibility: FOLLOWERS
    User is not following author
    Result: Error 403 - Must follow author to view
    

    Example 3: View Mentioned Post (Not Mentioned)

    GET /e-social/posts/770e8400-e29b-41d4-a716-446655440002
    
    Post visibility: MENTIONED
    User not mentioned in post
    Result: Error 403 - Only mentioned users can view
    

    Example 4: View Own Draft Post

    GET /e-social/posts/880e8400-e29b-41d4-a716-446655440003
    
    Post status: DRAFT
    User is post author
    Result: Full post details returned with status = DRAFT
    

    Example 5: View Collaborative Post (As Collaborator)

    GET /e-social/posts/990e8400-e29b-41d4-a716-446655440004
    
    Post visibility: PRIVATE
    User is accepted collaborator
    Result: Full post details returned (collaborators can always view)
    

    5. Get Published Posts

    Purpose: Retrieve all published posts with pagination (for discovery/explore feed)

    Endpoint: GET {base_url}/e-social/posts

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication (format: Bearer <token>)
    Content-Type string Yes Must be application/json

    Query Parameters:

    Parameter Type Required Description Validation Default
    page integer No Page number (1-indexed) Min: 1 1
    size integer No Number of items per page Min: 1, Max: 100 20

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Posts retrieved successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": [
        {
          // PostResponse object
        },
        {
          // PostResponse object
        }
      ]
    }
    

    Success Response Fields:

    Field Description
    data Array of PostResponse objects

    Standard Error Types:

    Application-Level Exceptions (400-499)

    • 401 UNAUTHORIZED: Authentication issues
    • 500 INTERNAL_SERVER_ERROR: Unexpected server errors

    6. Get Posts by Author

    Purpose: Retrieve all posts from a specific author with pagination

    Endpoint: GET {base_url}/e-social/posts/author/{authorId}

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication (format: Bearer <token>)
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    authorId string Yes UUID of the author Must be valid UUID format

    Query Parameters:

    Parameter Type Required Description Validation Default
    page integer No Page number (1-indexed) Min: 1 1
    size integer No Number of items per page Min: 1, Max: 100 20

    Success Response: Returns array of PostResponse objects

    Success Response Message: "Posts retrieved successfully"

    Standard Error Types:

    Application-Level Exceptions (400-499)

    • 401 UNAUTHORIZED: Authentication issues
    • 404 NOT_FOUND: Author not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected server errors

    7. Get My Scheduled Posts

    Purpose: Retrieve all scheduled posts for the authenticated user

    Endpoint: GET {base_url}/e-social/posts/scheduled

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication (format: Bearer <token>)
    Content-Type string Yes Must be application/json

    Success Response: Returns array of PostResponse objects with status SCHEDULED

    Success Response Message: "Scheduled posts retrieved successfully"

    Standard Error Types:

    Application-Level Exceptions (400-499)

    • 401 UNAUTHORIZED: Authentication issues
    • 500 INTERNAL_SERVER_ERROR: Unexpected server errors

    8. Get My Current Draft

    Purpose: Retrieve the authenticated user's current draft post

    Endpoint: GET {base_url}/e-social/posts/draft

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication (format: Bearer <token>)
    Content-Type string Yes Must be application/json

    Success Response: Returns standard PostResponse structure with status DRAFT, or null if no draft exists

    Success Response Message: "Draft retrieved successfully"

    Standard Error Types:

    Application-Level Exceptions (400-499)

    • 401 UNAUTHORIZED: Authentication issues
    • 500 INTERNAL_SERVER_ERROR: Unexpected server errors

    9. Discard Draft

    Purpose: Delete the current draft post permanently

    Endpoint: DELETE {base_url}/e-social/posts/draft

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication (format: Bearer <token>)
    Content-Type string Yes Must be application/json

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Draft discarded successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    Application-Level Exceptions (400-499)

    • 400 BAD_REQUEST: No draft found or can only discard your own draft
    • 401 UNAUTHORIZED: Authentication issues
    • 500 INTERNAL_SERVER_ERROR: Unexpected server errors

    10. Update Draft

    Purpose: Update content, media, or privacy settings of the current draft

    Endpoint: PUT {base_url}/e-social/posts

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication (format: Bearer <token>)
    Content-Type string Yes Must be application/json

    Request JSON Sample:

    {
      "content": "Updated post content",
      "media": [
        {
          "mediaType": "IMAGE",
          "mediaUrl": "https://cdn.nexgate.com/uploads/new_image.jpg",
          "width": 1920,
          "height": 1080
        }
      ],
      "privacySettings": {
        "visibility": "FOLLOWERS",
        "whoCanComment": "FOLLOWERS"
      }
    }
    

    Request Body Parameters:

    Parameter Type Required Description Validation
    content string No Updated post text content Max: 5000 characters
    media array No Updated media array Max: 10 items
    privacySettings object No Updated privacy settings

    Success Response: Returns standard PostResponse structure with updated values

    Success Response Message: "Draft updated successfully"

    Standard Error Types:

    Application-Level Exceptions (400-499)

    • 400 BAD_REQUEST: No draft found, can only update your own posts, or only draft posts can be updated
    • 401 UNAUTHORIZED: Authentication issues
    • 422 UNPROCESSABLE_ENTITY: Validation errors
    • 500 INTERNAL_SERVER_ERROR: Unexpected server errors

    11-20. Draft Commerce Attachments (Attach/Remove Products, Shops, Events, Groups, Plans)

    For brevity, these endpoints follow the same pattern:

    Attach Endpoints: POST {base_url}/e-social/posts/draft/attach-{type}/{id}

    • /draft/attach-product/{productId}
    • /draft/attach-shop/{shopId}
    • /draft/attach-event/{eventId}
    • /draft/attach-group/{groupId}
    • /draft/attach-plan/{planId}

    Remove Endpoints: DELETE {base_url}/e-social/posts/draft/remove-{type}/{id}

    • /draft/remove-product/{productId}
    • /draft/remove-shop/{shopId}
    • /draft/remove-event/{eventId}
    • /draft/remove-group/{groupId}
    • /draft/remove-plan/{planId}

    All return standard PostResponse structure. Success messages follow pattern: "{Type} attached/removed to/from draft successfully"


    21. Update Draft Content Only

    Purpose: Update only the text content of the current draft

    Endpoint: PUT {base_url}/e-social/posts/content

    Request Body: Plain text string (not JSON object)

    Success Response: Returns standard PostResponse structure

    Success Response Message: "Draft content updated successfully"


    22. Update Draft Media Only

    Purpose: Update only the media attachments of the current draft

    Endpoint: PUT {base_url}/e-social/posts/media

    Request Body: Array of MediaRequest objects

    Success Response: Returns standard PostResponse structure

    Success Response Message: "Media added to draft successfully"


    23. Update Draft Privacy Settings Only

    Purpose: Update only the privacy settings of the current draft

    Endpoint: PUT {base_url}/e-social/posts/privacy

    Request Body: PrivacySettingsRequest object

    Success Response: Returns standard PostResponse structure

    Success Response Message: "Privacy settings updated successfully"


    24. Update Draft Collaboration

    Purpose: Update collaborator invitations for the current draft

    Endpoint: PUT {base_url}/e-social/posts/collaboration

    Request Body: CollaborationRequest object with collaboratorIds array

    Success Response: Returns standard PostResponse structure

    Success Response Message: "Collaboration settings updated successfully"


    25. Accept Collaboration

    Purpose: Accept a collaboration invitation on a published post

    Endpoint: POST {base_url}/e-social/posts/{postId}/collaboration/accept

    Success Response: Returns standard PostResponse structure

    Success Response Message: "Collaboration accepted successfully"


    26. Decline Collaboration

    Purpose: Decline a collaboration invitation on a published post

    Endpoint: POST {base_url}/e-social/posts/{postId}/collaboration/decline

    Success Response: Returns standard PostResponse structure

    Success Response Message: "Collaboration declined successfully"


    27. Remove Collaborator

    Purpose: Remove a collaborator from a published post (author or self only)

    Endpoint: DELETE {base_url}/e-social/posts/{postId}/collaborators/{collaboratorId}

    Success Response Message: "Collaborator removed successfully"


    28. Create Quote Post

    Purpose: Create a new post that quotes an existing post

    Endpoint: POST {base_url}/e-social/posts/quote/{quotedPostId}

    Request Body: CreateQuotePostRequest object (similar to CreatePostRequest but without poll support)

    Success Response: Returns standard PostResponse structure with quotedPost field populated

    Success Response Message: "Quote post created successfully"


    Interaction Endpoints (29-38)

    29. Like Post

    Purpose: Add a like to a post

    Endpoint: POST {base_url}/e-social/posts/{postId}/like

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Adds current user's like to the specified post
    • Increments post's likesCount by 1
    • Creates like record with timestamp
    • Sends notification to post author (unless liking own post)
    • Updates user's userInteraction.hasLiked to true
    • Idempotent: If already liked, returns success without changes
    • Respects post visibility (must be able to view post to like it)
    • For collaborative posts, all collaborators receive notification

    Business Rules:

    1. Visibility Check: User must have permission to view post based on privacy settings
    2. Blocking: Cannot like posts from blocked users or if author blocked you
    3. Deleted Posts: Cannot like deleted posts (isDeleted = true)
    4. Draft/Scheduled: Cannot like unpublished posts (must be PUBLISHED status)
    5. Idempotent: Multiple like attempts don't create duplicate likes
    6. Notification: Author receives notification (unless self-like)
    7. Counter Update: Post's engagement counter incremented atomically
    8. User State: User's interaction state updated for this post

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the post to like Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Post liked successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot like this post (blocked, visibility, etc.)
    • 404 NOT_FOUND: Post not found or deleted
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Error Response Examples:

    Cannot Like - Blocked User (403):

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Cannot like this post",
      "action_time": "2025-12-11T10:30:45",
      "data": "You cannot interact with posts from this user"
    }
    

    Post Not Found (404):

    {
      "success": false,
      "httpStatus": "NOT_FOUND",
      "message": "Post not found",
      "action_time": "2025-12-11T10:30:45",
      "data": "Post with ID 550e8400-e29b-41d4-a716-446655440000 not found"
    }
    

    30. Unlike Post

    Purpose: Remove a like from a post

    Endpoint: DELETE {base_url}/e-social/posts/{postId}/like

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Removes current user's like from the specified post
    • Decrements post's likesCount by 1
    • Deletes like record from database
    • No notification sent (unlike is silent)
    • Updates user's userInteraction.hasLiked to false
    • Idempotent: If not liked, returns success without changes
    • Can unlike even if post is now deleted or user is blocked

    Business Rules:

    1. Silent Operation: No notification sent to post author
    2. Always Allowed: Can unlike even if blocked or post deleted (to clean up state)
    3. Idempotent: Multiple unlike attempts don't cause errors
    4. Counter Decrement: Post's engagement counter decremented atomically
    5. State Cleanup: User's interaction state updated

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the post to unlike Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Post unliked successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 404 NOT_FOUND: Post not found (permanent deletion from DB)
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    31. Bookmark Post

    Purpose: Save a post to bookmarks for later viewing

    Endpoint: POST {base_url}/e-social/posts/{postId}/bookmark

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Adds post to user's bookmark collection
    • Creates bookmark record with timestamp
    • Post appears in user's bookmarks list (GET /posts/bookmarks)
    • Increments post's bookmarksCount by 1
    • No notification sent (bookmarking is private)
    • Updates user's userInteraction.hasBookmarked to true
    • Idempotent: If already bookmarked, returns success without changes
    • Respects visibility (must be able to view post to bookmark it)

    Business Rules:

    1. Private Action: Bookmarks are private, author doesn't get notified
    2. Visibility Required: Must have permission to view post based on privacy settings
    3. Persistent: Bookmarks persist even if post is deleted (for user's reference)
    4. Organization: Can be organized into collections (future feature)
    5. No Limit: Unlimited bookmarks allowed per user
    6. Idempotent: Multiple bookmark attempts don't create duplicates
    7. Counter Update: Post's engagement counter incremented
    8. Access Anytime: User can always access their bookmarked posts

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the post to bookmark Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Post bookmarked successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot bookmark this post (visibility restrictions)
    • 404 NOT_FOUND: Post not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Use Case Examples:

    Example 1: Bookmark for Later Reading

    POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/bookmark
    
    User sees interesting post with products attached
    Bookmarks to check products later
    Result: Post saved to bookmarks, appears in GET /posts/bookmarks
    

    Example 2: Bookmark Collaborative Post

    POST /e-social/posts/660e8400-e29b-41d4-a716-446655440001/bookmark
    
    Post has 3 collaborators
    User bookmarks for reference
    Result: Post bookmarked, visible in bookmarks even if one collaborator leaves
    

    32. Unbookmark Post

    Purpose: Remove a post from bookmarks

    Endpoint: DELETE {base_url}/e-social/posts/{postId}/bookmark

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Removes post from user's bookmark collection
    • Deletes bookmark record from database
    • Post no longer appears in user's bookmarks list
    • Decrements post's bookmarksCount by 1
    • No notification sent (unbookmarking is private)
    • Updates user's userInteraction.hasBookmarked to false
    • Idempotent: If not bookmarked, returns success without changes

    Business Rules:

    1. Silent Operation: No notification sent
    2. Always Allowed: Can unbookmark anytime, even if post deleted
    3. Idempotent: Multiple unbookmark attempts don't cause errors
    4. Counter Decrement: Post's engagement counter decremented

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the post to unbookmark Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Post unbookmarked successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 404 NOT_FOUND: Post not found (permanent deletion)
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    33. Repost Post

    Purpose: Share a post to your profile and followers' feeds (with optional comment)

    Endpoint: POST {base_url}/e-social/posts/{postId}/repost

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Creates a repost record linking user to original post
    • Original post appears in user's profile with "reposted" indicator
    • Original post appears in all followers' feeds attributed to reposter
    • Increments original post's repostsCount by 1
    • If comment provided, creates quote post instead (separate post with original embedded)
    • Sends notification to original post author
    • For collaborative posts, all collaborators receive notification
    • Updates user's userInteraction.hasReposted to true
    • Idempotent: If already reposted without comment, returns success
    • Respects post's whoCanRepost privacy setting

    Business Rules:

    1. Permission Check: Post must allow reposts (whoCanRepost setting)
    2. Visibility Check: Must have permission to view post
    3. Blocking: Cannot repost from blocked users
    4. With Comment: If comment provided, creates separate quote post
    5. Without Comment: Direct repost, original post shown on profile
    6. Notification: Original author notified
    7. Feed Distribution: Appears in reposter's followers' feeds
    8. Attribution: Always shows original author prominently
    9. Idempotent: Second repost without comment is no-op
    10. Counter Update: Original post's repost counter incremented

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the post to repost Must be valid UUID format

    Request Body (Optional):

    {
      "comment": "This is amazing! Everyone should see this 🔥"
    }
    

    Request Body Parameters:

    Parameter Type Required Description Validation
    comment string No Optional comment for quote post Max: 500 characters. If provided, creates quote post instead

    Success Response JSON Sample (Simple Repost):

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Post reposted successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Success Response JSON Sample (Quote Post):

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Quote post created successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": {
        // Returns full PostResponse for the new quote post
        // with quotedPost field containing original post
      }
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot repost (blocked, privacy settings, disabled reposts)
    • 404 NOT_FOUND: Post not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Error Response Examples:

    Reposts Disabled (403):

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Cannot repost this post",
      "action_time": "2025-12-11T10:30:45",
      "data": "The author has disabled reposts for this post"
    }
    

    Reposts Followers Only (403):

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Cannot repost this post",
      "action_time": "2025-12-11T10:30:45",
      "data": "Only followers can repost this post. Follow the author to repost."
    }
    

    Use Case Examples:

    Example 1: Simple Repost (No Comment)

    POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/repost
    
    Body: {} or no body
    
    Result: Original post appears on user's profile with "reposted" badge
    Appears in followers' feeds
    Original author gets notification
    

    Example 2: Quote Post (With Comment)

    POST /e-social/posts/660e8400-e29b-41d4-a716-446655440001/repost
    
    Body: {
      "comment": "This is exactly what I've been saying! Great insight 🎯"
    }
    
    Result: Creates new quote post with comment
    Original post embedded in quote
    New post has own likes/comments
    Both posts' repost counters incremented
    

    34. Unrepost Post

    Purpose: Remove a repost from your profile

    Endpoint: DELETE {base_url}/e-social/posts/{postId}/repost

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Removes repost from user's profile
    • Original post no longer appears in user's profile reposts
    • Decrements original post's repostsCount by 1
    • No notification sent (unrepost is silent)
    • Updates user's userInteraction.hasReposted to false
    • Does NOT delete quote posts (those are separate posts, use delete endpoint)
    • Idempotent: If not reposted, returns success without changes

    Business Rules:

    1. Simple Reposts Only: Only removes simple reposts, not quote posts
    2. Quote Posts: To remove quote post, use DELETE /posts/{quotePostId}
    3. Silent Operation: No notification sent to original author
    4. Always Allowed: Can unrepost anytime, even if blocked or post deleted
    5. Counter Decrement: Original post's repost counter decremented
    6. Idempotent: Multiple unrepost attempts don't cause errors

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the original post to unrepost Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Post unreposted successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 404 NOT_FOUND: Post not found (permanent deletion)
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    35. Record View

    Purpose: Track post views for analytics

    Endpoint: POST {base_url}/e-social/posts/{postId}/view

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Records that current user viewed the post
    • Increments post's viewsCount by 1 (first view only)
    • Creates view record with timestamp
    • Idempotent: Multiple views from same user only count once
    • Updates user's userInteraction.hasViewed to true
    • No notification sent (views are private analytics)
    • View counts visible to post author in analytics dashboard
    • Automatic: Usually called by frontend when post enters viewport

    Business Rules:

    1. One View Per User: Each user counted only once regardless of repeat views
    2. Private Metric: View counts not shown publicly (author sees in analytics)
    3. No Notification: Viewing doesn't notify author
    4. Automatic Tracking: Frontend typically calls this when post visible for 2+ seconds
    5. Respects Visibility: Must have permission to view post
    6. Author Excluded: Author's own views don't count
    7. Idempotent: Multiple calls from same user don't inflate count

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the post being viewed Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "View recorded successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot view this post (visibility restrictions)
    • 404 NOT_FOUND: Post not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    36. Get My Bookmarks

    Purpose: Retrieve all posts bookmarked by current user

    Endpoint: GET {base_url}/e-social/posts/bookmarks

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Returns all posts bookmarked by current user
    • Sorted by bookmark date (newest first)
    • Includes posts even if deleted or author blocked (user retains access)
    • Paginated results for performance
    • Each post includes full PostResponse structure
    • Shows deleted posts with special indicator (for user reference)
    • Includes posts from private/followers-only accounts if bookmarked when accessible

    Business Rules:

    1. Personal Collection: Only user's own bookmarks visible
    2. Persists Deletions: Bookmarked posts remain accessible even if deleted
    3. Persists Blocking: Can view bookmarked posts even if author blocked
    4. Chronological: Sorted by bookmark time (newest first)
    5. Full Details: Each post includes complete information
    6. Pagination: Default 20 per page, max 100

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Query Parameters:

    Parameter Type Required Description Validation Default
    page integer No Page number (1-indexed) Min: 1 1
    size integer No Items per page Min: 1, Max: 100 20

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Bookmarks retrieved successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": [
        {
          // Full PostResponse object
          "id": "550e8400-e29b-41d4-a716-446655440000",
          "content": "Bookmarked post content...",
          // ... rest of PostResponse
        },
        {
          // Another PostResponse object
        }
      ]
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    37. Get My Reposts

    Purpose: Retrieve all posts reposted by current user

    Endpoint: GET {base_url}/e-social/posts/my-reposts

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Returns all posts reposted by current user (simple reposts only)
    • Does NOT include quote posts (those are separate posts in user's profile)
    • Sorted by repost date (newest first)
    • Paginated results for performance
    • Each post shows original author and content
    • Respects current visibility settings of original posts

    Business Rules:

    1. Simple Reposts Only: Only shows direct reposts, not quote posts
    2. Quote Posts: Appear in regular "Get User Posts" endpoint as authored posts
    3. Current Visibility: If original post now private/deleted, it's excluded
    4. Chronological: Sorted by repost time (newest first)
    5. Full Details: Each post includes complete original information

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Query Parameters:

    Parameter Type Required Description Validation Default
    page integer No Page number (1-indexed) Min: 1 1
    size integer No Items per page Min: 1, Max: 100 20

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Reposts retrieved successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": [
        {
          // Full PostResponse object of reposted post
          "id": "550e8400-e29b-41d4-a716-446655440000",
          "author": {
            // Original author info
          },
          "content": "Original post content...",
          // ... rest of PostResponse
        }
      ]
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    38. Get User Reposts

    Purpose: Retrieve all posts reposted by a specific user

    Endpoint: GET {base_url}/e-social/posts/users/{userId}/reposts

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Returns all posts reposted by specified user (simple reposts only)
    • Does NOT include quote posts (those are in user's authored posts)
    • Respects privacy settings of original posts
    • Only shows reposts visible to requesting user based on:
      • Original post visibility settings
      • Blocking status
      • Follow relationships
    • Sorted by repost date (newest first)
    • Paginated results for performance

    Business Rules:

    1. Simple Reposts Only: Only shows direct reposts, not quote posts
    2. Visibility Filtering: Only shows original posts requesting user can see
    3. Privacy Respected: Follows same visibility rules as original posts
    4. Blocking: Hidden if original author blocked requesting user
    5. Chronological: Sorted by repost time (newest first)

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    userId string Yes UUID of user whose reposts to retrieve Must be valid UUID format

    Query Parameters:

    Parameter Type Required Description Validation Default
    page integer No Page number (1-indexed) Min: 1 1
    size integer No Items per page Min: 1, Max: 100 20

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "User reposts retrieved successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": [
        {
          // Full PostResponse object of reposted post
          "id": "550e8400-e29b-41d4-a716-446655440000",
          "author": {
            // Original author info
          },
          "content": "Original post content...",
          // ... rest of PostResponse
        }
      ]
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 404 NOT_FOUND: User not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Summary: All interaction endpoints return data: null except GET endpoints (36-38) which return paginated PostResponse arrays.


    Poll Endpoints (39-42)

    39. Vote on Poll

    Purpose: Cast a vote on a poll post

    Endpoint: POST {base_url}/e-social/posts/{postId}/vote

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Records user's vote on poll options
    • Supports single or multiple option selection based on poll settings
    • If allowVoteChange is true, replaces existing vote
    • If allowVoteChange is false, rejects vote if user already voted
    • Increments vote counts for selected options
    • Updates poll's totalVotes count
    • If non-anonymous, records voter identity
    • If anonymous, records vote without identity
    • Validates poll hasn't expired before accepting vote
    • Respects post visibility (must be able to view post to vote)

    Business Rules:

    1. Single vs Multiple: Respects poll's allowMultipleVotes setting
    2. Vote Changes: Allowed only if allowVoteChange is true
    3. Expiration: Cannot vote on expired polls
    4. Visibility: Must have access to view post
    5. Blocking: Cannot vote on polls from blocked users
    6. Option Validation: All optionIds must belong to this poll
    7. Single Vote Mode: If allowMultipleVotes false, only 1 optionId allowed
    8. Multiple Vote Mode: If allowMultipleVotes true, can select multiple options
    9. Anonymous: If isAnonymous true, voter identity hidden
    10. Non-Anonymous: If isAnonymous false, voter identity visible to post author

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the poll post Must be valid UUID format

    Request JSON Sample (Single Vote):

    {
      "optionIds": ["option-uuid-1"]
    }
    

    Request JSON Sample (Multiple Votes):

    {
      "optionIds": ["option-uuid-1", "option-uuid-2", "option-uuid-4"]
    }
    

    Request Body Parameters:

    Parameter Type Required Description Validation
    optionIds array Yes Array of poll option UUIDs Min: 1 option. If allowMultipleVotes false, max: 1. All IDs must belong to poll

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Vote recorded successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 400 BAD_REQUEST: Poll expired, vote change not allowed, or invalid options
    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot vote (blocked, visibility restrictions)
    • 404 NOT_FOUND: Post or poll not found
    • 422 UNPROCESSABLE_ENTITY: Validation errors (too many options, invalid IDs)
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Error Response Examples:

    Poll Expired (400):

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Cannot vote on poll",
      "action_time": "2025-12-11T10:30:45",
      "data": "This poll has expired and is no longer accepting votes"
    }
    

    Vote Change Not Allowed (400):

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Cannot change vote",
      "action_time": "2025-12-11T10:30:45",
      "data": "You have already voted on this poll and vote changes are not allowed"
    }
    

    Too Many Options - Single Vote Mode (422):

    {
      "success": false,
      "httpStatus": "UNPROCESSABLE_ENTITY",
      "message": "Validation failed",
      "action_time": "2025-12-11T10:30:45",
      "data": {
        "optionIds": "This poll allows only one vote. You selected 3 options."
      }
    }
    

    Invalid Option ID (404):

    {
      "success": false,
      "httpStatus": "NOT_FOUND",
      "message": "Invalid poll option",
      "action_time": "2025-12-11T10:30:45",
      "data": "Option option-uuid-5 does not belong to this poll"
    }
    

    Use Case Examples:

    Example 1: Single Vote Poll

    POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/vote
    
    Poll settings: allowMultipleVotes = false
    
    Body: {
      "optionIds": ["option-uuid-2"]
    }
    
    Result: Vote recorded for option 2, totalVotes++, option vote count++
    

    Example 2: Multiple Vote Poll

    POST /e-social/posts/660e8400-e29b-41d4-a716-446655440001/vote
    
    Poll settings: allowMultipleVotes = true
    
    Body: {
      "optionIds": ["option-uuid-1", "option-uuid-3", "option-uuid-5"]
    }
    
    Result: Votes recorded for 3 options, totalVotes++, each option count++
    

    Example 3: Change Vote (Allowed)

    POST /e-social/posts/770e8400-e29b-41d4-a716-446655440002/vote
    
    Poll settings: allowVoteChange = true
    User already voted for option 1
    
    Body: {
      "optionIds": ["option-uuid-4"]
    }
    
    Result: Previous vote removed, new vote recorded, counts updated
    

    Example 4: Change Vote (Not Allowed)

    POST /e-social/posts/880e8400-e29b-41d4-a716-446655440003/vote
    
    Poll settings: allowVoteChange = false
    User already voted
    
    Body: {
      "optionIds": ["option-uuid-2"]
    }
    
    Result: Error 400 - Vote changes not allowed, original vote preserved
    

    40. Remove Vote

    Purpose: Remove your vote from a poll

    Endpoint: DELETE {base_url}/e-social/posts/{postId}/vote

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Removes all of user's votes from the poll
    • Decrements vote counts for previously selected options
    • Decrements poll's totalVotes count
    • Only allowed if allowVoteChange is true
    • Idempotent: If not voted, returns success without changes
    • Can remove votes even if poll expired (cleanup)

    Business Rules:

    1. Vote Change Required: Only works if allowVoteChange is true
    2. Complete Removal: Removes ALL votes (if multiple vote poll)
    3. Idempotent: Safe to call if not voted
    4. Expired Polls: Can remove votes even after expiration
    5. Counter Updates: All affected option counts decremented
    6. Silent Operation: No notification sent

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the poll post Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Vote removed successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 400 BAD_REQUEST: Vote removal not allowed (allowVoteChange is false)
    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot access poll
    • 404 NOT_FOUND: Post or poll not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Error Response Examples:

    Vote Removal Not Allowed (400):

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Cannot remove vote",
      "action_time": "2025-12-11T10:30:45",
      "data": "This poll does not allow vote changes or removal"
    }
    

    Use Case Examples:

    Example 1: Remove Single Vote

    DELETE /e-social/posts/550e8400-e29b-41d4-a716-446655440000/vote
    
    Poll settings: allowVoteChange = true
    User voted for option 2
    
    Result: Vote removed, option 2 count--, totalVotes--
    

    Example 2: Remove Multiple Votes

    DELETE /e-social/posts/660e8400-e29b-41d4-a716-446655440001/vote
    
    Poll settings: allowMultipleVotes = true, allowVoteChange = true
    User voted for options 1, 3, 5
    
    Result: All 3 votes removed, all option counts--, totalVotes--
    

    Example 3: Remove Vote - Not Allowed

    DELETE /e-social/posts/770e8400-e29b-41d4-a716-446655440002/vote
    
    Poll settings: allowVoteChange = false
    
    Result: Error 400 - Vote removal not allowed, original vote preserved
    

    41. Get Poll Results

    Purpose: Get detailed poll results including vote counts and percentages

    Endpoint: GET {base_url}/e-social/posts/{postId}/poll-results

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Returns complete poll details and voting statistics
    • Calculates percentages for each option
    • Shows user's voting status (hasVoted, which options voted)
    • Displays poll configuration (anonymous, multiple votes, change allowed)
    • Shows expiration status
    • Respects post visibility (must be able to view post)
    • Real-time results update as votes come in

    Business Rules:

    1. Visibility: Must have access to view parent post
    2. Real-Time: Results update immediately after each vote
    3. Percentages: Calculated as (optionVotes / totalVotes) × 100
    4. User State: Shows which options current user voted for
    5. Expiration Check: Indicates if poll has expired
    6. Zero Votes: Shows 0.0% for options with no votes
    7. Anonymous Respect: Voter identities hidden if isAnonymous true
    8. Public Results: Anyone who can view post can see results

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the poll post Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Poll results retrieved successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": {
        "pollId": "poll-uuid",
        "title": "What's your favorite programming language?",
        "description": "Choose your top pick for backend development",
        "totalVotes": 150,
        "allowMultipleVotes": false,
        "isAnonymous": true,
        "allowVoteChange": true,
        "expiresAt": "2025-12-15T10:30:45",
        "hasExpired": false,
        "userHasVoted": true,
        "options": [
          {
            "optionId": "option-uuid-1",
            "optionText": "Python",
            "optionImageUrl": null,
            "optionOrder": 1,
            "votesCount": 75,
            "percentage": 50.0,
            "userVoted": true
          },
          {
            "optionId": "option-uuid-2",
            "optionText": "JavaScript",
            "optionImageUrl": null,
            "optionOrder": 2,
            "votesCount": 50,
            "percentage": 33.3,
            "userVoted": false
          },
          {
            "optionId": "option-uuid-3",
            "optionText": "Java",
            "optionImageUrl": null,
            "optionOrder": 3,
            "votesCount": 25,
            "percentage": 16.7,
            "userVoted": false
          }
        ]
      }
    }
    

    Response Fields Explained:

    Field Type Description
    pollId string UUID of the poll
    title string Poll question/title
    description string Additional poll description (optional)
    totalVotes integer Total number of votes cast
    allowMultipleVotes boolean Can users select multiple options
    isAnonymous boolean Are voter identities hidden
    allowVoteChange boolean Can users change their vote
    expiresAt string Poll expiration datetime (ISO 8601, null if no expiration)
    hasExpired boolean Whether poll has passed expiration time
    userHasVoted boolean Has current user voted on this poll
    options array Array of poll options with results
    options[].optionId string UUID of this option
    options[].optionText string Text for this option
    options[].optionImageUrl string Optional image for this option (null if none)
    options[].optionOrder integer Display order (1, 2, 3...)
    options[].votesCount integer Number of votes for this option
    options[].percentage number Percentage of total votes (0.0-100.0)
    options[].userVoted boolean Did current user vote for this option

    Success Response Message: "Poll results retrieved successfully"

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot view poll (post visibility restrictions)
    • 404 NOT_FOUND: Post not found or not a poll post
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Use Case Examples:

    Example 1: View Active Poll Results

    GET /e-social/posts/550e8400-e29b-41d4-a716-446655440000/poll-results
    
    Poll has 150 total votes, user voted for Python
    Result: Returns all options with vote counts, percentages, user's vote highlighted
    

    Example 2: View Expired Poll

    GET /e-social/posts/660e8400-e29b-41d4-a716-446655440001/poll-results
    
    Poll expired yesterday, hasExpired = true
    Result: Results displayed, voting disabled, final counts shown
    

    Example 3: View Poll Without Voting

    GET /e-social/posts/770e8400-e29b-41d4-a716-446655440002/poll-results
    
    User hasn't voted yet, userHasVoted = false
    Result: All options shown with current results, all userVoted = false
    

    42. Get Poll Voters

    Purpose: Get list of users who voted for a specific poll option (post author/collaborators only, non-anonymous polls only)

    Endpoint: GET {base_url}/e-social/posts/{postId}/poll-voters/{optionId}

    Access Level: 🔒 Protected (Requires Bearer Token Authentication + Post Author/Collaborator)

    Authentication: Bearer Token

    Behavior:

    • Returns list of users who voted for specific poll option
    • Only available for non-anonymous polls (isAnonymous = false)
    • Only accessible by post author and accepted collaborators
    • Sorted by vote time (newest first)
    • Includes user profile information
    • Paginated for large polls

    Business Rules:

    1. Non-Anonymous Only: Only works if isAnonymous is false
    2. Author/Collaborator Access: Only post author and collaborators can view
    3. Privacy Protection: Regular users cannot see who voted
    4. Vote Time: Includes when each user voted
    5. Profile Info: Returns basic user profile (name, photo, verified status)
    6. Pagination: Default 50 voters per page
    7. Current Votes: Shows current votes (if user changed vote, shows new choice)

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the poll post Must be valid UUID format
    optionId string Yes UUID of the poll option Must belong to this poll

    Query Parameters:

    Parameter Type Required Description Validation Default
    page integer No Page number (1-indexed) Min: 1 1
    size integer No Items per page Min: 1, Max: 100 50

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Voters retrieved successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": {
        "pollId": "poll-uuid",
        "pollTitle": "What's your favorite programming language?",
        "optionId": "option-uuid-1",
        "optionText": "Python",
        "totalVoters": 75,
        "voters": [
          {
            "userId": "123e4567-e89b-12d3-a456-426614174000",
            "userName": "john_doe",
            "firstName": "John",
            "lastName": "Doe",
            "profilePictureUrl": "https://cdn.nexgate.com/profiles/john_doe.jpg",
            "isVerified": true,
            "votedAt": "2025-12-11T10:25:30"
          },
          {
            "userId": "987e6543-e21b-12d3-a456-426614174999",
            "userName": "jane_smith",
            "firstName": "Jane",
            "lastName": "Smith",
            "profilePictureUrl": "https://cdn.nexgate.com/profiles/jane_smith.jpg",
            "isVerified": false,
            "votedAt": "2025-12-11T10:20:15"
          }
        ],
        "pagination": {
          "currentPage": 1,
          "pageSize": 50,
          "totalPages": 2,
          "totalElements": 75,
          "hasNext": true,
          "hasPrevious": false
        }
      }
    }
    

    Success Response Message: "Voters retrieved successfully"

    Standard Error Types:

    • 400 BAD_REQUEST: Anonymous poll (voter list not available)
    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Not post author/collaborator
    • 404 NOT_FOUND: Post or option not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Error Response Examples:

    Anonymous Poll (400):

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Voters not available",
      "action_time": "2025-12-11T10:30:45",
      "data": "This is an anonymous poll. Voter identities are hidden."
    }
    

    Not Post Author (403):

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Access denied",
      "action_time": "2025-12-11T10:30:45",
      "data": "Only the post author and collaborators can view voter lists"
    }
    

    Use Case Examples:

    Example 1: View Voters as Post Author

    GET /e-social/posts/550e8400-e29b-41d4-a716-446655440000/poll-voters/option-uuid-1
    
    User is post author
    Poll is non-anonymous
    Option has 75 voters
    
    Result: Returns paginated list of 75 users who voted for this option
    

    Example 2: View Voters as Collaborator

    GET /e-social/posts/660e8400-e29b-41d4-a716-446655440001/poll-voters/option-uuid-2
    
    User is accepted collaborator
    Poll is non-anonymous
    
    Result: Returns voter list (collaborators have same access as author)
    

    Example 3: Anonymous Poll - Access Denied

    GET /e-social/posts/770e8400-e29b-41d4-a716-446655440002/poll-voters/option-uuid-3
    
    User is post author
    Poll is anonymous (isAnonymous = true)
    
    Result: Error 400 - Voter identities hidden for anonymous polls
    

    Example 4: Regular User - Access Denied

    GET /e-social/posts/880e8400-e29b-41d4-a716-446655440003/poll-voters/option-uuid-1
    
    User is neither author nor collaborator
    Poll is non-anonymous
    
    Result: Error 403 - Only author/collaborators can view voters
    

    Comment Endpoints (43-52)

    43. Create Comment

    Purpose: Create a comment or reply on a post

    Endpoint: POST {base_url}/e-social/posts/{postId}/comments

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Creates top-level comment if parentCommentId is null
    • Creates nested reply if parentCommentId provided
    • Increments post's commentsCount by 1
    • Sends notification to post author (unless commenting on own post)
    • For replies, notifies parent comment author
    • Automatically parses @mentions in comment content
    • All mentioned users receive notifications
    • Respects post's whoCanComment privacy setting
    • Supports nested replies (unlimited depth)
    • Updates post's engagement metrics

    Business Rules:

    1. Permission Check: Post must allow comments (whoCanComment setting)
    2. Visibility Check: Must have permission to view post to comment
    3. Blocking: Cannot comment on posts from blocked users
    4. Nesting: Supports unlimited reply depth (replies to replies to replies...)
    5. Mentions: All @mentioned users notified
    6. Notification: Post author and parent comment author notified
    7. Content Length: Min 1, Max 2000 characters
    8. Spam Prevention: Rate limited (max 10 comments per minute per user)
    9. Edit Window: Can edit within 15 minutes of posting
    10. Deleted Posts: Cannot comment on deleted posts

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the post to comment on Must be valid UUID format

    Request JSON Sample (Top-level Comment):

    {
      "content": "Great post! @john_doe you should check this out",
      "parentCommentId": null
    }
    

    Request JSON Sample (Nested Reply):

    {
      "content": "I completely agree with you @jane_doe! 💯",
      "parentCommentId": "660e8400-e29b-41d4-a716-446655440001"
    }
    

    Request Body Parameters:

    Parameter Type Required Description Validation
    content string Yes Comment text Min: 1, Max: 2000 characters
    parentCommentId string No UUID of parent comment for replies Must be valid UUID if provided, must belong to same post

    Success Response: Returns CommentResponse object

    CommentResponse Structure:

    {
      "id": "770e8400-e29b-41d4-a716-446655440001",
      "postId": "550e8400-e29b-41d4-a716-446655440000",
      "author": {
        "id": "123e4567-e89b-12d3-a456-426614174000",
        "userName": "john_doe",
        "firstName": "John",
        "lastName": "Doe",
        "profilePictureUrl": "https://cdn.nexgate.com/profiles/john_doe.jpg",
        "isVerified": true
      },
      "content": "Great post! @john_doe you should check this out",
      "contentParsed": {
        "text": "Great post! @john_doe you should check this out",
        "entities": [
          {
            "type": "MENTION",
            "text": "@john_doe",
            "startIndex": 12,
            "endIndex": 21,
            "user": {
              "id": "987e6543-e21b-12d3-a456-426614174999",
              "userName": "john_doe"
            }
          }
        ]
      },
      "parentCommentId": null,
      "replyCount": 5,
      "likesCount": 12,
      "isPinned": false,
      "isEdited": false,
      "userInteraction": {
        "hasLiked": false
      },
      "createdAt": "2025-12-11T10:30:45",
      "updatedAt": null
    }
    

    Success Response Message: "Comment created successfully"

    Standard Error Types:

    • 400 BAD_REQUEST: Invalid content, parent comment not found, or spam detected
    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot comment (permissions, blocked, disabled comments)
    • 404 NOT_FOUND: Post not found
    • 422 UNPROCESSABLE_ENTITY: Validation errors (content too long/short)
    • 429 TOO_MANY_REQUESTS: Rate limit exceeded
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Error Response Examples:

    Comments Disabled (403):

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Cannot comment on this post",
      "action_time": "2025-12-11T10:30:45",
      "data": "The author has disabled comments for this post"
    }
    

    Comments Followers Only (403):

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Cannot comment on this post",
      "action_time": "2025-12-11T10:30:45",
      "data": "Only followers can comment on this post. Follow the author to comment."
    }
    

    Invalid Parent Comment (400):

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Invalid parent comment",
      "action_time": "2025-12-11T10:30:45",
      "data": "Parent comment does not belong to this post"
    }
    

    Rate Limit Exceeded (429):

    {
      "success": false,
      "httpStatus": "TOO_MANY_REQUESTS",
      "message": "Too many comments",
      "action_time": "2025-12-11T10:30:45",
      "data": "Maximum 10 comments per minute. Please wait 30 seconds."
    }
    

    Use Case Examples:

    Example 1: Top-Level Comment

    POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/comments
    
    Body: {
      "content": "This is exactly what I needed! Thank you 🙏",
      "parentCommentId": null
    }
    
    Result: Top-level comment created, post author notified, commentsCount++
    

    Example 2: Reply to Comment

    POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/comments
    
    Body: {
      "content": "Glad you found it helpful! @jane_doe",
      "parentCommentId": "660e8400-e29b-41d4-a716-446655440001"
    }
    
    Result: Nested reply created, parent comment author + @jane_doe notified
    

    Example 3: Nested Reply (Reply to Reply)

    POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/comments
    
    Body: {
      "content": "Same here! Following this thread 👀",
      "parentCommentId": "770e8400-e29b-41d4-a716-446655440002"
    }
    
    Result: 2nd-level nested reply created, forms conversation thread
    

    44. Get Comments

    Purpose: Retrieve all top-level comments for a post (paginated)

    Endpoint: GET {base_url}/e-social/posts/{postId}/comments

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Returns top-level comments only (parentCommentId = null)
    • Sorted by: Pinned first, then by createdAt (newest first)
    • Includes replyCount for each comment
    • Respects post visibility (must be able to view post)
    • Paginated for performance
    • Each comment includes author info and engagement metrics
    • Does NOT include replies (use Get Replies endpoint)

    Business Rules:

    1. Top-Level Only: Returns only direct comments on post, not replies
    2. Pinned Priority: Pinned comments always appear first
    3. Sorting: After pinned, sorted by newest first
    4. Reply Count: Each comment shows number of replies
    5. Pagination: Default 20 per page, max 100
    6. Visibility: Same visibility rules as viewing the post

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the post Must be valid UUID format

    Query Parameters:

    Parameter Type Required Description Validation Default
    page integer No Page number (1-indexed) Min: 1 1
    size integer No Items per page Min: 1, Max: 100 20

    Success Response: Returns array of CommentResponse objects

    Success Response Message: "Comments retrieved successfully"

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot view post
    • 404 NOT_FOUND: Post not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    45. Get Comment

    Purpose: Retrieve a single comment by ID with full details

    Endpoint: GET {base_url}/e-social/posts/comments/{commentId}

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Returns full comment details including author, content, engagement
    • Includes parsed content with @mentions
    • Shows user's interaction state (hasLiked)
    • Respects post visibility rules
    • Returns parent comment info if it's a reply

    Business Rules:

    1. Visibility: Must be able to view parent post
    2. Deleted: Returns 404 if comment deleted
    3. Full Details: Includes all engagement metrics
    4. Context: Can get comment without knowing postId

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    commentId string Yes UUID of the comment Must be valid UUID format

    Success Response: Returns CommentResponse object

    Success Response Message: "Comment retrieved successfully"

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot view post
    • 404 NOT_FOUND: Comment not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    46. Get Replies

    Purpose: Retrieve all replies to a specific comment (nested comments)

    Endpoint: GET {base_url}/e-social/posts/comments/{commentId}/replies

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Returns all direct replies to specified comment
    • Sorted by createdAt (oldest first for conversation flow)
    • Each reply can have its own replies (nested)
    • Paginated for performance
    • Includes reply count for each reply (supports infinite nesting)

    Business Rules:

    1. Direct Replies Only: Returns immediate children, not grandchildren
    2. Conversation Order: Sorted oldest first (chronological conversation)
    3. Nested Support: Each reply shows its own replyCount
    4. Recursive Loading: Frontend loads nested replies on-demand
    5. Pagination: Default 50 per page (comments usually have fewer replies)

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    commentId string Yes UUID of parent comment Must be valid UUID format

    Query Parameters:

    Parameter Type Required Description Validation Default
    page integer No Page number (1-indexed) Min: 1 1
    size integer No Items per page Min: 1, Max: 100 50

    Success Response: Returns array of CommentResponse objects

    Success Response Message: "Replies retrieved successfully"

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot view post
    • 404 NOT_FOUND: Comment not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    47. Update Comment

    Purpose: Edit an existing comment's content

    Endpoint: PUT {base_url}/e-social/posts/comments/{commentId}

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Updates comment content
    • Sets isEdited flag to true
    • Updates updatedAt timestamp
    • Preserves original createdAt timestamp
    • Re-parses @mentions in updated content
    • Sends notifications to newly mentioned users
    • Only comment author can edit
    • Edit window: 15 minutes from creation (configurable)

    Business Rules:

    1. Author Only: Only comment author can edit
    2. Time Window: Can only edit within 15 minutes of creation
    3. Edit Flag: isEdited set to true (visible to users)
    4. Content Validation: Same rules as creation (1-2000 chars)
    5. Mention Updates: New mentions trigger notifications
    6. No History: Only current version stored (no edit history)

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    commentId string Yes UUID of comment to edit Must be valid UUID format

    Request JSON Sample:

    {
      "content": "Updated comment with correction! @new_user check this"
    }
    

    Request Body Parameters:

    Parameter Type Required Description Validation
    content string Yes Updated comment text Min: 1, Max: 2000 characters

    Success Response: Returns updated CommentResponse object with isEdited = true

    Success Response Message: "Comment updated successfully"

    Standard Error Types:

    • 400 BAD_REQUEST: Edit window expired (>15 minutes)
    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Not comment author
    • 404 NOT_FOUND: Comment not found
    • 422 UNPROCESSABLE_ENTITY: Validation errors
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Error Response Examples:

    Edit Window Expired (400):

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Cannot edit comment",
      "action_time": "2025-12-11T10:30:45",
      "data": "Comments can only be edited within 15 minutes of posting"
    }
    

    Not Comment Author (403):

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Cannot edit comment",
      "action_time": "2025-12-11T10:30:45",
      "data": "Only the comment author can edit this comment"
    }
    

    48. Delete Comment

    Purpose: Soft delete a comment (marks as deleted, preserves data)

    Endpoint: DELETE {base_url}/e-social/posts/comments/{commentId}

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Performs soft delete: Sets isDeleted flag, doesn't remove from DB
    • Decrements post's commentsCount by 1
    • Replies remain visible but show "[deleted]" as parent
    • Comment author and post author can delete
    • Preserves comment data for audit/analytics
    • Updates comment content to "[deleted]" in responses
    • No notification sent

    Business Rules:

    1. Who Can Delete: Comment author OR post author
    2. Soft Delete: Data retained in database
    3. Replies Preserved: Child replies remain visible
    4. Parent Reference: Replies show "[deleted]" as parent content
    5. Counter Update: Post's comment count decremented
    6. Cascade Option: Post author can cascade delete all replies (optional)
    7. Silent Operation: No notifications sent

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    commentId string Yes UUID of comment to delete Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Comment deleted successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Not comment author or post author
    • 404 NOT_FOUND: Comment not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Use Case Examples:

    Example 1: Author Deletes Own Comment

    DELETE /e-social/posts/comments/770e8400-e29b-41d4-a716-446655440001
    
    User is comment author
    Comment has 3 replies
    Result: Comment deleted, replies preserved, show "[deleted]" as parent
    

    Example 2: Post Author Deletes Inappropriate Comment

    DELETE /e-social/posts/comments/880e8400-e29b-41d4-a716-446655440002
    
    User is post author (not comment author)
    Comment violates community guidelines
    Result: Comment deleted by post author, content moderation applied
    

    49. Pin Comment

    Purpose: Pin a comment to the top of post's comment section (post author only)

    Endpoint: POST {base_url}/e-social/posts/{postId}/comments/{commentId}/pin

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Pins comment to top of comment list
    • Sets isPinned flag to true
    • Only one comment can be pinned per post
    • If another comment already pinned, it gets unpinned automatically
    • Post author or collaborators can pin
    • Pinned comment always appears first in GET /comments
    • Sends notification to comment author

    Business Rules:

    1. Post Author Only: Only post author/collaborators can pin
    2. Single Pin: Only 1 comment pinned at a time
    3. Auto-Unpin: Pinning new comment unpins previous
    4. Top-Level Only: Can only pin top-level comments (not replies)
    5. Notification: Comment author notified of pin
    6. Visibility: Pinned indicator shown to all users

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    postId string Yes UUID of the post Must be valid UUID format
    commentId string Yes UUID of comment to pin Must be valid UUID, must be top-level comment

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Comment pinned successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 400 BAD_REQUEST: Cannot pin replies, only top-level comments
    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Not post author/collaborator
    • 404 NOT_FOUND: Post or comment not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    Error Response Examples:

    Cannot Pin Reply (400):

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Cannot pin reply",
      "action_time": "2025-12-11T10:30:45",
      "data": "Only top-level comments can be pinned. Replies cannot be pinned."
    }
    

    Use Case Examples:

    Example 1: Pin Important Comment

    POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/comments/770e8400-e29b-41d4-a716-446655440001/pin
    
    Post author pins helpful comment
    Result: Comment appears at top, comment author notified, isPinned = true
    

    Example 2: Pin New Comment (Auto-Unpins Previous)

    POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/comments/880e8400-e29b-41d4-a716-446655440002/pin
    
    Already have pinned comment
    Result: Previous comment unpinned automatically, new comment pinned
    

    50. Unpin Comment

    Purpose: Remove pin from a comment

    Endpoint: DELETE {base_url}/e-social/posts/comments/{commentId}/pin

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Removes pin from comment
    • Sets isPinned flag to false
    • Comment returns to normal sort order (by createdAt)
    • Post author or collaborators can unpin
    • No notification sent
    • Idempotent: Unpinning non-pinned comment returns success

    Business Rules:

    1. Post Author Only: Only post author/collaborators can unpin
    2. Silent Operation: No notification sent
    3. Idempotent: Safe to call on non-pinned comments
    4. Sort Restoration: Comment returns to chronological position

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    commentId string Yes UUID of comment to unpin Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Comment unpinned successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Not post author/collaborator
    • 404 NOT_FOUND: Comment not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    51. Like Comment

    Purpose: Add a like to a comment

    Endpoint: POST {base_url}/e-social/posts/comments/{commentId}/like

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Adds current user's like to comment
    • Increments comment's likesCount by 1
    • Sends notification to comment author (unless self-like)
    • Updates user's interaction state (hasLiked = true)
    • Idempotent: Multiple like attempts don't create duplicates
    • Must be able to view parent post to like comment

    Business Rules:

    1. Visibility: Must have access to parent post
    2. Blocking: Cannot like comments from blocked users
    3. Deleted: Cannot like deleted comments
    4. Idempotent: Safe to call multiple times
    5. Notification: Comment author notified (unless self-like)
    6. Counter Update: Atomic increment

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    commentId string Yes UUID of comment to like Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Comment liked successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 403 FORBIDDEN: Cannot like (blocked, no post access)
    • 404 NOT_FOUND: Comment not found
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    52. Unlike Comment

    Purpose: Remove a like from a comment

    Endpoint: DELETE {base_url}/e-social/posts/comments/{commentId}/like

    Access Level: 🔒 Protected (Requires Bearer Token Authentication)

    Authentication: Bearer Token

    Behavior:

    • Removes current user's like from comment
    • Decrements comment's likesCount by 1
    • No notification sent (silent operation)
    • Updates user's interaction state (hasLiked = false)
    • Idempotent: Multiple unlike attempts safe
    • Can unlike even if comment deleted or user blocked

    Business Rules:

    1. Silent Operation: No notification sent
    2. Always Allowed: Can unlike even if blocked or comment deleted
    3. Idempotent: Safe to call multiple times
    4. Counter Decrement: Atomic decrement

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication
    Content-Type string Yes Must be application/json

    Path Parameters:

    Parameter Type Required Description Validation
    commentId string Yes UUID of comment to unlike Must be valid UUID format

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Comment unliked successfully",
      "action_time": "2025-12-11T10:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Authentication required
    • 404 NOT_FOUND: Comment not found (permanent deletion)
    • 500 INTERNAL_SERVER_ERROR: Unexpected errors

    53. Share Post

    Purpose: Record a post share action and track which platform was used for sharing

    Endpoint: POST {base_url}/api/v1/e-social/posts/{postId}/share

    Access Level: 🔒 Protected (Requires Authentication)

    Authentication: Bearer Token

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication

    Path Parameters:

    Parameter Type Required Description Validation
    postId UUID Yes Unique identifier of the post to share Valid UUID format

    Query Parameters:

    Parameter Type Required Description Validation Default
    platform string No Platform where the post is being shared Enum: WHATSAPP, TWITTER, FACEBOOK, INSTAGRAM, TELEGRAM, COPY_LINK, OTHER , IN_APP OTHER

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Post shared successfully",
      "action_time": "2025-12-29T14:30:45",
      "data": null
    }
    

    Success Response Fields:

    Field Description
    success Indicates if the share was recorded successfully
    message Confirmation message

    Error Response JSON Samples:

    Post Not Found:

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Post not found",
      "action_time": "2025-12-29T14:30:45",
      "data": null
    }
    

    Post Not Published:

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Can only share published posts",
      "action_time": "2025-12-29T14:30:45",
      "data": null
    }
    

    Unauthorized:

    {
      "success": false,
      "httpStatus": "UNAUTHORIZED",
      "message": "User not authenticated",
      "action_time": "2025-12-29T14:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 400 BAD_REQUEST: Post not found or post is not published
    • 401 UNAUTHORIZED: Missing or invalid authentication token

    Share Platform Values:

    Platform Description
    WHATSAPP Shared via WhatsApp
    TWITTER Shared via Twitter/X
    FACEBOOK Shared via Facebook
    INSTAGRAM Shared via Instagram
    TELEGRAM Shared via Telegram
    COPY_LINK User copied the post link
    OTHER Shared via other means or unspecified

    Usage Notes:

    • Unlike likes and bookmarks, shares can be recorded multiple times by the same user
    • Each share is tracked separately for analytics purposes
    • The share count on the post increments with each share action
    • Invalid platform values default to OTHER

    Usage Examples:

    # Share post to WhatsApp
    curl -X POST "{base_url}/api/v1/e-social/posts/550e8400-e29b-41d4-a716-446655440000/share?platform=WHATSAPP" \
      -H "Authorization: Bearer {token}"
    
    # Share post to Twitter
    curl -X POST "{base_url}/api/v1/e-social/posts/550e8400-e29b-41d4-a716-446655440000/share?platform=TWITTER" \
      -H "Authorization: Bearer {token}"
    
    # Record copy link action
    curl -X POST "{base_url}/api/v1/e-social/posts/550e8400-e29b-41d4-a716-446655440000/share?platform=COPY_LINK" \
      -H "Authorization: Bearer {token}"
    
    # Generic share (defaults to OTHER)
    curl -X POST "{base_url}/api/v1/e-social/posts/550e8400-e29b-41d4-a716-446655440000/share" \
      -H "Authorization: Bearer {token}"
    

    Response in Post Object:

    After sharing, the post's engagement and user interaction data will reflect the share:

    {
      "engagement": {
        "likesCount": 42,
        "commentsCount": 15,
        "repostsCount": 8,
        "quotesCount": 3,
        "bookmarksCount": 12,
        "sharesCount": 25,
        "viewsCount": 1500,
        "canLike": true,
        "canComment": true,
        "canRepost": true,
        "canShare": true
      },
      "userInteraction": {
        "hasLiked": true,
        "hasBookmarked": false,
        "hasReposted": false,
        "hasCommented": true,
        "hasViewed": true,
        "hasShared": true
      }
    }
    

    54. Report Post

    Purpose: Report a post for violating community guidelines or platform rules

    Endpoint: POST {base_url}/api/v1/e-social/posts/{postId}/report

    Access Level: 🔒 Protected (Requires Authentication)

    Authentication: Bearer Token

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for authentication

    Path Parameters:

    Parameter Type Required Description Validation
    postId UUID Yes Unique identifier of the post to report Valid UUID format

    Request JSON Sample:

    {
      "reason": "HATE_SPEECH",
      "description": "This post contains discriminatory language targeting a specific group."
    }
    

    Request Body Parameters:

    Parameter Type Required Description Validation
    reason string Yes Reason for reporting Enum: SPAM, MISLEADING_INFO, FALSE_INFORMATION, HATE_SPEECH, HARASSMENT, BULLYING, THREATS, NUDITY, SEXUAL_CONTENT, VIOLENCE, GRAPHIC_CONTENT, ILLEGAL_GOODS, FRAUD, SCAM, INTELLECTUAL_PROPERTY, SELF_HARM, SUICIDE, PRIVACY_VIOLATION, PERSONAL_INFO_EXPOSED, IMPERSONATION, FAKE_ACCOUNT, UNDERAGE_USER, OTHER
    description string No Additional details about the report Max 1000 characters

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Post reported successfully",
      "action_time": "2025-12-29T15:30:45",
      "data": null
    }
    

    Success Response Fields:

    Field Description
    success Indicates if the report was submitted successfully
    message Confirmation message

    Error Response JSON Sample:

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "You have already reported this post",
      "action_time": "2025-12-29T15:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 400 BAD_REQUEST: Post not found, already reported, or attempting to report own post
    • 401 UNAUTHORIZED: Missing or invalid authentication token

    55. Get Post Reports (Admin)

    Purpose: Retrieve all reports for a specific post (Admin only)

    Endpoint: GET {base_url}/api/v1/e-social/posts/{postId}/reports

    Access Level: 🔒 Protected (Admin Only)

    Authentication: Bearer Token (Admin role required)

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for admin authentication

    Path Parameters:

    Parameter Type Required Description Validation
    postId UUID Yes Unique identifier of the post Valid UUID format

    Query Parameters:

    Parameter Type Required Description Validation Default
    page integer No Page number for pagination Min: 1 1
    size integer No Number of results per page Min: 1, Max: 100 20

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Post reports retrieved successfully",
      "action_time": "2025-12-29T15:30:45",
      "data": {
        "content": [
          {
            "id": "550e8400-e29b-41d4-a716-446655440000",
            "postId": "660e8400-e29b-41d4-a716-446655440001",
            "reporter": {
              "id": "770e8400-e29b-41d4-a716-446655440002",
              "userName": "john_doe",
              "firstName": "John",
              "lastName": "Doe",
              "profilePictureUrl": "https://storage.example.com/profiles/john.jpg"
            },
            "postAuthor": {
              "id": "880e8400-e29b-41d4-a716-446655440003",
              "userName": "jane_smith",
              "firstName": "Jane",
              "lastName": "Smith",
              "profilePictureUrl": "https://storage.example.com/profiles/jane.jpg"
            },
            "reason": "HATE_SPEECH",
            "description": "This post contains discriminatory language",
            "status": "PENDING",
            "review": null,
            "createdAt": "2025-12-29T14:00:00",
            "updatedAt": "2025-12-29T14:00:00"
          },
          {
            "id": "550e8400-e29b-41d4-a716-446655440099",
            "postId": "660e8400-e29b-41d4-a716-446655440001",
            "reporter": {
              "id": "990e8400-e29b-41d4-a716-446655440004",
              "userName": "alex_wilson",
              "firstName": "Alex",
              "lastName": "Wilson",
              "profilePictureUrl": null
            },
            "postAuthor": {
              "id": "880e8400-e29b-41d4-a716-446655440003",
              "userName": "jane_smith",
              "firstName": "Jane",
              "lastName": "Smith",
              "profilePictureUrl": "https://storage.example.com/profiles/jane.jpg"
            },
            "reason": "HARASSMENT",
            "description": "Targeted harassment in the comments",
            "status": "ACTION_TAKEN",
            "review": {
              "reviewedBy": "aa0e8400-e29b-41d4-a716-446655440005",
              "reviewerName": "Admin User",
              "reviewedAt": "2025-12-29T15:00:00",
              "adminNotes": "Verified harassment, post removed",
              "actionTaken": "POST_REMOVED"
            },
            "createdAt": "2025-12-29T13:00:00",
            "updatedAt": "2025-12-29T15:00:00"
          }
        ],
        "pageable": {
          "pageNumber": 0,
          "pageSize": 20,
          "sort": {
            "empty": true,
            "sorted": false,
            "unsorted": true
          },
          "offset": 0,
          "paged": true,
          "unpaged": false
        },
        "last": true,
        "totalPages": 1,
        "totalElements": 2,
        "first": true,
        "size": 20,
        "number": 0,
        "numberOfElements": 2,
        "empty": false
      }
    }
    

    Success Response Fields:

    Field Description
    content Array of report objects for the post
    content[].id Unique identifier of the report
    content[].postId ID of the reported post
    content[].reporter Information about the user who filed the report
    content[].postAuthor Information about the post author
    content[].reason Reason for the report
    content[].description Additional details provided by reporter
    content[].status Current status of the report
    content[].review Review information if report has been reviewed
    totalElements Total number of reports for this post

    Error Response JSON Sample:

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Access denied",
      "action_time": "2025-12-29T15:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Missing or invalid authentication token
    • 403 FORBIDDEN: User does not have admin role

    56. Get All Reports (Admin)

    Purpose: Retrieve all reports with optional filters for status, reason, and date range (Admin only)

    Endpoint: GET {base_url}/api/v1/e-social/posts/reports

    Access Level: 🔒 Protected (Admin Only)

    Authentication: Bearer Token (Admin role required)

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for admin authentication

    Query Parameters:

    Parameter Type Required Description Validation Default
    status string No Filter by report status Enum: PENDING, UNDER_REVIEW, ACTION_TAKEN, DISMISSED, ESCALATED null (all)
    reason string No Filter by report reason Enum: SPAM, MISLEADING_INFO, FALSE_INFORMATION, HATE_SPEECH, HARASSMENT, BULLYING, THREATS, NUDITY, SEXUAL_CONTENT, VIOLENCE, GRAPHIC_CONTENT, ILLEGAL_GOODS, FRAUD, SCAM, INTELLECTUAL_PROPERTY, SELF_HARM, SUICIDE, PRIVACY_VIOLATION, PERSONAL_INFO_EXPOSED, IMPERSONATION, FAKE_ACCOUNT, UNDERAGE_USER, OTHER null (all)
    startDate datetime No Filter reports created after this date ISO 8601 format null
    endDate datetime No Filter reports created before this date ISO 8601 format null
    page integer No Page number for pagination Min: 1 1
    size integer No Number of results per page Min: 1, Max: 100 20

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Reports retrieved successfully",
      "action_time": "2025-12-29T15:30:45",
      "data": {
        "content": [
          {
            "id": "550e8400-e29b-41d4-a716-446655440000",
            "postId": "660e8400-e29b-41d4-a716-446655440001",
            "reporter": {
              "id": "770e8400-e29b-41d4-a716-446655440002",
              "userName": "john_doe",
              "firstName": "John",
              "lastName": "Doe",
              "profilePictureUrl": "https://storage.example.com/profiles/john.jpg"
            },
            "postAuthor": {
              "id": "880e8400-e29b-41d4-a716-446655440003",
              "userName": "jane_smith",
              "firstName": "Jane",
              "lastName": "Smith",
              "profilePictureUrl": "https://storage.example.com/profiles/jane.jpg"
            },
            "reason": "SPAM",
            "description": "This account is posting spam content repeatedly",
            "status": "PENDING",
            "review": null,
            "createdAt": "2025-12-29T14:00:00",
            "updatedAt": "2025-12-29T14:00:00"
          }
        ],
        "pageable": {
          "pageNumber": 0,
          "pageSize": 20,
          "sort": {
            "empty": true,
            "sorted": false,
            "unsorted": true
          },
          "offset": 0,
          "paged": true,
          "unpaged": false
        },
        "last": true,
        "totalPages": 1,
        "totalElements": 1,
        "first": true,
        "size": 20,
        "number": 0,
        "numberOfElements": 1,
        "empty": false
      }
    }
    

    Success Response Fields:

    Field Description
    content Array of report objects matching the filters
    content[].id Unique identifier of the report
    content[].postId ID of the reported post
    content[].reporter Information about the user who filed the report
    content[].postAuthor Information about the post author
    content[].reason Reason for the report
    content[].status Current status: PENDING, UNDER_REVIEW, ACTION_TAKEN, DISMISSED, ESCALATED
    totalElements Total number of matching reports
    totalPages Total number of pages

    Error Response JSON Sample:

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Access denied",
      "action_time": "2025-12-29T15:30:45",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Missing or invalid authentication token
    • 403 FORBIDDEN: User does not have admin role

    57. Review Report (Admin)

    Purpose: Review and update the status of a report (Admin only)

    Endpoint: PATCH {base_url}/api/v1/e-social/posts/reports/{reportId}/review

    Access Level: 🔒 Protected (Admin Only)

    Authentication: Bearer Token (Admin role required)

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for admin authentication

    Path Parameters:

    Parameter Type Required Description Validation
    reportId UUID Yes Unique identifier of the report Valid UUID format

    Request JSON Sample:

    {
      "status": "ACTION_TAKEN",
      "adminNotes": "Verified hate speech violation. Post has been removed and user warned.",
      "actionTaken": "POST_REMOVED_USER_WARNED"
    }
    

    Request Body Parameters:

    Parameter Type Required Description Validation
    status string Yes New status for the report Enum: PENDING, UNDER_REVIEW, ACTION_TAKEN, DISMISSED, ESCALATED
    adminNotes string No Internal notes about the review Max 500 characters
    actionTaken string No Description of action taken Max 50 characters

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Report reviewed successfully",
      "action_time": "2025-12-29T16:00:00",
      "data": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "postId": "660e8400-e29b-41d4-a716-446655440001",
        "reporter": {
          "id": "770e8400-e29b-41d4-a716-446655440002",
          "userName": "john_doe",
          "firstName": "John",
          "lastName": "Doe",
          "profilePictureUrl": "https://storage.example.com/profiles/john.jpg"
        },
        "postAuthor": {
          "id": "880e8400-e29b-41d4-a716-446655440003",
          "userName": "jane_smith",
          "firstName": "Jane",
          "lastName": "Smith",
          "profilePictureUrl": "https://storage.example.com/profiles/jane.jpg"
        },
        "reason": "HATE_SPEECH",
        "description": "This post contains discriminatory language",
        "status": "ACTION_TAKEN",
        "review": {
          "reviewedBy": "aa0e8400-e29b-41d4-a716-446655440005",
          "reviewerName": "Admin User",
          "reviewedAt": "2025-12-29T16:00:00",
          "adminNotes": "Verified hate speech violation. Post has been removed and user warned.",
          "actionTaken": "POST_REMOVED_USER_WARNED"
        },
        "createdAt": "2025-12-29T14:00:00",
        "updatedAt": "2025-12-29T16:00:00"
      }
    }
    

    Success Response Fields:

    Field Description
    id Unique identifier of the report
    postId ID of the reported post
    reporter Information about the user who filed the report
    postAuthor Information about the post author
    reason Reason for the report
    status Updated status of the report
    review Review details including reviewer info, notes, and action taken
    review.reviewedBy UUID of the admin who reviewed
    review.reviewerName Name of the admin who reviewed
    review.reviewedAt Timestamp of the review
    review.adminNotes Internal notes from the admin
    review.actionTaken Action taken on the report

    Error Response JSON Sample:

    {
      "success": false,
      "httpStatus": "BAD_REQUEST",
      "message": "Report not found",
      "action_time": "2025-12-29T16:00:00",
      "data": null
    }
    

    Standard Error Types:

    • 400 BAD_REQUEST: Report not found or invalid status
    • 401 UNAUTHORIZED: Missing or invalid authentication token
    • 403 FORBIDDEN: User does not have admin role

    58. Get Report Statistics (Admin)

    Purpose: Retrieve aggregate statistics about reports (Admin only)

    Endpoint: GET {base_url}/api/v1/e-social/posts/reports/stats

    Access Level: 🔒 Protected (Admin Only)

    Authentication: Bearer Token (Admin role required)

    Request Headers:

    Header Type Required Description
    Authorization string Yes Bearer token for admin authentication

    Success Response JSON Sample:

    {
      "success": true,
      "httpStatus": "OK",
      "message": "Report statistics retrieved successfully",
      "action_time": "2025-12-29T16:30:00",
      "data": {
        "totalReports": 1250,
        "pendingReports": 45,
        "underReviewReports": 12,
        "actionTakenReports": 890,
        "dismissedReports": 298,
        "escalatedReports": 5,
        "reportsByReason": {
          "SPAM": 320,
          "HATE_SPEECH": 180,
          "HARASSMENT": 150,
          "MISLEADING_INFO": 120,
          "NUDITY": 95,
          "VIOLENCE": 85,
          "SCAM": 75,
          "FALSE_INFORMATION": 60,
          "BULLYING": 55,
          "SEXUAL_CONTENT": 40,
          "PRIVACY_VIOLATION": 30,
          "IMPERSONATION": 20,
          "OTHER": 20
        }
      }
    }
    

    Success Response Fields:

    Field Description
    totalReports Total number of reports in the system
    pendingReports Number of reports awaiting review
    underReviewReports Number of reports currently being reviewed
    actionTakenReports Number of reports where action was taken
    dismissedReports Number of reports that were dismissed
    escalatedReports Number of reports escalated for further review
    reportsByReason Object containing count of reports grouped by reason

    Error Response JSON Sample:

    {
      "success": false,
      "httpStatus": "FORBIDDEN",
      "message": "Access denied",
      "action_time": "2025-12-29T16:30:00",
      "data": null
    }
    

    Standard Error Types:

    • 401 UNAUTHORIZED: Missing or invalid authentication token
    • 403 FORBIDDEN: User does not have admin role

    Quick Reference Guide

    Common HTTP Status Codes

    • 200 OK: Successful GET/POST/PUT/DELETE request
    • 400 Bad Request: Invalid request data or business rule violation
    • 401 Unauthorized: Authentication required/failed
    • 404 Not Found: Resource not found
    • 422 Unprocessable Entity: Validation errors
    • 500 Internal Server Error: Server error

    Authentication

    • Bearer Token: Include Authorization: Bearer your_token in headers

    Data Format Standards

    • Dates: Use ISO 8601 format (2025-12-11T14:30:00Z)
    • IDs: UUID format (e.g., 550e8400-e29b-41d4-a716-446655440000)
    • Pagination: 1-indexed pages (page=1 for first page), default size=20

    Post Type Values

    • REGULAR: Standard text/media post
    • POLL: Poll post with voting options

    Post Status Values

    • DRAFT: Unpublished draft
    • SCHEDULED: Scheduled for future publication
    • PUBLISHED: Live and visible
    • DELETED: Soft deleted

    Visibility Levels

    • PUBLIC: Anyone can see
    • FOLLOWERS: Only followers can see
    • MENTIONED: Only mentioned users can see
    • PRIVATE: Only author can see

    Permission Levels

    • EVERYONE: All users
    • FOLLOWERS: Only followers
    • MENTIONED: Only mentioned users (for comments)
    • DISABLED: Feature disabled