Gece gündüz seyahatlerinizi, mekanlarınızı ve notlarınızı akıllıca yönetin. Yapay zeka destekli, konum tabanlı kişisel rehberinizin geliştirici dokümantasyonu.
Pinwise backend'i, sektör standartlarında kurumsal kalitede bir altyapı sunmak üzere en modern .NET yaklaşımlarıyla donatılmıştır.
Uygulama Domain, Application, Infrastructure ve API olmak üzere soyutlanmış 4 temel katmana ayrılmıştır. Bu sayede merkezdeki iş kuralları (Application/Domain), dış dünyadan (Veritabanı, Web API vb.) tamamen izoledir.
Mekan koordinatları (Enlem/Boylam) veritabanında "Point" veri tipinde saklanır. Bu sayede metinsel karşılaştırmalar yerine matematiksel-coğrafi işlemler veritabanı motoru seviyesinde halledilir.
Kullanıcı yönetimi ve şifreleme Firebase'e delege edilmiştir. API sadece Bearer JWT token'ları dinler.
Controller'ların şişmesini engellemek ve kod okunaklığını maksimal seviyeye çıkarmak için modern araçlar kullanılmıştır.
Uygulamanın farklı bileşenleri ve veritabanı Docker Compose ağı ile sarmalanmıştır. "Benim makinemde çalışıyordu" problemi tamamen ortadan kalkar.
docker-compose up komutunu çalıştırmak
yeterlidir.Uzun sürebilen yapay zeka işlem süreçleri (mekanların AI ile analiz edilmesi, tag oluşturulması vb.) asenkron olarak Hangfire Dashboard yönetimindeki güvenilir kuyruklara (Queue) atılır.
Geliştiricilerin Pinwise API'sini kullanarak oluşturabileceği örnek kullanıcı senaryoları.
GET /api/v1/Places/nearby isteğini enlem/boylam vererek atar.POST /api/v1/Collections idarecisi ile "Roma Gezisi" klasörü yaratır.
Genişletilmiş dokümantasyon. Tüm başlıklara tıklayarak açabilirsiniz. Her istekte
Header: Authorization: Bearer {FirebaseToken} zorunludur.
| Parametre | Tip | Açıklama |
|---|---|---|
| pageNumber | int | Sayfa numarası (Varsayılan: 1) |
| pageSize | int | Sayfa başına kayıt sayısı (Varsayılan: 20) |
{
"success": true,
"data": {
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Blue Bottle Coffee",
"latitude": 41.0289,
"longitude": 28.9743,
"category": "Cafe",
"status": "Saved", // Enum: Saved, Visited, Archived
"processingStatus": "Completed" // Enum: Pending, Completed, Failed
}
],
"pageNumber": 1,
"pageSize": 20,
"totalCount": 124,
"totalPages": 7,
"hasNextPage": true,
"hasPreviousPage": false
},
"errors": null
}
| Parametre | Tip | Açıklama |
|---|---|---|
| latitude * | double | Geçerli Kullanıcı Enlemi |
| longitude * | double | Geçerli Kullanıcı Boylamı |
| radiusInMeters | int | Yarıçap (Metre). Varsayılan: 5000 |
| pageNumber | int | Sayfa No |
| pageSize | int | Adet |
{
"success": true,
"data": {
"items": [
{
"id": "e023...",
"name": "Galata Kulesi",
"distance": 850.5 // PostGIS tarafından metre cinsi dönen özel hesaplanmış alan
}
],
"pageNumber": 1,
"pageSize": 20,
"totalCount": 3
}
}
| Parametre | Tip | Açıklama |
|---|---|---|
| searchTerm | string | Mekan adı veya açıklamasında `%like%` araması yapar. |
| category | string | Kategori tam eşleşme arar. |
| city | string | Şehir eşleşmesi arar. |
| status | string | Durum filtresi (Örn: `Visited` gönderilirse sadece ziyaret edilenler gelir). |
(Aynı Pagination yapısı döner)
| id * | guid | UUID formatında mekan kimliği |
{
"success": true,
"data": {
"id": "3fa85f64...",
"name": "Minoa Village",
"city": "Istanbul",
"costLevel": 3,
"aiRawJson": "{...yZekaAnalizSonucu...}",
"tags": [ "Sakin", "Çalışmaya Uygun" ],
"notes": [],
"expenses": []
}
}
{
"name": "Petra Roasting", // Zorunlu (Min 2 karakter)
"latitude": 41.0503, // Zorunlu (-90 ile +90 arası)
"longitude": 29.0065, // Zorunlu (-180 ile +180 arası)
"description": "Kahvesi meşhur, bilgisayarla gidilir.", // Opsiyonel
"category": "Coffee", // Opsiyonel
"sourceUrl": "https://maps.google.com/..." // Opsiyonel (AI işlenmesi için verilebilir)
}
{
"success": true,
"data": {
"id": "...",
"processingStatus": "PendingAiAnalysis" // Arka plan işi tetiklendi
}
}
{id}: İşlem
yapılacak mekanın UUID'si
{
"visitedAt": "2024-03-24T18:30:00Z" // UTC Formatında ISO-8601 Tarihi (Zorunlu)
}
Mekanın güncellenmiş DTO hali döner (Status = "Visited" olarak gelir).
{
"success": true,
"data": [
{
"id": "d9f10a...",
"name": "Moda Gece Kulüpleri",
"description": "Sadece rock çalanlar",
"itemCount": 3 // Koleksiyonun içindeki yerlerin sayısı
}
]
}
{id}:
Koleksiyon UUID
{
"success": true,
"data": {
"id": "d9f10a...",
"name": "...",
"places": [
{ "id": "...", "name": "..." } // Bağlı mekanların listesi
]
}
}
{
"name": "İş Yemekleri", // Zorunlu (Max 100 karakter)
"description": "Müşterilerle gidilecek lüks restoranlar" // Opsiyonel
}
201 Created
{id}:
Modifiye edilecek klasörün UUID'si
{
"name": "Değiştirilen İsim",
"description": "Yeni açıklama eklendi"
}
204 No Content
204 No Content
| id * | guid | Koleksiyon Kimliği (Örn: "Avrupa Turu" klasör id'si) |
| placeId * | guid | Mekan Kimliği (Örn: "Galata Kulesi" mekan id'si) |
RequestBody gönderilmez. Doğrudan URL üzerinden işlem yapılır.
204 No Content
| id * | guid | Koleksiyon Kimliği |
| placeId * | guid | Ayrılacak Mekan Kimliği |
(Aynı şekilde sadece bağ tablosundaki satır silinir. Mekan var olmaya devam eder.)
204 No Content
API, öngörülebilir tüm hataları standart bir Exception Handling yapısıyla döner. Hata
olması durumunda "success": false ve "errors": [...] objesi dönülür.