Skip to Content
Living documentation — last reviewed 2026-05-28
FeaturesLocationsLocations — QA Plan

Locations — QA Plan

Pre-requisites

  • Test org on lite platform tier (lowest tier — caps maxLocations lowest, lets you hit the tier ceiling quickly).
  • A second org for isolation tests.
  • Owner, admin, coach, member personas.
  • An org session with location_id set to a location WITH coordinates, and another session with location_id set to a location WITHOUT coordinates.

Golden paths

G1 — Owner adds a location with autocomplete

StepActionExpected
1Owner navigates to settings → locations.List loads.
2Click “Add a location”. Type address into autocomplete.Suggestions appear from Google Places.
3Pick a result.Fields populate: address, city, country, lat, lng.
4Set name + capacity. Submit.POST succeeds; row appears with non-null lat/lng.

G2 — Owner adds a location without coords (manual)

StepActionExpected
1Submit form with name only, no autocomplete.Row inserted; lat/lng null.
2Try GPS check-in on a session linked to this location.400 ‘Session location coordinates are not configured’.

G3 — Deactivate

StepActionExpected
1Delete location.is_active=false. List omits it.
2A future session still linked: opens fine; location name still resolvable for display.

Edge cases

E1 — Tier limit

StepActionExpected
1Org at lite already has maxLocations active locations.
2POST a new location.403 ‘Location limit reached (N/M). Upgrade your plan to add more.‘
3Upgrade to pro (or whatever the next tier is — TODO verify mapping).Now POST succeeds.

E2 — Tier downgrade with over-limit

StepActionExpected
1Org at pro with locations > lite cap. Downgrade to lite.Locations remain active. (Tier check is creation-time only — verify whether a separate enforcement exists in platform-billing TODO.)

E3 — Cross-org access

StepActionExpected
1Owner of org A: GET /organizations/A/locations/{idFromB}.404.
2Same for PATCH and DELETE.404 each.

E4 — Non-staff mutation

StepActionExpected
1Coach POST/PATCH/DELETE.403.
2Member same.403.

E5 — Partial coords

StepActionExpected
1POST with latitude=32.07 and no longitude.Row inserted (both nullable).
2GPS check-in against a session linked here.400 ‘Session location coordinates are not configured’.

E6 — GPS Haversine boundary

StepActionExpected
1Location at known coords. Self-checkin from just inside GPS_MAX_METERS.Succeeds.
2From just outside GPS_MAX_METERS.400 ‘GPS_TOO_FAR’.

Cross-persona

  • Members can list and get-by-id; cannot mutate.
  • Coaches read but cannot mutate.

i18n

LangStrings to verify
enschedule.locationsTab.empty reads “No locations yet. Add one to assign to class sessions.”
heSame key, Hebrew.
ruSame key, Russian.
All”Location limit reached” copy localized; “GPS_TOO_FAR” is a stable machine string the client translates via schedule.checkinPage.tooFar.

Expected vs actual

  • After deactivation: is_active=false, deleted_at still NULL.
  • After autocomplete fill: latitude and longitude both non-null and within plausible bounds (-90 to 90, -180 to 180).
  • Tier check: count of is_active=true locations in the org against the tier’s cap.