Skip to content

Repository files navigation

VibeCodingEx

Nuxt TypeScript Tailwind CSS SQLite License: MIT

Sahada, kapı kapı gezerek yazılım satan bir kişi için yapılmış, tamamen kendi bilgisayarında çalışan bir keşif aracı. Haritadan bir bölge seçiyorsun; VibeCodingEx çevredeki işletmeleri buluyor, her biri için elle tutulur bir yazılım fikri üretiyor ve içeri girdiğinde ağzından çıkacak satış cümlesini önceden yazıyor.

🇹🇷 Türkçe  ·  🇬🇧 English


🇹🇷 Türkçe

Fikir basit: bir esnafın kapısından "web sitenizi konuşalım mı?" diye boş bir cümleyle değil, elinde ona özel, somut bir teklifle girmek. VibeCodingEx bu teklifi senin yerine hazırlıyor — hepsi Türkçe, hepsi yerelde, tek bir kişinin tek bir kasabayı yürüyerek dolaşması ölçeğinde.

Neler yapıyor

  • 📍 Haritadan ya da adresten keşif — bir pin bırak veya adres yaz, yarıçapı seç, o kadar. Aynı yeri tekrar tararsan eldeki veri bozulmuyor.
  • 🚫 Çöp sonuçları eler — durak, ATM, benzinlik, cami, park gibi işletme olmayan yerler otomatik dışarıda kalır.
  • 🧠 İşletmeye özel yazılım fikri — sabit bir cümle değil; her işletmeye 2-3 gerçekçi fikir, her birinin kendi fiyat aralığıyla.
  • Gerçek yorumlar, geldiği dilde — makine çevirisi yok.
  • 🗺️ Tek haritada her şey — bütün işletmeler durumuna göre renklenmiş halde.
  • 🔎 Durum ve kategoriyle filtre + arama, canlı sayaçlarla birlikte.
  • 💾 Baştan sona yerel — tek bir SQLite dosyası. Bulut yok, hesap yok, üçüncü taraf analitik yok.
  • 💰 Kullanım sayacı gömülü — para harcayan iki işlem için ücretsiz kotaya ne kadar yaklaştığını hep görürsün.
  • 🗑️ Tek tıkla sıfırla — bütün kayıtlı veriyi bir hamlede temizle.

Çalışma mantığı

Uygulama dört adımlı tek bir akış üzerine kurulu:

  1. Keşfet — haritadan bir konum ve yarıçap ver. VibeCodingEx Google Places'a sorar, dönen işletmeleri yerele kaydeder: isim, kategori, adres, telefon, site, puan ve birkaç gerçek yorum.
  2. Üret — bir işletmeyi açıp "üret" dersin. Gemini işletme hakkında bilinen her şeyi okuyup 2-3 ayrı yazılım/ürün fikri çıkarır (QR menü, randevu, sadakat sistemi, kendi güncelleyebileceği bir site — e-ticaret ve muhasebe yazılımı hariç), her fikir için bir fiyat tahminiyle.
  3. Pitch al — aynı üretim, işletmenin kısa profilini ve kapıda okuyabileceğin, kopyala-yapıştır hazır bir satış metnini de verir.
  4. Takip et — gezerken işletmeleri ziyaret edildi / kazanıldı / kaybedildi diye işaretle; listeyi filtrele, ara; hepsini durum rengiyle haritada gör.

Hiçbir yeri ölçeklenmek üzere tasarlanmadı — tam olarak "bir kişi, bir kasaba, yaya" senaryosu için yazıldı.

Kurulum

Gerekenler:

  • Node.js 18+ ve npm
  • Google Cloud hesabı (Maps Platform için)
  • Google AI Studio hesabı (Gemini için — ücretsiz, kredi kartı istemiyor)

Adımlar:

git clone <bu-repo>
cd vibecodingex
npm install
cp .env.example .env

.env içindeki üç anahtarı doldur (bkz. API anahtarları), sonra:

npm run dev

http://localhost:3000 — açılışta doğrudan işletme listesine düşer.

API anahtarları

Üç anahtar gerekiyor, üçü de Google'dan. İkisi sunucuda kalan gizli anahtar, biri bilerek tarayıcıya açık.

1. GOOGLE_MAPS_API_KEY — yalnız sunucu Places API (New) ile keşif, Geocoding API ile adres → koordinat çevirimi için.

  1. Google Cloud Console → proje oluştur/seç.
  2. APIs & Services → LibraryPlaces API (New) ve Geocoding API'yi aç.
  3. Credentials → Create Credentials → API key.
  4. Anahtarı yalnızca bu iki API'yle sınırla (API restrictions).
  5. .env içine GOOGLE_MAPS_API_KEY olarak yaz.

2. NUXT_PUBLIC_GOOGLE_MAPS_BROWSER_KEY — tarayıcıya açık Sadece haritayı çizmek için (pin bırakma + harita görünümü). Maps JavaScript API sunucudan çalışmadığı için bu anahtar bilinçli olarak yukarıdakinden ayrı. Riski düşürmek için mutlaka kısıtla:

  1. Aynı projede Maps JavaScript API'yi aç.
  2. İkinci bir API key oluştur.
  3. HTTP referrer ile kısıtla (yerelde localhost:3000/*, yayına alırsan kendi domain'in).
  4. .env içine NUXT_PUBLIC_GOOGLE_MAPS_BROWSER_KEY olarak yaz.

3. GEMINI_API_KEY

  1. Google AI Studio → giriş yap.
  2. Get API key → Create API key.
  3. .env içine GEMINI_API_KEY olarak yaz.

💰 Maliyet uyarısı — tıklamadan önce oku

  • Yalnızca iki işlem para harcar: Keşfet ve Profil + Pitch Üret. Gezinme, filtre, harita, geri kalan her şey sadece yerel veritabanını okur — hiçbir ücret çıkmaz.
  • Gemini'nin gerçek bir ücretsiz katmanı var — kredi kartsız, günde ~1.500 istek (gemini-flash-latest). Normal kullanım bu sınırın yanına yaklaşmaz.
  • Google Maps Platform varsayılan olarak ücretsiz değil. Google Mart 2025'te eski aylık 200$ krediyi kaldırdı; artık her API'nin ayrı aylık ücretsiz kotası var:
    • Geocoding API — ayda 10.000 ücretsiz çağrı
    • Places Nearby Search — ayda 5.000 ücretsiz çağrı (Pro katmanı; iletişim + puan verisi istendiği için)
    • Maps JavaScript API — ayda 10.000 ücretsiz yükleme
  • Her "Keşfet" tıklaması bir geocode + bir nearby-search harcar. Tek kişilik kullanım rahatça ücretsiz kalır ama uygulama içinde sabit bir harcama tavanı yok.
  • Tavanı kendin koy. Cloud Console → ilgili API → Quotas kısmından günlük bir limit belirle (ör. Nearby Search için günde 100-150). Ayrıca Billing → Budgets & alerts altından küçük bir uyarı kur; bir emniyet ipi gibi düşün.
  • Sayacı izle. Sol menüde günlük "🔍 X arama · ✨ Y üretim" görünür.

Mimari

app/
  components/
    AppIcon.vue            – uygulamadaki tüm ikonlar (emoji değil), tek `name` prop'u
    BusinessCard.vue       – listedeki tek işletme kartı
    BusinessDetail.vue     – tam detay: profil, pitch, fikirler, durum aksiyonları
    LocationPicker.vue     – Keşfet sayfasındaki haritadan pin seçici
    ConfirmDialog.vue      – uygulama geneli onay modalı (window.confirm yerine)
  composables/
    useClipboard.ts        – kısa "kopyalandı" durumuyla panoya kopyalama
    useConfirm.ts          – ConfirmDialog'un tekil state'i, her yerden çağrılır
    useGoogleMapsScript.ts – Maps JS script'ini tek sefer yükler, tüm haritalar paylaşır
  layouts/
    default.vue            – sol menü + sayfa çerçevesi
  pages/
    index.vue              – /businesses'e yönlendirir
    discover.vue           – keşif formu
    businesses/index.vue   – filtrelenebilir liste + istatistikler
    businesses/[id].vue    – detay sayfası sarmalayıcısı
    map.vue                – tüm işletmeler harita üzerinde
  utils/
    category.ts   – Google tipi → Türkçe etiket + ikon grubu
    status.ts     – kart/liste/haritada ortak durum etiketleri ve renkleri
    maps.ts       – işletme için Google Haritalar linki üretir
    mapStyle.ts   – koyu harita teması + varsayılan merkez/zoom

server/
  api/
    discover.post.ts                – geocode + Places arama, sonuçları kaydeder
    businesses.get.ts               – kayıtlı tüm işletmeler
    businesses.delete.ts            – tümünü sil
    businesses/[id].get.ts          – tek işletme
    businesses/[id].delete.ts       – tek işletmeyi sil
    businesses/[id]/status.patch.ts – durum güncelle
    process/[id].post.ts            – işletme için Gemini üretimi
    usage.get.ts                    – günün keşif/üretim sayıları
  utils/
    db.ts       – SQLite bağlantısı, şema ve tüm sorgular
    places.ts   – Google Places/Geocoding + tip filtreleme
    gemini.ts   – prompt kurma + structured-output ayrıştırma

shared/
  types/
    business.ts – Business, ProductIdea, ReviewSnippet — tek doğruluk kaynağı
    usage.ts    – DailyUsage tipi, sunucu ile istemci arası ortak

shared/ bir Nuxt 4 konvansiyonu: buradaki dosyalar #shared alias'ıyla hem app/ hem server/ tarafından import edilir, böylece istemci ve sunucu veri şekli konusunda hep aynı fikirde kalır.

Veri akışı

  • Keşif: discover.vuePOST /api/discovergeocodeAddress() (pin yoksa) → nearbySearch() (rankPreference: DISTANCE, tip filtreli) → upsertBusinesses() sonuçları Google'ın place_id'siyle eşleştirerek SQLite'a yazar; böylece aynı bölge yeniden taranınca bir işletmenin AI çıktısı ne silinir ne tekrarlanır.
  • Üretim: BusinessDetail.vuePOST /api/process/:idprocessBusinessWithGemini() bilinen her şeyden bir prompt kurar, responseSchema ile structured JSON ister → saveProcessResult() profili, pitch'i ve fikir dizisini yazar. Bozuk JSON ya da boş yanıt asla yarım sonuç yazmaz; işletme yeniden üretilebilir kalır.
  • Diğer her şey (liste, filtre, harita, durum, silme) doğrudan yerel SQLite okuma/yazma — dış API karışmaz.

Kendine göre uyarlama

Kendi bölgen/pazarın için değiştirmen muhtemel yerler:

  • Varsayılan harita merkeziapp/utils/mapStyle.tsDEFAULT_MAP_CENTER / DEFAULT_MAP_ZOOM. Hem Keşfet haritası hem Harita sayfası buradan besleniyor; kendi şehrinin koordinatını yaz.
  • Kategori listesiapp/utils/category.tsCATEGORY_META. Filtre dropdown'u ve ikonlar buradan gelir. Geçerli tip adları için Google Place Types (New).
  • Hariç tutulanlarserver/utils/places.tsDEFAULT_EXCLUDED_TYPES (Google'a "hiç gösterme" dediklerimiz) ve POST_FILTER_EXCLUDED_TYPES (sonradan elediklerimiz).
  • AI'ın tonu ve fiyat mantığıserver/utils/gemini.tsbuildPrompt(). Pitch'in açılış tonu, yasak fikir türleri (şu an e-ticaret/muhasebe) ve fiyat bantları (500 TL–10.000 TL arası 4 kademe) hep bu tek fonksiyonda.
  • Dil — tüm arayüz ve prompt'lar Türkçe hardcoded; ayrı i18n katmanı yok. Başka dile çevireceksen .vue metinlerini ve gemini.ts'teki prompt'u (çıktı dilini de) güncelle.
  • Renk teması — vurgu rengi (amber) Tailwind class'ları olarak (bg-amber-500 vb.) doğrudan yazılı; merkezi bir değişken yok. Değiştirmek için .vue içinde ara-değiştir.
  • Yarıçap seçenekleriapp/pages/discover.vue içindeki <select>'te sabit 1/3/5 km.

Sınırlamalar — güvenmeden önce oku

Bu, görünümünden bağımsız olarak kişisel, tek kullanıcılı, tamamen yerel bir araç; barındırılan bir SaaS değil:

  • Kimlik doğrulama ve çoklu kullanıcı yok. Çalışan uygulamaya erişen herkes tüm veriye erişir.
  • Veri tek dosyada (data/vibecodingex.db), uygulamayı çalıştırdığın makinede. Senkron yok, yedek yok, bulut kopyası yok — dosyayı kaybetmek her şeyi kaybetmek.
  • Arayüz ve AI çıktısı bilinçli olarak Türkçe — Türkiye'de saha satışı için yapıldı, uluslararasılaştırılmadı.
  • Aramada sabit 20 sonuç sınırı. Google'ın Nearby Search uç noktası 20'de kilitli ve sayfalama yok. Yoğun bölgelerde tek büyük arama yerine küçük yarıçaplarla gezerek tara.
  • Otomatik test yok. Her değişiklik build/typecheck + gerçek API'lere karşı manuel kontrolle doğrulandı. Ciddi genişleteceksen dokunduğun yere test eklemeyi düşün.

⚖️ KVKK ve veri kullanımı

Bu proje Google Places API üzerinden herkese açık işletme verisi çeker. Dönen veride şahıs esnafına ait bilgiler (ad, telefon, adres) bulunabilir ve bunlar 6698 sayılı KVKK kapsamında kişisel veri sayılabilir.

Bu aracı kullanarak veri işleyen kişi, KVKK uyumundan (hukuki dayanak, aydınlatma yükümlülüğü, açık rıza vb.) bizzat sorumludur. Proje sahibi, üçüncü kişilerin aracı nasıl kullandığından sorumlu tutulamaz.

Pazarlama/tanıtım amaçlı iletişim kurmadan önce ilgili mevzuatı (KVKK, 6563 sayılı E-Ticaret Kanunu) incelemeni öneririm.

Lisans

MIT — bkz. LICENSE.


🇬🇧 English

The interface and all AI output are intentionally in Turkish — this tool was built for door-to-door sales in Turkey and was never internationalized. This English section documents the project for developers; the running app stays Turkish.

A fully local discovery tool for one person selling software door to door. You pick an area on the map, VibeCodingEx finds the nearby businesses, works out a concrete software idea for each one, and pre-writes the sales line you'll actually say when you walk in.

The whole point: instead of knocking with an empty "can we talk about your website?", you show up with something specific already in hand. VibeCodingEx prepares that pitch for you — all in Turkish, all on your own machine, at the scale of one person walking one town.

What it does

  • 📍 Discover from the map or an address — drop a pin or type an address, choose a radius, done. Re-scanning the same area never corrupts existing data.
  • 🚫 Filters out the junk — bus stops, ATMs, gas stations, mosques, parks and other non-business results are dropped automatically.
  • 🧠 Business-specific software ideas — not a canned line; 2-3 realistic ideas per business, each with its own price range.
  • Real reviews in their original language — no machine translation.
  • 🗺️ Everything on one map — every business, color-coded by status.
  • 🔎 Filter + search by status and category, with live counters.
  • 💾 Local end to end — a single SQLite file. No cloud, no account, no third-party analytics.
  • 💰 Usage counter built in — always see how close the two paid actions are to the free quota.
  • 🗑️ One-click reset — wipe all stored data in one move.

How it works

The app is a single four-step flow:

  1. Discover — give the map a location and radius. VibeCodingEx asks Google Places and saves the returned businesses locally: name, category, address, phone, website, rating and a few real reviews.
  2. Generate — open a business and hit generate. Gemini reads everything known about it and produces 2-3 distinct software/product ideas (QR menu, appointments, loyalty, a site the owner can update — no e-commerce or accounting software), each with a price estimate.
  3. Get a pitch — the same run also produces a short profile and a copy-paste-ready sales script you can read at the door.
  4. Track — mark businesses as visited / won / lost as you go; filter and search the list; see everything on the map by status color.

Nothing here is built to scale — it's written for exactly the "one person, one town, on foot" case.

Setup

Requirements:

  • Node.js 18+ and npm
  • A Google Cloud account (for Maps Platform)
  • A Google AI Studio account (for Gemini — free, no credit card)

Steps:

git clone <this-repo>
cd vibecodingex
npm install
cp .env.example .env

Fill the three keys in .env (see API keys), then:

npm run dev

Open http://localhost:3000 — it lands straight on the business list.

API keys

Three keys, all from Google. Two are server-side secrets, one is intentionally exposed to the browser.

1. GOOGLE_MAPS_API_KEY — server only Used for Places API (New) discovery and Geocoding (address → coordinates).

  1. Google Cloud Console → create/select a project.
  2. APIs & Services → Library → enable Places API (New) and Geocoding API.
  3. Credentials → Create Credentials → API key.
  4. Restrict the key to just those two APIs (API restrictions).
  5. Put it in .env as GOOGLE_MAPS_API_KEY.

2. NUXT_PUBLIC_GOOGLE_MAPS_BROWSER_KEY — browser-exposed Only used to draw the interactive map (pin dropping + map view). Maps JavaScript API can't run server-side, so this key is deliberately separate from the one above. Restrict it to keep the risk low:

  1. In the same project, enable Maps JavaScript API.
  2. Create a second API key.
  3. Restrict by HTTP referrer (localhost:3000/* in dev, your domain in production).
  4. Put it in .env as NUXT_PUBLIC_GOOGLE_MAPS_BROWSER_KEY.

3. GEMINI_API_KEY

  1. Google AI Studio → sign in.
  2. Get API key → Create API key.
  3. Put it in .env as GEMINI_API_KEY.

💰 Cost warning — read before you click

  • Only two actions cost money: Discover and Generate Profile + Pitch. Browsing, filtering, viewing the map and everything else only reads the local database — never billed.
  • Gemini has a real free tier — no credit card, ~1,500 requests/day (gemini-flash-latest). Normal use won't come close.
  • Google Maps Platform is not free by default. Google removed the old $200/month credit in March 2025; each API now has its own monthly free quota:
    • Geocoding API — 10,000 free calls/month
    • Places Nearby Search — 5,000 free calls/month (Pro tier, since contact + rating data is requested)
    • Maps JavaScript API — 10,000 free loads/month
  • Every "Discover" click spends one geocode + one nearby-search. Single-person use stays comfortably free, but there's no hard spending cap enforced inside the app.
  • Set your own cap. In Cloud Console → the relevant API → Quotas, set a daily request limit (e.g. 100-150/day for Nearby Search). Also set a small alert under Billing → Budgets & alerts as a tripwire.
  • Watch the counter. The left sidebar shows the day's "🔍 X searches · ✨ Y generations".

Architecture

app/
  components/    – AppIcon, BusinessCard, BusinessDetail, LocationPicker, ConfirmDialog
  composables/   – useClipboard, useConfirm (ConfirmDialog singleton), useGoogleMapsScript
  layouts/       – default.vue (sidebar + page frame)
  pages/         – index (redirect), discover, businesses/index, businesses/[id], map
  utils/         – category, status, maps, mapStyle

server/
  api/           – discover.post, businesses(.get/.delete), businesses/[id](.get/.delete),
                   businesses/[id]/status.patch, process/[id].post, usage.get
  utils/         – db (SQLite + schema + queries), places (Google integration + type filtering),
                   gemini (prompt building + structured-output parsing)

shared/
  types/         – business.ts, usage.ts (single source of truth, shared client ↔ server)

shared/ is a Nuxt 4 convention: files there are imported via the #shared alias from both app/ and server/, so client and server always agree on the shape of the data.

Data flow

  • Discovery: discover.vuePOST /api/discovergeocodeAddress() (only if no pin) → nearbySearch() (rankPreference: DISTANCE, type-filtered) → upsertBusinesses() writes to SQLite keyed by Google's place_id, so re-scanning an area never wipes or duplicates a business's AI output.
  • Generation: BusinessDetail.vuePOST /api/process/:idprocessBusinessWithGemini() builds a prompt from everything known, requests structured JSON via responseSchemasaveProcessResult() stores the profile, pitch and ideas. A bad response (broken JSON, empty output) never writes a half result — the business stays regenerable.
  • Everything else (list, filter, map, status, delete) is direct read/write to the local SQLite file — no external API involved.

Customizing

Likely places to change for your own area/market:

  • Default map centerapp/utils/mapStyle.tsDEFAULT_MAP_CENTER / DEFAULT_MAP_ZOOM. Feeds both the Discover map and the Map page.
  • Category listapp/utils/category.tsCATEGORY_META. Drives the filter dropdown and icons. Valid type names: Google Place Types (New).
  • Excluded typesserver/utils/places.tsDEFAULT_EXCLUDED_TYPES and POST_FILTER_EXCLUDED_TYPES.
  • AI tone & pricing logicserver/utils/gemini.tsbuildPrompt(). Pitch tone, banned idea types (currently e-commerce/accounting) and price bands (four tiers, 500–10,000 TL) all live here.
  • Language — all UI text and prompts are hardcoded Turkish; there's no i18n layer.
  • Color theme — the accent (amber) is written directly as Tailwind classes; no central variable.
  • Radius options — the <select> in app/pages/discover.vue has fixed 1/3/5 km.

Limitations — read before you rely on it

This is a personal, single-user, fully local tool regardless of how it looks — not a hosted SaaS:

  • No auth, no multi-user. Anyone with access to the running app has access to all data.
  • Data lives in one file (data/vibecodingex.db) on the machine you run it on. No sync, no backup, no cloud copy — losing that file loses everything.
  • UI and AI output are intentionally Turkish — built for field sales in Turkey, not internationalized.
  • Fixed 20-result search limit. Google's Nearby Search endpoint is capped at 20 with no pagination. In dense areas, scan with smaller radii rather than expecting one big search to catch everything.
  • No automated tests. Every change was verified with build/typecheck + manual checks against the real APIs. If you extend it seriously, add tests where you touch.

⚖️ Data-use note (KVKK)

This project pulls publicly available business data via the Google Places API. The results can include information about individual proprietors (name, phone, address), which may count as personal data under Turkey's KVKK (Law No. 6698).

Anyone processing data with this tool is personally responsible for KVKK compliance (legal basis, disclosure obligation, explicit consent, etc.). The project owner is not responsible for how third parties use it. Review the relevant legislation (KVKK, E-Commerce Law No. 6563) before making any marketing contact.

License

MIT — see LICENSE.

About

AI destekli yerel işletme keşif ve saha satış aracı. Google Places ile çevredeki işletmeleri bul, Gemini ile her biri için özel yazılım fikri + satış pitch'i üret. Nuxt 4, SQLite, %100 yerel.

Topics

Resources

Stars

71 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages