Skip to content

Commit e76d781

Browse files
committed
Open Property — initial template
0 parents  commit e76d781

56 files changed

Lines changed: 9575 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Sync main ↔ master
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- master
8+
9+
jobs:
10+
sync:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Sync branches
20+
run: |
21+
if [ "${{ github.ref_name }}" = "main" ]; then
22+
TARGET="master"
23+
else
24+
TARGET="main"
25+
fi
26+
27+
git push origin HEAD:refs/heads/$TARGET

‎.gitignore‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules
2+
dist
3+
.wrangler
4+
.clawnify
5+
.DS_Store
6+
*.log
7+
.dev.vars

‎README.md‎

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Open Property
2+
3+
Open-source **property management software** — a self-hosted, cloud-based alternative to TenantCloud, AppFolio, Buildium, and Propertyware for landlords, small property managers, and apartment / multi-family back-office teams.
4+
5+
Rental property management with everything you need to run a portfolio: properties and units, tenants and leases, rent collection and a ledger, maintenance work orders, and a vendor directory.
6+
7+
> Built on the [Clawnify](https://clawnify.com) template format. Deploy your own copy in minutes, customize freely, own the data.
8+
9+
## Features
10+
11+
### Dashboard
12+
- **At-a-glance KPIs** — occupancy rate, active leases, outstanding rent, open work orders
13+
- **This month's rent** — collected, outstanding, overdue at a glance
14+
- **Open work orders** + **upcoming lease expirations** — what to act on this week
15+
16+
### Properties & units
17+
- Property cards with type, address, color tag, occupancy snapshot
18+
- Per-property page with summary tiles, unit grid, and the property's open work orders
19+
- Units track bedrooms, bathrooms, square footage, market rent, and status (vacant / occupied / turnover / unavailable)
20+
21+
### Tenants
22+
- Searchable list showing each tenant's active unit and contact info
23+
- Detail page with active lease, contact, employer, income, emergency contact, lease history
24+
25+
### Leases
26+
- One row per lease with tenant, property · unit, term, monthly rent, and status
27+
- Filters for active / upcoming / ended / all
28+
- Edit-in-dialog with start / end / rent / deposit / due day / late fee / status
29+
30+
### Rent ledger
31+
- One charge per active lease per month, generated idempotently with one click
32+
- Period navigator (◀ / today / ▶) and totals: charged, collected, outstanding, overdue
33+
- Record payments by amount, method, date, and reference. Status auto-updates as payments roll in
34+
- Past payments visible per charge with one-click removal
35+
36+
### Maintenance
37+
- Work orders with title, description, priority (urgent / high / normal / low), and status (open / assigned / in progress / completed / cancelled)
38+
- Tabs: open / unassigned / assigned / in progress / completed / all
39+
- Link work orders to a property, unit, and vendor; track scheduled date and cost
40+
41+
### Vendors & policy
42+
- Vendor directory by category (plumber / electrician / HVAC / handyman / cleaning / landscaping / general)
43+
- Rent policy defaults: due day, late fee, grace days, currency
44+
45+
## Stack
46+
47+
- React 19 + Vite + TypeScript
48+
- Tailwind CSS v4 + shadcn/ui (Radix primitives)
49+
- Hono on Cloudflare Workers (D1-native — same code locally and in production)
50+
- `lucide-react` for icons
51+
- pushState URL routing
52+
53+
## Develop
54+
55+
```bash
56+
pnpm install
57+
pnpm dev # Vite at :5173, Wrangler at :8787 (D1 schema applied automatically)
58+
pnpm typecheck
59+
pnpm build
60+
```
61+
62+
The dev script applies `src/server/schema.sql` to the local D1 database, then runs Vite and Wrangler in parallel. The schema seeds 3 sample properties, 5 units, and 3 vendors so the app is usable on first boot.
63+
64+
## Deploy
65+
66+
If you have the Clawnify CLI installed:
67+
68+
```bash
69+
clawnify deploy
70+
```
71+
72+
Or wire it up to Cloudflare Workers + D1 directly using the bindings in `wrangler.toml` (binding `DB`, database name `open-property-db`).
73+
74+
## Project layout
75+
76+
```
77+
src/
78+
server/
79+
index.ts Hono routes for every entity
80+
db.ts D1 adapter (query / get / run)
81+
schema.sql Tables + seed data
82+
client/
83+
app.tsx Shell + routing
84+
components/
85+
dashboard/ Portfolio + month-at-a-glance
86+
properties/ List, property detail, property + unit dialogs
87+
tenants/ List, tenant detail, tenant dialog
88+
leases/ Leases page + lease dialog
89+
rent/ Rent ledger + payment dialog
90+
maintenance/ Work orders board + work-order dialog
91+
settings/ Vendors + rent policy defaults
92+
ui/ Vendored shadcn primitives
93+
hooks/ use-router, use-app-state
94+
lib/utils.ts cn helper, color palette, date / money / period helpers
95+
```
96+
97+
## What's intentionally not included
98+
99+
To keep this template self-hostable with no third-party SaaS dependencies and no public-facing endpoints, these features are out of scope:
100+
101+
- Listing syndication to external rental sites
102+
- Real credit / background screening (placeholder application records only)
103+
- 2-way SMS, email blasts, automated texting
104+
- Online card / ACH payment processing
105+
- Public tenant or owner portals
106+
107+
These can all be layered on top once you fork the template.
108+
109+
## License
110+
111+
MIT

‎clawnify.json‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"$schema": "https://app.clawnify.com/schema/v1/clawnify.json",
3+
"version": 1,
4+
"name": "Open Property",
5+
"description": "Open-source property management software — a self-hosted, cloud-based alternative to TenantCloud, AppFolio, Buildium, and Propertyware. Rental property management for landlords, small property managers, and apartment / multi-family back-office teams: properties and units, tenants and leases, rent collection and ledger, work orders and maintenance, and a vendor directory.",
6+
"icon": "icon.svg",
7+
"tags": [
8+
"property-management",
9+
"property-management-software",
10+
"rental-property-management",
11+
"rental-management-software",
12+
"landlord-software",
13+
"real-estate",
14+
"leases",
15+
"rent-collection",
16+
"maintenance",
17+
"apartment-management",
18+
"tenantcloud-alternative",
19+
"appfolio-alternative",
20+
"buildium-alternative",
21+
"propertyware-alternative"
22+
],
23+
"app": {
24+
"framework": "react+hono",
25+
"database": true,
26+
"storage": false
27+
},
28+
"deploy": {
29+
"title": "Deploy your property management software",
30+
"subtitle": "Like TenantCloud or AppFolio — set up in minutes",
31+
"prompts": [
32+
{
33+
"key": "company_name",
34+
"label": "Company / portfolio name",
35+
"placeholder": "e.g. Oakwood Properties",
36+
"required": true
37+
},
38+
{
39+
"key": "portfolio_size",
40+
"label": "How many units do you manage?",
41+
"placeholder": "e.g. 12"
42+
},
43+
{
44+
"key": "property_types",
45+
"label": "What kinds of properties?",
46+
"type": "textarea",
47+
"placeholder": "e.g. single-family rentals, a 4-unit duplex, two condos..."
48+
},
49+
{
50+
"key": "details",
51+
"label": "Anything else?",
52+
"type": "textarea",
53+
"placeholder": "Rent due day, late-fee policy, regular vendors, brand colors, special features..."
54+
}
55+
]
56+
}
57+
}

‎components.json‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "default",
4+
"rsc": false,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "",
8+
"css": "src/client/styles.css",
9+
"baseColor": "neutral",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils",
16+
"ui": "@/components/ui",
17+
"lib": "@/lib",
18+
"hooks": "@/hooks"
19+
},
20+
"iconLibrary": "lucide"
21+
}

‎icon.svg‎

Lines changed: 5 additions & 0 deletions
Loading

‎index.html‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Open Property — open-source property management software</title>
7+
<meta name="description" content="Open-source property management software, a self-hosted alternative to TenantCloud, AppFolio, Buildium, and Propertyware. Rental property management with units, tenants, leases, rent collection, and maintenance work orders.">
8+
<link rel="icon" type="image/svg+xml" href="/icon.svg">
9+
<link rel="preconnect" href="https://fonts.googleapis.com">
10+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12+
</head>
13+
<body>
14+
<div id="app"></div>
15+
<script type="module" src="/src/client/main.tsx"></script>
16+
</body>
17+
</html>

‎manifest.json‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"name": "Open Property",
3+
"description": "Open-source property management software — a self-hosted, cloud-based alternative to TenantCloud, AppFolio, Buildium, and Propertyware for landlords and small property managers. Rental property management with properties and units, tenants and leases, rent collection and ledger, work orders and maintenance, and a vendor directory.",
4+
"framework": "react+hono",
5+
"files": [
6+
"src/server/index.ts",
7+
"src/server/db.ts",
8+
"src/server/schema.sql",
9+
"src/client/main.tsx",
10+
"src/client/app.tsx",
11+
"src/client/api.ts",
12+
"src/client/types.ts",
13+
"src/client/context.tsx",
14+
"src/client/styles.css",
15+
"src/client/lib/utils.ts",
16+
"src/client/hooks/use-router.ts",
17+
"src/client/hooks/use-app-state.ts",
18+
"src/client/components/sidebar.tsx",
19+
"src/client/components/error-banner.tsx",
20+
"src/client/components/dashboard/dashboard-page.tsx",
21+
"src/client/components/properties/properties-list.tsx",
22+
"src/client/components/properties/property-page.tsx",
23+
"src/client/components/properties/property-dialog.tsx",
24+
"src/client/components/properties/unit-dialog.tsx",
25+
"src/client/components/tenants/tenants-list.tsx",
26+
"src/client/components/tenants/tenant-page.tsx",
27+
"src/client/components/tenants/tenant-dialog.tsx",
28+
"src/client/components/leases/leases-page.tsx",
29+
"src/client/components/leases/lease-dialog.tsx",
30+
"src/client/components/rent/rent-page.tsx",
31+
"src/client/components/rent/payment-dialog.tsx",
32+
"src/client/components/maintenance/maintenance-page.tsx",
33+
"src/client/components/maintenance/work-order-dialog.tsx",
34+
"src/client/components/settings/settings-page.tsx",
35+
"src/client/components/ui/badge.tsx",
36+
"src/client/components/ui/button.tsx",
37+
"src/client/components/ui/card.tsx",
38+
"src/client/components/ui/dialog.tsx",
39+
"src/client/components/ui/dropdown-menu.tsx",
40+
"src/client/components/ui/input.tsx",
41+
"src/client/components/ui/label.tsx",
42+
"src/client/components/ui/scroll-area.tsx",
43+
"src/client/components/ui/select.tsx",
44+
"src/client/components/ui/separator.tsx",
45+
"src/client/components/ui/tabs.tsx",
46+
"src/client/components/ui/table.tsx",
47+
"src/client/components/ui/textarea.tsx",
48+
"src/client/components/ui/tooltip.tsx",
49+
"package.json",
50+
"vite.config.ts",
51+
"tsconfig.json",
52+
"index.html",
53+
"components.json"
54+
]
55+
}

‎package.json‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"name": "@clawnify/open-property",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"dev": "pnpm db:migrate && concurrently -n ui,api -c cyan,green \"vite\" \"wrangler dev --port 8787\"",
8+
"db:migrate": "wrangler d1 execute open-property-db --local --file=src/server/schema.sql",
9+
"build": "vite build",
10+
"typecheck": "tsc --noEmit"
11+
},
12+
"dependencies": {
13+
"@radix-ui/react-dialog": "^1.1.15",
14+
"@radix-ui/react-dropdown-menu": "^2.1.16",
15+
"@radix-ui/react-label": "^2.1.8",
16+
"@radix-ui/react-popover": "^1.1.15",
17+
"@radix-ui/react-scroll-area": "^1.2.10",
18+
"@radix-ui/react-select": "^2.2.6",
19+
"@radix-ui/react-separator": "^1.1.8",
20+
"@radix-ui/react-slot": "^1.2.4",
21+
"@radix-ui/react-tabs": "^1.1.13",
22+
"@radix-ui/react-tooltip": "^1.2.8",
23+
"class-variance-authority": "^0.7.0",
24+
"clsx": "^2.1.0",
25+
"hono": "^4.6.0",
26+
"lucide-react": "^0.575.0",
27+
"react": "^19.0.0",
28+
"react-dom": "^19.0.0",
29+
"tailwind-merge": "^2.2.0",
30+
"zod": "^3.24.0"
31+
},
32+
"devDependencies": {
33+
"@cloudflare/workers-types": "^4.20250101.0",
34+
"@tailwindcss/vite": "^4.0.0",
35+
"@types/react": "^19.0.0",
36+
"@types/react-dom": "^19.0.0",
37+
"@vitejs/plugin-react": "^4.3.0",
38+
"concurrently": "^9.0.0",
39+
"tailwindcss": "^4.0.0",
40+
"tw-animate-css": "^1.2.0",
41+
"typescript": "^5.7.0",
42+
"vite": "^6.0.0",
43+
"wrangler": "^4.0.0"
44+
},
45+
"pnpm": {
46+
"onlyBuiltDependencies": [
47+
"esbuild",
48+
"workerd"
49+
]
50+
}
51+
}

0 commit comments

Comments
 (0)