Skip to content

chore/mypy slice failgate#7

Merged
msaedi merged 1 commit intomainfrom
chore/mypy-slice-failgate
Sep 17, 2025
Merged

chore/mypy slice failgate#7
msaedi merged 1 commit intomainfrom
chore/mypy-slice-failgate

Conversation

@msaedi
Copy link
Copy Markdown
Owner

@msaedi msaedi commented Sep 17, 2025

  • types: clean MyPy bookings/availability slice; adjust types only\n\n- WeekOperationRepository instructor_id params: str (ULID).\n- BookingService: remove redundant casts; exclude_booking_id type is Optional[str].\n- No runtime changes.
  • ci: promote MyPy bookings/availability slice to fail-gate\n\n- CI: switch slice step to fail; keep summary.\n- Pre-push: add slice mypy fast gate.\n- No runtime changes.

…itch slice step to fail; keep summary.\n- Pre-push: add slice mypy fast gate.\n- No runtime changes.
@vercel
Copy link
Copy Markdown

vercel bot commented Sep 17, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
instainstru-preview Ready Ready Preview Comment Sep 17, 2025 2:04am
instructly Ready Ready Preview Comment Sep 17, 2025 2:04am

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

app/services/week_operation_service.py \
app/routes/bookings.py \
app/routes/availability_windows.py)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Duplicate Mypy Check in Prepush Hook

The mypy bookings/availability slice check is duplicated in the prepush.sh script, causing it to run twice. This unnecessarily slows down the pre-push hook and generates redundant output.

Fix in Cursor Fix in Web

@msaedi msaedi merged commit 4ef4d22 into main Sep 17, 2025
14 checks passed
@msaedi msaedi deleted the chore/mypy-slice-failgate branch September 17, 2025 02:22
msaedi added a commit that referenced this pull request Feb 11, 2026
Address issues found during founding instructor journey testing:
- #2: Welcome page copy "your area" → "NYC"
- #3/#7: Add "(Optional)" labels to preferred locations fields
- #6: Default years_experience to 1 instead of 0
- #9: Reorder category display_order, fix catalog spacing
- #14: Three-state identity verification (verified/pending/not started),
  clear session_id on terminal failures to prevent stuck pending state
- #15: Fix BGC disclosure modal empty space with flex layout
- #16: Add post-invite confirmation modal and inline pending banner
- #19: Hide BGC button and timing message for passed/pending statuses
- #20: Fix completed step color (brand purple at 60% opacity),
  add dark mode support and consistent row heights to checklist
msaedi added a commit that referenced this pull request Mar 9, 2026
Bugs fixed:
- #1: effective_hourly_rate added to RankedResult, passed through
  to search response for format-specific price display
- #2: None hourly_rate guard in _normalize_format_prices prevents
  InvalidOperation crash
- #3: sync_format_prices rejects empty list to maintain at-least-one
  format invariant

Medium fixes:
- #4: FilterService DB ops wrapped in asyncio.to_thread matching
  RankingService and PostgresRetriever patterns
- #5: Documented eager-load requirement on format_prices relationship
- #6: prices_by_format cached to avoid recomputation during
  serialization
- #7: Removed redundant DomainException catch-and-reraise in
  pricing_service

Style:
- #8: f-string logger calls replaced with lazy formatting
- #9: from_orm extracted into helper methods (_serialize_services,
  _serialize_neighborhoods, _serialize_coverage_areas)
- #10: Comments on hybrid expression methods explaining SQLAlchemy
  pattern

Tests added:
- Cascade delete (service deletion removes format prices)
- Boundary values (/bin/zsh.01, .00, exact floor amounts)
- Differentiated rates in booking/pricing/search fixtures
- sync_format_prices update path and empty list rejection
msaedi added a commit that referenced this pull request Mar 9, 2026
* feat(pricing): per-format pricing — full backend migration

New service_format_pricing table: each service has 1-3 format prices
(student_location, instructor_location, online) with independent rates.

Removed from instructor_services: hourly_rate column, offers_travel,
offers_at_location, offers_online columns. Capabilities derived from
format price existence via hybrid_property.

Service layer: format_prices on create/update, config-driven floor
validation, capabilities PATCH route removed.

Booking: price_for_booking(duration, location_type) resolves format
rate. neutral_location accepts either in-person capability, prefers
instructor_location rate with student_location fallback.

Search: MIN subquery for min_hourly_rate, EXISTS for capability
filtering, format-aware price+lesson_type intersection so in-person
max_price filters against in-person rates not global min. Ranking
uses effective_hourly_rate for queried format.

Pricing: PricingPreviewIn.location_type selects fmat-specific rate.

12,791+ tests passing. All legacy hourly_rate and capability boolean
references removed. OpenAPI spec regenerated.

* feat(onboarding): per-format pricing UI + skill-selection restructure

Frontend — Per-Format Pricing:
FormatPricingCards component with three-card layout (student_location,
online, instructor_location). Greyed until toggled, floor-based
placeholders (80/60), inline validation, take-home calculation.

Onboarding skill-selection: replaced single hourly rate + capability
toggles with format cards. Service Areas and Class Locations moved
from account-setup to skill-selection, conditional on enabled formats.
Instructor_location freely toggleable (removed circular gating).
Save flow: service areas PUT with error handling before profile PUT.

Profile editing (SkillsPricingInline): same format card pattern,
format_prices replaces hourly_rate + offers_* in state/payload.

Backend: reordered update_profile to save teaching locations before
services, fixing 422 when instructor_location enabled in same request.

Account setup: client-side bio validation (10-1000 chars) with
character cnt display. Prevents raw Pydantic error surfacing.

8313 frontend tests passing, 12799 backend tests passing.

* feat(pricing): per-format pricing — full stack implementation

Backend:
- New service_format_pricing table (Option B): each service has 1-3
  format prices (student_location, instructor_location, online)
- Removed hourly_rate, offers_travel, offers_at_location, offers_online
  columns from instructor_services. Capabilities derived from format
  price existence via hybrid_property.
- Service layer: format_prices on create/update, config-driven floor
  validation ( in-person,  online,  cap).
- Booking: price_for_booking(duration, location_type) resolves format
  rate. neutral_location accepts either in-person capability, prefers
  instructor_location rate with student_location fallback.
- Search: MIN subquery for min_hourly_rate, EXISTS for capability
  filtering, format-aware price+lesson_type intersection. Ranking
  uses effective_hourly_rate for queried format.
- Format prerequisite validation (service areas, teaching locations)
  moved from profile save to go-le only.
- NL parser: added 'at their studio/location' to lesson type regex.
- Seed data: realistic per-format pricing across 82 services.
- 12,802 backend tests passing.

Frontend — Instructor-facing:
- FormatPricingCards shared component (three-card layout, floor-based
  placeholders, inline validation, take-home calculation).
- Onboarding skill-selection: format cards replace hourly rate input.
  Service Areas + Class Locations moved from account-setup, conditional
  on enabled formats.
- Dashboard profile: same format cards, sections reordered (skills
  first, locations below conditional on formats).
- EditProfileModal: removed broken services variant (replaced by
  SkillsPricingInline).

Frontend — Student-facing:
- Search cards: format-specific rate when filtered, 'from X/hr' when
  not. InstructorCard receives searchLessonType for contextual pricing.
- Instructor profile: ServiceCards show per-format rate breakdown.
- Booking flow: location types derived from format_prices.
- NL search: raw query  on initial search (no keyword stripping),
  parsed lesson_type and price auto-applied to filter UI.
- In-person filter option added (maps to both travel + studio).
- Admin NL search: format_prices breakdown in results.

8,344 frontend tests, 12,802 backend tests passing.

* fix(pricing): audit cleanup — CTE extraction, stale refs, DB tests

Backend:
- Extracted service_price_summary CTE to _price_cte_query() helper
  in retriever_repository.py (eliminates 5 copies, passes Bandit)
- Added covering index (service_id) INCLUDE (hourly_rate, format)
- Explicit flush in sync_format_prices before inserts
- is_founding_instructor added to text-only search path
- Defensive BusinessRuleException in _floor_for_format
- Repository ordering aligned to SERVICE_PRICE_FORMAT_ORDER
- neutral_location fallback comment added
- Return type annotation fixed on serialized_format_prices
- DB-level integration tests: unique constraint, price cap, zero
  rate, invalid format

Frontend:
- EditProfileModal full variant: service editing removed
- RescheduleTimeSelectionModal: hourly_rate → min_hourly_rate
- Test fixture price_per_hour → format_prices + min_hourly_rate
- Stale reference sweep clean across all surfaces

* fix(pricing): address all PR review findings

Bugs fixed:
- #1: effective_hourly_rate added to RankedResult, passed through
  to search response for format-specific price display
- #2: None hourly_rate guard in _normalize_format_prices prevents
  InvalidOperation crash
- #3: sync_format_prices rejects empty list to maintain at-least-one
  format invariant

Medium fixes:
- #4: FilterService DB ops wrapped in asyncio.to_thread matching
  RankingService and PostgresRetriever patterns
- #5: Documented eager-load requirement on format_prices relationship
- #6: prices_by_format cached to avoid recomputation during
  serialization
- #7: Removed redundant DomainException catch-and-reraise in
  pricing_service

Style:
- #8: f-string logger calls replaced with lazy formatting
- #9: from_orm extracted into helper methods (_serialize_services,
  _serialize_neighborhoods, _serialize_coverage_areas)
- #10: Comments on hybrid expression methods explaining SQLAlchemy
  pattern

Tests added:
- Cascade delete (service deletion removes format prices)
- Boundary values (/bin/zsh.01, .00, exact floor amounts)
- Differentiated rates in booking/pricing/search fixtures
- sync_format_prices update path and empty list rejection

* fix(pricing): final PR review — pipeline consistency + test gaps

- Added lesson_type_hourly_rate to ServiceCandidate dataclass
- Clarifying comments on filter rate assumption and soft filter rebuild
- Confirmed eager-load on ConflictCheckerRepository.get_active_service
- Tests: missing format raises BusinessRuleException, serialization
  order matches SERVICE_PRICE_FORMAT_ORDER, coerce rejects invalid
  inputs

* fix(pricing): early validation for location_type, lesson_type, empty format

- Booking: validate location_type against format_prices early in
  _validate_location_capability with clear user-facing error
- Search: guard unknown lesson_type in FilterService — log warning
  and return unfiltered instead of silently dropping results
- Model: reject empty-string format in _coerce_format_price_row
  with ValueError listing valid formats
msaedi added a commit that referenced this pull request Mar 20, 2026
…,14,15,17,19,20,21,22,23)

Icons and visual cleanup:
- Replace confetti emoji with Lucide Rocket on Go Live button (#1)
- Replace crooked star with Phosphor Star on Reviews card (#6)
- Proportional star fill based on rating, inline "4.5★ (3)" metadata (#7)
- Add @phosphor-icons/react dependency

Account settings overhaul:
- Single-open accordion — only one section expanded at a time (#14)
- Section icons: UserRoundPen (Account), SlidersHorizontal (Prefs), Info (About) (#21)
- Remove Acknowledgments from About, rename support label (#20)
- Remove phone management block from Preferences (#17)
- Format phone display as (212) 555-1001 in Account Details (#10)
- Shared formatPhoneDisplay helper in lib/phone.ts
- 2FA state refreshes immediately after enable/disable (#12)

2FA modal copy:
- Title → "Connect your authenticator app" (#15)
- Step 1/Step 2 labels, button → "Verify"

Notification preferences:
- Isolate per-toggle pendi single toggle change no longer
  flashes entire Push column (#19)

Instructor profile:
- Remove Personal Information accordion from dashboard context (#22)
- Skills & Pricing icon → Phosphor Tag (#23)

Verify: 13,194 backend + 389 frontend tests passing.
msaedi added a commit that referenced this pull request Mar 21, 2026
…design (#339)

* feat(dashboard): A-Team quick wins Part 1 — 12 UI fixes (#1,6,7,10,12,14,15,17,19,20,21,22,23)

Icons and visual cleanup:
- Replace confetti emoji with Lucide Rocket on Go Live button (#1)
- Replace crooked star with Phosphor Star on Reviews card (#6)
- Proportional star fill based on rating, inline "4.5★ (3)" metadata (#7)
- Add @phosphor-icons/react dependency

Account settings overhaul:
- Single-open accordion — only one section expanded at a time (#14)
- Section icons: UserRoundPen (Account), SlidersHorizontal (Prefs), Info (About) (#21)
- Remove Acknowledgments from About, rename support label (#20)
- Remove phone management block from Preferences (#17)
- Format phone display as (212) 555-1001 in Account Details (#10)
- Shared formatPhoneDisplay helper in lib/phone.ts
- 2FA state refreshes immediately after enable/disable (#12)

2FA modal copy:
- Title → "Connect your authenticator app" (#15)
- Step 1/Step 2 labels, button → "Verify"

Notification preferences:
- Isolate per-toggle pendi single toggle change no longer
  flashes entire Push column (#19)

Instructor profile:
- Remove Personal Information accordion from dashboard context (#22)
- Skills & Pricing icon → Phosphor Tag (#23)

Verify: 13,194 backend + 389 frontend tests passing.

* feat(dashboard): A-Team quick wins Part 2 — 8 UI fixes (#5,27,28,29,36,37,38)

Platform launch gate:
- Replace hardcoded date gate on Public Profile with student_launch_enabled
  platform config flag, default false (#5)
- Exposed through /api/v1/config/public, read-only in this pass

Tab indicators:
- Standardize all tab indicators to text-width across platform (#27)
- Shared textWidthTabs helper, applied to Bookings + Earnings tabs

Booking status consistency:
- Completed badge → blue everywhere: list cards, detail page, modal (#28)
- Shared bookingStatus helper for badge color standard
  (Confirmed=green, Completed=blue, Cancelled=red)
- Empty states for Upcoming + Past booking tabs (#29)

Messages fixes:
- "Last updated manually" → actual timestamp or hidden (#36)
- "NEXT BOOKING" → sentence case "Next booking" (#37)
- Upcoming badge → green (matches Confirmed standard)
- Booking cards in dropdown are now clickable links

Left nav:
- Reordered: Dashboard, Bookings, Messages, Availability,
  Referrals, Reviews, Instructor Profile, Account (#38)
- Messages added as route link with MessageSquare icon
- Shared nav config drives both desktop and mobile

Verify: 13,198 backend + 392 frontend tests passing.

* fix(dashboard): address testing feedback on quick wins branch

Fixes from manual testing:
- Restore two-line empty state format: bold heading + muted subtitle
  in dashed card (Upcoming + Past booking tabs)
- Remove MessageSquare icon from Messages nav item (text-only like others)
- Public Profile button: environment-aware — always enabled on
  preview/localhost, gated by student_launch_enabled on beta hosts only
- 2FA: redirect to /login after disable (immediate) and after enable
  (after backup codes acknowledgment) to prevent stale session UI
- Account Details: split Name into First name + Last name (locked),
  inline phone verification with Verified/Verify/Pending states
- Update e2e tests for new reviews card DOM (reviews-summary testid)
msaedi added a commit that referenced this pull request Mar 25, 2026
…at + 2FA ordering

Review pass fixes:
- #8b: Address sync only fires when ZIP actually changed
- #7: Reviews stat card matches other cards (title, value size, outlined star)
- #19: Push notification warning copy differentiated from subtitle
- #31: Earnings empty states updated (invoices + payouts)
- #24/#25 prep: Booking card layout foundations
- #OB-3: Years of experience no longer defaults to 1, select-all on focus
- #OB-5: Max rate ,000 enforced frontend + backend, blocks save on violation
- #OB-9: Progress indicator requires address when instructor_location selected
- #OB-11: Removed duplicate BGC mismatch warning
- #OB-12: Fixed 'Finish Resolve' broken banner copy
- #OB-1: Removed Availability Commitment from founding perks
- #OB-2: Removed founding instructor cap count from welcome
- #OB-6: Skill config labels converted tsentence case
- #OB-13: Subcategory labels converted to title case
- #OB-8: Fixed broken View map on student lesson detail

Student chat fix:
- ChatModal uses shared createConversation (was sending instructor_id → 422)
- Query gated on isOpen, retries disabled when closed

2FA transaction ordering:
- Token invalidation moved to last step in setup_verify and disable
- Trusted device revocation wrapped in try/except (non-critical)
- Prevents lockout if trusted device operation fails

13,296 backend + 8,339 frontend tests passing. Type coverage 100%.
msaedi added a commit that referenced this pull request Mar 25, 2026
…at + 2FA ordering

Review pass fixes:
- #8b: Address sync only fires when ZIP actually changed
- #7: Reviews stat card matches other cards (title, value size, outlined star)
- #19: Push notification warning copy differentiated from subtitle
- #31: Earnings empty states updated (invoices + payouts)
- #24/#25 prep: Booking card layout foundations
- #OB-3: Years of experience no longer defaults to 1, select-all on focus
- #OB-5: Max rate ,000 enforced frontend + backend, blocks save on violation
- #OB-9: Progress indicator requires address when instructor_location selected
- #OB-11: Removed duplicate BGC mismatch warning
- #OB-12: Fixed 'Finish Resolve' broken banner copy
- #OB-1: Removed Availability Commitment from founding perks
- #OB-2: Removed founding instructor cap count from welcome
- #OB-6: Skill config labels converted tsentence case
- #OB-13: Subcategory labels converted to title case
- #OB-8: Fixed broken View map on student lesson detail

Student chat fix:
- ChatModal uses shared createConversation (was sending instructor_id → 422)
- Query gated on isOpen, retries disabled when closed

2FA transaction ordering:
- Token invalidation moved to last step in setup_verify and disable
- Trusted device revocation wrapped in try/except (non-critical)
- Prevents lockout if trusted device operation fails

13,296 backend + 8,339 frontend tests passing. Type coverage 100%.
msaedi added a commit that referenced this pull request Mar 25, 2026
…at + 2FA ordering

Review pass fixes:
- #8b: Address sync only fires when ZIP actually changed
- #7: Reviews stat card matches other cards (title, value size, outlined star)
- #19: Push notification warning copy differentiated from subtitle
- #31: Earnings empty states updated (invoices + payouts)
- #24/#25 prep: Booking card layout foundations
- #OB-3: Years of experience no longer defaults to 1, select-all on focus
- #OB-5: Max rate ,000 enforced frontend + backend, blocks save on violation
- #OB-9: Progress indicator requires address when instructor_location selected
- #OB-11: Removed duplicate BGC mismatch warning
- #OB-12: Fixed 'Finish Resolve' broken banner copy
- #OB-1: Removed Availability Commitment from founding perks
- #OB-2: Removed founding instructor cap count from welcome
- #OB-6: Skill config labels converted tsentence case
- #OB-13: Subcategory labels converted to title case
- #OB-8: Fixed broken View map on student lesson detail

Student chat fix:
- ChatModal uses shared createConversation (was sending instructor_id → 422)
- Query gated on isOpen, retries disabled when closed

2FA transaction ordering:
- Token invalidation moved to last step in setup_verify and disable
- Trusted device revocation wrapped in try/except (non-critical)
- Prevents lockout if trusted device operation fails

13,296 backend + 8,339 frontend tests passing. Type coverage 100%.
msaedi added a commit that referenced this pull request Mar 25, 2026
…at + 2FA ordering

Review pass fixes:
- #8b: Address sync only fires when ZIP actually changed
- #7: Reviews stat card matches other cards (title, value size, outlined star)
- #19: Push notification warning copy differentiated from subtitle
- #31: Earnings empty states updated (invoices + payouts)
- #24/#25 prep: Booking card layout foundations
- #OB-3: Years of experience no longer defaults to 1, select-all on focus
- #OB-5: Max rate ,000 enforced frontend + backend, blocks save on violation
- #OB-9: Progress indicator requires address when instructor_location selected
- #OB-11: Removed duplicate BGC mismatch warning
- #OB-12: Fixed 'Finish Resolve' broken banner copy
- #OB-1: Removed Availability Commitment from founding perks
- #OB-2: Removed founding instructor cap count from welcome
- #OB-6: Skill config labels converted tsentence case
- #OB-13: Subcategory labels converted to title case
- #OB-8: Fixed broken View map on student lesson detail

Student chat fix:
- ChatModal uses shared createConversation (was sending instructor_id → 422)
- Query gated on isOpen, retries disabled when closed

2FA transaction ordering:
- Token invalidation moved to last step in setup_verify and disable
- Trusted device revocation wrapped in try/except (non-critical)
- Prevents lockout if trusted device operation fails

13,296 backend + 8,339 frontend tests passing. Type coverage 100%.
msaedi added a commit that referenced this pull request Mar 25, 2026
Review pass fixes:
- #8b: Address sync only fires when ZIP actually changed
- #7: Reviews stat card matches other cards (title, value size, outlined star)
- #19: Push notification warning copy differentiated from subtitle
- #31: Earnings empty states updated (invoices + payouts)
- #24/#25 prep: Booking card layout foundations
- #OB-3: Years of experience no longer defaults to 1, select-all on focus
- #OB-5: Max rate ,000 enforced frontend + backend, blocks save on violation
- #OB-9: Progress indicator requires address when instructor_location selected
- #OB-11: Removed duplicate BGC mismatch warning
- #OB-12: Fixed 'Finish Resolve' broken banner copy
- #OB-1: Removed Availability Commitment from founding perks
- #OB-2: Removed founding instructor cap count from welcome
- #OB-6: Skill config labels converted tsentence case
- #OB-13: Subcategory labels converted to title case
- #OB-8: Fixed broken View map on student lesson detail

Student chat fix:
- ChatModal uses shared createConversation (was sending instructor_id → 422)
- Query gated on isOpen, retries disabled when closed

2FA transaction ordering:
- Token invalidation moved to last step in setup_verify and disable
- Trusted device revocation wrapped in try/except (non-critical)
- Prevents lockout if trusted device operation fails

13,296 backend + 8,339 frontend tests passing. Type coverage 100%.
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