Skip to content
SaaS.Dev

Oct 25, 2026

Leaseclock, from three files to its first payment

Leaseclock is three short files. Here is every step from the first push to Northgate Rentals paying $29 into Leaseclock’s own Stripe account.

Leaseclock tracks lease renewals for small property managers. Its customers keep a list of units and the leases on them, and they need to know which lease ends next and renew it before it lapses. That is the whole product, and it is three short files.

Three files

A Lease ties a renter to a Unit until a date. People renew it or end it. A property manager pays $29 a month for up to 200 units.

Noun/Lease.mdx
---name: Leasefields:  unit: { type: link, target: Unit, required: true }  renter: { type: email, required: true }  endsOn: { type: date, required: true, indexed: true }  status: { type: choice, options: [{ key: active }, { key: ended }] }verbs:  renew:    does: Move the end date forward    input: { endsOn: { says: the new end date, type: date, required: true } }    from: [active]  end: { does: End the lease, from: [active], to: ended }  remind:    does: Email the renter that the lease ends in 60 days    emails: renter    from: [active]    on: endsOn - 60 days---
Noun/Unit.mdx
---name: Unitfields:  label: { type: text, required: true }  building: { type: text }---
Offer/pro.mdx
---name: Leaseclock Proprice: { amount: 29, currency: USD, unit: month }limits: { Unit: 200 }personas: Property manager, Leasing coordinatorstatus: Live---

Nothing else is written. The admin, the customer app, the API, the CLI, the MCP server, the SDK, the site, the docs and the blog are generated from these files and run on SaaS.Dev.

The first push

The first push fails, and the error says exactly why:

Terminal
$ npx saas.dev push422  Lease.mdx line 6: field "EndsOn" must start lower-case. Rename it to "endsOn". $ npx saas.dev pushPushed version 2 · https://leaseclock.test.saas.dev

The field is renamed and the second push lands. Leaseclock runs in Test with its list of leases, a Renew button on each active one, and a docs page for every Verb, such as Renew a lease.

A domain and a Stripe account

Terminal
$ npx saas.dev domain add leaseclock.com✓ leaseclock.com is connected, with HTTPS $ npx saas.dev stripe connect✓ Stripe connected · acct ••••7c1e $ npx saas.dev push --liveLive · https://leaseclock.com

Leaseclock is live at leaseclock.com, and its pricing page sells Leaseclock Pro through Stripe Checkout, in Leaseclock's teal and under Leaseclock's name.

The first payment

Priya Shah, the leasing coordinator at Northgate Rentals, subscribes on August 21. The payment lands in Leaseclock's own Stripe account, and the admin's Billing screen shows it in Live: Northgate Rentals, Leaseclock Pro, $29.00, Paid. Northgate imports its 24 units the same afternoon, and Priya works from the Leases list every Monday after.

A new field

On October 21, Leaseclock adds rent to a lease. One line:

Noun/Lease.mdx
  endsOn: { type: date, required: true, indexed: true }+ rent: { type: money }

On the next push the Leases list has a Rent column, the API and the SDK have rent, and the changelog has an entry for Northgate to read: “Leases now track rent.” Nobody writes the column, the type or the entry.

Start yours

The Quickstart is the same six steps, starting from a copy of Leaseclock.