[object Object]

← back to Nationalrealestate

chore: harden sublease.ts (enum allowlists on status/lease_type/rate_period, status-aware total count), v0.2.0 (session close)

dc6baf0594fbb3c50d11789a184b0cb7f16eb06a · 2026-07-22 20:24:42 -0700 · Steve

Files touched

Diff

commit dc6baf0594fbb3c50d11789a184b0cb7f16eb06a
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Jul 22 20:24:42 2026 -0700

    chore: harden sublease.ts (enum allowlists on status/lease_type/rate_period, status-aware total count), v0.2.0 (session close)
---
 package-lock.json      |  4 ++--
 package.json           |  4 ++--
 src/server/sublease.ts | 11 +++++++----
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index c526df1..c5e8382 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "nationalrealestate",
-  "version": "0.1.0",
+  "version": "0.2.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "nationalrealestate",
-      "version": "0.1.0",
+      "version": "0.2.0",
       "dependencies": {
         "better-sqlite3": "^13.0.1",
         "dotenv": "^16.4.5",
diff --git a/package.json b/package.json
index 42bb1a3..260e7a1 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,9 @@
 {
   "name": "nationalrealestate",
-  "version": "0.1.0",
+  "version": "0.2.0",
   "private": true,
   "type": "module",
-  "description": "USRealEstate \u2014 national U.S. residential market explorer. Free-data v1 (Redfin Data Center, Zillow Research, Census ACS, FHFA). Internal analyst tool behind basic auth.",
+  "description": "USRealEstate — national U.S. residential market explorer. Free-data v1 (Redfin Data Center, Zillow Research, Census ACS, FHFA). Internal analyst tool behind basic auth.",
   "scripts": {
     "server": "tsx src/server/index.ts",
     "migrate": "tsx db/migrate.ts",
diff --git a/src/server/sublease.ts b/src/server/sublease.ts
index d8bc18b..0a24b7f 100644
--- a/src/server/sublease.ts
+++ b/src/server/sublease.ts
@@ -24,8 +24,8 @@ const FIELDS: Record<string, (v: unknown) => unknown> = {
   floor_suite: v => (v == null ? null : String(v).trim()),
   sqft: v => (v === '' || v == null ? null : Number(v)),
   asking_rate: v => (v === '' || v == null ? null : Number(v)),
-  rate_period: v => (v == null ? 'yr' : String(v)),
-  lease_type: v => (v == null ? 'sublease' : String(v)),
+  rate_period: v => (['yr', 'mo'].includes(String(v)) ? String(v) : 'yr'),
+  lease_type: v => (['sublease', 'direct'].includes(String(v)) ? String(v) : 'sublease'),
   term_months: v => (v === '' || v == null ? null : Math.round(Number(v))),
   available_date: v => (v === '' || v == null ? null : String(v)),
   sublandlord: v => (v == null ? null : String(v).trim()),
@@ -36,7 +36,7 @@ const FIELDS: Record<string, (v: unknown) => unknown> = {
   listing_url: v => (v == null ? null : String(v).trim()),
   lat: v => (v === '' || v == null ? null : Number(v)),
   lng: v => (v === '' || v == null ? null : Number(v)),
-  status: v => (v == null ? 'active' : String(v)),
+  status: v => (['active', 'leased', 'withdrawn'].includes(String(v)) ? String(v) : 'active'),
   notes: v => (v == null ? null : String(v).trim()),
 };
 
@@ -72,7 +72,10 @@ export function mountSublease(app: Express): void {
           LIMIT $${params.length}`,
         params,
       );
-      const total = await query<{ n: string }>(`SELECT COUNT(*)::text AS n FROM sublease WHERE status='active'`);
+      const st = String(req.query.status || 'active');
+      const total = st === 'all'
+        ? await query<{ n: string }>(`SELECT COUNT(*)::text AS n FROM sublease`)
+        : await query<{ n: string }>(`SELECT COUNT(*)::text AS n FROM sublease WHERE status=$1`, [st]);
       res.json({ count: r.rows.length, total: Number(total.rows[0].n), rows: r.rows });
     } catch (e: any) {
       res.status(500).json({ error: String(e.message || e) });

← aa180e3 add sublease inventory: table + /api/sublease GET + gated ad  ·  back to Nationalrealestate  ·  auth: support multiple Basic-Auth users (add Daniel), keep a 2d8dfbe →