Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,23 @@

> **Note:** This file tracks migration and release notes for the **Turborepo Cloudflare** app (`apps/web` Next.js Pages + `apps/api` Elysia Worker, `bun`, `bun.lock`). Older single-app / Astro-era detail is archived below for context — see [README.md](README.md) and [AGENTS.md](AGENTS.md).

## Codebase cleanup, perf optimization & tech integrations (2026-04-30)

- Removed Zustand badge from the "Our Edge" stack display — dependency was previously removed but badge remained.
- Removed stray `console.warn` in the competitor-scan catch block of `apps/api/src/routes/audit.ts`.
- Cleaned up outdated Firebase/Firestore references in `lighthouse2.md` (now reflects Cloudflare Pages/Workers + KV/D1).
- Added `manifest.webmanifest` to `apps/web/public/` with PWA metadata — triggers PWA detection on Wappalyzer/BuiltWith.
- Added JSON-LD structured data (`Organization`, `LocalBusiness`, `WebSite`) in root layout — zero render cost, boosts SEO.
- Verification: `bun run lint`, `bun run build` pass from the repo root.

## Lockfile fix + backend PDF offload (2026-04-30)


- **Lockfile fix (P0):** Removed conflicting workspace-level `overrides` from `apps/web/package.json` (stale `postcss ^8.4.38` vs root `^8.5.12`, duplicate `uuid`, unrecorded `yaml@<2.8.3`). Moved `yaml@<2.8.3` override to root `package.json`. Regenerated `bun.lock` — `bun install --frozen-lockfile` now passes in CI.
- **Dependency hygiene:** Relocated heavy backend-only packages (`@google/genai`, `googleapis`, `cheerio`, `jspdf`) from `apps/web` to `packages/shared` where they are actually imported. Frontend bundle no longer ships these libraries.
- **PDF offload to API Worker:** Created `GET /api/report/:id/pdf` on the ElysiaJS Worker (`apps/api/src/routes/reportPdf.ts`). The route fetches the persisted report from the KV store, calls `buildAuditPdf` server-side, and streams the PDF back with `Content-Disposition: attachment`. `AuditResults.tsx` now fetches from this endpoint instead of importing `jspdf` client-side — removes ~250 KB from the browser bundle and eliminates client-side PDF generation latency.
- Added `./lighthouse/*` export to `packages/shared` so `AuditData` types are accessible from any workspace.
- Verification: `bun install --frozen-lockfile`, `bun run build`, `bun run typecheck`, and `bun run lint` pass from the repo root.

## Micro SaaS store /tools page build-out (2026-04-30)

- Replaced the "Coming Soon" waitlist on `/tools` with a full product catalog showcasing 6 Stripe-backed micro-SaaS products: SiteScan, ReviewPilot, ClientHub, LocalRank, TestiFlow, and ContentMill.
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/routes/audit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,8 @@ export const auditRoute = new Elysia({ aot: false }).post(
placesData.primaryType,
3,
);
} catch (compErr) {
console.warn("Competitor scan failed:", compErr);
} catch {
/* competitor scan is best-effort — swallow errors silently */
}

const categories = lighthouse.categories;
Expand Down
26 changes: 26 additions & 0 deletions apps/web/public/manifest.webmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "Designed by Anthony",
"short_name": "DBA",
"description": "Custom web design and local SEO for service businesses in the Mohawk Valley and Central New York.",
"start_url": "/",
"display": "standalone",
"background_color": "#0f1218",
"theme_color": "#0f1218",
"icons": [
{
"src": "/site-icon-48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "/site-icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/site-icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
5 changes: 5 additions & 0 deletions apps/web/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import "@/design-system/dba-global.css";
import { CrispBootstrap } from "@/components/CrispBootstrap";
import { JsonLd } from "@/components/JsonLd";
import "@/styles/layout-shell.css";
import type { Metadata, Viewport } from "next";
import type { ReactNode } from "react";
Expand All @@ -25,6 +26,7 @@ export const metadata: Metadata = {
},
description:
"Custom web design and local SEO for service businesses in the Mohawk Valley and Central New York.",
manifest: "/manifest.webmanifest",
appleWebApp: {
capable: true,
statusBarStyle: "black-translucent",
Expand Down Expand Up @@ -77,6 +79,9 @@ export default function RootLayout({ children }: { children: ReactNode }) {
data-scroll-behavior="smooth"
data-lead-webhook={leadWebhookDefault || undefined}
>
<head>
<JsonLd />
</head>
<body>
{/* Google Tag Manager (noscript) */}
<noscript>
Expand Down
25 changes: 25 additions & 0 deletions apps/web/src/components/JsonLd.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {
buildBaseOrganizationSchema,
buildBaseWebsiteSchema,
} from "@/lib/seo";

const ENTRIES = [buildBaseOrganizationSchema(), buildBaseWebsiteSchema()];

export function JsonLd() {
return (
<>
{ENTRIES.map((entry) => {
const id =
typeof entry["@id"] === "string" ? entry["@id"] : JSON.stringify(entry);
return (
<script
key={id}
type="application/ld+json"
// biome-ignore lint/security/noDangerouslySetInnerHtml: structured data requires raw JSON injection
dangerouslySetInnerHTML={{ __html: JSON.stringify(entry) }}
/>
);
})}
</>
);
}
1 change: 0 additions & 1 deletion apps/web/src/components/marketing/EnrichedPages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,6 @@ export function OurEdgePage() {
href: "https://deepmind.google/technologies/gemini/",
},
{ label: "Zod", href: "https://zod.dev" },
{ label: "Zustand", href: "https://zustand.docs.pmnd.rs" },
].map(({ label, href }) => (
<a
key={label}
Expand Down
4 changes: 2 additions & 2 deletions lighthouse2.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Lighthouse Scanner — product description & operator guide

This document is the **single source of truth** for how we **describe** the scanner (marketing, OG tags, splash copy) and what **you** configure in **Firebase App Hosting** / env. Structure is inspired by common open-source SEO audit READMEs (for example [vchaitanyachowdari/seo-audits-generator](https://github.com/vchaitanyachowdari/seo-audits-generator)) — clear feature blocks, stack, env, usage — adapted to **this repo’s real implementation**, not a generic SaaS template.
This document is the **single source of truth** for how we **describe** the scanner (marketing, OG tags, splash copy) and what **you** configure in **Cloudflare Pages / Workers** env. Structure is inspired by common open-source SEO audit READMEs (for example [vchaitanyachowdari/seo-audits-generator](https://github.com/vchaitanyachowdari/seo-audits-generator)) — clear feature blocks, stack, env, usage — adapted to **this repo’s real implementation**, not a generic SaaS template.

---

Expand All @@ -21,7 +21,7 @@ This document is the **single source of truth** for how we **describe** the scan
| **Authority / links** | “Backlink snapshot when configured” | **Moz API** when `MOZ_API_CREDENTIALS` / token is set; otherwise omit or show “not configured” in UI |
| **Conversion / UX** | “Trust + conversion lens” | AI **conversionScore** + CTA/schema/tel/form signals from HTML |
| **AI report** | Plain-English executive summary + top fixes | **Gemini** (`generateAiInsight`) with fallback |
| **Persistence** | Sharable report when storage works | Firestore report store when configured |
| **Persistence** | Sharable report when storage works | KV / D1 report store when configured |
| **CRM / leads** | Optional | Convex webhooks, Sheets, Gmail — see `.env.example` (`AUDIT_LEAD_WEBHOOK_*`, `LEAD_WEBHOOK_URL`) |

Do **not** claim: unlimited full-site crawl like Semrush/Ahrefs, JS-rendered crawl of every route, or “Moz DA” unless Moz is configured.
Expand Down