
Who
I build operator tools for people who get paid when the NAP is right: agencies, multi-location owners, anyone tired of logging into Google, Yelp, and a dozen legacy directories by hand.
Citation Manager is that lane. Business listings out. Tracking what stuck. Skip the academic bibliography frame and the WNC city-guide frame.
If you care about local SEO plumbing, directory registries, or how a two-week SaaS sprint accumulates three auth stacks and a 500 on the homepage URL, these are the field notes.
What
I shipped HurleyUS/citation-manager. Public TypeScript repo, package 0.0.1, 83 commits, HEAD 78e9fb1.
GitHub description is blunt: manage business listings across 1000+ directories. Uberall competitor. The README narrows it to 958+ directories and names Uberall, BrightLocal, and Yext as the alternatives it wants to undercut on price ($99 vs $500–2000/mo copy in the roadmap).
Stack on the box: Next.js 16.2, React 19, Convex, Tailwind v4, Bun, Lucide, Puppeteer, Argon2. Clerk and @convex-dev/auth sit in package.json; Fallow marks both unused while the UI talks to /api/auth and localStorage tokens.

The real artifact is data/directories.json: 958 rows. Rank 1 is Google Business Profile. Methods break down api 88 / form 773 / manual 70 / email 27. apiAvailable is true on 219. Convex schema mirrors that world: locations, directories, submissions with pending to submitted to verified to failed, plus verifications.
Surfaces that exist: auth, dashboard, locations CRUD, directories browser with "View All 958", bulk submit with search/filter, submissions tracker, seed-directories API, google/yelp/facebook API routes.
What is also true:
bulkSubmitinsertspendingrows. The schedule helpers flip tosubmittedonly if env keys exist. They do not call the fetch helpers in that path.generateGoogleJWTis a documented placeholder.- Login hashes the password with Argon2 again and string-compares to the stored hash. New salt means verify cannot work as written.
- Dashboard copy still says "100+ directories" while the registry is 958.

Where
It is supposed to run on Vercel against Convex. Dev uses Caddy cm.localhost:8080 to Next on 3000.
Probed 2026-09-08:
- https://citation-manager-pi.vercel.app (GitHub homepageUrl) returns 500
MIDDLEWARE_INVOCATION_FAILED - https://citation-manager.vercel.app returns 200, but it is a different "research workflow" citation app with Admin/User portals. Name collision, not this product.
Audience: local-SEO operators, agencies replacing BrightLocal/Yext spend, builders watching auth and integration honesty in a Convex/Next SaaS.

When
Created 2026-03-22. Same day: scaffold, directory research, API skeletons, Clerk blank-page fix, Convex Auth swap, "FULL PHASE 2 READY FOR 6PM SHIP," Google Maps submission claim, locations wired to Convex.
Late March: Argon2, push-to-directories UI, View All 958, submissions dashboard.
2026-04-01–02. Registry expanded 100 to 958, Issue #12 Google/Yelp/Facebook modules, Clerk middleware returns, Phase 2B bypass + test infra, form validation, GBP PR.
2026-05-14–15. Seven "Standardize Blacksmith CI gates" commits (same batch pattern as sibling repos) plus deploy verification fixes.
2026-08-08. HEAD sets X-Robots-Tag: index, follow. Same day pattern as other HurleyUS pushes.
README still says Phase 2A 100% complete and Phase 2B "current" as of early April. Stripe is still Phase 4 fiction.

Why
Local citations are still a grind. The expensive tools win on coverage and integrations, not on elegance. I wanted an API-first Convex backend, a ranked directory registry I own as JSON, and a submit queue I can reason about in one schema.
I also wanted to ship before the story was clean. That is why the homepage 500s, why login verify is wrong, why Clerk middleware and a bypass flag coexist, and why the integration modules look finished while bulkSubmit mostly writes pending.
The registry is real. The competitor framing is real. The production URL on the GitHub homepage is not a product yet. It is an error page.
If you run citations for clients: would you trust a 958-row registry with honest pending states more than a vendor dashboard that always says "submitted"? What is the minimum live integration (Google only) before this is worth putting a real domain on?
