From a838a89d2497952acb5dffa502551ce06327888f Mon Sep 17 00:00:00 2001 From: Grayson Adams <51373669+GraysonCAdams@users.noreply.github.com> Date: Tue, 10 Mar 2026 21:52:36 -0500 Subject: [PATCH] docs: update api, data-model, and architecture for clout system --- docs/api.md | 18 +++++++++++++++--- docs/architecture.md | 3 +++ docs/data-model.md | 5 ++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/docs/api.md b/docs/api.md index 950b0fc..1ddb400 100644 --- a/docs/api.md +++ b/docs/api.md @@ -242,6 +242,7 @@ Response: { "ok": true } | Method | Path | Description | |--------|------|-------------| | GET | `/api/clout` | Get user's clout score, tier, and breakdown | +| POST | `/api/clout` | Acknowledge tier change modal was shown | ### GET /api/clout Returns the user's clout score and tier when queue pacing is enabled. Clout is computed from the engagement on the user's last 10 matured clips (48h+ old). Users with fewer than 10 matured clips default to Rising tier. @@ -257,7 +258,9 @@ Response: { "icon": "/icons/clout/viral.png", "breakdown": [{ "clipId": "...", "score": 2 }, ...], "nextTier": { "tier": "iconic", "tierName": "Iconic", "minScore": 1.0, "burst": 5, "queueLimit": null, "icon": "..." }, - "underperforming": [{ "clipId": "...", "title": "...", "platform": "tiktok", "originalUrl": "...", "thumbnailPath": "..." }] + "underperforming": [{ "clipId": "...", "title": "...", "platform": "tiktok", "originalUrl": "...", "thumbnailPath": "..." }], + "lastTier": "rising", + "tierChanged": true } ``` @@ -265,6 +268,14 @@ Response: { **Per-clip scoring:** 0 = no reactions/favorites from others, 1 = reaction or favorite but no comment, 2 = reaction/favorite AND comment. Self-interactions excluded. +**Tier change detection:** The server tracks each user's last acknowledged tier (`cloutTier`) and last modal shown time (`cloutChangeShownAt`). When the computed tier differs from the acked tier and the 3-day cooldown has elapsed, `tierChanged: true` is returned. The `lastTier` field shows what the user was previously at. + +### POST /api/clout +Acknowledges that the tier change modal was shown. Updates the user's stored tier and resets the cooldown timer. +``` +Response: { "ok": true } +``` + ## Queue Management Manage queued clips when share pacing is enabled. @@ -378,13 +389,14 @@ Response: { "dailyShareLimit": 5 } ### PATCH /api/group/share-pacing Host-only. Configures queue-based share pacing. When switching away from `queue` mode, all queued clips are flushed to `ready`. ``` -Request: { "sharePacingMode": "queue", "shareBurst": 2, "shareCooldownMinutes": 120, "dailyShareLimit": null } -Response: { "sharePacingMode": "queue", "shareBurst": 2, "shareCooldownMinutes": 120, "dailyShareLimit": null } +Request: { "sharePacingMode": "queue", "shareBurst": 2, "shareCooldownMinutes": 120, "dailyShareLimit": null, "cloutEnabled": true } +Response: { "sharePacingMode": "queue", "shareBurst": 2, "shareCooldownMinutes": 120, "dailyShareLimit": null, "cloutEnabled": true } ``` - `sharePacingMode`: `"off"` | `"daily_cap"` | `"queue"` - `shareBurst`: 1–10 (clips per scheduled time slot) - `shareCooldownMinutes`: 30 | 60 | 120 | 240 | 360 - `dailyShareLimit`: positive integer or null +- `cloutEnabled`: boolean (enables reputation-based queue adjustments) ### GET /api/group/provider ``` diff --git a/docs/architecture.md b/docs/architecture.md index f114eb2..758fc54 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -98,6 +98,9 @@ scrolly/ │ │ │ ├── AddVideoModal.svelte # Modal wrapper for AddVideo │ │ │ ├── AvatarCropModal.svelte # Profile picture crop UI │ │ │ ├── QueueSheet.svelte # Bottom sheet for viewing/reordering queued clips +│ │ │ ├── QueueCloutBanner.svelte # Clout tier banner inside QueueSheet +│ │ │ ├── CloutChangeModal.svelte # Tier change celebration modal +│ │ │ ├── CloutTipsView.svelte # Clout tips/breakdown view (tier details, scoring) │ │ │ ├── CatchUpModal.svelte # Catch-up modal for bulk unwatched clips │ │ │ ├── MeGrid.svelte # Profile clip grid (favorites/uploads) │ │ │ ├── MeReelView.svelte # Profile reel overlay view diff --git a/docs/data-model.md b/docs/data-model.md index 8f6304a..c2c84ef 100644 --- a/docs/data-model.md +++ b/docs/data-model.md @@ -22,6 +22,7 @@ SQLite database via Drizzle ORM. All IDs are UUIDs stored as text. Timestamps ar | share_pacing_mode | text | Default `'off'`. `'off'` / `'daily_cap'` / `'queue'`. | | share_burst | integer | Default 2. Clips per scheduled time slot in queue mode (1–10). | | share_cooldown_minutes | integer | Default 120. Minutes between clip groups in queue mode. | +| clout_enabled | integer | Boolean (0/1). Default 1. Enables reputation-based queue adjustments. | | shortcut_token | text | Nullable, unique. Token for iOS Shortcut clip sharing. | | shortcut_url | text | Nullable. URL for iOS Shortcut integration. | | created_by | text | FK → users.id (host/admin) | @@ -42,6 +43,8 @@ SQLite database via Drizzle ORM. All IDs are UUIDs stored as text. Timestamps ar | avatar_path | text | Nullable. Path to uploaded profile picture. | | last_legacy_share_at | integer | Nullable. Unix timestamp of last legacy shortcut share. Used for upgrade banner. | | used_new_share_flow | integer | Boolean (0/1). Default 0. Tracks if user has adopted new web view share flow. | +| clout_tier | text | Nullable. Last acknowledged clout tier (for tier change detection). | +| clout_change_shown_at | integer | Nullable. Unix timestamp when tier change modal was last shown (3-day cooldown). | | removed_at | integer | Nullable. Unix timestamp when removed from group. | | created_at | integer | Unix timestamp | @@ -249,4 +252,4 @@ users 1──∞ verification_codes - **Duplicate URL prevention:** A unique index on `(group_id, original_url)` prevents the same link from being shared twice within a group. - **Music clip trim workflow:** Music clips enter `pending_trim` status after download. The user can trim audio via the trim UI or skip trimming. If neither occurs before `trim_deadline`, the clip auto-publishes to `ready` status via the scheduler. - **Dismissed clips:** The `dismissed_clips` table tracks clips dismissed by users in the catch-up modal. Users can dismiss unwatched clips in bulk, then restore them later from the Skipped Clips viewer in settings. -- **Clout (reputation):** Computed on-demand from existing tables — no new schema. A user's clout score is the rolling average of per-clip engagement scores (0/1/2) for their last 10 matured clips (48h+ old). Scores are derived from `reactions`, `favorites`, and `comments` tables, excluding self-interactions. Tiers (Fresh/Rising/Viral/Iconic) determine queue cooldown multiplier, burst size, and queue depth limits. +- **Clout (reputation):** Computed on-demand from `reactions`, `favorites`, and `comments` tables. A user's clout score is the rolling average of per-clip engagement scores (0/1/2) for their last 10 matured clips (48h+ old). Self-interactions are excluded. Tiers (Fresh/Rising/Viral/Iconic) determine queue cooldown multiplier, burst size, and queue depth limits. The `clout_enabled` flag on `groups` controls whether clout adjustments are applied. The `clout_tier` and `clout_change_shown_at` columns on `users` track server-driven tier change notifications with a 3-day cooldown.