{"data":{"featured":{"edges":[{"node":{"frontmatter":{"title":"Linea","cover":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAC4jAAAuIwF4pT92AAACO0lEQVQoz23Py04TURwG8ENnOnPu58ycTjstzNRCJAJK65T7O5gQRYiW3qQ+hyJRFywMEPUBoFDQBWBY+BS+iQsXxnDpMQOVhZB8i5Oc75d8f7BzXt05r7ZPl/d/Pev8qeydVXe6td1ubVfX2he1dreXq1qvfFHd1XEBHOnWoW6d6Bffu7WTn0tff1c6urGvG3u6dqAbB7rZ0fWOrh/q1tFljnXri262dezByue55qe5lY2Z+oep+TfF+Vfjj18Xn65FS28nlt5FT1aLi2vlxbWJxuZsY2u2+XGusj71/sej2F9UgWnafX02AAa06NCdewPZgu8FhXA4mwl9L8xm8pYNDdMCwADAMEwTAPB8ffKbfrl9ugxEmlHFIEPSc8ejYjQVjYyNlR6WS+XS/dKDaHqiUPIHRpWNESQICwyA0diaOdat7bMqQIJAim2Mkrbdl0gkbdg/7A2WfeYIKjiixEbITNoWhBaEkCIAEvWNfxiSWF792RglEtb0wtDCauRmlHSUBaFpWRaESTsuoP+whaCNEMT4OkkTGQkkfUElxYwKV2JGECWI4BsYQogxoew63BEi5QQjvvLdlO+Fg0Eun/ODrPJSiOLbMWU9TDnnlwd7AyoTpMPBMFfIKj8llXs75kK6ynNc1/Vcx1WOUun+1PBkPribk67DJBeOw4W4fTZlnHHJhWCCcxE/KOdBLiOlFFKFhdF4FGGI3MQIMyG4FJhQQhkmjFIGEc0HaaUkJtxxvauLLmcb9c0e/gvBe7xDl1rcugAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/758036376924a2cbf7a828988515596f/d2194/linea1.png","srcSet":"/static/758036376924a2cbf7a828988515596f/cebcc/linea1.png 175w,\n/static/758036376924a2cbf7a828988515596f/272cf/linea1.png 350w,\n/static/758036376924a2cbf7a828988515596f/d2194/linea1.png 700w,\n/static/758036376924a2cbf7a828988515596f/b50c4/linea1.png 1400w","sizes":"(min-width: 700px) 700px, 100vw"},"sources":[{"srcSet":"/static/758036376924a2cbf7a828988515596f/9aa63/linea1.avif 175w,\n/static/758036376924a2cbf7a828988515596f/e6db6/linea1.avif 350w,\n/static/758036376924a2cbf7a828988515596f/f47db/linea1.avif 700w,\n/static/758036376924a2cbf7a828988515596f/8fee6/linea1.avif 1400w","type":"image/avif","sizes":"(min-width: 700px) 700px, 100vw"},{"srcSet":"/static/758036376924a2cbf7a828988515596f/240e7/linea1.webp 175w,\n/static/758036376924a2cbf7a828988515596f/faefe/linea1.webp 350w,\n/static/758036376924a2cbf7a828988515596f/d5dc4/linea1.webp 700w,\n/static/758036376924a2cbf7a828988515596f/e2f1a/linea1.webp 1400w","type":"image/webp","sizes":"(min-width: 700px) 700px, 100vw"}]},"width":700,"height":438}}},"tech":["React","TypeScript","Next.js","Express","WebSocket (ws)","PostgreSQL","Prisma","Zod","Turborepo","Rough.js","Tailwind CSS","JWT / argon2id","Vercel","Railway"],"github":"https://github.com/SunnyBagal/Linea","external":"https://linea.sunnybagal.com","cta":null},"html":"<p>A real-time collaborative whiteboard (think Excalidraw) where multiple people sketch on an infinite canvas together. Every action — draw, move, edit, delete — is recorded as an operation in an append-only op-log, and that single mechanism powers live multiplayer sync, instant hydration when someone joins a room, undo via compensating operations, and a time-travel slider that replays the board's entire history. Hand-drawn shapes are rendered with Rough.js over the Canvas 2D API, with pan/zoom, selection, and a text tool on top. Built as a Turborepo monorepo with Next.js, TypeScript, an Express HTTP + WebSocket backend, PostgreSQL, and Prisma.</p>"}},{"node":{"frontmatter":{"title":"GeoGrid","cover":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAC4jAAAuIwF4pT92AAACQ0lEQVQoz1WQS0/bQBSFs43t2JNg5207fszDY3vGjvOgLSjlESBEqIuiVn1IgBqgZdH+gESARIrY0a6q7pH4m5UTIPTozO5+c+49Gb51MfN56v7CdH3S27/ZO/w1PLgdHty+Ofrd27+h65OHyZkzczgeTJvD62R4HQ+m0c60vXfdHFy9+/b3+/n92fjubHz34+J+//RPa3faGv6Mdq5mY1cpzPrnsHts8k919tFtHzmtw3B1tLz1NVk7YaujqJear35J1k5ebp8FK8do+RR3R3h5lOHbl+HGeG3w+e37k43BB9PGhmnphl3XLbPhmHUD6nq1qouqKuXyogSygqQAFYCCVqxm+NYl25z4ya4fb+LgNfYCjBHBmBAc8jDyUAxNglzX1lVtCeSBosiKLOckqVx5hHU6qKF+yYgRpghBNHs+CzlyuGNAx+4SB9uNnCzLuVTZbFZViw+wGezp3k7FegGxh2aCCIWcdT0aOg2PkiZxoetIaaQkimIKa6U5PNbxRllvVYwWIv48GSGEuZ9ELHItH9nUtS3o5hRZnElYwP1J1V2pNTrVRudpbYQQ8WkziTqUxI7FoIV8T8kDSRRlOf1C1R7XrsNezV2pO6+eJ6dwzNqel7iQQYvysFQuK4oCABAEYQEXzXbBYKrO/kvmAfe9gHphxAkLKKV6XQcAzFtbeiisP9H0Zl7DSxX6HPZ42GUB54HX5NAnlWoFADAvTBAE7enmopHkS0SthYgsYMz8TidhCfd8H7qwUCgIgrAorFj7B65pk4Q+OG++AAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/3cffc98d1397f2d9ecdceaedd52e7ddc/d2194/4.png","srcSet":"/static/3cffc98d1397f2d9ecdceaedd52e7ddc/cebcc/4.png 175w,\n/static/3cffc98d1397f2d9ecdceaedd52e7ddc/272cf/4.png 350w,\n/static/3cffc98d1397f2d9ecdceaedd52e7ddc/d2194/4.png 700w,\n/static/3cffc98d1397f2d9ecdceaedd52e7ddc/b50c4/4.png 1400w","sizes":"(min-width: 700px) 700px, 100vw"},"sources":[{"srcSet":"/static/3cffc98d1397f2d9ecdceaedd52e7ddc/9aa63/4.avif 175w,\n/static/3cffc98d1397f2d9ecdceaedd52e7ddc/e6db6/4.avif 350w,\n/static/3cffc98d1397f2d9ecdceaedd52e7ddc/f47db/4.avif 700w,\n/static/3cffc98d1397f2d9ecdceaedd52e7ddc/8fee6/4.avif 1400w","type":"image/avif","sizes":"(min-width: 700px) 700px, 100vw"},{"srcSet":"/static/3cffc98d1397f2d9ecdceaedd52e7ddc/240e7/4.webp 175w,\n/static/3cffc98d1397f2d9ecdceaedd52e7ddc/faefe/4.webp 350w,\n/static/3cffc98d1397f2d9ecdceaedd52e7ddc/d5dc4/4.webp 700w,\n/static/3cffc98d1397f2d9ecdceaedd52e7ddc/e2f1a/4.webp 1400w","type":"image/webp","sizes":"(min-width: 700px) 700px, 100vw"}]},"width":700,"height":438}}},"tech":["Next.js","React","TypeScript","Node.js","Express","PostgreSQL","Redis","BullMQ"],"github":null,"external":"https://github.com/SunnyBagal/GeoGrid","cta":"https://github.com/SunnyBagal/GeoGrid"},"html":"<p>A geospatial lead-generation platform that helps sales teams discover and qualify local businesses on a map. Users define an area, and the app pulls nearby businesses, enriches each one with location and contact data, and organizes the results into exportable lead lists. Heavy scraping and enrichment run asynchronously through a BullMQ queue backed by Redis, so the UI stays responsive while jobs process in the background. Built with Next.js, TypeScript, Node.js, PostgreSQL, Redis, and BullMQ during my internship at InteleCorp, where I led the technical build as Technical Head.</p>"}},{"node":{"frontmatter":{"title":"Recall","cover":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAC4jAAAuIwF4pT92AAADFUlEQVQoz2MQl3ZHRmLS7mJSbiKSrrKKPmqawVJynqqaQRIyHqKSrmJSbmiKGUCUjIeEjIekrJekrJeUvLeiqp+0grepRXxaRktoREVKWrO6doisoq+8sp+UnLeUnLe4jIeIhKu4tAcDyB4JJxFxRz5BKz4BKyFRO3lFF2lZRxl5Z2UVD0UlN2VVDzkFF2kZR2lZJy5ecw5uM2FxJzlFb2FxBwZpWUc/T18Xe6fk+MSUlLTkuISi3IKq8sqCrNzo8MiEhKSk2PjyoqKaiorC3IKSgqLGmtrinNzwoFBDHSMGWTlHHWUVB2vLnroqZ03NuPjYV8+efPnx48GDewsn96yb2L5j8+p3r14/f/Lo6eN7Hz59+v///8bFc2MjI0oKihikZR2kRUTNDPSnT5nU394+b97cO3fvvX777uq1axtXrdixZtX2zetPHD9x4fzZE8eO3Lp16+3796tXrbI1M7MwNgNplpeQtDA0vHHz9svXr69curhrz5a1W9Zt27755s1rx04cPXbk4LVrV16/fXvl8sUTRw7cv3NtzowpVsYmdpY2ID/LiolZm5g8ePL8y/ffjx49XrZqVnVr+apV8x/ev/f08YOrly88fPjo249ft66en9GQsGNp1/xJVXaW1vaWNgxSMg4SgkKWxkY3b9x49OjhpQvn37x5/f37t6vXrvoGhDm6eNfWNjx69Oj+g4eXL5w7f/LAiyd31q1c5GJn52zrwCAhZSspKCgvLm5uYGCopeXv4X708KELF8/v3bWzrKohr7B86rQZi5cszCktWLRgztlzF6/cuDFnxgw7c3MHazuQZikhYSkhITE+Pj52dhNNjUQjvTglhUJ3l6y01NS4mLqK8uvXb9598OjQwf1dqX6zswPioyLcHBwc4ZqlhYVkRUREeXhsjI2Wzpi2acXyrvoaPlZWTgYGWTHR2PCwqNCQ7PTUvVvnHV47p7KyytXOxtEGpNleVlxWSkRSWlRSQlBUTVE1NTk9Jzs/wC9ISlhCVkxaUlicn5OPi5ldXVGtsKCivLw2OizKSNfQRM8MAK7VPUdWoiJbAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/9a72389b4030e46b9e2188467d33c34c/d2194/recall_img3.png","srcSet":"/static/9a72389b4030e46b9e2188467d33c34c/cebcc/recall_img3.png 175w,\n/static/9a72389b4030e46b9e2188467d33c34c/272cf/recall_img3.png 350w,\n/static/9a72389b4030e46b9e2188467d33c34c/d2194/recall_img3.png 700w,\n/static/9a72389b4030e46b9e2188467d33c34c/b50c4/recall_img3.png 1400w","sizes":"(min-width: 700px) 700px, 100vw"},"sources":[{"srcSet":"/static/9a72389b4030e46b9e2188467d33c34c/9aa63/recall_img3.avif 175w,\n/static/9a72389b4030e46b9e2188467d33c34c/e6db6/recall_img3.avif 350w,\n/static/9a72389b4030e46b9e2188467d33c34c/f47db/recall_img3.avif 700w,\n/static/9a72389b4030e46b9e2188467d33c34c/8fee6/recall_img3.avif 1400w","type":"image/avif","sizes":"(min-width: 700px) 700px, 100vw"},{"srcSet":"/static/9a72389b4030e46b9e2188467d33c34c/240e7/recall_img3.webp 175w,\n/static/9a72389b4030e46b9e2188467d33c34c/faefe/recall_img3.webp 350w,\n/static/9a72389b4030e46b9e2188467d33c34c/d5dc4/recall_img3.webp 700w,\n/static/9a72389b4030e46b9e2188467d33c34c/e2f1a/recall_img3.webp 1400w","type":"image/webp","sizes":"(min-width: 700px) 700px, 100vw"}]},"width":700,"height":438}}},"tech":["React","TypeScript","Tailwind CSS","Zustand","TanStack Query","Express","PostgreSQL","Drizzle ORM","pgvector","BullMQ","Redis","Claude API","OpenAI API","Vercel","Railway"],"github":"https://github.com/SunnyBagal/Recall","external":"https://recall.sunnybagal.com","cta":null},"html":"<p>A full-stack link-saving app where any URL (YouTube, Twitter, GitHub, articles) becomes a rich embedded card with auto-generated summaries and tags. Search your saved links by meaning using pgvector semantic search, or ask an AI that's read everything you've saved. Built with React, TypeScript, Express, PostgreSQL, Drizzle ORM, BullMQ, Claude API, and deployed on Railway + Vercel.</p>"}}]}}}