Deploy on DigitalOcean App Platform (GitHub-source build) + consolidate audit-fixes
Deploy config: - .do/app.yaml: build the Dockerfile directly from GitHub (deploy_on_push) instead of a pre-built DOCR image; NEXT_PUBLIC_* set RUN_AND_BUILD_TIME with the propertymanagement.network domain so they bake into the client bundle; add custom domains block (apex + www); wire Sentry DSN (server + browser). Included pending work from the audit-fixes branch: - AI provider abstraction (OpenAI/Anthropic, admin-selectable; Anthropic default) - Per-landlord e-signature (DocuSign OAuth + Dropbox Sign) + migration 0010 - Outbound webhooks / Zapier integration - PayPal removal (Stripe-only billing) - Storage hardening (fail-loud when Spaces unconfigured), security fixes Verified: full production Docker build (same build-args as DO) passes clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
917a06ee85
commit
5495b94924
+33
-12
@@ -1,17 +1,38 @@
|
||||
import type { MetadataRoute } from "next"
|
||||
import { LEGAL_PAGES } from "@/lib/legal"
|
||||
|
||||
const base = process.env.NEXT_PUBLIC_APP_URL ?? "https://propertymanagement.network"
|
||||
|
||||
type ChangeFrequency = MetadataRoute.Sitemap[number]["changeFrequency"]
|
||||
|
||||
// Single source of truth for the public, indexable URL surface. Every entry
|
||||
// must resolve to a real 200 page that is NOT noindex'd. Private/app routes are
|
||||
// blocked in app/robots.ts, and the /login and /forgot-password auth pages are
|
||||
// noindex, so all three are intentionally omitted here. /signup is kept as a
|
||||
// conversion landing page.
|
||||
const PAGES: { path: string; changeFrequency: ChangeFrequency; priority: number }[] = [
|
||||
{ path: "/", changeFrequency: "weekly", priority: 1 },
|
||||
{ path: "/tenant-portal-info", changeFrequency: "monthly", priority: 0.8 },
|
||||
{ path: "/api-docs", changeFrequency: "monthly", priority: 0.8 },
|
||||
{ path: "/signup", changeFrequency: "monthly", priority: 0.7 },
|
||||
// Legal pages are derived from the shared LEGAL_PAGES constant (the same list
|
||||
// the footer renders) so the sitemap can never drift from the real routes.
|
||||
...LEGAL_PAGES.map((page) => ({
|
||||
path: page.href,
|
||||
changeFrequency: "yearly" as const,
|
||||
priority: 0.3,
|
||||
})),
|
||||
]
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
const base = process.env.NEXT_PUBLIC_APP_URL ?? "https://propertymanagement.network"
|
||||
const lastModified = new Date("2026-07-01")
|
||||
// Build-time timestamp, refreshed on every deploy. We don't track per-page
|
||||
// modification dates, so a single honest "last built" date is used throughout.
|
||||
const lastModified = new Date()
|
||||
|
||||
return [
|
||||
{ url: base, lastModified, changeFrequency: "weekly", priority: 1 },
|
||||
{ url: `${base}/tenant-portal-info`, lastModified, changeFrequency: "monthly", priority: 0.8 },
|
||||
{ url: `${base}/api-docs`, lastModified, changeFrequency: "monthly", priority: 0.6 },
|
||||
{ url: `${base}/signup`, lastModified, changeFrequency: "monthly", priority: 0.7 },
|
||||
{ url: `${base}/privacy`, lastModified, changeFrequency: "yearly", priority: 0.3 },
|
||||
{ url: `${base}/terms`, lastModified, changeFrequency: "yearly", priority: 0.3 },
|
||||
{ url: `${base}/cookie-policy`, lastModified, changeFrequency: "yearly", priority: 0.3 },
|
||||
{ url: `${base}/gdpr`, lastModified, changeFrequency: "yearly", priority: 0.3 },
|
||||
]
|
||||
return PAGES.map(({ path, changeFrequency, priority }) => ({
|
||||
url: path === "/" ? base : `${base}${path}`,
|
||||
lastModified,
|
||||
changeFrequency,
|
||||
priority,
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user