Skip to content
Ali Hassan — home

Work

Property management portal

A community portal for a property owners' association, with a custom CMS where staff build pages and forms without a developer, and residents search deed restrictions, submit requests and pay online.

Role
Full-stack engineer
Status
Live in production
Client
Property owners' association
  • React
  • Redux
  • Tailwind CSS
  • Node.js
  • Express
  • Knex
  • MySQL
  • Stripe
View live
Public home, deed-restriction search and resources pages of a community portal its staff run through a CMS.

The problem

Context
A property owners' association needed a community website its own staff could run, and a resident area where owners find deed restrictions, submit forms, request paid house-checks while away, and pay online. The association's people and property records already lived in a separate legacy membership system.
Constraints
The legacy system stays the source of truth, so the portal keeps its own copy of residents and properties in step with it automatically and creates resident logins as new contacts appear. Staff build pages and forms without a developer, and the schema had to keep evolving for years without losing old form submissions.
What was at stake
The portal is live for the association's whole membership. A bad sync could orphan or delete residents' accounts and history, and dues and house-check requests take real payments, so payment records have to be complete and trustworthy.

What I built

Staying in step with a legacy system

  • Scheduled one-way sync

    A scheduled job reads properties, contacts and their links from the legacy database in small batches and updates the portal's copy, creating a resident login when a new contact appears. It is deliberately gentle on the legacy server; the trade-off is that a bad record is skipped and logged rather than blocking the run.

  • Removals reconciled too

    A second job removes residents and properties that no longer exist in the legacy system, together with everything attached to them, so the portal never shows people who have left.

  • A data model keyed to properties

    As the sync matured, the schema moved from user-centred records to property-centred ones, with documents, house-checks, payments and form submissions linked to the property.

Content management

  • Forms with version history

    Every edit to a form saves a new version, and each submission stays linked to the version it was filled in on. Staff can change a form without breaking the meaning of last year's answers.

  • Pages and menus staff control

    Staff manage nested pages, drafts, menus, the home page, sliders and FAQs, and each page can be limited to particular roles.

  • Deed-restriction search

    Residents search deed restrictions by street address, with indexes added once the data grew large enough to make searches slow.

Payments

  • Card and bank-account payments

    Checkout supports cards and US bank accounts with instant verification, and payment notifications are verified against the raw request before they are trusted.

  • A complete payment ledger

    Each payment records its breakdown, total, status, payer and property, including paid house-check requests, so staff can answer any 'did this go through?' question.

Operations

  • Large exports queued, not blocking

    Staff queue exports of users or payment history; a background job builds the spreadsheet and emails it, so a big export never times out a page.

  • Residents' services and newsletters

    Lost-and-found pets, newsletter subscriptions and an email send log run as resident services alongside the CMS.

Tell me what you’re building and where it’s stuck.

I’ll tell you the cleanest path forward, including if it’s “don’t build that.”

Or write tocontact@alihassan.dev

Ali Hassan in a dark winter jacket, looking off to one side, standing in a stone courtyard with a minaret and cloudy sky behind him.