Your building isn't a community yet. Lobby makes it one.
Lobby is a hyper-local community platform for residential buildings. Management posts announcements. Residents raise requests. When enough residents support a request, the system automatically sends a priority notice to management — anonymously, professionally, and with a documented timestamp.
One QR code turns a building full of strangers into a community that communicates.
Try it now! https://lobby-pied.vercel.app/
View on Devpost → https://devpost.com/software/lobby-o4ubnj
Most buildings have dozens of people behind the same walls who never talk to each other. When something breaks, you email your landlord alone and get ignored. Your neighbor does the same thing separately. Management sees two isolated complaints and does nothing. The problem isn't that tenants lack a voice — it's that they can't see each other.
Lobby gives every building a shared feed where management communicates downward (announcements, safety notices, maintenance schedules) and residents communicate upward (requests, issues, feedback). Resident support is aggregated anonymously — when a request crosses the priority threshold, management receives a formal notice they can't ignore.
Building management generates a QR code and distributes it in common areas. Residents scan it, enter their unit number, and they're in. No signup forms, no emails, no passwords. Physical proximity to the QR code acts as lightweight verification.
A single stream of announcements from management and requests from residents. Filterable by type. Real-time updates via Supabase subscriptions — when someone supports a request, every resident sees the progress bar move live.
Residents describe their issue in their own words. Gemini AI rewrites it into a clear, professional request with a structured title and description. The original emotion is preserved; the language becomes actionable. Requests are anonymous by default — residents can optionally reveal their unit number.
Before posting, the system checks if a similar request already exists and suggests the resident support it instead. This consolidates voices rather than fragmenting them across duplicate posts.
When a configurable percentage of verified residents (default 40%) support a request, three things happen automatically:
- The request status changes to Priority
- A professionally formatted email is sent to building management
- All supporters are notified
The email includes the request title, AI-polished description, photo evidence, supporter count, building percentage, and a timestamp — creating a documented record.
Residents can attach photos to requests — cracked walls, broken locks, flooded hallways. Photos appear on the request card and are embedded in the priority notice email.
A dashboard showing the building's communication health: active requests, priority notices sent, issues resolved, and an overall resolution rate. Visible to all residents.
| Layer | Technology |
|---|---|
| Frontend | SvelteKit (PWA) |
| Database | Supabase (Postgres) |
| Auth | Supabase Anonymous Auth |
| Real-time | Supabase Realtime |
| File Storage | Supabase Storage |
| AI | Gemini API |
| Resend | |
| QR | qrcode + html5-qrcode |
| Hosting | Vercel |
┌─────────────────────────────────────────────────┐
│ SvelteKit PWA │
│ Landing · Feed · Create Request · Pulse · QR │
└──────────┬──────────────────┬───────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────────────┐
│ Supabase │ │ SvelteKit API Routes │
│ - Postgres DB │ │ /api/polish-request │
│ - Auth │ │ /api/check-duplicate │
│ - Realtime │ │ /api/send-priority-email│
│ - Storage │ └─────┬──────────┬─────────┘
└─────────────────┘ │ │
▼ ▼
┌──────────┐ ┌─────────┐
│ Gemini │ │ Resend │
│ API │ │ API │
└──────────┘ └─────────┘
Data flow: Resident scans QR → anonymous auth → joins building → posts request → Gemini polishes text → deduplication check → request appears in feed → residents support it → progress bar updates in real-time → threshold met → Resend sends priority email → status updates across all clients.
- Node.js 18+
- A Supabase account
- A Gemini API key
- A Resend account
git clone https://github.com/your-team/lobby.git
cd lobby
npm installCreate a new Supabase project, then run the following SQL in the SQL Editor:
-- Buildings
CREATE TABLE buildings (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
name TEXT NOT NULL,
address TEXT NOT NULL,
unit_count INTEGER NOT NULL,
management_email TEXT NOT NULL,
threshold_percentage INTEGER DEFAULT 40,
qr_secret TEXT DEFAULT gen_random_uuid()::text,
created_at TIMESTAMPTZ DEFAULT now()
);
-- Residents
CREATE TABLE residents (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
building_id UUID REFERENCES buildings(id) ON DELETE CASCADE,
unit_number TEXT NOT NULL,
auth_id UUID NOT NULL,
created_at TIMESTAMPTZ DEFAULT now(),
UNIQUE(building_id, unit_number)
);
-- Requests
CREATE TABLE requests (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
building_id UUID REFERENCES buildings(id) ON DELETE CASCADE,
created_by UUID REFERENCES residents(id),
title TEXT NOT NULL,
raw_description TEXT,
polished_description TEXT NOT NULL,
category TEXT DEFAULT 'general',
photo_url TEXT,
show_unit BOOLEAN DEFAULT false,
status TEXT DEFAULT 'open' CHECK (status IN ('open', 'priority', 'resolved')),
supporter_count INTEGER DEFAULT 1,
created_at TIMESTAMPTZ DEFAULT now()
);
-- Supporters
CREATE TABLE supporters (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
request_id UUID REFERENCES requests(id) ON DELETE CASCADE,
resident_id UUID REFERENCES residents(id),
created_at TIMESTAMPTZ DEFAULT now(),
UNIQUE(request_id, resident_id)
);
-- Announcements
CREATE TABLE announcements (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
building_id UUID REFERENCES buildings(id) ON DELETE CASCADE,
title TEXT NOT NULL,
body TEXT NOT NULL,
category TEXT DEFAULT 'general',
created_at TIMESTAMPTZ DEFAULT now()
);Enable Anonymous Auth under Authentication → Providers.
Enable Realtime on the requests, supporters, and announcements tables.
Create a public storage bucket called request-photos.
Create a .env file in the project root:
PUBLIC_SUPABASE_URL=your_supabase_project_url
PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
RESEND_API_KEY=your_resend_api_key
GEMINI_API_KEY=your_gemini_api_key
npm run devOpen http://localhost:5173.
lobby/
├── src/
│ ├── lib/
│ │ ├── supabase.js
│ │ └── components/
│ │ ├── ProgressBar.svelte
│ │ ├── RequestCard.svelte
│ │ ├── AnnouncementCard.svelte
│ │ ├── QrScanner.svelte
│ │ └── PhotoUpload.svelte
│ ├── routes/
│ │ ├── +page.svelte # Landing
│ │ ├── create/+page.svelte # Create building
│ │ ├── building/[id]/qr/+page.svelte # QR display
│ │ ├── join/[buildingId]/+page.svelte # Join building
│ │ ├── feed/+page.svelte # Building feed
│ │ ├── create-request/+page.svelte # New request
│ │ ├── request/[id]/+page.svelte # Request detail
│ │ ├── pulse/+page.svelte # Building pulse
│ │ └── api/
│ │ ├── polish-request/+server.js
│ │ ├── check-duplicate/+server.js
│ │ └── send-priority-email/+server.js
│ └── app.html
├── static/
│ ├── manifest.json
│ └── service-worker.js
├── .env
└── package.json
Privacy is architectural, not policy-based.
- Residents are verified by unit number internally but anonymous by default to both other residents and management.
- Requests display "A resident raised this" unless the poster opts in to showing their unit number.
- Supporters are always anonymous — the count is visible, individual identities are not.
- Priority notice emails contain only the issue, supporter count, and building percentage. No unit numbers. No names.
- The infrastructure to reveal anonymous supporters does not exist in the codebase.
When a request crosses the threshold, management receives:
PRIORITY NOTICE
[Request Title]
[Polished description]
This issue has been supported by [X] residents, representing [Y]% of verified residents at [Building Name], [Address].
This is an automated priority notice from Lobby. This issue crossed the building's priority threshold on [date].
Every email is a timestamped record. If management ignores it and the issue escalates to a tenancy tribunal or strata dispute, the documented trail proves they were notified.
Populate the database with realistic demo data for presentations and testing.
.envmust containPUBLIC_SUPABASE_URLandSUPABASE_SERVICE_ROLE_KEY- The Supabase schema must already be applied
npm run seed:demoWARNING: This wipes ALL existing data — every building, resident, request, announcement, and auth user is deleted before seeding. Run only on dev/demo databases.
Safe to rerun — the script performs a full cleanup then recreates everything from scratch.
| Count | |
|---|---|
| Manager account | 1 (marcusmicc@gmail.com) |
| Resident accounts | 80 (randomly distributed across buildings) |
| Buildings | 3 (Riverside Towers, Maple Gardens, Oakwood Heights) |
| Announcements | 35 (general, maintenance, safety, event) |
| Requests | 40 (request, issue, feedback) |
| Supporter rows | ~236 |
| Building | Residents | Threshold | Target Supporters |
|---|---|---|---|
| Riverside Towers | 28 | 40% | ~12 |
| Maple Gardens | 24 | 35% | ~9 |
| Oakwood Heights | 28 | 30% | ~9 |
- Near-threshold — 6 requests sitting 1 supporter away from flipping to priority (2 per building)
- Priority — 5 requests that have already crossed the threshold
- Resolved — 4 requests marked as resolved
- Open — 25 requests at various supporter counts
- Categories span requests, issues, and feedback with realistic topics (EV chargers, gym equipment, noise complaints, playground safety, mould, parking, etc.)
- Pinned welcome messages per building
- Multi-day maintenance windows (elevator, painting, carpet cleaning)
- Single-day events with specific times (BBQ, trivia, yoga, movie night, garage sale)
- All-day events (pool closure, water meter reading, power outage)
- Non-calendar general notices (package policy, pet registration, bin etiquette)
All seeded accounts use password LobbyDemo!2026.
| Account | Role | |
|---|---|---|
| Manager | marcusmicc@gmail.com |
Manages all 3 buildings |
| Residents | resident.001@lobby.demo through resident.080@lobby.demo |
Randomly assigned to buildings |
The terminal output after seeding prints building join codes, notable requests, and sample resident logins per building.
Built in 48 hours for MACATHON 2026. See the full project submission on Devpost.
Released under the MIT License. Copyright (c) 2026 Lobby.