← back to Trademarks Copyright

src/app/changelog/page.tsx

76 lines

import Link from "next/link";

export const metadata = {
  title: "Changelog",
  description: "What's shipped on Drops.",
};

type Entry = { date: string; items: string[] };

const CHANGELOG: Entry[] = [
  {
    date: "2026-04-24",
    items: [
      "Welcome drop — new trial subscribers now get the most recent drop immediately on signup instead of waiting until 9am tomorrow.",
      "Daily drop composition fully parallelized (~3× faster).",
      "Admin: inline drop-item editor (edit headlines/blurbs/PRO hints without recomposing).",
      "Admin: subscribers list with tier/status/open-rate, edit inline.",
      "Referral system — subscribers get a unique URL; 3 signups = 30 free days.",
      "Email open-tracking pixel; open-rate visible in admin drops dashboard.",
      "Public archive at /drops/archive with teased past issues for SEO + conversion.",
      "Sample-drop preview embedded in the landing page for instant social proof.",
      "Seed catalog expanded by 25 items — defunct retail (Linens 'n Things, Filene's Basement, Sharper Image, Montgomery Ward, Tower Records), defunct restaurants (HoJo, Chi-Chi's, Bennigan's), and the 1929 public-domain cohort (Sherlock Holmes final stories, Steamboat-contemporary animation, A Farewell to Arms).",
      "Legal pages: Terms, Privacy, Refund — Stripe-ready, California-governed.",
      "Marketing pages: About, Pricing, FAQ — each with its own metadata + SEO.",
      "SEO: per-page metadata, Organization + WebApp JSON-LD, OpenGraph + Twitter Card, robots.txt + sitemap.xml, dynamic /opengraph-image route.",
      "Health endpoint /api/health returns db + ollama + email-backend + stripe status (200/503).",
      "Admin auth: cookie-gated /admin/* routes via ADMIN_TOKEN.",
      "Rate limit + disposable-email filter on signup.",
      "Custom 404/500 pages.",
      "Test suite (23 tests) for scoring + lifecycle classification.",
    ],
  },
  {
    date: "2026-04-23",
    items: [
      "Drops SaaS shipped — signup, Stripe checkout (optional), daily cron, multi-backend email (Resend / SMTP / file).",
      "Qwen-powered drop composer reads items + brand_candidates tables.",
      "Subscriber portal + unsubscribe flow.",
      "Brand hunter — DDG HTML + DDG Lite + Brave Search fallback, Qwen classifies live USPTO registration status.",
      "Brand-domain sanity gate (flags parked/registrar-redirect pages as 'parked').",
      "Opportunity labels: domain_snipe / abandonment_watch / licensing_outreach / do_not_target.",
      "Activity clock — scans homepage for © year, classifies active / stale / abandoned.",
      "Domain lifecycle — HTTP liveness + WHOIS expiry.",
      "Underlying 'Trademarks & Copyright' opportunity finder: 30-item seed, TanStack table with multi-select, 4-agent SWOT via Qwen (no paid APIs), composite scoring, React Flow canvas.",
    ],
  },
];

export default function ChangelogPage() {
  return (
    <article className="mx-auto max-w-3xl space-y-4">
      <div className="card p-6">
        <div className="text-xs uppercase tracking-widest text-brass">Changelog</div>
        <h1 className="mt-2 text-3xl font-semibold">What's shipped.</h1>
        <p className="mt-2 text-sm text-ink/70">
          We ship frequently. See <Link href="/drops" className="text-brass underline">drops</Link> for the daily product,
          or the <Link href="/faq" className="text-brass underline">FAQ</Link> for common questions.
        </p>
      </div>

      {CHANGELOG.map((entry) => (
        <div key={entry.date} className="card p-5">
          <div className="text-xs uppercase tracking-wide text-brass mb-2">
            {new Date(entry.date).toLocaleDateString(undefined, { weekday: "long", month: "long", day: "numeric", year: "numeric" })}
          </div>
          <ul className="list-disc pl-5 space-y-1 text-sm">
            {entry.items.map((it, i) => (
              <li key={i} className="text-ink/80 leading-relaxed">{it}</li>
            ))}
          </ul>
        </div>
      ))}
    </article>
  );
}