thoughtleaders-cli 0.6.2__py3-none-any.whl → 0.6.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {thoughtleaders_cli-0.6.2.dist-info → thoughtleaders_cli-0.6.3.dist-info}/METADATA +1 -1
- {thoughtleaders_cli-0.6.2.dist-info → thoughtleaders_cli-0.6.3.dist-info}/RECORD +10 -10
- tl_cli/__init__.py +1 -1
- tl_cli/_plugin/.claude-plugin/plugin.json +1 -1
- tl_cli/_plugin/skills/tl/SKILL.md +1 -1
- tl_cli/_plugin/skills/tl/references/business-glossary.md +84 -0
- tl_cli/_plugin/skills/tl/references/postgres-schema.md +42 -5
- {thoughtleaders_cli-0.6.2.dist-info → thoughtleaders_cli-0.6.3.dist-info}/WHEEL +0 -0
- {thoughtleaders_cli-0.6.2.dist-info → thoughtleaders_cli-0.6.3.dist-info}/entry_points.txt +0 -0
- {thoughtleaders_cli-0.6.2.dist-info → thoughtleaders_cli-0.6.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thoughtleaders-cli
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.3
|
|
4
4
|
Summary: ThoughtLeaders CLI — query sponsorship data, channels, brands, and intelligence
|
|
5
5
|
Project-URL: Homepage, https://thoughtleaders.io
|
|
6
6
|
Project-URL: Repository, https://github.com/ThoughtLeaders-io/thoughtleaders-cli
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
tl_cli/__init__.py,sha256=
|
|
1
|
+
tl_cli/__init__.py,sha256=bKYaEYAmhhf9Wq40L1AAdb-fz0a-aPnUksQ9ZMobTHw,112
|
|
2
2
|
tl_cli/_completions.py,sha256=kOyEUqC26vbYvyXWi513WX8fF73qQLR5WWuRSe_wqyk,164
|
|
3
3
|
tl_cli/config.py,sha256=teQF2Smk38AFkrkaUnR0peo-CPy5CMIKiNoA0D5R9jQ,1945
|
|
4
4
|
tl_cli/filters.py,sha256=jymgt21vl2d67yTXD_ceRIxTn6H6OYI5-QvQyE4Y4z0,2937
|
|
@@ -37,7 +37,7 @@ tl_cli/commands/whoami.py,sha256=HL_0X0hWI-NsmWfjgy0mhWO3TNdWztt_AAlWRJysyVk,734
|
|
|
37
37
|
tl_cli/output/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
38
|
tl_cli/output/formatter.py,sha256=3XowEGCLyEGpZy0LoN0r8WI9GfbhyPWSa9PHkBJmPiM,16590
|
|
39
39
|
tl_cli/_plugin/.claude-plugin/marketplace.json,sha256=l56PMmyjfGXNGlV30wRyOAe74B6gJNCVNCxgsBbSNxc,446
|
|
40
|
-
tl_cli/_plugin/.claude-plugin/plugin.json,sha256=
|
|
40
|
+
tl_cli/_plugin/.claude-plugin/plugin.json,sha256=PNIjq_AO83VfWAy914NFFJpeuYbuviT71BHOHFmAyfc,466
|
|
41
41
|
tl_cli/_plugin/agents/tl-analyst.md,sha256=5ho4gyZOjqeVwQKhg4jtgye4WI0BAFem4oBzfhqUBJQ,6735
|
|
42
42
|
tl_cli/_plugin/commands/tl-balance.md,sha256=0sQjVBu1xZXmzoTBqFZF8MhYAsuc9F7Vci23nbTDZ9Q,204
|
|
43
43
|
tl_cli/_plugin/commands/tl-reports.md,sha256=uB1u9gvcSSgxsXEPfHvT1iZjSxm-jH63nUbs_wsS5_o,511
|
|
@@ -46,13 +46,13 @@ tl_cli/_plugin/commands/tl.md,sha256=9DB7P_sLeJDe6RYDjjowZvhNTEa_wbAkCa7wPccXfhU
|
|
|
46
46
|
tl_cli/_plugin/hooks/hooks.json,sha256=lU4w5iZGSnVJ1sZn18kbJGh2s-iOvG3TtAXmiVK61mE,476
|
|
47
47
|
tl_cli/_plugin/hooks/scripts/post-usage.sh,sha256=WVvZLkZik6lbeZ20Kh-wgm4JkRFHFN0Uwl4C8S3Y0sY,759
|
|
48
48
|
tl_cli/_plugin/hooks/scripts/pre-check.sh,sha256=E9KeuXy6yeHEBOnOFW4hDW-Et-Dbp1Oh--3WXKfOX78,898
|
|
49
|
-
tl_cli/_plugin/skills/tl/SKILL.md,sha256=
|
|
50
|
-
tl_cli/_plugin/skills/tl/references/business-glossary.md,sha256=
|
|
49
|
+
tl_cli/_plugin/skills/tl/SKILL.md,sha256=r3QR8RX-PCP_-JMOLiU0VpDoqiACz7wi4v5dFesOMu4,37495
|
|
50
|
+
tl_cli/_plugin/skills/tl/references/business-glossary.md,sha256=BQC1_ct0vLMUNrbmpsfjVujOWRkQ1E3MZsNIs-7-fjA,17411
|
|
51
51
|
tl_cli/_plugin/skills/tl/references/elasticsearch-schema.md,sha256=c7zFBj3PHweyw7AhrV_-Fy0GAxz9aralWdDSC16yd_s,10713
|
|
52
52
|
tl_cli/_plugin/skills/tl/references/firebolt-schema.md,sha256=3Y9lV-2zMJRNgyXCQ80djzBHECEA5HikqCF-jwYa4kY,10187
|
|
53
|
-
tl_cli/_plugin/skills/tl/references/postgres-schema.md,sha256=
|
|
54
|
-
thoughtleaders_cli-0.6.
|
|
55
|
-
thoughtleaders_cli-0.6.
|
|
56
|
-
thoughtleaders_cli-0.6.
|
|
57
|
-
thoughtleaders_cli-0.6.
|
|
58
|
-
thoughtleaders_cli-0.6.
|
|
53
|
+
tl_cli/_plugin/skills/tl/references/postgres-schema.md,sha256=z1xO7b7AXxWDQy24-cJeFl5c1l2zMXffb1zCG6qPhDM,14796
|
|
54
|
+
thoughtleaders_cli-0.6.3.dist-info/METADATA,sha256=5jS0KW5Vu20ZYfIjh9i4wxDjlsslg7nf2mBBkfi5VZ8,9127
|
|
55
|
+
thoughtleaders_cli-0.6.3.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
56
|
+
thoughtleaders_cli-0.6.3.dist-info/entry_points.txt,sha256=umZp-1BkGkHDG0bNZXpTXrjwW0HGf9IDFN40eAWuuvg,39
|
|
57
|
+
thoughtleaders_cli-0.6.3.dist-info/licenses/LICENSE,sha256=RUfdfLsn6jygiyrnnVUHt6r4IPwr2rbDm9Kixgtu8fo,1071
|
|
58
|
+
thoughtleaders_cli-0.6.3.dist-info/RECORD,,
|
tl_cli/__init__.py
CHANGED
|
@@ -56,7 +56,7 @@ The centre of the data model is **Sponsorships** — business relationships betw
|
|
|
56
56
|
- **Proposals** — matches that have been proposed to both sides to consider
|
|
57
57
|
- **Deals** — contractually agreed-upon sponsorships (sold), either in production or published
|
|
58
58
|
|
|
59
|
-
Sponsorships are sometimes called "Ads" or "Ad campaigns".
|
|
59
|
+
Sponsorships are sometimes called "Ads" or "Ad campaigns". **"AdLink"** is another name for the same thing — it's the term the database uses (`thoughtleaders_adlink`) and shows up across internal code, schema docs, and AM Slack threads. Treat "sponsorship" and "adlink" as interchangeable; the user-facing word is "sponsorship," the engineering/DB word is "adlink."
|
|
60
60
|
|
|
61
61
|
The CLI has shortcut commands for each type: `tl matches`, `tl proposals`, `tl deals`. These filter `tl sponsorships` by status.
|
|
62
62
|
|
|
@@ -79,6 +79,90 @@ Maps business terms to database concepts.
|
|
|
79
79
|
- **Rule:** Only one active adspot with `integration=mention` per channel at any time
|
|
80
80
|
- MSN quality depends on having current, accurate contact info
|
|
81
81
|
|
|
82
|
+
## Channels & Audience
|
|
83
|
+
|
|
84
|
+
Vocabulary that AMs use about channels, mapped to the actual DB encoding. Most of these are silent-wrong-name traps where the team term doesn't match the column name.
|
|
85
|
+
|
|
86
|
+
| Business Term | DB Concept | Notes |
|
|
87
|
+
|---------------|------------|-------|
|
|
88
|
+
| **Subscribers** | `thoughtleaders_channel.reach` (bigint) | ⚠️ There is no `subscribers` column. The DB column is `reach`. |
|
|
89
|
+
| **MSN member** | `media_selling_network_join_date IS NOT NULL` | Whole MSN pool. NOT `is_tl_channel = true` — that's the VIP subset only. |
|
|
90
|
+
| **TPP / VIP channel** | `is_tl_channel = true` | The small VIP subset of MSN (~144 channels at 100k+ reach). Don't use as a general "MSN" proxy — silently drops ~98% of MSN. |
|
|
91
|
+
| **Active channel** | `is_active = true AND last_published >= CURRENT_DATE - INTERVAL '120 days'` | Standard filter for "channel is live and posting." Always include `is_active = true` in channel queries. |
|
|
92
|
+
| **Country / Geo of a deal** | `thoughtleaders_channel.country` (ISO 3166-1 alpha-2) | `thoughtleaders_adlink` has NO geo column. Geo for sponsorships almost always means the channel's country. |
|
|
93
|
+
| **Language of a channel** | `thoughtleaders_channel.language` (short ISO 639 code) | ⚠️ Short ISO 639 codes — NOT BCP-47. Mostly 2-letter ISO 639-1 (`en`, `pt`, `hi`) for major languages; occasionally 3-letter ISO 639-2/3 (`arc`, `arz`, `ase`, `ceb`) for languages without a 2-letter code. Filtering with BCP-47 (`en-US`/`pt-BR`) returns zero. Don't assume `LENGTH(language) = 2`. |
|
|
94
|
+
| **Brand on a deal** | `adlink → creator_profile_id → profile_brands.profile_id → profile_brands.brand_id → brand` | 3-table chain. There is NO direct `brand_id` on adlink. See [postgres-schema.md](postgres-schema.md). |
|
|
95
|
+
| **Channel on a deal** | `adlink.ad_spot_id → adspot.channel_id → channel` | NO direct `channel_id` on adlink. |
|
|
96
|
+
| **Brand-virgin / VPN-virgin (etc.)** | Channel has no `adlink` row joined to any of the target brand_ids | Used in candidate sourcing ("never sponsored by any VPN brand"). Caveat: only catches TL-brokered deals; channels that ran the brand directly (no TL involvement) appear "virgin" but aren't — cross-check ES `sponsored_brand_mentions` before final outreach. |
|
|
97
|
+
| **Channel quality score** *(internal-only)* | `sponsorship_score` on the indexed channel doc + `thoughtleaders_channel.sponsorship_score` (PG) | TL-internal composite score combining engagement, fulfillment, and historical sponsorship performance. **Use it internally to rank/tiebreak candidates, but do NOT quote the raw decimal in AM-facing or external output** — the score isn't documented to AMs and the absolute value isn't meaningful without context. In AM-facing prose, translate to qualitative language: "top-quartile fit," "strongest quality score in the candidate set," "high sponsorship-quality signal." |
|
|
98
|
+
|
|
99
|
+
## Projected Views (PV) — three related but distinct fields
|
|
100
|
+
|
|
101
|
+
AMs use "PV" loosely. There are three different DB fields, each meaning something different:
|
|
102
|
+
|
|
103
|
+
| AM Term | DB Field | What it actually is |
|
|
104
|
+
|---------|----------|---------------------|
|
|
105
|
+
| **PV (channel baseline)** | `thoughtleaders_channel.impression` | Channel-level "typical views per video" used as CPM denominator. ⚠️ Coverage and freshness vary; cross-check Firebolt longform median for hero-tier deals. |
|
|
106
|
+
| **PV (deal-specific)** | `thoughtleaders_adlink.projected_views_at_purchase_date` | Snapshot of projected views at the moment the deal was sold. Use this for historical CPM analysis. |
|
|
107
|
+
| **VG (View Guarantee)** | `thoughtleaders_adlink.impressions_guarantee` | The contractual minimum views the brand is guaranteed. 0/NULL = no guarantee. NOT the same as PV — VG is a contractual floor, PV is an estimate. |
|
|
108
|
+
|
|
109
|
+
When an AM says "what's the PV on this channel?" — they almost always mean `channel.impression`. When they say "what was the PV on this deal?" — they mean `adlink.projected_views_at_purchase_date`. When they say "did we hit the VG?" — they mean `adlink.view_guarantee_hit_date IS NOT NULL`.
|
|
110
|
+
|
|
111
|
+
## Channel Sponsorship Signals
|
|
112
|
+
|
|
113
|
+
Two derived metrics on the indexed channel doc that AMs use to qualify a channel before pitching. Both are pre-aggregated in the search index, computed against historical sponsored-content patterns.
|
|
114
|
+
|
|
115
|
+
| AM Term | Underlying field | Definition | What an AM does with it |
|
|
116
|
+
|---------|------------------|------------|--------------------------|
|
|
117
|
+
| **Fulfillment rate** | `fulfillment_rate` (channel doc, scaled_float) | The share of a channel's content that is sponsored — `sponsored / all` content over the measurement window, expressed as a fraction. Higher = the channel reliably delivers paid integrations. | Quality signal: a high fulfillment rate means past brands have actually run on this channel, not just been pitched. AMs use it to filter out "looks promising but never closes" channels. |
|
|
118
|
+
| **Renewal rate** | `renewal_rate` (channel doc, scaled_float) | The rate at which a brand-channel sponsorship relationship repeats over time, computed from clusters of sponsorship deals between a single subject (channel or brand) and its linked entities, with date-distribution heuristics (default 365-day max interval). | Loyalty signal: a high renewal rate means brands keep coming back to this channel. AMs use it to identify "sticky" channels worth premium positioning, and to flag low-renewal channels as one-shots. |
|
|
119
|
+
|
|
120
|
+
Both metrics live on the channel side of the indexed video docs (the `channel.*` nested object). Channel pages in TL's product surface these as quality scores; in AM-facing reports, you can quote them as percentages (`0.45 → "45% renewal rate"`).
|
|
121
|
+
|
|
122
|
+
## Industry Terms vs TL Vocabulary
|
|
123
|
+
|
|
124
|
+
Some MarTech-industry terms are **NOT used at TL.** When you encounter them in a question, prompt, or message — translate to TL-native vocabulary before querying or answering. If you see one of these on the left, swap to the right.
|
|
125
|
+
|
|
126
|
+
| Industry term (don't use) | TL-native equivalent | Notes |
|
|
127
|
+
|---------------------------|----------------------|-------|
|
|
128
|
+
| **Flight** (a single ad-run instance) | **deal** / **sponsorship** / **adlink** | One row in `thoughtleaders_adlink`. "Every flight" → "every deal." |
|
|
129
|
+
| **Flight** (a campaign time window) | **window** / **campaign window** | "60-day flight" → "60-day window." Or just specify dates. |
|
|
130
|
+
| **Flight cadence** | **deal cadence** / **renewal cadence** | How often deals run on a channel. |
|
|
131
|
+
| **Flight-over-flight** | **deal-over-deal** / **renewal-over-renewal** | Comparing successive deals on the same channel. |
|
|
132
|
+
| **Post-flight** | **post-publish** / **post-deal** | After the deal/ad has run. |
|
|
133
|
+
|
|
134
|
+
**General rule:** if you reach for an ad-industry term that isn't already in this glossary, check whether TL actually uses it before introducing it.
|
|
135
|
+
|
|
136
|
+
## Infrastructure Terms — Translate Before User-Facing Output
|
|
137
|
+
|
|
138
|
+
AMs and brand-facing readers don't know (or care) what Postgres, Elasticsearch, or Firebolt are. **When surfacing data in any AM-facing or external output, translate infrastructure names and column names to business language.** Internal engineering chats are the only place these raw terms belong.
|
|
139
|
+
|
|
140
|
+
| Internal term (don't use in AM/external output) | AM-friendly translation | What it actually is |
|
|
141
|
+
|---|---|---|
|
|
142
|
+
| **PG** / **Postgres** / `thoughtleaders_*` table names / `tl db pg` invocations | **"our deals data"** / **"TL's deals book"** / **"our pipeline"** | The relational DB that holds deals, brands, channels, profiles — the source of truth for what TL has brokered |
|
|
143
|
+
| **ES** / **Elasticsearch** / `tl-platform-*` indices / `tl db es` invocations | **"TL's YouTube content tracking"** / **"our video index"** / **"our scraped video data"** | The search index that holds tracked YouTube videos, brand mentions, transcripts — the wider market view |
|
|
144
|
+
| **Firebolt** / `article_metrics` / `channel_metrics` / `tl db fb` invocations | **"historical metrics"** / **"view-curve data"** | The data warehouse that stores time-series snapshots — used for trend analysis |
|
|
145
|
+
| `sponsored_brand_mentions` (ES field) | **"tracked sponsorships"** / **"logged sponsored mentions"** / **"sponsored videos we tracked"** | Per-video brand-ID tags showing which brands paid for that video |
|
|
146
|
+
| `organic_brand_mentions` (ES field) | **"organic / unpaid mentions"** | Brand mentioned in a video without a paid sponsorship |
|
|
147
|
+
| `publish_status = 3` | **"sold"** | Already in glossary; never write the integer to AMs |
|
|
148
|
+
| `creator_profile_id` chain / 3-table join | **"the brand's record"** | Engineering plumbing for brand lookup; AMs just hear "the brand" |
|
|
149
|
+
| `reach` (PG column) | **"subscribers"** | Already in glossary; AMs say subscribers, SQL says reach |
|
|
150
|
+
| `impression` (PG column) | **"projected views"** / **"PV"** | Already in glossary; flagged for reliability caveats |
|
|
151
|
+
|
|
152
|
+
### Common translations in context
|
|
153
|
+
|
|
154
|
+
When you'd write internally → write this for an AM:
|
|
155
|
+
|
|
156
|
+
| Internal phrasing | AM-friendly phrasing |
|
|
157
|
+
|---|---|
|
|
158
|
+
| "Pulling ES `sponsored_brand_mentions` for the market view" | "Cross-checking against our video tracking data" |
|
|
159
|
+
| "ES has 11,304 sponsored mentions of Robinhood" | "Robinhood ran 11,304 sponsored videos in the last 12 months" |
|
|
160
|
+
| "PG has 139 sold adlinks for brand_id=29332" | "We sold Investing.com 139 sponsorships" |
|
|
161
|
+
| "Firebolt `article_metrics` 180-day longform median" | "Recent typical-video views over the last 6 months" |
|
|
162
|
+
| "Filter on `publish_status=3` AND `purchase_date>=2025-01-01`" | "Sold deals since the start of 2025" |
|
|
163
|
+
|
|
164
|
+
**General rule:** if a sentence mentions `tl db pg|fb|es` invocations, table names, column names, or integer codes, ask yourself — *would the AM Slack me a question using this language?* If no, translate. The infrastructure exists to serve the AM; the AM shouldn't have to know it exists.
|
|
165
|
+
|
|
82
166
|
## Teams & Ownership
|
|
83
167
|
|
|
84
168
|
### Brand-led Revenue (Sales / Account Management)
|
|
@@ -42,7 +42,7 @@ The main deals table. Each row = one sponsorship deal between a brand and a YouT
|
|
|
42
42
|
| `weighted_price_currency` | varchar | Always USD |
|
|
43
43
|
| `cost` | numeric | Cost to TL |
|
|
44
44
|
| `ad_spot_id` | int FK | → `thoughtleaders_adspot.id` |
|
|
45
|
-
| `creator_profile_id` | int FK | → brand/advertiser profile |
|
|
45
|
+
| `creator_profile_id` | int FK | → `thoughtleaders_profile.id` (the brand/advertiser's profile). ⚠️ The table is named `thoughtleaders_profile`, NOT `creator_profile` — the "creator_" prefix lives on the FK column, not the table. |
|
|
46
46
|
| `owner_advertiser_id` | int FK | → `auth_user.id` (brand-side owner) |
|
|
47
47
|
| `owner_publisher_id` | int FK | → `auth_user.id` (channel-side owner) |
|
|
48
48
|
| `owner_sales_id` | int FK | → `auth_user.id` (sales rep) |
|
|
@@ -125,13 +125,50 @@ A channel can have multiple adspots (different sellers: talent manager, direct,
|
|
|
125
125
|
| Column | Type | Description |
|
|
126
126
|
|--------|------|-------------|
|
|
127
127
|
| `id` | int | Primary key |
|
|
128
|
-
| `channel_name` | varchar | Display name |
|
|
129
|
-
| `external_channel_id` | varchar | YouTube channel ID (`UCxxxxxx`). ⚠️ There is NO `youtube_id` column. |
|
|
128
|
+
| `channel_name` | varchar | Display name. ⚠️ The column is `channel_name`, NOT `name`. |
|
|
129
|
+
| `external_channel_id` | varchar | YouTube channel ID (e.g., `UCxxxxxx`). ⚠️ There is NO `youtube_id` column — use this one. |
|
|
130
130
|
| `url` | varchar | Channel URL |
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
131
|
+
| `reach` | bigint | Subscriber count. ⚠️ There is NO `subscribers` column — `reach` is the subscriber count. Many internal docs and outputs use the word "subscribers"; in SQL, always query `reach`. |
|
|
132
|
+
| `media_selling_network_join_date` | date/timestamptz | When channel joined MSN. **MSN membership = this column IS NOT NULL.** |
|
|
133
|
+
| `is_tl_channel` | boolean | True = TPP/VIP channel (the small VIP subset, ~144 channels at 100k+ reach). ⚠️ **`is_tl_channel` is NOT the MSN flag.** Naive `WHERE is_tl_channel = true` as an "MSN filter" silently drops ~98% of the MSN pool (8,652 → 144 at 100k+). For MSN, use `media_selling_network_join_date IS NOT NULL`. |
|
|
134
|
+
| `content_category` | int | Content category code (1–22). See "`content_category` Constants" below for the code → label mapping. ⚠️ **Data-quality notes:** (1) per-row category assignments are often inconsistent with the official label (e.g. cat 15 = Technology, but many top-`reach` channels in cat 15 are clearly Entertainment). (2) Several codes are essentially unused in practice — codes 1, 2, 4, 6, 7, 8, 9, 11, 13 (Backend Development, Design, Frontend Development, Marketing, Mobile Development, Sales, Travel, Photography, Personal Finance) return ~0 active high-reach channels. Most travel creators land under Lifestyle (5), not Travel (9). The label table below is authoritative; the per-row assignment is best-effort. **For topic/category discovery, prefer `tl recommender top-channels "<tag>"` (ranked) over `WHERE content_category = <code>` (equality). |
|
|
135
|
+
| `is_active` | boolean | Whether the channel is active. ⚠️ **Always include `is_active = true` in channel queries** unless explicitly looking for archived rows. |
|
|
136
|
+
| `country` | varchar | Channel's primary country (ISO 3166-1 alpha-2 code, e.g. `US`, `GB`, `BR`). Often the cleanest answer to "geo" questions on sponsorships (since adlink itself has no geo). May be NULL or blank on ~10% of channels. |
|
|
137
|
+
| `language` | varchar | Primary content language. ⚠️ **Short ISO 639 codes — NOT BCP-47.** Mostly 2-letter ISO 639-1 (`en`, `pt`, `hi`) for major languages; occasionally 3-letter ISO 639-2/3 (`arc`, `arz`, `ase`, `ceb`) for languages without a 2-letter code. Filtering with `language = 'en-US'` returns zero rows. **Don't assume `LENGTH(language) = 2`** — that silently drops the 3-letter long-tail. May be NULL on ~10% of channels. |
|
|
138
|
+
| `last_published` | date | Date of the channel's most recent video. Use for "is the channel still active?" filters — e.g. `last_published >= CURRENT_DATE - INTERVAL '120 days'`. |
|
|
139
|
+
| `sponsorship_score` | double precision | TL-internal channel quality score (higher is better). Useful as a tiebreaker when ranking candidate channels. |
|
|
140
|
+
| `description` | text | LLM-generated description of the channel. Sometimes useful as a regex-target for thematic filtering when the integer category is too coarse (e.g. filtering "Technology" cat 15 down to actual tech reviewers via keywords like `tech|gadget|review|software`). |
|
|
133
141
|
| `evergreenness` | float | Cached evergreen score |
|
|
134
142
|
|
|
143
|
+
#### `content_category` Constants
|
|
144
|
+
|
|
145
|
+
Source of truth: `thoughtleaders.taxonomies.ContentCategory` (Django `IntEnum` in the main `thoughtleaders` repo).
|
|
146
|
+
|
|
147
|
+
| Value | Constant | Pretty Label |
|
|
148
|
+
|-------|----------|--------------|
|
|
149
|
+
| 1 | BACKEND_DEVELOPMENT | Backend Development |
|
|
150
|
+
| 2 | DESIGN | Design |
|
|
151
|
+
| 3 | ENTREPRENEURSHIP | Entrepreneurship |
|
|
152
|
+
| 4 | FRONTEND_DEVELOPMENT | Frontend Development |
|
|
153
|
+
| 5 | LIFESTYLE | Lifestyle |
|
|
154
|
+
| 6 | MARKETING | Marketing |
|
|
155
|
+
| 7 | MOBILE_DEVELOPMENT | Mobile Development |
|
|
156
|
+
| 8 | SALES | Sales |
|
|
157
|
+
| 9 | TRAVEL | Travel |
|
|
158
|
+
| 10 | BUSINESS | Business |
|
|
159
|
+
| 11 | PHOTOGRAPHY | Photography |
|
|
160
|
+
| 12 | GENERAL_KNOWLEDGE | General Knowledge |
|
|
161
|
+
| 13 | PERSONAL_FINANCE | Personal Finance |
|
|
162
|
+
| 14 | NEWS_POLITICS | News & Politics |
|
|
163
|
+
| 15 | TECHNOLOGY | Technology |
|
|
164
|
+
| 16 | GAMING | Gaming |
|
|
165
|
+
| 17 | FOOD | Food |
|
|
166
|
+
| 18 | SPORTS | Sports |
|
|
167
|
+
| 19 | HOWTO | How To & Crafts |
|
|
168
|
+
| 20 | ENTERTAINMENT | Entertainment |
|
|
169
|
+
| 21 | HEALTH_FITNESS | Health & Fitness |
|
|
170
|
+
| 22 | MUSIC | Music |
|
|
171
|
+
|
|
135
172
|
### `auth_user` (Django Users)
|
|
136
173
|
|
|
137
174
|
Standard Django user table. Used for owner lookups.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|