chore(bigmind): rename timestamp badge PNGs to achievement IDs
- Renamed 19 timestamp-named PNGs (20260404_*) to match original achievement IDs in profile_builder.py compute_achievements() order: first_breath, first_thought, eureka, honest_mind, scholar, deep_knowledge, scientist, veteran, on_fire, storyteller, night_owl, speed_thinker, first_handshake, birthday, shared_mind, frugal_mind, quarter_million, token_millionaire, sniper - Deleted 2 duplicate/excess timestamp PNGs - Added image= field to all 19 original _add() calls in profile_builder.py so every achievement now has a PNG path - All 39 achievements (19 original + 20 tiered) now have image fields - 303/303 tests pass
@@ -443,101 +443,120 @@ def compute_achievements(user_id: str) -> list[dict]:
|
|||||||
_add("first_breath", "🌱", "First Breath",
|
_add("first_breath", "🌱", "First Breath",
|
||||||
"Opened the very first session",
|
"Opened the very first session",
|
||||||
first_session_row is not None, _dt(first_session_row[0]) if first_session_row else None,
|
first_session_row is not None, _dt(first_session_row[0]) if first_session_row else None,
|
||||||
"Start your first session")
|
"Start your first session",
|
||||||
|
image="/static/achievements/first_breath.png")
|
||||||
|
|
||||||
_add("first_thought", "🧠", "First Thought",
|
_add("first_thought", "🧠", "First Thought",
|
||||||
"Formed the first hypothesis",
|
"Formed the first hypothesis",
|
||||||
first_hyp_row is not None, _dt(first_hyp_row[0]) if first_hyp_row else None,
|
first_hyp_row is not None, _dt(first_hyp_row[0]) if first_hyp_row else None,
|
||||||
"Add your first hypothesis")
|
"Add your first hypothesis",
|
||||||
|
image="/static/achievements/first_thought.png")
|
||||||
|
|
||||||
_add("eureka", "💡", "Eureka",
|
_add("eureka", "💡", "Eureka",
|
||||||
"First hypothesis confirmed as true",
|
"First hypothesis confirmed as true",
|
||||||
first_confirmed_row is not None, _dt(first_confirmed_row[0]) if first_confirmed_row else None,
|
first_confirmed_row is not None, _dt(first_confirmed_row[0]) if first_confirmed_row else None,
|
||||||
"Confirm your first hypothesis")
|
"Confirm your first hypothesis",
|
||||||
|
image="/static/achievements/eureka.png")
|
||||||
|
|
||||||
_add("honest_mind", "❌", "Honest Mind",
|
_add("honest_mind", "❌", "Honest Mind",
|
||||||
"First hypothesis refuted — being wrong is a feature",
|
"First hypothesis refuted — being wrong is a feature",
|
||||||
first_refuted_row is not None, _dt(first_refuted_row[0]) if first_refuted_row else None,
|
first_refuted_row is not None, _dt(first_refuted_row[0]) if first_refuted_row else None,
|
||||||
"Have a hypothesis refuted")
|
"Have a hypothesis refuted",
|
||||||
|
image="/static/achievements/honest_mind.png")
|
||||||
|
|
||||||
_add("scholar", "📚", "Scholar",
|
_add("scholar", "📚", "Scholar",
|
||||||
"Stored 25+ personal facts",
|
"Stored 25+ personal facts",
|
||||||
fact_count >= 25, scholar_date,
|
fact_count >= 25, scholar_date,
|
||||||
f"Store 25+ facts (currently: {fact_count})")
|
f"Store 25+ facts (currently: {fact_count})",
|
||||||
|
image="/static/achievements/scholar.png")
|
||||||
|
|
||||||
_add("deep_knowledge", "💎", "Deep Knowledge",
|
_add("deep_knowledge", "💎", "Deep Knowledge",
|
||||||
"Amassed 100+ stored facts",
|
"Amassed 100+ stored facts",
|
||||||
fact_count >= 100, deep_knowledge_date,
|
fact_count >= 100, deep_knowledge_date,
|
||||||
f"Store 100+ facts (currently: {fact_count})")
|
f"Store 100+ facts (currently: {fact_count})",
|
||||||
|
image="/static/achievements/deep_knowledge.png")
|
||||||
|
|
||||||
_add("scientist", "🔬", "Scientist",
|
_add("scientist", "🔬", "Scientist",
|
||||||
"Formed 10+ hypotheses — science is prediction",
|
"Formed 10+ hypotheses — science is prediction",
|
||||||
hyp_count >= 10, scientist_date,
|
hyp_count >= 10, scientist_date,
|
||||||
f"Form 10+ hypotheses (currently: {hyp_count})")
|
f"Form 10+ hypotheses (currently: {hyp_count})",
|
||||||
|
image="/static/achievements/scientist.png")
|
||||||
|
|
||||||
_add("veteran", "🏆", "Veteran",
|
_add("veteran", "🏆", "Veteran",
|
||||||
"Completed 50+ sessions — true longevity",
|
"Completed 50+ sessions — true longevity",
|
||||||
session_count >= 50, veteran_date,
|
session_count >= 50, veteran_date,
|
||||||
f"Complete 50+ sessions (currently: {session_count})")
|
f"Complete 50+ sessions (currently: {session_count})",
|
||||||
|
image="/static/achievements/veteran.png")
|
||||||
|
|
||||||
_add("on_fire", "🔥", "On Fire",
|
_add("on_fire", "🔥", "On Fire",
|
||||||
"5+ sessions in a single day",
|
"5+ sessions in a single day",
|
||||||
on_fire_row is not None, on_fire_row[0] if on_fire_row else None,
|
on_fire_row is not None, on_fire_row[0] if on_fire_row else None,
|
||||||
"Have 5+ sessions in a single day")
|
"Have 5+ sessions in a single day",
|
||||||
|
image="/static/achievements/on_fire.png")
|
||||||
|
|
||||||
_add("storyteller", "📖", "Storyteller",
|
_add("storyteller", "📖", "Storyteller",
|
||||||
"20+ sessions with detailed Tier-2 summaries",
|
"20+ sessions with detailed Tier-2 summaries",
|
||||||
tier2_count >= 20, storyteller_date,
|
tier2_count >= 20, storyteller_date,
|
||||||
f"Summarize 20+ sessions (currently: {tier2_count})")
|
f"Summarize 20+ sessions (currently: {tier2_count})",
|
||||||
|
image="/static/achievements/storyteller.png")
|
||||||
|
|
||||||
_add("night_owl", "🌙", "Night Owl",
|
_add("night_owl", "🌙", "Night Owl",
|
||||||
"Started a session after midnight UTC",
|
"Started a session after midnight UTC",
|
||||||
night_owl_row is not None, _dt(night_owl_row[0]) if night_owl_row else None,
|
night_owl_row is not None, _dt(night_owl_row[0]) if night_owl_row else None,
|
||||||
"Start a session after midnight")
|
"Start a session after midnight",
|
||||||
|
image="/static/achievements/night_owl.png")
|
||||||
|
|
||||||
_add("speed_thinker", "⚡", "Speed Thinker",
|
_add("speed_thinker", "⚡", "Speed Thinker",
|
||||||
"Hypothesis formed and confirmed in the same session",
|
"Hypothesis formed and confirmed in the same session",
|
||||||
speed_thinker_row is not None, _dt(speed_thinker_row[0]) if speed_thinker_row else None,
|
speed_thinker_row is not None, _dt(speed_thinker_row[0]) if speed_thinker_row else None,
|
||||||
"Form and confirm a hypothesis in one session")
|
"Form and confirm a hypothesis in one session",
|
||||||
|
image="/static/achievements/speed_thinker.png")
|
||||||
|
|
||||||
# First Handshake — hardcoded: 2026-03-31 (Patrick shared BigMind with Elias)
|
# First Handshake — hardcoded: 2026-03-31 (Patrick shared BigMind with Elias)
|
||||||
_add("first_handshake", "🤝", "First Handshake",
|
_add("first_handshake", "🤝", "First Handshake",
|
||||||
"BigMind shared with Elias on 2026-03-31 — the first person outside Patrick to receive it",
|
"BigMind shared with Elias on 2026-03-31 — the first person outside Patrick to receive it",
|
||||||
True, "2026-03-31",
|
True, "2026-03-31",
|
||||||
"Share BigMind with someone")
|
"Share BigMind with someone",
|
||||||
|
image="/static/achievements/first_handshake.png")
|
||||||
|
|
||||||
_add("birthday", "🎂", "Birthday",
|
_add("birthday", "🎂", "Birthday",
|
||||||
"One full year of existence",
|
"One full year of existence",
|
||||||
birthday_unlocked, birthday_date,
|
birthday_unlocked, birthday_date,
|
||||||
birthday_extra or "Complete one full year",
|
birthday_extra or "Complete one full year",
|
||||||
extra=birthday_extra)
|
extra=birthday_extra,
|
||||||
|
image="/static/achievements/birthday.png")
|
||||||
|
|
||||||
# Locked until Phase 3
|
# Locked until Phase 3
|
||||||
_add("shared_mind", "🌍", "Shared Mind",
|
_add("shared_mind", "🌍", "Shared Mind",
|
||||||
"Phase 3 Tier G — BigMind goes company-wide",
|
"Phase 3 Tier G — BigMind goes company-wide",
|
||||||
False, None,
|
False, None,
|
||||||
"Locked until Phase 3 Tier G is enabled")
|
"Locked until Phase 3 Tier G is enabled",
|
||||||
|
image="/static/achievements/shared_mind.png")
|
||||||
|
|
||||||
# Token achievements (Feature 6 — suggested by Klaus)
|
# Token achievements (Feature 6 — suggested by Klaus)
|
||||||
_add("frugal_mind", "🪙", "Frugal Mind",
|
_add("frugal_mind", "🪙", "Frugal Mind",
|
||||||
"Logged the first token efficiency save",
|
"Logged the first token efficiency save",
|
||||||
frugal_row is not None, _dt(frugal_row[0]) if frugal_row else None,
|
frugal_row is not None, _dt(frugal_row[0]) if frugal_row else None,
|
||||||
"Log your first token save")
|
"Log your first token save",
|
||||||
|
image="/static/achievements/frugal_mind.png")
|
||||||
|
|
||||||
_add("quarter_million", "💰", "Quarter Million",
|
_add("quarter_million", "💰", "Quarter Million",
|
||||||
"250,000 cumulative tokens saved",
|
"250,000 cumulative tokens saved",
|
||||||
token_total >= 250_000, quarter_million_date,
|
token_total >= 250_000, quarter_million_date,
|
||||||
f"Save 250,000+ tokens (currently: {token_total:,})")
|
f"Save 250,000+ tokens (currently: {token_total:,})",
|
||||||
|
image="/static/achievements/quarter_million.png")
|
||||||
|
|
||||||
_add("token_millionaire", "🏦", "Token Millionaire",
|
_add("token_millionaire", "🏦", "Token Millionaire",
|
||||||
"1,000,000 cumulative tokens saved",
|
"1,000,000 cumulative tokens saved",
|
||||||
token_total >= 1_000_000, millionaire_date,
|
token_total >= 1_000_000, millionaire_date,
|
||||||
f"Save 1,000,000+ tokens (currently: {token_total:,})")
|
f"Save 1,000,000+ tokens (currently: {token_total:,})",
|
||||||
|
image="/static/achievements/token_millionaire.png")
|
||||||
|
|
||||||
_add("sniper", "🎯", "Sniper",
|
_add("sniper", "🎯", "Sniper",
|
||||||
"Single token save > 500,000 — one massive efficiency win",
|
"Single token save > 500,000 — one massive efficiency win",
|
||||||
sniper_row is not None, _dt(sniper_row[0]) if sniper_row else None,
|
sniper_row is not None, _dt(sniper_row[0]) if sniper_row else None,
|
||||||
"Save 500,000+ tokens in a single operation")
|
"Save 500,000+ tokens in a single operation",
|
||||||
|
image="/static/achievements/sniper.png")
|
||||||
|
|
||||||
# ── Tiered Achievement Badges (20 PNG) ────────────────────────────────────
|
# ── Tiered Achievement Badges (20 PNG) ────────────────────────────────────
|
||||||
# NOTE: conn is already closed above; open a fresh connection for tiered queries
|
# NOTE: conn is already closed above; open a fresh connection for tiered queries
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 375 KiB |
|
Before Width: | Height: | Size: 513 KiB |
|
Before Width: | Height: | Size: 410 KiB After Width: | Height: | Size: 410 KiB |
|
Before Width: | Height: | Size: 372 KiB After Width: | Height: | Size: 372 KiB |
|
Before Width: | Height: | Size: 390 KiB After Width: | Height: | Size: 390 KiB |
|
Before Width: | Height: | Size: 261 KiB After Width: | Height: | Size: 261 KiB |
|
Before Width: | Height: | Size: 340 KiB After Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 406 KiB After Width: | Height: | Size: 406 KiB |
|
Before Width: | Height: | Size: 367 KiB After Width: | Height: | Size: 367 KiB |
|
Before Width: | Height: | Size: 319 KiB After Width: | Height: | Size: 319 KiB |
|
Before Width: | Height: | Size: 301 KiB After Width: | Height: | Size: 301 KiB |
|
Before Width: | Height: | Size: 439 KiB After Width: | Height: | Size: 439 KiB |
|
Before Width: | Height: | Size: 462 KiB After Width: | Height: | Size: 462 KiB |
|
Before Width: | Height: | Size: 429 KiB After Width: | Height: | Size: 429 KiB |
|
Before Width: | Height: | Size: 376 KiB After Width: | Height: | Size: 376 KiB |
|
Before Width: | Height: | Size: 400 KiB After Width: | Height: | Size: 400 KiB |
|
Before Width: | Height: | Size: 289 KiB After Width: | Height: | Size: 289 KiB |
|
Before Width: | Height: | Size: 431 KiB After Width: | Height: | Size: 431 KiB |
|
Before Width: | Height: | Size: 418 KiB After Width: | Height: | Size: 418 KiB |
|
Before Width: | Height: | Size: 458 KiB After Width: | Height: | Size: 458 KiB |
|
Before Width: | Height: | Size: 403 KiB After Width: | Height: | Size: 403 KiB |