spb/worthdoing Public
Autonomous investigation agent that discovers, challenges, and ranks things genuinely worth doing — Claude + Firecrawl, Next.js 16, PostgreSQL
TypeScript 91.5%
SQL 5.8%
CSS 2.2%
1/**2 * WorthDoing.ai3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File: src/app/explore/page.tsx6 * Description: Explore page — the accumulated opportunity database, ranked by Worth Score.7 */8import { desc, eq } from "drizzle-orm";9import { db } from "@/lib/db/client";10import { opportunities, investigations } from "@/lib/db/schema";11import { OpportunityCard } from "@/components/wd/OpportunityCard";1213export const dynamic = "force-dynamic";1415export default async function ExplorePage() {16 const rows = await db17 .select({18 id: opportunities.id,19 title: opportunities.title,20 summary: opportunities.summary,21 worthScore: opportunities.worthScore,22 evidenceConfidence: opportunities.evidenceConfidence,23 objective: investigations.objective,24 reportMd: opportunities.reportMd,25 })26 .from(opportunities)27 .innerJoin(investigations, eq(investigations.id, opportunities.investigationId))28 .orderBy(desc(opportunities.worthScore))29 .limit(100);3031 return (32 <div className="mx-auto w-full max-w-6xl px-4 py-10 sm:px-6">33 <h1 className="font-heading text-3xl font-semibold tracking-tight text-ink sm:text-4xl">34 The opportunity database35 </h1>36 <p className="mt-2 max-w-2xl text-ink-soft">37 Everything the agent has judged worth doing — ranked by Worth Score, with evidence38 confidence shown separately.39 </p>4041 {rows.length === 0 ? (42 <div className="mt-16 rounded-xl border border-dashed border-line bg-card/50 p-12 text-center">43 <p className="font-heading text-xl text-ink">Nothing here yet</p>44 <p className="mt-2 text-sm text-ink-soft">45 Run an investigation from the home page — validated opportunities land here.46 </p>47 </div>48 ) : (49 <div className="mt-8 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">50 {rows.map((o) => (51 <OpportunityCard52 key={o.id}53 id={o.id}54 title={o.title}55 summary={o.summary}56 worthScore={o.worthScore}57 evidenceConfidence={o.evidenceConfidence}58 objective={o.objective}59 hasReport={!!o.reportMd}60 />61 ))}62 </div>63 )}64 </div>65 );66}67