Files
property-management-network/README.md
T
Leon SerfatyandClaude Opus 4.8 917a06ee85 docs: overhaul README and mark project proprietary
- Rewrite README: accurate current feature set (public API, webhooks/Zapier,
  PayPal, accounting sync, e-sign, team, branding, inspections, maps, ~30 tables,
  4 cron jobs), emoji section headers, clearer setup and security sections.
- Remove the inline env-variable example block; point to .env.example / DIGITALOCEAN.md.
- Fix stale "local disk" storage references to DigitalOcean Spaces.
- License: change MIT -> Proprietary; add LICENSE file and package.json "UNLICENSED".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 13:51:59 -04:00

11 KiB

Property Management Network

🏠 Property Management Network

The all-in-one property-management platform for independent landlords.
Properties, tenants, rent, maintenance, leases, expenses, AI insights, and integrations — in one clean dashboard.

Next.js TypeScript PostgreSQL License


Overview

Property Management Network replaces the spreadsheet-and-WhatsApp chaos that most small landlords live with. It gives a solo landlord or a small team a single source of truth for their whole portfolio — and the automation, AI, and integrations to run it hands-off.

Everything is multi-tenant and team-aware: each landlord operates on their own isolated portfolio, and Landlord/Lifetime accounts can invite teammates with scoped roles.

🧰 What you can do

Core operations

  • 🏢 Properties & units — manage your whole portfolio with live occupancy tracking and a map view (addresses are auto-geocoded).
  • 👥 Tenants — profiles, lease history, payment records, and a private tenant portal (token-based, no login required).
  • 💵 Rent tracking — log payments, send Stripe or PayPal payment links, and auto-mark balances overdue with automatic late fees.
  • 🔧 Maintenance — full status workflow (Open → In Progress → Resolved), with tenant-submitted requests from the portal.
  • 📄 Leases — expiry countdowns, automated 60/30/7-day email alerts, and e-signature (DocuSign / Dropbox Sign).
  • 🧾 Expenses — categorized logging with recurring-expense support.
  • 🗂️ Documents — a per-property file vault stored in object storage and served through an auth-gated route.
  • 🔎 Inspections & vendors — move-in/out/routine inspection checklists and a vendor directory.
  • 📊 Reports & exports — portfolio analytics with CSV export.
  • 📅 Calendar — an in-app calendar plus a read-only iCal (ICS) feed you can subscribe to.

Automation & AI

  • 🤖 AI features — recommendations, predictions, impact tracking, and a portfolio assistant (OpenAI). (Pro and up.)
  • ✉️ Automated email — rent reminders, overdue notices, and lease-expiry alerts, plus a configurable follow-up engine.
  • 🎨 White-label branding — put your own brand on the tenant portal. (Landlord / Lifetime.)
  • 🛡️ Admin dashboard — superadmin tools with a full audit log.

🔌 Integrations & developer platform

Capability Details
🌐 Public REST API Versioned /api/v1 endpoints (properties, tenants, payments, maintenance, webhooks) authenticated with Bearer API keys. See /api-docs.
🪝 Outbound webhooks / Zapier Subscribe to events (tenant.created, payment.paid, maintenance.updated, …). Deliveries are HMAC-signed, retried with backoff, and Zapier-compatible via the REST-hook subscribe/unsubscribe pattern.
💳 Payments Stripe (subscriptions + rent payment links) and PayPal.
📚 Accounting sync One-way push of income & expenses to QuickBooks Online or Xero (OAuth).
✍️ E-signature Send leases for signature via DocuSign or Dropbox Sign.
🔑 Auth Email/password and Google OAuth (Better Auth).

Every integration is env-gated: unconfigured providers show a clean “not configured” state instead of a broken button.


💳 Plans & pricing

Plan Price Highlights
🆓 Starter Free 1 property, 3 tenants, no AI
🚀 Pro $29/mo 10 properties, unlimited tenants, AI (50 calls/mo)
🏆 Landlord $59/mo Unlimited properties, team access, white-label, AI (200/mo)
♾️ Lifetime $199 once Everything in Landlord, forever

Billing runs through Stripe or PayPal. Stripe products/prices are resolved by stable lookup keys and auto-created on first checkout, so going live is just an API-key swap — no price IDs to wire up.


🧱 Tech stack

Layer Technology
Framework Next.js 16.2 (App Router, TypeScript, React 19)
Styling Tailwind CSS + Geist
Database PostgreSQL via Drizzle ORM
Auth Better Auth (email/password + Google OAuth)
Object storage DigitalOcean Spaces (S3-compatible, CDN, auth-gated)
Payments Stripe + PayPal
AI OpenAI (gpt-4o-mini)
Email SMTP (SMTP2GO)
Maps Leaflet + OpenStreetMap / Nominatim geocoding
Cron DigitalOcean Functions (scheduled triggers)
Deploy DigitalOcean App Platform (Docker image via DOCR)

🚀 Getting started

1. Clone & install

git clone <your-repo>
cd property-management-network
npm install

2. ⚙️ Configure environment

Copy the template and fill in your own values:

cp .env.example .env.local

.env.local holds your database URL, auth secret, and credentials for Stripe/PayPal, OpenAI, SMTP, and object storage. Every variable is documented inline in .env.example, and the full production reference lives in DIGITALOCEAN.md. Never commit real secrets.

3. 🗄️ Run migrations

The schema is managed by Drizzle (see drizzle.config.ts). Point DATABASE_URL at your PostgreSQL instance, then:

npm run db:migrate      # apply migrations
npm run db:generate     # regenerate after schema changes
npm run db:push         # push schema directly (quick local prototyping)

4. 🔌 Wire up services (as needed)

  • Stripe — set the API keys, then add a webhook at https://yourdomain.com/api/stripe/webhook for checkout.session.completed, the customer.subscription.* events, invoice.payment_failed, and payment_intent.succeeded.
  • Email — verify a sending domain with your SMTP provider (e.g. SMTP2GO) and set the SMTP_* + EMAIL_FROM vars.
  • Google / PayPal / OpenAI / accounting / e-sign — each is optional and activates once its env vars are present.

5. ▶️ Run locally

npm run dev

Open http://localhost:3000.

6. 🚢 Deploy

The repo ships a production Dockerfile (Next.js standalone), an App Platform spec at .do/app.yaml, DO Functions cron under functions/, and a /api/health probe. Follow DIGITALOCEAN.md for the full walkthrough.


🗂️ Project structure

app/
├── (marketing)/         # Landing page, pricing, legal, API docs
├── (auth)/              # Login, signup, password reset
├── (dashboard)/         # Auth-gated app (properties, tenants, rent, maintenance,
│                        #   leases, expenses, inspections, vendors, reports,
│                        #   calendar, AI, onboarding, settings)
├── (admin)/             # Superadmin dashboard
├── api/
│   ├── v1/              # 🌐 Public REST API (Bearer API keys)
│   ├── webhooks + cron/ # 🪝 Outbound webhook delivery + scheduled jobs
│   ├── stripe/ paypal/  # 💳 Billing + payment links + provider webhooks
│   ├── integrations/    # 📚 QuickBooks / Xero OAuth
│   ├── esign/           # ✍️ DocuSign / Dropbox Sign
│   └── …                # Properties, tenants, rent, maintenance, documents, AI
└── tenant-portal/[token]/  # Public tenant portal (no login)

lib/
├── db/                  # Drizzle schema, queries, migrations
├── auth.ts  account.ts  # Better Auth + team/account scoping
├── storage.ts           # Object storage (Spaces) with local-disk dev fallback
├── webhooks/            # Event catalog, HMAC signing, SSRF guard, delivery
├── stripe/  paypal/     # Billing clients & plans
├── accounting/  esign/  # QuickBooks/Xero & DocuSign/Dropbox Sign
├── ai/                  # OpenAI client + prompts
├── email/               # SMTP (SMTP2GO) client + HTML templates
└── validations/         # Zod schemas for all entities

🗄️ Data model & isolation

The schema spans ~30 tables managed via Drizzle ORM, grouped roughly as:

  • Coreprofiles, properties, units, tenants, rent_payments, maintenance_requests, leases, expenses, documents, inspections, vendors
  • Automation & AInotifications, follow_up_rules, follow_up_log, ai_recommendations, ai_predictions, activity_log, usage_events
  • Accounts & platformaccount_members, api_keys, app_settings, admin_audit_log, accounting_connections, signature_requests, webhook_endpoints, webhook_deliveries
  • Auth (Better Auth)user, session, account, verification

🔐 Tenancy is enforced in the application layer. Every query scopes by the resolved account owner id (team-aware), never the raw session user. There is no database RLS, so this scoping must be preserved on every new route — see lib/account.ts (getEffectiveOwnerId).


Scheduled jobs

Cron is driven by DigitalOcean Functions hitting CRON_SECRET-protected endpoints (functions/project.yml):

Job Schedule (UTC) What it does
daily 09:00 Rent reminders, overdue marking, 60/30/7-day lease-expiry alerts
late-fees 08:00 Applies late fees past the grace period
follow-ups 10:00 Runs each account's active follow-up rules
webhooks every 5 min Retries pending outbound webhook deliveries

🔒 Security highlights

  • 🔑 API keys are stored as SHA-256 hashes; the plaintext is shown once.
  • 🪝 Webhook payloads are HMAC-SHA256 signed (X-PMN-Signature); endpoint URLs are SSRF-guarded (private/loopback/metadata ranges blocked).
  • 📁 Uploaded files are served only through an auth-gated route; object storage is required in production (uploads fail loud rather than silently hit ephemeral disk).
  • 🛢️ Verified TLS to Postgres in production (DATABASE_SSL=require + CA).
  • ⏱️ Cron endpoints use a constant-time bearer check and fail closed.

📜 License

Proprietary — © 2026 Property Management Network. All rights reserved.

This source code is proprietary and confidential. No license or permission is granted to use, copy, modify, merge, publish, distribute, sublicense, or sell any part of it without the prior written consent of the copyright holder. See LICENSE.