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",
|
||||
"Opened the very first session",
|
||||
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",
|
||||
"Formed the first hypothesis",
|
||||
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",
|
||||
"First hypothesis confirmed as true",
|
||||
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",
|
||||
"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,
|
||||
"Have a hypothesis refuted")
|
||||
"Have a hypothesis refuted",
|
||||
image="/static/achievements/honest_mind.png")
|
||||
|
||||
_add("scholar", "📚", "Scholar",
|
||||
"Stored 25+ personal facts",
|
||||
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",
|
||||
"Amassed 100+ stored facts",
|
||||
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",
|
||||
"Formed 10+ hypotheses — science is prediction",
|
||||
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",
|
||||
"Completed 50+ sessions — true longevity",
|
||||
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",
|
||||
"5+ sessions in a single day",
|
||||
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",
|
||||
"20+ sessions with detailed Tier-2 summaries",
|
||||
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",
|
||||
"Started a session after midnight UTC",
|
||||
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",
|
||||
"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,
|
||||
"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)
|
||||
_add("first_handshake", "🤝", "First Handshake",
|
||||
"BigMind shared with Elias on 2026-03-31 — the first person outside Patrick to receive it",
|
||||
True, "2026-03-31",
|
||||
"Share BigMind with someone")
|
||||
"Share BigMind with someone",
|
||||
image="/static/achievements/first_handshake.png")
|
||||
|
||||
_add("birthday", "🎂", "Birthday",
|
||||
"One full year of existence",
|
||||
birthday_unlocked, birthday_date,
|
||||
birthday_extra or "Complete one full year",
|
||||
extra=birthday_extra)
|
||||
extra=birthday_extra,
|
||||
image="/static/achievements/birthday.png")
|
||||
|
||||
# Locked until Phase 3
|
||||
_add("shared_mind", "🌍", "Shared Mind",
|
||||
"Phase 3 Tier G — BigMind goes company-wide",
|
||||
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)
|
||||
_add("frugal_mind", "🪙", "Frugal Mind",
|
||||
"Logged the first token efficiency save",
|
||||
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",
|
||||
"250,000 cumulative tokens saved",
|
||||
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",
|
||||
"1,000,000 cumulative tokens saved",
|
||||
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",
|
||||
"Single token save > 500,000 — one massive efficiency win",
|
||||
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) ────────────────────────────────────
|
||||
# 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 |