Appearance
ImBoy Moment API Contract (v1)
Last Updated: 2026-03-08
Status: Long-lived protocol contract
Scope: Moment contract across server, app, and admin frontend
Source of truth:src/imboy_router.erl+src/api/moment_handler.erl
Note:v1refers to the contract version, not the application release version.
Related docs:docs/reference/rest-api.md,docs/reference/websocket-api-2.md,docs/api/envelope.schema.json
1. Scope
This document defines the first stable contract for Moment (朋友圈) across:
- Server:
imboy - App:
imboyapp - Admin:
imboy-admin-frontend
2. Global Rules
2.1 Envelope
All responses must follow the canonical envelope:
json
{
"code": 0,
"msg": "ok",
"sv_ts": 1771481621000,
"payload": {}
}2.2 ID Rules (TSID)
- Client inputs use TSID integer (as string) at API boundary.
- API converts to integer before DB operations.
- API outputs return TSID integer directly.
- DB stores BIGINT IDs (generated by
elib_tsid).
2.3 Parameter Resolution (Hard Rule)
For endpoints with path bindings:
- Path param has highest priority.
- Body/query fallback is compatibility-only behavior.
2.4 Content Access Rule (Visibility)
Moment post visibility enum:
0public: all authenticated users.1friends-only: only confirmed friends.2private: author only.3include-list: only users in ACL allowlist.4exclude-list: all friends except users in ACL blocklist.
Additional hard constraints:
- Block/denylist relationship always wins over visibility.
- Deleted/disabled posts are never readable by normal users.
- Admin may access hidden content only via admin APIs.
3. Data Schemas
3.1 Moment Post (payload)
json
{
"id": 1838294017982464,
"author_uid": 1838294017982465,
"content": "text content",
"visibility": 1,
"allow_comment": true,
"media": [
{
"type": "image",
"url": "https://...",
"width": 1080,
"height": 1440,
"size": 235012
},
{
"type": "video",
"url": "https://...",
"cover_url": "https://...",
"duration_ms": 15300,
"width": 1080,
"height": 1920,
"size": 2940123
}
],
"stats": {
"like_count": 3,
"comment_count": 7
},
"created_at": "2026-02-26T09:00:00Z",
"updated_at": "2026-02-26T09:00:00Z"
}3.2 ACL Entry
json
{
"uid": 1838294017982465,
"acl_type": "allow|deny"
}3.3 Comment
json
{
"id": 1838294017982466,
"moment_id": 1838294017982464,
"user_id": 1838294017982465,
"reply_to_uid": 1838294017982467,
"content": "comment text",
"created_at": "2026-02-26T09:01:00Z"
}4. Core API Matrix
| Action | Method | Path | Query | Body | Payload (success) |
|---|---|---|---|---|---|
| Create moment | POST | /api/v1/moment/create | - | content, media[], visibility, allow_comment, allow_uids?, deny_uids? | Moment object |
| Get moment detail | GET | /api/v1/moment/:moment_id | - | - | Moment object |
| Delete moment | POST | /api/v1/moment/:moment_id/delete | - | - | {} |
| Feed list | GET | /api/v1/moments/feed | cursor?, limit? | - | {list, cursor, limit} |
| User moments | GET | /api/v1/moments/user/:uid | cursor?, limit? | - | {list, cursor, limit} |
5. Interaction API Matrix
| Action | Method | Path | Query | Body | Payload (success) |
|---|---|---|---|---|---|
| Like moment | POST | /api/v1/moment/:moment_id/like | - | - | {} |
| Unlike moment | POST | /api/v1/moment/:moment_id/unlike | - | - | {} |
| Add comment | POST | /api/v1/moment/:moment_id/comment | - | content, reply_to_uid? | Comment object |
| List comments | GET | /api/v1/moment/:moment_id/comments | cursor?, limit? | - | {list, cursor, limit} |
| Delete comment | POST | /api/v1/moment/:moment_id/comment/:comment_id/delete | - | - | {} |
6. Admin API Matrix
| Action | Method | Path | Query | Body | Payload (success) |
|---|---|---|---|---|---|
| List moments | GET | /api/adm/moment/list | keyword?, uid?, status?, page, size | - | {list, total} |
| Moment detail | GET | /api/adm/moment/detail/:moment_id | - | - | Moment object |
| Delete moment | POST | /api/adm/moment/delete | - | moment_id, reason | {} |
| List reports | GET | /api/adm/moment/report/list | status?, page, size | - | {list, total} |
| Resolve report | POST | /api/adm/moment/report/resolve | - | report_id, result, note? | {} |
7. Notification (S2C Action) Matrix
| Action | Trigger | Save Mode | Payload |
|---|---|---|---|
moment_new | Author posts new moment | save | moment_id, author_uid |
moment_like | User likes moment | no_save | moment_id, from_uid |
moment_comment | User comments | save | moment_id, comment_id, from_uid |
moment_deleted | Author/admin deletes | save | moment_id, deleted_by |
Rules:
- Push delivery is best-effort and must not break DB transactions.
- Feed pull API remains source of truth for cold-start resync.
8. Validation Rules
contentmax length:5000.mediamax item count:9.- Single image/video max size and mime policy is server-configurable.
commentmax length:500.limitdefault20, max100.
9. Error Semantics
Typical business messages:
动态不存在无权限查看该动态无权限删除该动态评论已关闭可见性参数无效媒体资源格式无效举报记录不存在
10. Consistency Rules
- Like/unlike must be idempotent.
- Delete moment must hide post from feed and detail consistently.
- Comment count/like count must be eventually consistent with source tables.
- ACL update and timeline fanout must be transactional or compensatable.
11. Change Policy
Any Moment contract change must update all:
src/imboy_router.erlroutes.src/api/moment_handler.erlparameter parsing and validation.- App API client and tests.
- Admin API client/pages and tests.
- This document.
12. Related Docs
docs/reference/rest-api.mddocs/reference/websocket-api-2.mddocs/api/envelope.schema.jsondocs/guides/operations/security.md