Skip to content

Initial setup

This guide takes a board member or property manager from an empty CondoPulse install to a working status page: the building modelled, assets tracked, and the operational plumbing (secrets, cron, email) configured.

CondoPulse models one property (the building/complex, with a street address and a timezone - get the timezone right, it drives the per-day uptime slats), containing:

  • Towers - e.g. Tower A, Tower B.
  • Units - per tower, with a number ("1204") and floor. Units let residents report in-suite and location-specific issues (“Urine in Tower B stairwell, floor 3” is a unit/common-area incident).
  • Assets - the systems and amenities you want uptime history for. Each asset has a name, a category (elevator, pool, gym, garden, fire_alarm, parking, hvac, laundry, common_area, other), a live status (operational | degraded | down | maintenance), and an optional tower - leave the tower empty for property-wide assets like the pool.

Granularity is the key decision. Recommendations:

  • One asset per elevator (Elevator A1, Elevator A2, Elevator B1) - not “Elevators”. Per-car uptime is exactly the evidence you’ll want when a vendor contract comes up for renewal.
  • One asset per amenity residents care about: Pool, Gym, Parking Garage Door, Fire Alarm System, Tower A HVAC.
  • Split things that fail independently; merge things that don’t. “Garden - North Bed” is a fine asset if it generates recurring reports.

Assets are managed in the admin area, /admin → Assets tab. Create them once; residents do the rest.

The web app reads its configuration from .env (start from .env.example). The operational variables you should know about:

VariablePurpose
DATABASE_URLPostgres connection string (Neon in production; a dev branch locally)
BETTER_AUTH_SECRETSession signing secret - set it (openssl rand -hex 32)
BETTER_AUTH_URLPublic base URL; also used to build QR sticker links
MOBILE_API_KEYBearer key the mobile app uses (default dev-mobile-key in dev)
CRON_SECRETGuards POST /api/cron/sweep and POST /api/cron/digest
INBOUND_EMAIL_SECRETGuards POST /api/inbound-email
SLA_HOURS_CRITICAL/HIGH/MEDIUM/LOWOverride SLA acknowledgement targets (defaults 4/24/72/168)
SMTP_URLOutgoing mail. Optional - when unset, every email is written to .data/outbox/*.eml.html instead, so you can preview without a mail server
DIGEST_FROMFrom-address for digest and notification email
STORAGE_DRIVERlocal (default, photos under .data/uploads/) or s3 with S3_BUCKET, S3_ENDPOINT, S3_REGION, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY (works with R2/MinIO)
EXPO_PUSH_ENABLEDtrue to deliver mobile push notifications
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRETOptional Google SSO on /login; SSO users start as residents until promoted
ANTHROPIC_API_KEYOptional - enables the AI triage suggestions on the report form

Data lives in the Postgres database DATABASE_URL points at (Neon in production, which keeps point-in-time restore). Uploaded photos land in .data/uploads/ with the local driver (or in your S3/R2 bucket); un-sent email in .data/outbox/. The database plus the photo store together are the building’s record.

npm run seed creates a deterministic demo building - “Harborview Towers”, two towers, 12 units each, nine assets, ~25 incidents over 90 days, plus demo logins (resident@demo.test, board@demo.test, manager@demo.test, admin@demo.test, password demo1234). It’s idempotent (wipes and re-creates), which makes it great for evaluation and fatal for production - don’t run it against a live database.

Everything operational lives at /admin, in tabs:

TabWhat it’s for
TriageUntriaged (email-sourced) and SLA-breached incidents first, with inline assign/acknowledge - see Triage queue & email-in
AssetsCreate/edit assets, set category, tower, live status
MaintenancePlanned windows with recurrence - see Maintenance windows
ContactsThe public directory: property manager, superintendent, vendors, emergency line - name, label, phone, email, notes, sort order
ResidentsThe resident directory (staff-only view of who’s in which unit)
WebhooksOutgoing webhook CRUD - see Webhooks & n8n
AuditThe append-only audit log, filterable, 50 per page - see Exports & audit log
DigestPreview of the weekly board digest - see Weekly digest
InsightsAssets ranked by health score (uptime, incident trend, recency), with downtime hours and 365-day repair costs - the “replace this elevator” view
OrganizationOrg-level settings and feature flags (cost_tracking, asset_health, ai_triage)
  1. Property basics - name, address, and the correct IANA timezone.
  2. Towers and units - enter every tower, then its units with floors.
  3. Assets - create your asset list (/admin → Assets) with sensible categories; set each one’s current status honestly.
  4. Contacts - fill the directory (/admin → Contacts). Residents see this at /directory; include the after-hours emergency line.
  5. Secrets - set BETTER_AUTH_SECRET, CRON_SECRET, INBOUND_EMAIL_SECRET, and a real MOBILE_API_KEY.
  6. Cron - schedule the SLA sweep (hourly) and the weekly digest. Exact crontab and n8n examples are in SLA policy & escalation and Weekly digest.
  7. Email - set SMTP_URL and DIGEST_FROM (or accept outbox-only mode while testing).
  8. Maintenance windows - add known recurring work (monthly fire-alarm test!) so planned work paints blue, not red.
  9. Roles - promote your board and manager accounts at /admin (admin-only) - see Roles & permissions.
  10. Surfaces - put the kiosk on the lobby TV (Kiosk mode) and print QR stickers for assets (QR stickers).