-
-
Landing page (dark mode)
-
sign in page
-
Owner dashboard
-
owner properties tab where they can easily add new properties and see dues and request based on the property easily here.
-
Owners fix it tab, where they can see requests from tenents and assign those task with their handyman of choice. (light mode)
-
Messaging page, looks the same for owner, handyman, and tenent.
-
Message example
-
Invite page, where the owner can easily invite a handyman to be synced with them, or a tenet to a unit.
-
Handyman job page, where they can update status, give estimate, and even have map to the job site.
-
Handymans earnings tab.
-
Tenets dashboard, where they can see dues and request in the same place.
-
Tenets request page, where they can see on going request or make new requests.
-
Tenets can attach images or videos to send to the owner and level of urgency as well for the request.
-
Tenets payment page where they can pay dues and set up automatic payments.
Inspiration
Abode was inspired by a problem we saw firsthand in Brighton's family real estate business. Like thousands of small, family-run property owners, everything was managed through text messages, and phone calls, and information stored on paper and spreadsheets. It meant mistakes were imminent and drastic. Large property owners lend their property management to separate companies that work like black boxes, and take a huge cut of income, and as a result small landlords and their tenants are left with either lacking service or higher costs. This was a critical gap that was not addressed by any current solutions, so we set out to create Abode, a management app that allowed smaller operators the same powerful tools that property management firms have, without putting the cost burden on themselves or their tenants.
What it does
Abode is a three-prong property-management app where each role gets a tailored experience over the same data.
Tenants: a home dashboard with payment management, detailed information updates and in depth support infrastructure built to quickly solve any issues with support for video/photos for more in depth analysis.
Owners: an analytics dashboard and a "Fix-it" board to assign a reported issue to the most appropriate/critical handyman, approve estimates, accept completed work, and generate invite codes.
Maintenance/handymen: a job queue to accept or decline, a flow of estimates, approvals, receipts, completion, and a map with current jobs to easily visualize and tackle tasks.
The core of this website is the interconnectedness of each group, allowing for a much more optimized and cleaner workflow for each user.
How we built it
App: Next.js 15 (App Router), React 19, TypeScript, Tailwind v4. Reads are Server Components; mutations are Zod-validated Server Actions with server-side role checks. Three role-based route groups share chat and notifications. Data: Drizzle ORM over AWS Aurora Serverless v2. Money is stored as integer cents. Security: Postgres Row-Level Security is the real authorization backstop. Tenant queries run in a transaction that sets the user id and drops to a low-privilege role, so a tenant cannot read another tenant's data even if app code has a bug. Auth: AWS Cognito (direct SDK, httpOnly token cookies, aws-jwt-verify), with invite-code onboarding per unit and per property. Media and payments: S3 presigned URLs for private direct uploads; Stripe for saved cards and charges, reconciled by a webhook. Infra: idempotent AWS CLI scripts for VPC, security groups, Aurora, S3, and Cognito.
Challenges we ran into
Most of our hard problems came from building the database backend and tuning it to run cheaply. To keep costs near zero, we ran Postgres on Aurora Serverless v2 with scale-to-zero auto-pause, which meant the first query after an idle period paid a ~30s cold-start penalty, and the IP-locked security group we used instead of a pricier networking setup silently blocked us whenever a laptop's public IP rotated. Enforcing tenant isolation with Postgres row-level security added a subtler issue: setting the user context naively pinned a pooled connection and leaked identity across requests, so we had to make the role switch and user ID transaction-local. For real-time chat and notifications, rather than paying for a pricey managed event service, we deployed AWS App Runner to hold a LISTEN connection to Postgres. This catches database changes and pushes them out instantly via Server-Sent Events to connected clients, which required careful tuning to maintain efficiently.
Accomplishments that we're proud of
The thing we're happiest about is that we made it genuinely affordable, which is the whole point. Abode is for small landlords and independent handymen, so we ran the database on Aurora Serverless v2 with scale-to-zero (MinCapacity=0, auto-pause after 5 minutes idle), meaning it costs nothing when no one's using it, around $20/month instead of a constantly-on instance. We backed that with an N+1 query we collapsed into two batched lookups, a 30-second session cache to avoid re-hitting Aurora on every navigation, and connection multiplexing through RDS Proxy for production. We're also proud that multi-tenant isolation is enforced at the PostgreSQL layer rather than in app code: every request runs as a locked-down abode_app role with the user ID set transaction-locally, RLS policies scope every row, and it's default-deny, so if we forget to set the context the query returns nothing instead of leaking, which we prove with an automated isolation test. And the handyman map came out exactly how we wanted. It's built with Mapbox GL JS via react-map-gl, drops teardrop pins color-coded by urgency, puts a live geolocation dot with a device-orientation compass heading on the handyman, computes the distance to each job, and shows the tenant's issue, the manager's note, and a "View job" link in a single popup. Fast, accurate, and good-looking.
What we learned
Using Postgres RLS as a real authorization layer and its interaction with connection pooling. The tradeoffs of serverless databases (cost vs. cold-start latency vs. networking). Next.js 15 Server Components and Server Actions, including where validation and role checks belong. Wiring Cognito, S3, and Aurora into a Next app end to end, where env config and webhooks eat the most time.
What's next for Abode
We want to sync up an email system where we can send receipts and invoices or even reminders through a connected email. Next, we are going to refine the ui so it works for mobile. Lastly, testing with real users will help us get better feedback and refine this app even better.
Built With
- amazon-web-services
- aurora
- mapbox
- nextjs
- react
- s3
- sql
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.