Small Business Builder
Search the build
-
a21cd752026-07-22 auto-save: 2026-07-22T21:46:55 (1 files) — package-lock.json -
8f615572026-07-22 chore: v0.1.1 (barber.aa PUBLIC_HOSTS, session close) -
3e1c27e2026-07-22 add barber.agentabrams.com to PUBLIC_HOSTS (directory renamed from livesiteaudit.aa) -
669babf2026-07-17 auto-save: 2026-07-17T19:47:29 (1 files) — data/wa-screenshots/fantaseayachts-com.png -
e7045812026-07-03 chore: macstudio3 migration — reconcile from mac2 + repoint paths (stevestudio2→macstudio3, node/npm/npx→/opt/homebrew) -
82a97292026-06-24 website-analysis: fix public-host critique page — whitelist screenshot+deep-dive, hide SHIP on public host (fantasea.agentabrams.com) -
0a5f3562026-06-24 auto-save: 2026-06-24T15:27:54 (1 files) — src/server/index.js -
771aaa92026-05-31 fix: add rel="noopener noreferrer" to target=_blank links missing it -
dadcde32026-05-13 snapshot: 66 file(s) changed, +54 new, ~12 modified -
783c9b72026-05-12 qa click-through: log session-minutes to cost-tracker via shared helper -
a3c524f2026-05-07 tighten .gitignore: add missing standing-rule patterns (dist/ build/ .next/) -
5aaf4a32026-05-06 fix(ops): port hawk to sf-style pm2-jlist pattern — old curl-only hawk had wrong /opt/homebrew/bin/pm2 path so it logged 'No such file' every fire and silently failed -
c6fa7852026-05-04 deploy: ship smb-builder to Kamatera + capture full schema in migrations 002-008 -
41c8a332026-05-04 [morning-review] small-business-builder: gate interview admin + whitelist QA keys + UI/render hardening -
b789cdc2026-05-04 [morning-review] small-business-builder: harden public profile + interview API -
035afe22026-05-04 yolo: iter 3 trivial patches from claude-codex debate -
980062b2026-05-04 yolo: iter 2 trivial patches from claude-codex debate -
ff56b972026-05-03 yolo: baseline before overnight
Authors
- Steve15
- yolo2
- local1
Agents used
- website-analysis1
Skills used
- /index3
- /interview3
- /homebrew2
- /server2
- /render2
- /biz2
- /wa-screenshots1
- /fantaseayachts-com1
- /npm1
- /npx1
- /builds-index1
- /pm21
- /deploy-kamatera1
- /live1
- /capture1
Creative ideas + design notes
771aaa9 · 2026-05-31 · fix: add rel="noopener noreferrer" to target=_blank links missing it
Three anchor elements in src/server/index.js (build URL kv-row, wa peek drawer FULL link) and five Quick Open sidebar links in src/render/builds-index.js were missing rel="noopener noreferrer", exposing opener context to cross-origin pages. All fixed; syntax clean. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
c6fa785 · 2026-05-04 · deploy: ship smb-builder to Kamatera + capture full schema in migrations 002-008
migrations 002-008 capture all tables that drifted into local DB ad-hoc. All use IF NOT EXISTS so re-running on a populated DB is a no-op. Validated end-to-end against a fresh smb_migration_test DB -> 13 tables, all clean. scripts/deploy-kamatera.sh: idempotent 6-step rsync->createdb->migrate->.env->pm2. ADMIN_TOKEN piped via stdin (never lands in argv / ps / shell history). Live at http://45.61.58.125:9760 (no public domain yet).
41c8a33 · 2026-05-04 · [morning-review] small-business-builder: gate interview admin + whitelist QA keys + UI/render hardening
Critical: - Gate GET /biz/:slug/interview and /interview/live behind ADMIN_TOKEN (POST already gated); adds shared requireAdmin() helper. - Whitelist incoming qa keys against QUESTIONS ids before persisting, so attackers can't balloon JSONB or inject collision keys. High: - Cast $2::jsonb on interview INSERT to avoid pg-driver double-encode. - profile.js: white-space:pre-wrap on .qa .a so multi-paragraph answers render with linebreaks intact. - profile.js: form maxlength now uses q.max_chars (was *2), aligning the soft limit with what the server keeps. Medium: - profile.js: format recorded_at in UTC so "Recorded January 2026" doesn't flicker by host TZ. - profile.js: new safeHref() validates http(s) scheme on b.website before rendering as href or schema.org url (blocks javascript: XSS). - profile.js: coerce qa_json from string when legacy rows stored JSON text rather than a jsonb object. - server/index.js: /n/:slug uses slugify() rather than an inline regex, matching the slugs emitted in links. - interview-questions.js: localizeQuestion substitutes [neighborhood] across every string field, not just q + placeholder.
b789cdc · 2026-05-04 · [morning-review] small-business-builder: harden public profile + interview API
- Strip third-party mcp.figma.com/capture.js from public home + profile pages - Escape JSON-LD payloads so user answers can't break out of <script> (XSS) - Wrap new URL(b.website) so scheme-less domains don't 500 the profile route - Gate POST /api/biz/interview behind ADMIN_TOKEN cookie + admin_token field; reject Array qa payloads, accept urlencoded qa_<id> for no-JS form fallback, redirect non-JSON callers, trim history to 5 most-recent rows per business - Cap homepage SELECT at 200 rows; replace /n/:slug full-table scan with WHERE neighborhood=$1 + DISTINCT slug resolution; 409 on slug collisions - Guard Number.isFinite on years_in_business, recorded_at date format, empty hoodSlug links, NaN max_chars in interview form - Move interview-form submit button inside <form> so no-JS submit + a11y work Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
File tree
- .env.example
- .gitignore
- DEPLOY.md
- README.md
- _qa/2026-05-05-builds/01-initial.png
- _qa/2026-05-05-builds/02-filter-morning.png
- _qa/2026-05-05-builds/03-after-reset.png
- _qa/2026-05-05-builds/04-top-chip.png
- _qa/2026-05-05-builds/05-stale-chip.png
- _qa/2026-05-05-builds/06-drawer-open.png
- _qa/2026-05-05-builds/07-drawer-after-dd.png
- _qa/2026-05-05-builds/08-drawer-next.png
- _qa/2026-05-05-builds/08-drawer-no-dd-btn.png
- _qa/2026-05-05-builds/09-drawer-closed.png
- _qa/2026-05-05-builds/09-drawer-next.png
- _qa/2026-05-05-builds/10-drawer-closed.png
- _qa/2026-05-05-builds/findings.json
- _qa/click-through.mjs
- _qa/ui-1-entry.png
- _qa/ui-2-wall.png
- _qa/ui-3-grades.png
- _qa/ui-3-leaderboard.png
- _qa/ui-4-wa-detail.png
- _qa/ui-5-mockup-brutalist.png
- _qa/ui-entry-dark-final.png
- _qa/ui-entry-dark-fixed.png
- _qa/ui-entry-dark.png
- _qa/ui-entry-light.png
- data/wa-screenshots/fantaseayachts-com.png
- data/wa-screenshots/retrowalls-com.png
- design/figma/website-analysis-brutalist.md
- design/north-star.md
- ecosystem.config.cjs
- migrations/001_init.sql
- migrations/002_website_analysis.sql
- migrations/003_neighborhood_display_name.sql
- migrations/004_business_articles.sql
- migrations/005_business_interviews.sql
- migrations/006_business_pricing.sql
- migrations/007_business_review_sources.sql
- migrations/008_enrichment_jobs.sql
- package-lock.json
- package.json
- public/favicon.svg
- scripts/audit-public-sites.mjs
- scripts/backfill-la-neighborhoods.js
- scripts/build-all-analyses.mjs
- scripts/bulk-draft-interviews.js
- scripts/data-hound-census.js
- scripts/data-hound-press.js
- scripts/data-hound-social.js
- scripts/deploy-kamatera.sh
- scripts/enrich-copy-local.mjs
- scripts/enrich-rescue.mjs
- scripts/flag-sole-prop-barbers.js
- scripts/generate-roasts.mjs
- scripts/geocode-via-nominatim.js
- scripts/hawk-local.sh
- scripts/ingest-bbcb-salons.js
- scripts/ingest-hollywood-corridor.js
- scripts/ingest-osm-salons.js
- scripts/ingest-sunset-corridor.js
- scripts/ingest-ventura-corridor.js
- scripts/ingest-wilshire-corridor.js
- scripts/loop-tick.sh
- scripts/overnight-loop.sh
- scripts/rerender-url-mockups.mjs
- seed-data/README.md
- seed-data/la-salons.json
- src/lib/audit-grade.js
- src/lib/builds-index.js
- src/lib/db.js
- src/lib/deep-dive.js
- src/lib/escape.js
- src/lib/interview-questions.js
- src/lib/log.js
- src/lib/ollama-draft.js
- src/lib/slug.js
- src/lib/svg-hero.js
- src/lib/vertical.js
- src/render/builds-index.js
- src/render/category.js
- src/render/corridor-map.js
- src/render/corridor.js
- src/render/edit.js
- src/render/fresh.js
- src/render/grid.js
- src/render/home.js
- src/render/interview-live.js
- src/render/map.js
- src/render/near.js
- src/render/neighborhoods.js
- src/render/profile.js
- src/render/proprietors.js
- src/render/templates/_helpers.js
- src/render/templates/index.js
- src/render/templates/template-1.js
- src/render/templates/template-2.js
- src/render/templates/template-3.js
- src/render/templates/template-4.js
- src/render/templates/template-5.js
- src/render/wall.js
- src/render/website-analysis-themes.js
- src/render/website-analysis.js
- src/scrape/instagram_public.js
- src/scrape/website_meta.js
- src/server/index.js