-
Notifications
You must be signed in to change notification settings - Fork 5
features flatmates
Active contributors: Saksham, Ravi
The Flatmates module is a swipe-based roommate and PG discovery system layered on top of the property and social models. Users post room listings, swipe on each other, match, chat, exchange QnA answers, and schedule visits, all moderated by an automated prescreen pipeline and an admin moderation workflow. App-wide realtime events flow to clients through Supabase Realtime private Broadcast channels.
app/api/api_v1/endpoints/
├── flatmates.py # profiles, swipes, matches, conversations, messages, QnA
└── flatmates_admin.py # moderation queue: approve, reject, request_edit
app/services/flatmates/
├── __init__.py # re-exports public symbols for backward compatibility
├── profiles.py # profile CRUD, discoverable list, catalogs, bootstrap
├── matching.py # record_swipe, list_matches, incoming/outgoing likes
├── conversations.py # _ensure_conversation, messages, QnA, mark_read
├── interactions.py # profile_view_event, society_tag_vote
├── moderation.py # prescreen, reports, blocks, stale-listing pause
├── compatibility.py # 7-dimension lifestyle compatibility engine
├── visits.py # update_visit_status + realtime event queue
├── realtime.py # Supabase Broadcast publisher + after-commit queue
└── helpers.py # canonical pair, payload builders, geocoding
app/models/
└── social.py # UserMatch, UserConversation, UserMessage, UserBlock, UserReport, AppCatalog, MatchQnAAnswer
app/models/enums.py # SwipeAction, SwipeTargetType, ConversationStatus, etc.
| Abstraction | File | Role |
|---|---|---|
record_swipe |
app/services/flatmates/matching.py |
Idempotent swipe; creates conversation on like; queues realtime on match |
_ensure_conversation |
app/services/flatmates/conversations.py |
Canonical-pair upsert of UserConversation
|
_canonical_pair |
app/services/flatmates/helpers.py |
Sorts (user_one_id, user_two_id) so pairs are stable |
list_discoverable_profiles |
app/services/flatmates/profiles.py |
Cursor-paginated feed of swipable peers |
calculate_compatibility |
app/services/flatmates/compatibility.py |
7-dimension lifestyle compatibility engine; powers match_percentage and compatibility_score
|
prescreen_flatmate_listing |
app/services/flatmates/moderation.py |
Auto prescreen: photo count, suspicious rent, spam patterns |
pause_stale_flatmate_listings |
app/services/flatmates/moderation.py |
Pauses flatmate/PG listings not updated in STALE_LISTING_PAUSE_DAYS (default 60) |
EnumStringType |
app/models/social.py |
TypeDecorator storing enums as strings with DB CHECK constraints |
queue_flatmates_realtime_event |
app/services/flatmates/realtime.py |
After-commit publisher to flatmates:user:{local_user_id} Supabase channels |
A swipe records a UserSwipe row keyed by (user_id, property_id) for property targets, or by (user_id, target_user_id) for profile targets. Positive actions (like, super_like) call _ensure_conversation, which canonicalises the user pair and upserts a UserConversation. When both sides have liked, a UserMatch row is created and new_match is queued for both users after commit. Messages append to UserMessage rows, update last_message_at / last_message_preview, and queue new_message / conversation_updated broadcasts.
graph TD
Client -->|POST /flatmates/swipes| EP[app/api/.../flatmates.py]
EP --> MS[matching.record_swipe]
MS --> US[(UserSwipe)]
MS -->|like/super_like| EC[_ensure_conversation]
EC --> UC[(UserConversation)]
MS -->|mutual?| UM[(UserMatch)]
UM --> RT1[Supabase Broadcast new_match]
Client -->|POST /flatmates/.../messages| MSG[conversations.send_message]
MSG --> UM2[(UserMessage)]
MSG --> RT2[Supabase Broadcast new_message]
Client -->|private channel| RT[flatmates:user:id]
RT --> Client
Mod[Admin] -->|POST /admin/.../moderate| AD[flatmates_admin.py]
AD --> MOD[moderation.prescreen/apply]
MOD -->|moderation_status| LP[listing_preferences JSONB]
Moderation runs in two layers. prescreen_flatmate_listing runs synchronously on profile create/update and writes moderation_status (pending_review, live, rejected) plus prescreen metadata into the property's listing_preferences JSONB. It checks MIN_REVIEW_PHOTO_COUNT (2), flags rents above SUSPICIOUS_RENT_CEILING (1,000,000), and scans descriptions against _SPAM_PATTERNS (adult content, illegal substances, commercial spam, off-platform spam). pause_stale_flatmate_listings runs on every flatmates endpoint entry and flips listings not updated in STALE_LISTING_PAUSE_DAYS (default 60 days) to paused. The admin moderation endpoint in flatmates_admin.py exposes approve/reject/request_edit actions and applies REPORT_AUTO_PAUSE_THRESHOLD (3 reports triggers an auto-pause).
Supabase Realtime private Broadcast is the real-time backbone. The bootstrap response includes the private topic and supported events. The backend publishes to flatmates:user:{local_user_id} through the Realtime REST Broadcast API after DB commit. Supabase Realtime Authorization on realtime.messages restricts each authenticated user to their own channel. Event types are new_match, new_message, conversation_updated, visit_updated, listing_status_changed, and new_notification.
-
Supabase Realtime: matching, conversations, visits, listing moderation, and flatmates notifications publish through
app/services/flatmates/realtime.py. -
Property model: flatmate/PG listings are
Propertyrows withproperty_typeinPG_FLATMATE_TYPES = {PropertyType.pg, PropertyType.flatmate}. Thelisting_preferencesJSONB column carries moderation status, QnA answers, and metadata. -
Visits:
flatmates/visits.pycalls into Ghar Core visit logic withvisit_context=flatmate_meetand_validate_flatmate_visit_contextenforces the canonical pair and an active match/conversation. -
Push notifications:
app/services/push_notification.pydispatches flatmates events (new_match,new_message, listing approved, visit scheduled) through the notifications pipeline with aroutedeep-link data field. -
Geocoding:
geocode_listinginhelpers.pypopulatesProperty.locationfor radius search.
Add new realtime event types by extending app/services/flatmates/realtime.py, queuing from the relevant service method, and updating CLAUDE.md and AGENTS.md. New moderation rules belong in prescreen_flatmate_listing or apply_listing_prescreen_metadata. Conversation and match queries always use the canonical pair to avoid duplicate rows; never query UserConversation by unordered user IDs.
| File | Purpose |
|---|---|
app/api/api_v1/endpoints/flatmates.py |
REST endpoints |
app/api/api_v1/endpoints/flatmates_admin.py |
Moderation endpoints (14 KB) |
app/services/flatmates/matching.py |
Swipe + match logic (489 lines) |
app/services/flatmates/conversations.py |
Conversation + message CRUD (545 lines) |
app/services/flatmates/moderation.py |
Prescreen, reports, blocks (568 lines) |
app/services/flatmates/profiles.py |
Profile CRUD + catalogs (516 lines) |
app/services/flatmates/compatibility.py |
7-dimension lifestyle compatibility engine |
app/services/flatmates/helpers.py |
Canonical pair, payload builders, geocoding |
app/services/flatmates/interactions.py |
Profile views, society tag votes |
app/services/flatmates/visits.py |
Visit status updates + realtime event queue |
app/models/social.py |
Social ORM models + EnumStringType
|
app/services/flatmates/realtime.py |
Supabase Broadcast publisher |
app/services/push_notification.py |
Flatmates push dispatch |
- Features overview
- Ghar Core (marketplace)
- 360 Stays (bookings)
- 360 Flatmates
- Property Management
- 360 Virtual Tours
- 360 Data Hub
- MCP servers and widgets
- AI agent
- Blog and SEO
- Notifications
- Vastu analyzer