From a65189b3943668fbed3c8a6d3410b96b5e61d0c9 Mon Sep 17 00:00:00 2001 From: anusbutt Date: Fri, 14 Aug 2026 04:47:07 +0500 Subject: [PATCH] fix(portfolio): share contact rules and canonicalize site metadata Reuse one dependency-free contact contract across the client and server, wire and test the existing honeypot, correct public documentation and canonical URL references, and clean the redundant ignore entry. --- .env.example | 4 +- .gitignore | 1 - CONTRIBUTING.md | 2 +- README.md | 4 +- next-env.d.ts | 4 +- src/app/page.tsx | 6 ++- .../sections/contact/ContactForm.tsx | 42 +++++++++++++++---- src/content/profile.ts | 4 +- src/server/contact/service.ts | 2 +- src/server/contact/validation.ts | 17 ++++---- src/shared/contact.ts | 20 +++++++++ tests/contact.spec.ts | 40 ++++++++++++++++++ tests/homepage.spec.ts | 3 ++ tests/seo.spec.ts | 5 ++- 14 files changed, 124 insertions(+), 30 deletions(-) create mode 100644 src/shared/contact.ts diff --git a/.env.example b/.env.example index 56c45c1..8682e4e 100644 --- a/.env.example +++ b/.env.example @@ -1,9 +1,9 @@ # Public site URL used for canonical metadata, sitemap, and robots. -NEXT_PUBLIC_SITE_URL=https://anusbutt.com +NEXT_PUBLIC_SITE_URL=https://www.anasbutt.site # Resend API key. Keep this server-only and configure it in Vercel/local .env.local. RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxxxx # Verified sender and destination addresses for the fixed portfolio contact workflow. -CONTACT_FROM_EMAIL=portfolio@anusbutt.com +CONTACT_FROM_EMAIL=portfolio@anasbutt.site CONTACT_TO_EMAIL=your-email@example.com \ No newline at end of file diff --git a/.gitignore b/.gitignore index f8584b9..13b3b5d 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,6 @@ Thumbs.db # IDE .vscode/ .idea/ -.vercel # Local Spec-Driven Development and agent workspace .agents/ .claude/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 59d98be..3d8d3d6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -1. Read the feature specification and plan under specs/portfolio-architecture-refactor/ before making architectural changes. +1. Read README.md and the relevant source files before making a change. 2. Keep portfolio content in src/content and avoid duplicating identity values in components. 3. Run npm run check and npm run test:e2e before opening a pull request. 4. Preserve accessible keyboard navigation, reduced-motion behavior, responsive layout, and the existing visual identity. diff --git a/README.md b/README.md index 3da624b..72838fe 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Personal portfolio for Anus Butt, an AI engineer and full-stack engineer building auditable agent systems, developer tools, and production web applications. -Live site: https://anusbutt.com +Live site: https://www.anasbutt.site ## Architecture @@ -62,7 +62,7 @@ npm run check ## Deployment -Deploy the repository to Vercel with the four environment variables configured in the project settings. Pushes to the main branch can use the included GitHub Actions checks as the merge gate. The contact limiter is intentionally an in-memory, per-instance guard suitable for low-volume portfolio traffic; a managed limiter would be the next step if abuse volume grows. +Deploy the repository to Vercel with the four environment variables configured in the project settings. Pushes to the default branch can use the included GitHub Actions checks as the merge gate. The contact limiter is intentionally an in-memory, per-instance guard suitable for low-volume portfolio traffic; a managed limiter would be the next step if abuse volume grows. ## Contributing and security diff --git a/next-env.d.ts b/next-env.d.ts index a419cbe..ce4e94a 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,7 +1,7 @@ /// /// -import "./.next/dev/types/routes.d.ts"; -import "./.next/dev/types/root-params.d.ts"; +import "./.next/types/routes.d.ts"; +import "./.next/types/root-params.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/src/app/page.tsx b/src/app/page.tsx index c7a199a..0c0a43a 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,4 +1,5 @@ import { profile } from "@/content/profile"; +import { siteUrl } from "@/content/site"; import Navbar from "@/components/layout/Navbar"; import Hero from "@/components/sections/hero/Hero"; import About from "@/components/sections/about/About"; @@ -14,6 +15,7 @@ const personJsonLd = { jobTitle: profile.title, address: { "@type": "PostalAddress", addressCountry: "Pakistan" }, sameAs: profile.sameAs, + url: siteUrl.toString(), }; export default function Home() { @@ -21,7 +23,9 @@ export default function Home() {