Skip to content

Lots#228

Merged
gregv merged 14 commits into
mainfrom
develop
May 27, 2026
Merged

Lots#228
gregv merged 14 commits into
mainfrom
develop

Conversation

@gregv
Copy link
Copy Markdown
Contributor

@gregv gregv commented May 27, 2026

No description provided.

gregv and others added 14 commits May 17, 2026 21:53
…-3ca3eb-blog-admin

Perf improvements and backfill
… display

Winning teams take ~3 months post-hackathon to satisfy the 8-item Definition
of Done (https://ohack.dev/about/completion). Adds the backend half of an
interactive checklist on /hack/<event_id>/team/<team_id>: each item, when
checked by a team member, posts a celebration to the team's Slack channel;
the final "mark complete" Slack-mentions all 6 OHack admins.

Backend changes:
- services/teams_service.py: get_team now enriches team.users[] from a list
  of doc-id strings into slim profile dicts {id, user_id, name, nickname,
  profile_image} via a single batched Firestore get_all. Backwards-compatible
  with callers (HackathonResults.js / TeamList.js already handle both shapes).
  Fixes the bug where /hack/.../team/<id> rendered "Team Member" for every
  person. The get_team TTLCache is now register_cache()-tracked so admin
  actions (add_team_member, etc.) correctly invalidate it.
- api/teams/teams_service.py: promoted the inline slack_admins list to a
  module-level TEAM_COMPLETION_SLACK_ADMINS constant (single source of truth
  for both queue_team admin invites and completion broadcasts). Added a
  canonical COMPLETION_ITEMS list (slugs must stay in lockstep with the
  frontend), plus user_is_on_team(), toggle_completion_item(), and
  mark_team_complete() service functions. user_is_on_team correctly
  translates the PropelAuth UUID -> OAuth user_id via
  get_propel_user_details_by_id (same pattern as get_my_teams_by_event_id),
  with a propel_id direct-match fallback.
- api/teams/teams_views.py: two new self-serve routes
    POST /api/team/<teamid>/completion/toggle    body { item: <slug> }
    POST /api/team/<teamid>/completion/complete  body {}
  Both @auth.require_user + team-membership gated. Toggle 409s on re-check
  (no unchecking, no double-Slack). Complete 409s if any item is missing or
  if already complete (idempotent).

New optional Firestore fields on a team doc (no migration):
  completion_checklist: { [slug]: { done, completed_at, completed_by_* } }
  completion_status: "not_started" | "in_progress" | "complete"
  completion_completed_at, completion_completed_by_propel_id,
  completion_completed_by_name

Frontend half ships in the matching frontend-ohack.dev PR.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…checklist

[Teams] Project-completion checklist + enriched team member display
Two bugs in the completion toggle/complete flow surfaced on the deployed
backend:

1. `TTLCache object has no attribute 'cache_clear'` — services/teams_service.py
   called register_cache(_GET_TEAM_CACHE) on the raw TTLCache instance,
   but clear_all_caches() expects entries to expose .cache_clear() (the
   method cachetools' @cached decorator adds to the wrapped function).
   TTLCache only has .clear(). Made clear_all_caches() try both, so
   either an @cached function or a bare cache object can be registered.

2. `TypeError: Object of type DocumentReference is not JSON serializable`
   — at the end of toggle_completion_item / mark_team_complete I returned
   team_doc.get().to_dict() directly. That dict contains users[] as raw
   Firestore DocumentReferences which Flask's JSON encoder can't serialize.
   Routed both return paths through get_team(team_id) instead, which
   produces the same JSON-safe + user-enriched payload the frontend
   already consumes from GET /api/messages/team/<id>. Cache is cleared
   right before this call so the fresh state is fetched, not stale.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…oggle-bugs

[Teams] Hotfix: completion toggle TTLCache + DocumentReference JSON errors
Comment thread api/teams/teams_views.py
item_slug = body.get("item")
if not item_slug:
return {"error": "Missing 'item' in request body"}, 400
return toggle_completion_item(auth_user.user_id, teamid, item_slug)
return vars(save_hackathon(request.get_json(), user_id))
result = save_hackathon(request.get_json(), user_id)
if isinstance(result, tuple):
return result
@gregv gregv merged commit f7c5b27 into main May 27, 2026
9 of 10 checks passed
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.

2 participants