Skip to content

Prep for 2026 - #270

Merged
gregv merged 6 commits into
mainfrom
develop
Aug 23, 2026
Merged

Prep for 2026#270
gregv merged 6 commits into
mainfrom
develop

Conversation

@gregv

@gregv gregv commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

No description provided.

gregv and others added 6 commits August 18, 2026 21:46
The frontend adds a times-only meals mode: meals_mode "schedule" shows
hackers just the meal times (no item selection) with an optional meals_note
intro line. Both hackathon validators now enforce meals_mode in
ALLOWED_MEALS_MODES {menu, schedule} and meals_note as a string capped at
MAX_MEALS_NOTE_LENGTH (500), with partial-save skip semantics. Kept in sync
with MEALS_MODE_* / MEALS_NOTE_MAX_LENGTH in the frontend MealSchedule.js.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…only-mode

Validate constraints.meals_mode + meals_note (times-only meal schedules)
Fixes the bug where an approved mentor/judge/volunteer/sponsor editing
their application was silently reset to isSelected=false (and could lose
check-in / refund state the same way).

- STAFF_OWNED_VOLUNTEER_FIELDS stripped from every self-service
  submit/update in create_or_update_volunteer: isSelected, check-in
  fields, refund bookkeeping, certificates, sent_emails. Deposit payment
  fields (stripe_payment_intent_id, deposit_amount_cents,
  deposit_disposition) deliberately excluded — the hacker Stripe return
  sets those on /update. Also closes authenticated self-approval on the
  create path (payload could override the isSelected=False seed).
- find_volunteer_by_caller_identity(): shared 3-way resolver (propel
  UUID -> PropelAuth email -> OAuth user_id) now used by handle_get,
  create_or_update_volunteer, and mentors' _find_mentor_volunteer.
  Read and write matching the same docs stops edits from falling into
  the create branch and spawning duplicate isSelected=False docs.
- All ten /api/{type}/application/<event>/{submit,update} routes are
  @auth.require_user (were optional_user); identity comes from the
  verified token only — the body user_id fallback is gone.
- _notifications_disabled(): ENVIRONMENT=test suppresses the
  Slack/Resend fan-out — unit tests were posting real Slack messages
  and attempting real Resend sends.
- Regression tests for all of the above (each verified to fail against
  the old code); fixed test_update_volunteer's stale .update() assert
  (code calls .set(merge=True)).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-owned-fields

Make volunteer approval server-authoritative; unify identity resolution
Volunteer job board backend for /jobs on the frontend. New api/jobs
blueprint with public listing routes, login-required apply routes
(signed-URL PDF resume upload, server-side URL verification, reCAPTCHA,
duplicate check), and volunteer.admin CRUD + one-click accept/reject
decision emails. Confirmation email carries a reply-within-5-days ask;
every application also sends an FYI to questions@ohack.org. Includes
validators, 300s caches, and an idempotent seed script for the three
Fall 2026 roles.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add jobs API: listings, applications, and emails
Comment thread api/jobs/jobs_views.py
data = request.get_json() or {}
payload, status = create_resume_upload_url(
auth_user.user_id, data.get("content_type"), data.get("content_length"))
return payload, status
Comment thread api/jobs/jobs_views.py
def admin_post_listing():
logger.info("POST /jobs/admin/listings called")
payload, status = admin_create_listing(request.get_json(), _actor_from_request())
return payload, status
Comment thread api/jobs/jobs_views.py
def admin_patch_listing(slug):
logger.info(f"PATCH /jobs/admin/listings/{slug} called")
payload, status = admin_update_listing(slug, request.get_json(), _actor_from_request())
return payload, status
Comment thread api/jobs/jobs_views.py
logger.info(f"POST /jobs/{slug}/apply called")
payload, status = submit_application(
auth_user.user_id, request.remote_addr, slug, request.get_json())
return payload, status
Comment thread api/jobs/jobs_views.py
def admin_post_listing():
logger.info("POST /jobs/admin/listings called")
payload, status = admin_create_listing(request.get_json(), _actor_from_request())
return payload, status
Comment thread api/jobs/jobs_views.py
def admin_patch_listing(slug):
logger.info(f"PATCH /jobs/admin/listings/{slug} called")
payload, status = admin_update_listing(slug, request.get_json(), _actor_from_request())
return payload, status
@gregv
gregv merged commit dff90ba into main Aug 23, 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