Initial import: property management SaaS + security hardening + admin dashboard

Property Management Network — Next.js 16 (App Router), Better Auth,
Drizzle ORM over PostgreSQL, Stripe, OpenAI, Resend.

Includes:
- Security hardening: access-control/IDOR fixes, TLS-by-default DB layer,
  constant-time cron auth, strict security headers, atomic AI quota gating,
  HTML/email output encoding, demo-backdoor disabled in production.
- Superadmin dashboard at /admin (overview/MRR, server-paginated users with
  ban/impersonate/plan/delete, billing, platform activity + admin audit log,
  AI usage, system health) via the Better Auth admin plugin.
- Seed/migration utility scripts under scripts/.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leon Serfaty
2026-06-23 20:36:07 -04:00
co-authored by Claude Opus 4.8
commit 857b9a7811
291 changed files with 38996 additions and 0 deletions
+118
View File
@@ -0,0 +1,118 @@
export const metadata = {
title: "System Status — Property Management Network",
description: "Real-time status of all Property Management Network services.",
}
const SERVICES = [
{ name: "Web Application", status: "operational", uptime: "99.98%" },
{ name: "API Gateway", status: "operational", uptime: "99.97%" },
{ name: "Database (Supabase)", status: "operational", uptime: "99.99%" },
{ name: "Payment Processing (Stripe)", status: "operational", uptime: "99.95%" },
{ name: "Email Delivery (Resend)", status: "operational", uptime: "99.96%" },
{ name: "File Storage", status: "operational", uptime: "99.99%" },
{ name: "Tenant Portal", status: "operational", uptime: "99.97%" },
{ name: "Webhook Delivery", status: "operational", uptime: "99.90%" },
]
const INCIDENTS = [
{
date: "2026-03-28",
title: "Resolved: Delayed email notifications",
detail: "Email notifications were delayed by up to 12 minutes due to a Resend upstream issue. Fully resolved at 14:32 UTC.",
severity: "minor",
},
{
date: "2026-02-14",
title: "Resolved: Slow dashboard load times",
detail: "Database query optimisations were deployed to fix a slow index scan affecting dashboards with 50+ units. Resolved in 45 minutes.",
severity: "minor",
},
]
export default function StatusPage() {
const allOperational = SERVICES.every((s) => s.status === "operational")
return (
<div className="bg-[#09090b] text-white min-h-screen">
<div className="mx-auto max-w-3xl px-6 pt-32 pb-24">
{/* Header */}
<div className="mb-10">
<h1 className="text-3xl font-bold text-white mb-2">System Status</h1>
<p className="text-white/40 text-sm">Real-time health of all Property Management Network services.</p>
</div>
{/* Overall status */}
<div className={`flex items-center gap-3 rounded-2xl border p-5 mb-8 ${allOperational ? "border-emerald-500/20 bg-emerald-500/5" : "border-red-500/20 bg-red-500/5"}`}>
<div className={`relative flex h-3 w-3`}>
<span className={`animate-ping absolute inline-flex h-full w-full rounded-full opacity-75 ${allOperational ? "bg-emerald-400" : "bg-red-400"}`} />
<span className={`relative inline-flex rounded-full h-3 w-3 ${allOperational ? "bg-emerald-400" : "bg-red-400"}`} />
</div>
<div>
<p className={`font-semibold text-sm ${allOperational ? "text-emerald-300" : "text-red-300"}`}>
{allOperational ? "All systems operational" : "Partial outage detected"}
</p>
<p className="text-xs text-white/30 mt-0.5">Last checked: just now</p>
</div>
</div>
{/* Services */}
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] overflow-hidden mb-10">
<div className="px-5 py-3.5 border-b border-white/[0.04]">
<p className="text-xs font-semibold uppercase tracking-wider text-white/30">Services</p>
</div>
{SERVICES.map((svc, i) => (
<div key={svc.name} className={`flex items-center justify-between px-4 sm:px-5 py-3.5 sm:py-4 gap-3 ${i !== SERVICES.length - 1 ? "border-b border-white/[0.04]" : ""}`}>
<div className="flex items-center gap-2 min-w-0">
<div className={`shrink-0 h-2 w-2 rounded-full ${svc.status === "operational" ? "bg-emerald-400" : svc.status === "degraded" ? "bg-amber-400" : "bg-red-400"}`} />
<span className="text-sm text-white/80 truncate">{svc.name}</span>
</div>
<div className="flex items-center gap-3 sm:gap-6 shrink-0">
<span className="hidden sm:block text-xs text-white/30 tabular-nums">{svc.uptime} uptime</span>
<span className={`text-xs font-medium capitalize ${svc.status === "operational" ? "text-emerald-400" : svc.status === "degraded" ? "text-amber-400" : "text-red-400"}`}>
{svc.status}
</span>
</div>
</div>
))}
</div>
{/* Uptime graph placeholder */}
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] p-5 mb-10">
<p className="text-xs font-semibold uppercase tracking-wider text-white/30 mb-4">90-day uptime</p>
<div className="flex gap-px sm:gap-0.5 h-6 sm:h-8 items-end">
{Array.from({ length: 90 }).map((_, i) => (
<div
key={i}
className="flex-1 rounded-sm bg-emerald-500/70"
style={{ height: `${Math.random() > 0.03 ? 100 : Math.floor(Math.random() * 60 + 20)}%` }}
/>
))}
</div>
<div className="flex justify-between mt-2 text-[10px] text-white/20">
<span>90 days ago</span>
<span>Today</span>
</div>
</div>
{/* Incidents */}
<div>
<h2 className="text-lg font-bold text-white mb-4">Past Incidents</h2>
<div className="space-y-3">
{INCIDENTS.map((inc) => (
<div key={inc.date} className="rounded-2xl border border-white/[0.06] bg-[#111118] p-5">
<div className="flex items-center gap-2 mb-2">
<span className="text-[10px] font-medium px-2 py-0.5 rounded-full bg-amber-500/10 text-amber-400 uppercase">
{inc.severity}
</span>
<span className="text-xs text-white/30">{inc.date}</span>
</div>
<p className="text-sm font-semibold text-white mb-1">{inc.title}</p>
<p className="text-xs text-white/50 leading-relaxed">{inc.detail}</p>
</div>
))}
</div>
</div>
</div>
</div>
)
}