Skip to content

feat(users): add staff avatar_url backfill command#72092

Draft
adboio wants to merge 2 commits into
posthog-code/user-avatar-urlfrom
posthog-code/staff-avatar-backfill
Draft

feat(users): add staff avatar_url backfill command#72092
adboio wants to merge 2 commits into
posthog-code/user-avatar-urlfrom
posthog-code/staff-avatar-backfill

Conversation

@adboio

@adboio adboio commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Problem

#72086 adds a UserPersonalization side table with avatar_url, but existing PostHog staff accounts have no value in it even though everyone already has a headshot on posthog.com/people. Populating those is a one-shot data task that shouldn't be tangled into the schema/serializer review.

Stacked on #72086 — merge that first.

Changes

  • backfill_staff_avatar_urls management command: fetches the public posthog.com/people roster (a Gatsby page-data artifact — there is no team API; falls back to rescanning the page manifest's static-query hashes if the known content hash drifts) and upserts UserPersonalization rows for active @posthog.com accounts matched by normalized full name.
  • Ambiguous roster names (two people with the same full name) are skipped so nobody gets a namesake's photo; non-matches are left untouched; user-set avatars are preserved unless --overwrite.
  • --dry-run reports without writing; idempotent otherwise.

Intended rollout: run with --dry-run first, review the printed matches, then run live — per region.

How did you test this code?

Automated tests added (not run locally — no dev stack in this environment, CI is the arbiter): posthog/management/commands/test/test_backfill_staff_avatar_urls.py covers name matching (including accounts holding the full name in first_name), ambiguous-name and non-staff skipping, --dry-run writing nothing, and --overwrite semantics, with the roster fetch mocked.

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Docs update

N/A — internal ops command.

🤖 Agent context

Human-driven (agent-assisted) — requested by Adam Bowker in the project-bluebird channel (PostHog Code); split out of #72086 at his request.


Created with PostHog Code

@github-actions

Copy link
Copy Markdown
Contributor

Hey @adboio! 👋

It looks like your git author email on this PR isn't your @posthog.com address (adambowker98@gmail.com). Since you're on the PostHog team, it's worth pointing your local git author email at your @posthog.com address. Why it matters:

  • Consistent work identity in git history — internal tooling that attributes commits to team members keys off your @posthog.com address.
  • Keeps team contributions easy to tell apart from external community ones when scanning history.

You can fix it for this repo with:

git config user.email "you@posthog.com"

Or set it globally with git config --global user.email "you@posthog.com". No need to redo this PR — just a nudge for next time. 🙂

@adboio
adboio force-pushed the posthog-code/user-avatar-url branch from ec9706d to fffc818 Compare July 17, 2026 21:17
@adboio
adboio force-pushed the posthog-code/staff-avatar-backfill branch from c5d388d to 23decca Compare July 17, 2026 21:18
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

Bundle size — no change

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 64.22 MiB · no change

No file changed by more than 1000 B.

Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report

Eager graph — within budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.23 MiB · 22 files no change ███░░░░░░░ 28.6% of 4.29 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
8.16 MiB · 2,988 files no change █████████░ 88.2% of 9.25 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.5 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
3.9 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.4 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.3 KiB src/RootErrorBoundary.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
789 B src/scenes/ChunkLoadErrorBoundary.tsx
762 B src/index.tsx
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
281.3 KiB ../node_modules/.pnpm/posthog-js@1.404.0/node_modules/posthog-js/dist/rrweb.js
267.7 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
235.5 KiB src/taxonomy/core-filter-definitions-by-group.json
223.2 KiB ../node_modules/.pnpm/posthog-js@1.404.0/node_modules/posthog-js/dist/module.js
164.0 KiB src/queries/validators.js
154.3 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
105.8 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
93.2 KiB ../packages/quill/packages/quill/dist/index.js

Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479

Dist folder size — 🔺 +1.1 KiB (+0.0%)

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 1341.50 MiB · 🔺 +1.1 KiB (+0.0%)

Django migration risk — migration analysis complete

We've analyzed your migrations for potential risks.

Summary: 0 Safe | 2 Needs Review | 0 Blocked

⚠️ Needs Review

May have performance impact

posthog.1259_userpersonalization
  └─ #1 ✅ CreateModel
     Creating new table is safe
     model: UserPersonalization
  └─ #2 ⚠️ AddForeignKeyNotValid: Unknown operation type: AddForeignKeyNotValid
  │
  └──> ℹ️  INFO:
       ℹ️  Skipped operations on newly created tables (empty tables
       don't cause lock contention).
posthog.1260_validate_userpersonalization_fk
  └─ #1 ⚠️ ValidateForeignKey: Unknown operation type: ValidateForeignKey

Last updated: 2026-07-17 23:37 UTC (273d089)

@adboio
adboio force-pushed the posthog-code/staff-avatar-backfill branch 3 times, most recently from 991bbcb to b05f8b5 Compare July 17, 2026 22:10
@adboio
adboio force-pushed the posthog-code/user-avatar-url branch from f592fe7 to 39fe807 Compare July 17, 2026 22:49
@adboio
adboio force-pushed the posthog-code/staff-avatar-backfill branch from b05f8b5 to 508fd98 Compare July 17, 2026 22:50
@adboio
adboio force-pushed the posthog-code/user-avatar-url branch from 39fe807 to c7c0ecc Compare July 17, 2026 22:53
@adboio
adboio force-pushed the posthog-code/staff-avatar-backfill branch from 508fd98 to 5fc3466 Compare July 17, 2026 22:53
@adboio
adboio force-pushed the posthog-code/user-avatar-url branch from c7c0ecc to d5c62a9 Compare July 17, 2026 22:59
@adboio
adboio force-pushed the posthog-code/staff-avatar-backfill branch from 5fc3466 to f243b69 Compare July 17, 2026 22:59
@adboio
adboio force-pushed the posthog-code/user-avatar-url branch from d5c62a9 to cdb8f15 Compare July 17, 2026 23:05
@adboio
adboio force-pushed the posthog-code/staff-avatar-backfill branch from f243b69 to 921f928 Compare July 17, 2026 23:05
@adboio
adboio force-pushed the posthog-code/user-avatar-url branch from 8ff71ae to 8768442 Compare July 17, 2026 23:13
@adboio
adboio force-pushed the posthog-code/staff-avatar-backfill branch from 2373786 to cc35034 Compare July 17, 2026 23:14
@adboio
adboio force-pushed the posthog-code/user-avatar-url branch from 8768442 to bf55fff Compare July 17, 2026 23:29
One-shot management command that backfills UserPersonalization rows
for active @posthog.com accounts from the public posthog.com/people
roster, matched by normalized full name. Ambiguous names are skipped
so nobody gets a namesake's photo; supports --dry-run and --overwrite
and is idempotent otherwise. Stacked on the personalization-table PR.
@adboio
adboio force-pushed the posthog-code/staff-avatar-backfill branch from 722649d to 4627cf2 Compare July 17, 2026 23:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant