Skip to content

Commit 253294b

Browse files
docs: update api, data-model, and architecture for clout system (#108)
1 parent 418bd75 commit 253294b

3 files changed

Lines changed: 22 additions & 4 deletions

File tree

docs/api.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ Response: { "ok": true }
242242
| Method | Path | Description |
243243
|--------|------|-------------|
244244
| GET | `/api/clout` | Get user's clout score, tier, and breakdown |
245+
| POST | `/api/clout` | Acknowledge tier change modal was shown |
245246

246247
### GET /api/clout
247248
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,14 +258,24 @@ Response: {
257258
"icon": "/icons/clout/viral.png",
258259
"breakdown": [{ "clipId": "...", "score": 2 }, ...],
259260
"nextTier": { "tier": "iconic", "tierName": "Iconic", "minScore": 1.0, "burst": 5, "queueLimit": null, "icon": "..." },
260-
"underperforming": [{ "clipId": "...", "title": "...", "platform": "tiktok", "originalUrl": "...", "thumbnailPath": "..." }]
261+
"underperforming": [{ "clipId": "...", "title": "...", "platform": "tiktok", "originalUrl": "...", "thumbnailPath": "..." }],
262+
"lastTier": "rising",
263+
"tierChanged": true
261264
}
262265
```
263266

264267
**Tiers:** Fresh (<0.4) → Rising (0.4–0.6) → Viral (0.7–0.9) → Iconic (≥1.0). Each tier adjusts cooldown multiplier, burst size, and queue depth limit.
265268

266269
**Per-clip scoring:** 0 = no reactions/favorites from others, 1 = reaction or favorite but no comment, 2 = reaction/favorite AND comment. Self-interactions excluded.
267270

271+
**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.
272+
273+
### POST /api/clout
274+
Acknowledges that the tier change modal was shown. Updates the user's stored tier and resets the cooldown timer.
275+
```
276+
Response: { "ok": true }
277+
```
278+
268279
## Queue Management
269280

270281
Manage queued clips when share pacing is enabled.
@@ -378,13 +389,14 @@ Response: { "dailyShareLimit": 5 }
378389
### PATCH /api/group/share-pacing
379390
Host-only. Configures queue-based share pacing. When switching away from `queue` mode, all queued clips are flushed to `ready`.
380391
```
381-
Request: { "sharePacingMode": "queue", "shareBurst": 2, "shareCooldownMinutes": 120, "dailyShareLimit": null }
382-
Response: { "sharePacingMode": "queue", "shareBurst": 2, "shareCooldownMinutes": 120, "dailyShareLimit": null }
392+
Request: { "sharePacingMode": "queue", "shareBurst": 2, "shareCooldownMinutes": 120, "dailyShareLimit": null, "cloutEnabled": true }
393+
Response: { "sharePacingMode": "queue", "shareBurst": 2, "shareCooldownMinutes": 120, "dailyShareLimit": null, "cloutEnabled": true }
383394
```
384395
- `sharePacingMode`: `"off"` | `"daily_cap"` | `"queue"`
385396
- `shareBurst`: 1–10 (clips per scheduled time slot)
386397
- `shareCooldownMinutes`: 30 | 60 | 120 | 240 | 360
387398
- `dailyShareLimit`: positive integer or null
399+
- `cloutEnabled`: boolean (enables reputation-based queue adjustments)
388400

389401
### GET /api/group/provider
390402
```

docs/architecture.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ scrolly/
9898
│ │ │ ├── AddVideoModal.svelte # Modal wrapper for AddVideo
9999
│ │ │ ├── AvatarCropModal.svelte # Profile picture crop UI
100100
│ │ │ ├── QueueSheet.svelte # Bottom sheet for viewing/reordering queued clips
101+
│ │ │ ├── QueueCloutBanner.svelte # Clout tier banner inside QueueSheet
102+
│ │ │ ├── CloutChangeModal.svelte # Tier change celebration modal
103+
│ │ │ ├── CloutTipsView.svelte # Clout tips/breakdown view (tier details, scoring)
101104
│ │ │ ├── CatchUpModal.svelte # Catch-up modal for bulk unwatched clips
102105
│ │ │ ├── MeGrid.svelte # Profile clip grid (favorites/uploads)
103106
│ │ │ ├── MeReelView.svelte # Profile reel overlay view

docs/data-model.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ SQLite database via Drizzle ORM. All IDs are UUIDs stored as text. Timestamps ar
2222
| share_pacing_mode | text | Default `'off'`. `'off'` / `'daily_cap'` / `'queue'`. |
2323
| share_burst | integer | Default 2. Clips per scheduled time slot in queue mode (1–10). |
2424
| share_cooldown_minutes | integer | Default 120. Minutes between clip groups in queue mode. |
25+
| clout_enabled | integer | Boolean (0/1). Default 1. Enables reputation-based queue adjustments. |
2526
| shortcut_token | text | Nullable, unique. Token for iOS Shortcut clip sharing. |
2627
| shortcut_url | text | Nullable. URL for iOS Shortcut integration. |
2728
| 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
4243
| avatar_path | text | Nullable. Path to uploaded profile picture. |
4344
| last_legacy_share_at | integer | Nullable. Unix timestamp of last legacy shortcut share. Used for upgrade banner. |
4445
| used_new_share_flow | integer | Boolean (0/1). Default 0. Tracks if user has adopted new web view share flow. |
46+
| clout_tier | text | Nullable. Last acknowledged clout tier (for tier change detection). |
47+
| clout_change_shown_at | integer | Nullable. Unix timestamp when tier change modal was last shown (3-day cooldown). |
4548
| removed_at | integer | Nullable. Unix timestamp when removed from group. |
4649
| created_at | integer | Unix timestamp |
4750

@@ -249,4 +252,4 @@ users 1──∞ verification_codes
249252
- **Duplicate URL prevention:** A unique index on `(group_id, original_url)` prevents the same link from being shared twice within a group.
250253
- **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.
251254
- **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.
252-
- **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.
255+
- **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.

0 commit comments

Comments
 (0)