7 Commits
Author SHA1 Message Date
beantownbabeandClaude Sonnet 5 0335e17e89 Add a 5-word Description column to the Posts table
LinkedIn's exports have no title/text field for a post anywhere (neither
Aggregate Analytics nor SinglePostAnalytics) - only the URL, whose slug is a
URL-safe truncation of the post's own opening words. post_title_from_url()
decodes it (handles accented names like Krutošíková), strips the trailing
-share-/-ugcPost-<id>-<code> suffix, and takes the first 5 words as a readable
stand-in for a title. Added to both the live dashboard's posts table and the
downloadable report.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-30 13:08:33 +01:00
beantownbabeandClaude Sonnet 5 3de9143e46 Rebuild post_details_tracker.py as an auto-parser - no hand-logging needed
Turns out every individual post's own analytics page has an "Export" button
(SinglePostAnalytics_<Name>_<id>.xlsx) giving exactly the detail that was being
hand-logged: Profile Viewers/Followers Gained from the post, and the Reactions/
Comments/Reposts/Saves/Sends/Link/Premium-button breakdown behind the Aggregate
Analytics file's single blended "Engagements" number.

Matches each file to a post by its own "Post URL" field, not the numeric id in
the filename - confirmed those two ids are actually different LinkedIn schemes,
so filename-based matching would have been wrong. Loaded once per render
(load_post_details) rather than re-parsed per table row.

All 4 of Mckinley's real posts are now auto-covered (55/80/17/365 impressions),
replacing the 1-of-4 hand-logged coverage from before. Kept showing both
engagement numbers side by side in the table/report - the per-post export's own
breakdown sum has been observed to disagree with the aggregate export's
Engagements figure for the same post more than once now.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-30 13:01:34 +01:00
beantownbabeandClaude Sonnet 5 ea7aa06484 Add hand-logged per-post detail: Profile Viewers, Followers Gained, reaction breakdown
LinkedIn's export has no per-post Profile Viewers/Followers Gained attribution,
and its "Engagements" column is a single blended number - none of that exists
anywhere in the Aggregate Analytics file. Each individual post's own analytics
panel does show it, so this is a hand-logged, per-post-URL dict
(post_details_tracker.py, same add-an-entry pattern as the other two trackers).

Added as extra columns to the Posts table (both the live dashboard and the
downloadable report) alongside the exported Impressions/Engagements, rather
than replacing them - the two Engagement numbers have been observed to
genuinely disagree for the same post (export said 25, the post's own panel
summed reactions+comments+reposts+saves+sends to 20), so both are shown
instead of one silently overriding the other.

Seeded with one real logged post (the July 2 post: 3 profile viewers, 0
followers gained, 15 reactions, 5 comments).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-30 11:58:11 +01:00
beantownbabeandClaude Sonnet 5 0ed6e6c457 Team tab: June 2026 = 0 baseline, calendar grid + split charts to match Overview
Starting Followers is now a fixed, human-confirmed anchor (everyone started this
work June 1, 2026 with 0 followers) instead of borrowing the Page's own unrelated
BASELINE_DATE or the export's meaningless ~365-day window edge. Lives in
team_exports.TEAM_BASELINE_DATE/TEAM_BASELINE_FOLLOWERS so both the dashboard and
the downloadable report use the same anchor.

Rebuilt the chart section to mirror the Overview tab's actual layout: a static
Follower Gains calendar grid (reuses the Page's own _monthly_summary/_month_box_*
helpers, renamed columns to fit) + New Followers per Day bar chart side by side,
then separate Impressions and Daily Engagement Rate line cards instead of one
combined dual-axis chart. Daily CTR and Page Views (Desktop/Mobile) are left out
entirely - personal-profile exports have no click or device-level data at all,
so those two Overview cards have no real equivalent here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-30 11:18:43 +01:00
beantownbabeandClaude Sonnet 5 0c6baad4f1 Team tab: match Overview's exact 8-tile KPI row, fix baseline date, move report button to hero
Three corrections against the Overview tab's real KPI row:
- Tile set now matches exactly (Total Page Views / Total Clicks included as
  "not available for personal profiles" rather than silently substituting
  Members Reached in their place).
- Starting/New Followers now anchor to the same BASELINE_DATE (Jun 16, 2026)
  the Overview tab uses, not the export's own ~365-day rolling window edge -
  that was showing a meaningless "as of last October" date. Passed into
  build_person_report_docx() as a parameter (team_exports.py stays free of
  any app.py import, same rule report.py already follows).
- Download Report button moved from the tab's own row into the hero banner's
  upper-right actions slot, same spot the Followers tab's Directory/Study
  links live - the actual "upper right" of the page, not just of the tab.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-30 11:06:37 +01:00
beantownbabeandClaude Sonnet 5 db4587f75e Build real Team tab parsing from LinkedIn's personal Aggregate Analytics export
Replaces the empty placeholder with actual parsing of the "AggregateAnalytics_
<Name>_<start>_<end>.xlsx" personal-profile export (DISCOVERY, ENGAGEMENT, TOP
POSTS, FOLLOWERS, and both DEMOGRAPHICS sheets). Weekly submissions are a new
~365-day trailing window each time, so the daily series (engagement, followers)
merge across every file on disk the same way the Page's own Followers export
does - newest file wins on an overlapping date.

Reposts vs original posts are distinguished from the post URL itself
(.../share-<id> vs .../ugcPost-<id>), since LinkedIn's "Engagements" column
doesn't separate them - this was the open design question about measuring
repost/comment activity, and the data turns out to answer it directly.

Verified against Mckinley's own first real export (2026-10-30): Impressions,
Followers, and Engagements all cross-check against the file's own DISCOVERY
summary row. The other four team members still show the "no export yet"
placeholder until their first Monday submission lands.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-30 10:23:59 +01:00
beantownbabeandClaude Sonnet 5 436e52254a Add Team tab with per-member submenu (data starts Dec 2026)
New tab for analyzing each team member's own personal LinkedIn export
data (separate from the Page-level Content/Followers/Visitors exports),
starting December 2026 per Mckinley. Submenu dropdown lists Peter Gaal,
Daniel Schmidt, Niklas Meidow, Aleksandra Kotenko, Mckinley Black.

Same "starts empty" pattern as the Engagement Response tab: a hand-
maintained team_exports.py module (empty for now) backs the tab, and
each person shows a clean placeholder until their real export data
gets added - no other code changes needed at that point.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-30 10:10:04 +01:00