Loading...
Loading...
Everything we ship, as we ship it. BGC is built in public by one person with a lot of caffeine and a small army of AI assistants.
Built branded social sharing images using Next.js ImageResponse with self-hosted brand fonts. Pillar-colored OG images for events, directory, handbook, ranges, exchange, and campfire. Dynamic /api/og route generates unique images per entity.
Fixed 17+ critical SEO issues: noindexed auth/submit pages, added OG+Twitter cards to 10K+ campfire topics, fixed broken homepage canonical URLs, capped meta descriptions at 160 chars, standardized Twitter card fields, fixed event venue schema fallback.
Researched and locked down the production build configuration after 5 failed deployments. Restored working webpack base (build worker + memory optimizations + filesystem cache + splitChunks), added static generation limits (cpus: 2, workerThreads: false), explicit source map disabling, and Sentry deprecation fix. Build context slashed from 1.33GB to ~400MB via .dockerignore overhaul.
Fixed a bug where all user-submitted events defaulted to Idaho regardless of actual location. Event form now includes state (required dropdown) and ZIP code fields. Corrected 6 misrouted events in production (AZ, TX, DE, AL, MS).
Added geography columns and GIST spatial indexes to listings, events, and shooting_locations tables. Proximity queries now run in ~7ms across 128K+ businesses. Auto-populate triggers keep geog column in sync.
Fixed 68% failure rate in product scraper — root cause was Shopify CDN per-IP rate limiting triggered by concurrent requests. Switched to sequential processing with 0.5s pacing. Now 75/76 retailers succeed (99%), products scraped jumped from 21K to 133K per run. Fixed manifest cross-contamination bug in --retry mode.
BLM, USFS, NPS, BIA, and DOD public land boundaries for 9 western states (ID, MT, UT, NV, AZ, WY, CO, OR, NM). Self-hosted as PMTiles, toggleable on all map views. Color-coded by agency.
Successful scraper fix recovered 50+ previously failing retailers, bringing total indexed products from 168K to 338K across 75 Shopify stores.
Directions modal now supports adding waypoints between origin and destination. Add stops by searching or clicking nearby businesses along the route. Valhalla handles multi-leg routing with per-stop distance/time breakdown. Exports to Google Maps with waypoints.
Use My Location button on directory, events, and ranges sidebars. Browser geolocation with reverse-geocode display. Events page now has full distance filtering parity with directory and ranges. Auto-sorts by distance when location is shared.
New API endpoints /api/directory/nearby and /api/events/nearby return results sorted by real distance using PostGIS ST_DWithin. Upgraded /api/routing/nearby from bounding box to spatial index.
Restored 5 branded map skins (Dawn, Day, Noon, Evening, Night) that were hidden behind a satellite redirect. Fixed labels (lang parameter was missing), added hillshade with multidirectional rendering, corrected sprite theme switching, enhanced state boundary visibility.
New Terrain map style with hypsometric tinting (color-relief elevation ramp), per-theme sun angles for hillshade, contour lines with elevation labels, and 3D terrain exaggeration. Uses MapLibre v5.20 color-relief layer.
MUTCD-accurate highway shields (Interstate blue/red, US Route black/white) via @americana/maplibre-shield-generator. Renders dynamically at runtime from ShieldJSON definitions.
Imperial scale bar on all maps, cooperative gestures to prevent accidental zoom, hover highlighting on map pins with GPU-accelerated feature state.
Removed 3,673 lines of dead map code — 9 orphaned hooks, 5 unused components, 3 npm packages. Map system reduced from 12 hooks to 6, all rendering in production.
The Exchange ammo section now shows real product data from 26 online ammo retailers. Every listing links to an actual product page with real prices. Sortable table view with inline caliber and brand filters, plus card view with DirectoryCard design language.
The Marketplace now shows all 160K products organized into 13 categories: Ammunition, Firearms, Optics, Parts, Magazines, Holsters, Reloading, Cleaning, Gear, Knives, Airguns, Archery, and NFA/Suppressors. Each category has a clickable card with product count and a preview row with View All links.
11 automated scrapers collecting reloading component reference data — 895 powders with burn rates, 220 SAAMI cartridge specs, 106 bullets with BCs from 7 manufacturers, 39 primers, and Hodgdon RLDC load data integration. Foundation for The Bench reloading calculator.
The Exchange is now The Marketplace — reflecting the expansion from C2C classifieds to a full product aggregator with 200K+ products from 87+ retailers. All old /exchange URLs permanently redirect to /marketplace.
New import_stockpile.py parses raw Shopify product JSON from 585 retailer files, detects caliber/grain/bullet type/casing from titles, and upserts into stockpile_products table with ON CONFLICT dedup.
Parser now handles both Shopify and WooCommerce product formats. Title-based ammo detection catches retailers with empty product_type fields. Up from 6,429 products / 26 retailers.
Each product category now has its own visual treatment: Ammunition shows a hero deal card with CPR ranking, Firearms uses a staggered featured grid, Optics has horizontal scroll with price comparison, Parts uses a dense 4-column grid, and Reloading includes a cross-sell for The Bench calculator. All with real product data from 87 retailers.
Three card variants for the product aggregator: Hero cards with white image zones and full metadata for featured products, Grid cards as the 4-across workhorse with image fallbacks and type badges, and compact Row cards for ranked lists. Every card shows retailer name, stock status, keyword-detected type badges (firearm type, optic type, platform compatibility), hover lift animations, and click tracking.
Same product from multiple retailers collapses into one row showing price range, retailer count, and savings spread. Price context badges (Great Deal / Good Price / Average / Above Avg) computed from per-caliber median CPR. Click any row to see all prices side by side on the Depot comparison page.
/marketplace/ammunition (and all 13 categories) now has a full-page comparison experience with caliber filter chips, search, sort by CPR/price/retailers/savings, pagination, and grouped product rows with price context badges.
Replaced Mapbox with a fully self-hosted map stack: MapLibre GL JS + Protomaps PMTiles + ESRI satellite imagery. 17GB of USA map tiles served from maps.boisegunclub.com via Nginx + Cloudflare. Five branded time-of-day themes (dawn, day, noon, evening, night) with brand colors infused. Satellite view with state boundary overlays as default. Static map card images rendered server-side via mbgl-renderer. Zero external API dependencies, zero monthly cost.
Swapped Nominatim (7GB RAM) for Photon geocoder (500MB RAM). Same OpenStreetMap data, fraction of the resources. All 16 geocoding touchpoints updated — frontend autocomplete, Python batch scripts, maintenance tools. Runs at localhost:2322 with full US address coverage.
Deployed Valhalla routing engine with the entire US road network (800MB RAM, 87M graph nodes). Provides turn-by-turn directions, isochrone drive-time polygons, distance matrices, and optimized multi-stop routes. Replaced OSRM (which needed 30GB+ RAM) and the public OSRM demo API.
Every "Get Directions" button across the site now opens an in-app directions modal instead of sending users to Google Maps. Features: animated route line on satellite map, custom tactical markers (green crosshair origin, orange target destination), estimated arrival time, weather at destination, nearby gun shops along the route, drive/bike/walk mode toggle, share route link, print directions. Works without login — browser geolocation with manual address fallback. 35+ components updated site-wide.
Identified @sentry/nextjs as the #1 performance bottleneck (594KB, 30s main thread time). Enabled bundleSizeOptimizations to tree-shake performance monitoring code (GlitchTip only needs error capture). Split react-icons optimizePackageImports into per-library entries for proper tree-shaking. Added @turf/turf to optimization list. Expected vendor bundle reduction from 1.4MB to ~300KB.
Refreshed all 7 working event scrapers (3 weeks stale) and activated 14 dormant scrapers that had never been run. Wired 4 unregistered scrapers (SSUSA, NFAA, SCTP, ISRPA) into the import pipeline. Range calendars alone netted 12,842 new events from 15,248 range websites. Other top contributors: Ducks Unlimited (+246), Register-Ed (+232), CMP Matches (+222), GunShowTrader (+172). Three broken sources identified for repair.
Archived dead code, fixed stale refs, optimized images. Rewrote CLAUDE.md with mandatory audit-first workflow, documented known failure modes (Resend incident, urllib incident, pg_stat incident), and mapped all existing infrastructure.
Resolved all pre-existing TypeScript errors blocking production builds. Fixed stale @ts-expect-error directives, added nav-campfire to accentColor union types, removed dead initializedRef reference in map setup hook.
Campfire forum page was statically cached at build time and never revalidating. Added ISR revalidation so new posts appear without a full rebuild.
Discovered 35 real user inquiries silently dropped over 2+ weeks because a previous session built a Resend API integration instead of using the existing Stalwart SMTP sendEmail() function. Ripped out Resend, wired all event contact routes to existing email infrastructure.
New static map API generates server-side Mapbox images with GeoJSON pin markers for contact cards and SEO. Five branded map styles (standard, satellite, terrain, dark, light) with React Strict Mode stability fixes for all map components.
New dropdown on the My Listings dashboard tab for quick switching between claimed businesses. Campfire tab now shows the user's full comment history across all forum threads with timestamps and context.
Promoted community-submitted photos from a hidden tab to inline display on all business, event, and location detail pages. Photos now appear in the main content flow where users actually see them.
Locked down direct PostgreSQL access (was exposed on port 5433), added API scraping protections with rate limiting and bot detection, tuned CrowdSec rules, and hardened robots.txt to block AI crawlers from scraping business data.
Excluded law articles from handbook hero carousel rotation. Fixed events page sections landing — Zustand default viewMode was set to waterfall instead of grid. Removed views badges from all public-facing pages.
Discovered 60% of CTA click events were silently dropped before reaching Umami. Fixed the event pipeline to properly batch and flush analytics events.
Audited all 18,000+ production GlitchTip errors. Root-caused hydration mismatches (14K errors) to SSR/client timing on relative timestamps — added suppressHydrationWarning to 35+ render sites. Filtered Sentry streaming errors (272), wrapped sendBeacon for bot/crawler compat, and enhanced Web Vitals CLS attribution with element selectors.
Fixed auth cookies using sameSite: strict which prevented browsers from sending session cookies when clicking links from emails (claim approvals, verification, welcome emails). Users were silently logged out and redirected to the homepage. Changed to sameSite: lax across all auth endpoints — still blocks CSRF on cross-site POST, but allows top-level GET navigations from emails, Google, and bookmarks.
Fixed auth cookies using sameSite: strict which prevented browsers from sending session cookies when clicking links from emails (claim approvals, verification, welcome emails). Users were silently logged out and redirected to the homepage. Changed to sameSite: lax across all auth endpoints — still blocks CSRF on cross-site POST, but allows top-level GET navigations from emails, Google, and bookmarks.
Fixed a bug where approving multiple moderation queue items quickly caused earlier approvals to silently fail. The undo timer system used a single ref — approving item B cancelled item A's pending API call. Now each approval tracks independently via a Map, so any number of rapid approvals execute correctly.
Fixed a bug where approving multiple moderation queue items quickly caused earlier approvals to silently fail. The undo timer system used a single ref — approving item B cancelled item A's pending API call. Now each approval tracks independently via a Map, so any number of rapid approvals execute correctly.
Business, event, and location claims now appear directly in the moderation queue alongside submissions, photos, reviews, and comments. Dedicated claims review page retired. Claim detail panel shows verification status, uploaded documents, and relationship to entity. Approve/deny triggers email notifications, audit trail, and sets claimed_by on the content record.
Business, event, and location claims now appear directly in the moderation queue alongside submissions, photos, reviews, and comments. Dedicated claims review page retired. Claim detail panel shows verification status, uploaded documents, and relationship to entity. Approve/deny triggers email notifications, audit trail, and sets claimed_by on the content record.
New BGC Staff author page with mesh gradient hero, searchable articles grid, and rewritten voice copy. Dashboard owner tools section added. Business scores page shows coming-soon state. Tab renamed from My Business to My Listings.
New BGC Staff author page with mesh gradient hero, searchable articles grid, and rewritten voice copy. Dashboard owner tools section added. Business scores page shows coming-soon state. Tab renamed from My Business to My Listings.
Events sidebar stat counts and filter badges now use server-reported totals instead of counting the current page slice, fixing inaccurate numbers on paginated results.
Events sidebar stat counts and filter badges now use server-reported totals instead of counting the current page slice, fixing inaccurate numbers on paginated results.
Fixed nested anchor tag violations across article cards, event cards, and directory cards. Interactive elements inside links now use button/span wrappers to prevent hydration errors and improve screen reader navigation.
Fixed nested anchor tag violations across article cards, event cards, and directory cards. Interactive elements inside links now use button/span wrappers to prevent hydration errors and improve screen reader navigation.
Replaced browser alert/confirm dialogs with toast notifications across appeals, auto-mod rules, and scheduled actions pages. Raw fetch calls upgraded to safeFetch for consistent error handling. Filter dropdowns replaced with styled button-based filters matching the queue toolbar pattern. Delete confirmation uses inline buttons instead of browser confirm dialog.
Replaced browser alert/confirm dialogs with toast notifications across appeals, auto-mod rules, and scheduled actions pages. Raw fetch calls upgraded to safeFetch for consistent error handling. Filter dropdowns replaced with styled button-based filters matching the queue toolbar pattern. Delete confirmation uses inline buttons instead of browser confirm dialog.
Moderation queue now shows approved, rejected, and revision-needed items via status tabs. Filter counts pull from server-side totals. Game-industry icon set (react-icons/gi) replaces Heroicons across queue, detail panel, and toolbar for a distinctive look.
Moderation queue now shows approved, rejected, and revision-needed items via status tabs. Filter counts pull from server-side totals. Game-industry icon set (react-icons/gi) replaces Heroicons across queue, detail panel, and toolbar for a distinctive look.
Fixed article categories, replaced broken/missing featured images, corrected geolocation coordinates for state-specific articles, and set news as the default handbook landing category.
Fixed article categories, replaced broken/missing featured images, corrected geolocation coordinates for state-specific articles, and set news as the default handbook landing category.
Users can now edit pending submissions and appeal rejected ones from their dashboard. New edit modal pre-fills submission data, appeal modal captures reason text. Status filters and type filters added to submissions tab. Published entity links now use federation-aware state routes.
Users can now edit pending submissions and appeal rejected ones from their dashboard. New edit modal pre-fills submission data, appeal modal captures reason text. Status filters and type filters added to submissions tab. Published entity links now use federation-aware state routes.
Owner moderation queue rebuilt with Zustand state management, extracted components, and keyboard shortcuts. New detail panel with submission preview, submitter context sidebar, photo lightbox, and action modal with reason templates. Bulk actions support approve/reject/needs-revision on multiple items.
Owner moderation queue rebuilt with Zustand state management, extracted components, and keyboard shortcuts. New detail panel with submission preview, submitter context sidebar, photo lightbox, and action modal with reason templates. Bulk actions support approve/reject/needs-revision on multiple items.
Corrected 111 events misassigned to Idaho that belonged to Montana, Oregon, and North Carolina. Great Falls, Helena, Missoula, Kalispell events reassigned to MT. 10 duplicate events archived.
Corrected 111 events misassigned to Idaho that belonged to Montana, Oregon, and North Carolina. Great Falls, Helena, Missoula, Kalispell events reassigned to MT. 10 duplicate events archived.
Events page sidebar map and full-screen map view now display all upcoming events for the state, not just the current page of 24. New lightweight /api/events/map-markers endpoint fetches coordinates on demand — zero impact on initial page load payload.
Events page sidebar map and full-screen map view now display all upcoming events for the state, not just the current page of 24. New lightweight /api/events/map-markers endpoint fetches coordinates on demand — zero impact on initial page load payload.
New server-side static map API route for generating Mapbox map images. Business, event, and location contact cards updated with consistent layout, improved phone/email formatting, and static map integration.
Replaced 8 discipline carousel hero images with editorially curated Wikipedia lead photos. Eliminated military/DoD image dominance across action pistol, shotgun, precision rifle, 3-gun, cowboy action, gun shows, training, and rimfire categories.
Sold exchange listings now display on the marketplace with a visual SOLD banner overlay instead of being hidden entirely. Buyers can browse completed sales for price research.
New image carousel component on business detail pages. Displays multiple business photos with swipe navigation, fullscreen lightbox, and lazy loading. Supports Wikimedia Commons attribution.
Progressive Web App installable with proper manifest, Apple touch icon, 192px and 512px icons, and SVG favicon. Updated manifest.json with theme colors and display standalone mode.
Holy Script #17: extracts contact information (email, phone, website, registration URL) from event descriptions using regex patterns and backfills structured contact fields. Two modes: --extract for analysis and --backfill for applying changes.
Expanded profile hover cards across Campfire, reviews, and social feeds. Shows avatar, join date, post count, badges, and quick-follow action. Consistent hover behavior across all user mentions.
Public members page at /community/members with search, sorting, and profile previews. New API route with pagination and role-based filtering.
Four transactional email templates for the exchange marketplace: inquiry received, listing expiring, listing published, and listing sold. Matches BGC brand design language with dark headers and warm accent colors.
Replaced all hardcoded stat numbers with real-time database queries. Single source of truth via getPlatformStats() service. Footer, homepage, AI chatbot, map page, and exchange SEO pages all render live counts. Homepage metadata rounds to nearest 5K for SEO.
Consolidated 4 competing article image scripts into Holy Script #15 (article_images.py). Unified modes: --featured, --sections, --brands, --reformat, --promote, --report. Safety gate prevents overwriting existing featured images without explicit --force.
New cron route automatically creates Campfire discussion threads for handbook articles. Campfire feed default sort changed to newest-first.
Complete Campfire forum overhaul: flat card design with read-more collapse, threaded comment nesting, persistent left navigation, top bar with category switching, and handbook article carousel. Replaced category grid, topic filters, and legacy layout components.
Theme-reactive mountain gradient transition between page content and footer. Mountain silhouette adapts to light/dark mode with smooth OKLCH color blending. Events discipline carousel also received major layout improvements.
You are here. Public timeline of every major update, derived from 1,776 git commits across 6 months of solo development.
Replaced the legacy PostgreSQL message system with Matrix (Synapse) for real-time encrypted DMs between buyers and sellers. Admin provisioning, room creation, typing indicators.
Full-screen drawer with sliding panels and portal escape. Replaced the old hamburger menu with a production-grade mobile nav system.
Overhauled the homepage with dark-mode-first design. New hero, handbook feature cards, footer mountain dissolve, and theme-reactive backgrounds.
Free C2C firearms classifieds. No listing fees, no transaction fees. Teal-tabbed UI with sort dropdowns, trust bar, and growth callouts. Full legal framework with ToS v4.0 and Exchange Rules policy.
Behavioral threat detection with 59 active scenarios parsing Traefik access logs. IP reputation scoring, nftables enforcement, and Cloudflare bouncer integration.
Server-component loading skeletons, font-display:optional, and layout shift elimination across all pillar pages.
Segmented sitemaps, cache headers, slug enrichment, cross-pillar internal linking, structured JSON-LD, and state-aware breadcrumbs. Indexed pages jumped from 20K to 26,771.
Sig Sauer, Ruger, Smith & Wesson, Remington, and 78 more. Each with dealer maps, event feeds, and SEO-optimized content.
Credit card payments active under MCC 7311. Business subscriptions can now be purchased. Billing dashboard and subscription management.
Five-pillar scoring system: Data Completeness, Web Presence, Community Engagement, Verification Status, and Content Quality. Every business gets a letter grade A through F.
Built 8 autonomous skills for database queries, pipeline runs, sync guards, enrichment, validation, scraper creation, schema migration, and component generation.
Automatic state correction from ZIP codes via database triggers, Python validators, and TypeScript route guards. Fixed 1,819 misattributed records across all insert paths.
Deterministic cleanup, word segmentation for smushed domains, and AI-assisted fixes. 2,358 business names fixed, 37 unlisted, 3,378 chain stores marked.
Competitions, classes, shows, and meetups pulled from 96 Python scrapers across national organizations. Backfilled 7,914 event locations via Nominatim reverse geocoding.
Built 13 manufacturer scrapers pulling 2,579 product images from Savage Arms, S&W, Ruger, Glock, and others. ZIP press kits, CDN tricks, and WordPress lazy-load unwrapping.
Replaced stock photo fallbacks with curated Wikimedia Commons images uploaded to S3. 139 unique images across 152 articles. Killed the Pexels/Pixabay pool system.
Structured logger conversion, Sentry cleanup, nixpacks heap tuning, and 15 archived unused UI components. 236 commits this month.
Consolidated scattered pipeline scripts into 16 canonical entry points under scripts/core/. Clear names, documented usage, archived duplicates.
Built 16 aggregator scrapers: WhereToShoot, SHOT Show, IDPA, CMP, NRA State Associations, GunShowTrader, and more. 16,207 records imported.
Interactive Mapbox-powered range finder covering every state. Filter by type, amenities, and distance. Cross-state redirects for SEO.
Expanded from Idaho-only to all 50 states plus DC. Every state gets its own directory, events calendar, and range finder with localized content and cultural voice. Version 2.0.0.
Comprehensive business classification system covering retail, FFLs, ranges, training, hunting services, archery, tactical, organizations, professional services, online communities, airsoft, and specialty niches.
Rich visual hierarchy in article markdown, discipline landing pages, TLDR callouts, and ticker improvements.
Deduplicated shooting locations, renamed foreign keys, synced schema between businesses and locations. Smart geocoding scripts for batch coordinate resolution.
Built a 5-step pipeline using the Anthropic Batch API: discover, validate, scrape, validate again, enrich. 50% cost savings over synchronous calls. The backbone of data quality.
AI-generated business descriptions, meta titles, and structured markdown with callouts. Listing quality scoring for directory prioritization.
Major ESLint cleanup session, production-ready build config, and GlitchTip error tracking integration. 606 commits this month.
Boise Gun Club goes live on November 24, 2025. Idaho-focused directory, events calendar, range finder, and handbook. The starting line, not the finish.
Production CAPTCHA on all forms with dev bypass mode. Blocks bot submissions without third-party dependency.
Business owners can claim their listing, manage details, upload photos, and track analytics. Full owner moderation panel.
Consolidated all map components into a single architecture with core, variants, and controls. Geolocation, distance rings, traffic layers, and cluster rendering.
Mobile-first end-to-end tests across 6 device profiles. Full user journey coverage for registration, directory, events, and ranges.
Daily login rewards, brass earned notifications, and the foundation for community engagement scoring.
Encyclopedic firearms reference with infoboxes, sticky table of contents, TLDR callouts, and structured markdown rendering. BBC-style news grid on the dashboard.
Migrated from NextAuth to a custom JWT authentication system. Proper token handling, secure cookie management, and Zustand auth store.
Massive typography standardization, Tailwind semantic utility migration, and color consolidation. Eliminated 122 unused files, reducing codebase by 31%. 537 commits in one month.
Consolidated 74 bloated components into a unified design system. CVA button variants, atomic component hierarchy, enterprise animation hooks. 83 commits in 3 weeks.
Integrated Drizzle ORM with type-safe schema, TanStack Query for client caching, Zustand stores for filters, and Zod validation. Built the first data pipeline for event ingestion.
Fresh codebase initialized. Next.js 15, React 19, Tailwind v4, Drizzle ORM, Zustand, Framer Motion. The foundation for everything that follows.
Boise Gun Club has been in active development since July 31, 2025.
This log is generated from 9,706+ git commits across 7 months of development.