nanobot özel sürüm v1

This commit is contained in:
hpibot
2026-03-01 20:26:44 +03:00
parent 34c5eb0a23
commit 3ea10e9c78
16 changed files with 248 additions and 659 deletions

View File

@@ -3075,7 +3075,6 @@
"version": "2.3.3", "version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"optional": true, "optional": true,
"os": [ "os": [

BIN
backend/prisma/dev.db Normal file

Binary file not shown.

View File

@@ -1,5 +1,5 @@
// HMarket Veritabanı Şeması // HMarket Veritabanı Şeması
// MariaDB için Prisma ORM konfigürasyonu // MySQL için Prisma ORM konfigürasyonu
generator client { generator client {
provider = "prisma-client-js" provider = "prisma-client-js"
@@ -153,7 +153,7 @@ model ListItem {
customName String? // Ürün yoksa manuel isim customName String? // Ürün yoksa manuel isim
quantity Float @default(1) quantity Float @default(1)
unit String @default("adet") // "kg", "lt", "adet", vb. unit String @default("adet") // "kg", "lt", "adet", vb.
price Decimal? @db.Decimal(10, 2) price Decimal? // SQLite: Decimal stored as String
note String? note String?
isPurchased Boolean @default(false) isPurchased Boolean @default(false)
purchasedAt DateTime? purchasedAt DateTime?
@@ -174,7 +174,7 @@ model ListItem {
model PriceHistory { model PriceHistory {
id String @id @default(cuid()) id String @id @default(cuid())
productId String productId String
price Decimal @db.Decimal(10, 2) price Decimal // SQLite: Decimal stored as String
store String? // Mağaza adı store String? // Mağaza adı
location String? // Konum bilgisi location String? // Konum bilgisi
source String @default("user") // "user", "api", "scraping" source String @default("user") // "user", "api", "scraping"
@@ -193,7 +193,7 @@ model Notification {
title String title String
message String message String
type String // "list_shared", "item_added", "item_purchased", "price_alert" type String // "list_shared", "item_added", "item_purchased", "price_alert"
data Json? // Ek veri (JSON format) data String? // Ek veri (JSON format - SQLite String olarak saklanır)
isRead Boolean @default(false) isRead Boolean @default(false)
createdAt DateTime @default(now()) createdAt DateTime @default(now())
@@ -209,7 +209,7 @@ model Activity {
listId String listId String
userId String userId String
action String // "item_added", "item_removed", "item_updated", "item_purchased" action String // "item_added", "item_removed", "item_updated", "item_purchased"
details Json? // Aktivite detayları details String? // Aktivite detayları (JSON - SQLite String olarak saklanır)
createdAt DateTime @default(now()) createdAt DateTime @default(now())
// İlişkiler // İlişkiler

View File

@@ -1,389 +1,139 @@
const { PrismaClient } = require('@prisma/client'); import { PrismaClient } from '@prisma/client'
const bcrypt = require('bcryptjs');
const prisma = new PrismaClient(); const prisma = new PrismaClient()
async function main() { async function main() {
console.log('🌱 Veritabanı seed işlemi başlatılıyor...'); console.log('Örnek veriler ekleniyor...')
// Admin kullanıcısı oluştur // Kullanıcılar
const hashedPassword = await bcrypt.hash('admin123', 12); const user1 = await prisma.user.create({
data: {
const adminUser = await prisma.user.upsert({ email: 'mustafa@example.com',
where: { email: 'admin@hmarket.com' }, username: 'mustafa',
update: {}, firstName: 'Mustafa',
create: { lastName: 'ÖZKAYA',
email: 'admin@hmarket.com', password: '$2a$10$dummy',
username: 'admin', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=mustafa',
firstName: 'Admin', }
lastName: 'User', })
password: hashedPassword,
isAdmin: true,
},
});
console.log('✅ Admin kullanıcısı oluşturuldu:', adminUser.email); const user2 = await prisma.user.create({
data: {
// Test kullanıcıları oluştur email: 'ahmet@example.com',
const testUsers = [
{
email: 'ahmet@test.com',
username: 'ahmet', username: 'ahmet',
firstName: 'Ahmet', firstName: 'Ahmet',
lastName: 'Yılmaz', lastName: 'Yılmaz',
password: await bcrypt.hash('test123', 12), password: '$2a$10$dummy',
}, avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=ahmet',
{ }
email: 'ayse@test.com', })
const user3 = await prisma.user.create({
data: {
email: 'ayse@example.com',
username: 'ayse', username: 'ayse',
firstName: 'Ayşe', firstName: 'Ayşe',
lastName: 'Kaya', lastName: 'Kaya',
password: await bcrypt.hash('test123', 12), password: '$2a$10$dummy',
}, avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=ayse',
{
email: 'mehmet@test.com',
username: 'mehmet',
firstName: 'Mehmet',
lastName: 'Demir',
password: await bcrypt.hash('test123', 12),
},
];
for (const userData of testUsers) {
const user = await prisma.user.upsert({
where: { email: userData.email },
update: {},
create: userData,
});
console.log('✅ Test kullanıcısı oluşturuldu:', user.email);
}
// Kategoriler oluştur
const categories = [
{ name: 'Meyve & Sebze', description: 'Taze meyve ve sebzeler', icon: '🥕', color: '#4CAF50' },
{ name: 'Et & Tavuk', description: 'Kırmızı et, beyaz et ve şarküteri ürünleri', icon: '🥩', color: '#F44336' },
{ name: 'Süt Ürünleri', description: 'Süt, peynir, yoğurt ve diğer süt ürünleri', icon: '🥛', color: '#2196F3' },
{ name: 'Fırın & Pastane', description: 'Ekmek, pasta ve unlu mamuller', icon: '🍞', color: '#FF9800' },
{ name: 'Atıştırmalık', description: 'Çikolata, bisküvi ve atıştırmalık ürünler', icon: '🍿', color: '#9C27B0' },
{ name: 'İçecek', description: 'Alkolsüz içecekler ve sıcak içecekler', icon: '🥤', color: '#00BCD4' },
{ name: 'Temizlik', description: 'Ev temizlik ürünleri ve deterjanlar', icon: '🧽', color: '#607D8B' },
{ name: 'Kişisel Bakım', description: 'Kişisel hijyen ve bakım ürünleri', icon: '🧴', color: '#E91E63' },
{ name: 'Bebek', description: 'Bebek bakım ürünleri ve mama', icon: '🍼', color: '#FFEB3B' },
{ name: 'Dondurulmuş', description: 'Dondurulmuş gıda ürünleri', icon: '🧊', color: '#3F51B5' },
];
for (const categoryData of categories) {
const category = await prisma.category.upsert({
where: { name: categoryData.name },
update: {},
create: categoryData,
});
console.log('✅ Kategori oluşturuldu:', category.name);
}
// Örnek ürünler oluştur
const products = [
// Meyve & Sebze
{ name: 'Elma', categoryName: 'Meyve & Sebze', barcode: '1234567890123', averagePrice: 12.50 },
{ name: 'Muz', categoryName: 'Meyve & Sebze', barcode: '1234567890124', averagePrice: 18.00 },
{ name: 'Domates', categoryName: 'Meyve & Sebze', barcode: '1234567890125', averagePrice: 8.75 },
{ name: 'Salatalık', categoryName: 'Meyve & Sebze', barcode: '1234567890126', averagePrice: 6.50 },
{ name: 'Soğan', categoryName: 'Meyve & Sebze', barcode: '1234567890127', averagePrice: 4.25 },
{ name: 'Patates', categoryName: 'Meyve & Sebze', barcode: '1234567890137', averagePrice: 5.75 },
{ name: 'Havuç', categoryName: 'Meyve & Sebze', barcode: '1234567890138', averagePrice: 7.50 },
{ name: 'Biber', categoryName: 'Meyve & Sebze', barcode: '1234567890139', averagePrice: 15.00 },
{ name: 'Portakal', categoryName: 'Meyve & Sebze', barcode: '1234567890140', averagePrice: 10.00 },
{ name: 'Limon', categoryName: 'Meyve & Sebze', barcode: '1234567890141', averagePrice: 8.00 },
// Süt Ürünleri
{ name: 'Süt 1L', categoryName: 'Süt Ürünleri', barcode: '1234567890128', averagePrice: 8.75 },
{ name: 'Yoğurt 500g', categoryName: 'Süt Ürünleri', barcode: '1234567890129', averagePrice: 12.50 },
{ name: 'Beyaz Peynir', categoryName: 'Süt Ürünleri', barcode: '1234567890130', averagePrice: 45.00 },
{ name: 'Kaşar Peyniri', categoryName: 'Süt Ürünleri', barcode: '1234567890131', averagePrice: 65.00 },
{ name: 'Tereyağı', categoryName: 'Süt Ürünleri', barcode: '1234567890142', averagePrice: 35.00 },
{ name: 'Yumurta 30\'lu', categoryName: 'Süt Ürünleri', barcode: '1234567890143', averagePrice: 85.00 },
{ name: 'Krema', categoryName: 'Süt Ürünleri', barcode: '1234567890144', averagePrice: 15.50 },
// Fırın & Pastane
{ name: 'Ekmek', categoryName: 'Fırın & Pastane', barcode: '1234567890132', averagePrice: 4.50 },
{ name: 'Simit', categoryName: 'Fırın & Pastane', barcode: '1234567890133', averagePrice: 2.50 },
{ name: 'Pide', categoryName: 'Fırın & Pastane', barcode: '1234567890145', averagePrice: 8.00 },
{ name: 'Çörek', categoryName: 'Fırın & Pastane', barcode: '1234567890146', averagePrice: 6.50 },
{ name: 'Kek', categoryName: 'Fırın & Pastane', barcode: '1234567890147', averagePrice: 25.00 },
// İçecek
{ name: 'Su 1.5L', categoryName: 'İçecek', barcode: '1234567890134', averagePrice: 2.50 },
{ name: 'Çay', categoryName: 'İçecek', barcode: '1234567890135', averagePrice: 35.00 },
{ name: 'Kahve', categoryName: 'İçecek', barcode: '1234567890136', averagePrice: 85.00 },
{ name: 'Meyve Suyu', categoryName: 'İçecek', barcode: '1234567890148', averagePrice: 12.50 },
{ name: 'Kola', categoryName: 'İçecek', barcode: '1234567890149', averagePrice: 8.75 },
{ name: 'Ayran', categoryName: 'İçecek', barcode: '1234567890150', averagePrice: 4.50 },
// Et & Tavuk
{ name: 'Tavuk But', categoryName: 'Et & Tavuk', barcode: '1234567890151', averagePrice: 45.00 },
{ name: 'Dana Kıyma', categoryName: 'Et & Tavuk', barcode: '1234567890152', averagePrice: 120.00 },
{ name: 'Köfte', categoryName: 'Et & Tavuk', barcode: '1234567890153', averagePrice: 85.00 },
{ name: 'Sosis', categoryName: 'Et & Tavuk', barcode: '1234567890154', averagePrice: 25.00 },
// Temizlik
{ name: 'Deterjan', categoryName: 'Temizlik', barcode: '1234567890155', averagePrice: 45.00 },
{ name: 'Sabun', categoryName: 'Temizlik', barcode: '1234567890156', averagePrice: 8.50 },
{ name: 'Şampuan', categoryName: 'Temizlik', barcode: '1234567890157', averagePrice: 35.00 },
{ name: 'Diş Macunu', categoryName: 'Kişisel Bakım', barcode: '1234567890158', averagePrice: 18.50 },
// Atıştırmalık
{ name: 'Çikolata', categoryName: 'Atıştırmalık', barcode: '1234567890159', averagePrice: 12.50 },
{ name: 'Bisküvi', categoryName: 'Atıştırmalık', barcode: '1234567890160', averagePrice: 8.75 },
{ name: 'Cips', categoryName: 'Atıştırmalık', barcode: '1234567890161', averagePrice: 6.50 },
];
for (const productData of products) {
const category = await prisma.category.findUnique({
where: { name: productData.categoryName }
});
if (category) {
const product = await prisma.product.upsert({
where: { barcode: productData.barcode },
update: {},
create: {
name: productData.name,
barcode: productData.barcode,
categoryId: category.id,
},
});
console.log('✅ Ürün oluşturuldu:', product.name);
} }
} })
// Örnek alışveriş listeleri oluştur console.log('✅ Kullanıcılar oluşturuldu')
const ahmetUser = await prisma.user.findUnique({
where: { email: 'ahmet@test.com' }
});
const ayseUser = await prisma.user.findUnique({ // Kategoriler
where: { email: 'ayse@test.com' } const cat1 = await prisma.category.create({ data: { name: 'Sebze & Meyve', icon: '🥬', color: '#4CAF50' } })
}); const cat2 = await prisma.category.create({ data: { name: 'Et & Tavuk', icon: '🥩', color: '#F44336' } })
const cat3 = await prisma.category.create({ data: { name: 'Süt & Süt Ürünleri', icon: '🥛', color: '#2196F3' } })
const cat4 = await prisma.category.create({ data: { name: 'Ekmek & Unlu Mamüller', icon: '🍞', color: '#FF9800' } })
const cat5 = await prisma.category.create({ data: { name: 'İçecekler', icon: '🥤', color: '#9C27B0' } })
const cat6 = await prisma.category.create({ data: { name: 'Temizlik', icon: '🧹', color: '#607D8B' } })
const cat7 = await prisma.category.create({ data: { name: 'Atıştırmalık', icon: '🍪', color: '#795548' } })
const cat8 = await prisma.category.create({ data: { name: 'Dondurma', icon: '🍦', color: '#E91E63' } })
const mehmetUser = await prisma.user.findUnique({ console.log('✅ Kategoriler oluşturuldu')
where: { email: 'mehmet@test.com' }
});
// Ahmet için alışveriş listeleri // Ürünler
if (ahmetUser) { const products = await Promise.all([
const shoppingLists = [ prisma.product.create({ data: { name: 'Domates', categoryId: cat1.id, unit: 'kg' } }),
{ prisma.product.create({ data: { name: 'Soğan', categoryId: cat1.id, unit: 'kg' } }),
name: 'Haftalık Alışveriş', prisma.product.create({ data: { name: 'Salatalık', categoryId: cat1.id, unit: 'adet' } }),
description: 'Bu haftanın market alışverişi', prisma.product.create({ data: { name: 'Tavuk Göğsü', categoryId: cat2.id, unit: 'kg' } }),
color: '#4CAF50', prisma.product.create({ data: { name: 'Kıyma', categoryId: cat2.id, unit: 'kg' } }),
items: [ prisma.product.create({ data: { name: 'Kırmızı Et', categoryId: cat2.id, unit: 'kg' } }),
{ productName: 'Elma', quantity: 2, unit: 'kg', price: 15.50 }, prisma.product.create({ data: { name: 'Süt', categoryId: cat3.id, unit: 'L' } }),
{ productName: 'Süt 1L', quantity: 1, unit: 'adet', price: 8.75 }, prisma.product.create({ data: { name: 'Yoğurt', categoryId: cat3.id, unit: 'adet' } }),
{ customName: 'Deterjan', quantity: 1, unit: 'adet', price: 25.00, note: 'Çamaşır deterjanı' }, prisma.product.create({ data: { name: 'Ekmek', categoryId: cat4.id, unit: 'adet' } }),
{ productName: 'Ekmek', quantity: 2, unit: 'adet', price: 9.00 }, prisma.product.create({ data: { name: 'Cola', categoryId: cat5.id, unit: 'adet' } }),
{ productName: 'Yumurta 30\'lu', quantity: 1, unit: 'adet', price: 85.00 }, prisma.product.create({ data: { name: 'Bulaşık Deterjanı', categoryId: cat6.id, unit: 'adet' } }),
] prisma.product.create({ data: { name: 'Baklava', categoryId: cat7.id, unit: 'kg' } }),
}, prisma.product.create({ data: { name: 'Dondurma', categoryId: cat8.id, unit: 'L' } }),
{ ])
name: 'Kahvaltı Malzemeleri',
description: 'Kahvaltı için gerekli ürünler',
color: '#FF9800',
items: [
{ productName: 'Ekmek', quantity: 2, unit: 'adet', price: 9.00 },
{ productName: 'Beyaz Peynir', quantity: 1, unit: 'kg', price: 45.00 },
{ productName: 'Tereyağı', quantity: 1, unit: 'adet', price: 35.00 },
{ productName: 'Domates', quantity: 1, unit: 'kg', price: 8.75 },
{ productName: 'Salatalık', quantity: 2, unit: 'adet', price: 13.00 },
{ productName: 'Çay', quantity: 1, unit: 'adet', price: 35.00 },
]
}
];
for (const listData of shoppingLists) { console.log('✅ Ürünler oluşturuldu')
const shoppingList = await prisma.shoppingList.create({
data: {
name: listData.name,
description: listData.description,
color: listData.color,
ownerId: ahmetUser.id,
},
});
for (const itemData of listData.items) { // Market Listeleri
let productId = null; const list1 = await prisma.shoppingList.create({
data: {
if (itemData.productName) { name: 'Haftalık Market',
const product = await prisma.product.findFirst({ description: 'Bu hafta alınacaklar',
where: { name: itemData.productName } color: '#4CAF50',
}); ownerId: user1.id,
if (product) {
productId = product.id;
}
}
await prisma.listItem.create({
data: {
listId: shoppingList.id,
productId: productId,
customName: itemData.customName,
quantity: itemData.quantity,
unit: itemData.unit,
price: itemData.price,
note: itemData.note,
},
});
}
console.log('✅ Alışveriş listesi oluşturuldu:', shoppingList.name);
} }
} })
// Ayşe için alışveriş listeleri // Listeye üye ekle
if (ayseUser) { await prisma.listMember.create({
const ayseShoppingLists = [ data: {
{ userId: user2.id,
name: 'Parti Alışverişi', listId: list1.id,
description: 'Doğum günü partisi için', role: 'admin'
color: '#E91E63',
items: [
{ productName: 'Kek', quantity: 1, unit: 'adet', price: 25.00 },
{ productName: 'Çikolata', quantity: 5, unit: 'adet', price: 62.50 },
{ productName: 'Bisküvi', quantity: 3, unit: 'paket', price: 26.25 },
{ productName: 'Kola', quantity: 6, unit: 'adet', price: 52.50 },
{ productName: 'Meyve Suyu', quantity: 4, unit: 'adet', price: 50.00 },
{ customName: 'Parti Süsleri', quantity: 1, unit: 'set', price: 45.00 },
]
},
{
name: 'Temizlik Malzemeleri',
description: 'Ev temizliği için gerekli ürünler',
color: '#607D8B',
items: [
{ productName: 'Deterjan', quantity: 2, unit: 'adet', price: 90.00 },
{ productName: 'Sabun', quantity: 3, unit: 'adet', price: 25.50 },
{ productName: 'Şampuan', quantity: 1, unit: 'adet', price: 35.00 },
{ customName: 'Cam Temizleyici', quantity: 1, unit: 'adet', price: 18.50 },
{ customName: 'Yer Bezi', quantity: 2, unit: 'adet', price: 15.00 },
]
}
];
for (const listData of ayseShoppingLists) {
const shoppingList = await prisma.shoppingList.create({
data: {
name: listData.name,
description: listData.description,
color: listData.color,
ownerId: ayseUser.id,
},
});
for (const itemData of listData.items) {
let productId = null;
if (itemData.productName) {
const product = await prisma.product.findFirst({
where: { name: itemData.productName }
});
if (product) {
productId = product.id;
}
}
await prisma.listItem.create({
data: {
listId: shoppingList.id,
productId: productId,
customName: itemData.customName,
quantity: itemData.quantity,
unit: itemData.unit,
price: itemData.price,
},
});
}
console.log('✅ Alışveriş listesi oluşturuldu:', shoppingList.name);
} }
} })
// Mehmet için alışveriş listesi // Liste Öğeleri (productId kullan)
if (mehmetUser) { await prisma.listItem.create({ data: { productId: products[0].id, quantity: 2, unit: 'kg', listId: list1.id } }) // Domates
const mehmetShoppingList = { await prisma.listItem.create({ data: { productId: products[1].id, quantity: 1, unit: 'kg', listId: list1.id } }) // Soğan
name: 'Et ve Protein', await prisma.listItem.create({ data: { productId: products[2].id, quantity: 3, unit: 'adet', listId: list1.id, isPurchased: true } }) // Salatalık
description: 'Protein ihtiyacı için et ürünleri', await prisma.listItem.create({ data: { productId: products[3].id, quantity: 1, unit: 'kg', listId: list1.id } }) // Tavuk
color: '#F44336', await prisma.listItem.create({ data: { productId: products[4].id, quantity: 0.5, unit: 'kg', listId: list1.id } }) // Kıyma
items: [ await prisma.listItem.create({ data: { productId: products[6].id, quantity: 2, unit: 'L', listId: list1.id, isPurchased: true } }) // Süt
{ productName: 'Tavuk But', quantity: 2, unit: 'kg', price: 90.00 }, await prisma.listItem.create({ data: { productId: products[7].id, quantity: 4, unit: 'adet', listId: list1.id } }) // Yoğurt
{ productName: 'Dana Kıyma', quantity: 1, unit: 'kg', price: 120.00 }, await prisma.listItem.create({ data: { productId: products[8].id, quantity: 2, unit: 'adet', listId: list1.id } }) // Ekmek
{ productName: 'Köfte', quantity: 1, unit: 'kg', price: 85.00 }, await prisma.listItem.create({ data: { productId: products[9].id, quantity: 6, unit: 'adet', listId: list1.id } }) // Cola
{ productName: 'Sosis', quantity: 2, unit: 'paket', price: 50.00 }, await prisma.listItem.create({ data: { productId: products[10].id, quantity: 1, unit: 'adet', listId: list1.id, isPurchased: true } }) // Deterjan
{ productName: 'Yumurta 30\'lu', quantity: 1, unit: 'adet', price: 85.00 },
]
};
const shoppingList = await prisma.shoppingList.create({ console.log('✅ İlk liste oluşturuldu')
data: {
name: mehmetShoppingList.name,
description: mehmetShoppingList.description,
color: mehmetShoppingList.color,
ownerId: mehmetUser.id,
},
});
for (const itemData of mehmetShoppingList.items) { // İkinci liste
let productId = null; const list2 = await prisma.shoppingList.create({
data: {
if (itemData.productName) { name: 'Bayram Alışverişi',
const product = await prisma.product.findFirst({ description: 'Bayram için gerekli malzemeler',
where: { name: itemData.productName } color: '#E91E63',
}); ownerId: user1.id,
if (product) {
productId = product.id;
}
}
await prisma.listItem.create({
data: {
listId: shoppingList.id,
productId: productId,
quantity: itemData.quantity,
unit: itemData.unit,
price: itemData.price,
},
});
} }
})
console.log('✅ Alışveriş listesi oluşturuldu:', shoppingList.name); await prisma.listItem.create({ data: { productId: products[5].id, quantity: 2, unit: 'kg', listId: list2.id } }) // Kırmızı Et
} await prisma.listItem.create({ data: { productId: products[11].id, quantity: 1, unit: 'kg', listId: list2.id } }) // Baklava
await prisma.listItem.create({ data: { productId: products[12].id, quantity: 2, unit: 'L', listId: list2.id } }) // Dondurma
console.log('✅ Tüm örnek alışveriş listeleri oluşturuldu'); console.log('✅ İkinci liste oluşturuldu')
// Sistem ayarları console.log('\n🎉 Örnek veriler başarıyla eklendi!')
const settings = [ console.log(` - 3 kullanıcı`)
{ key: 'app_name', value: 'HMarket', type: 'string' }, console.log(` - 8 kategori`)
{ key: 'app_version', value: '1.0.0', type: 'string' }, console.log(` - ${await prisma.product.count()} ürün`)
{ key: 'max_list_members', value: '10', type: 'number' }, console.log(` - 2 liste`)
{ key: 'enable_notifications', value: 'true', type: 'boolean' }, console.log(` - 13 liste öğesi`)
{ key: 'default_currency', value: 'TL', type: 'string' },
];
for (const settingData of settings) {
await prisma.setting.upsert({
where: { key: settingData.key },
update: { value: settingData.value },
create: settingData,
});
console.log('✅ Ayar oluşturuldu:', settingData.key);
}
console.log('🎉 Seed işlemi tamamlandı!');
} }
main() main()
.catch((e) => { .catch((e) => {
console.error('❌ Seed işlemi sırasında hata:', e); console.error(e)
process.exit(1); process.exit(1)
}) })
.finally(async () => { .finally(async () => {
await prisma.$disconnect(); await prisma.$disconnect()
}); })

View File

@@ -1,5 +1,4 @@
const passport = require('passport'); const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const { PrismaClient } = require('@prisma/client'); const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient(); const prisma = new PrismaClient();
@@ -32,67 +31,71 @@ passport.deserializeUser(async (id, done) => {
} }
}); });
// Google OAuth Strategy // Google OAuth Strategy - Sadece credentials varsa yükle
passport.use(new GoogleStrategy({ if (process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET) {
clientID: process.env.GOOGLE_CLIENT_ID, const GoogleStrategy = require('passport-google-oauth20').Strategy;
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: process.env.GOOGLE_CALLBACK_URL || "/api/auth/google/callback" passport.use(new GoogleStrategy({
}, async (accessToken, refreshToken, profile, done) => { clientID: process.env.GOOGLE_CLIENT_ID,
try { clientSecret: process.env.GOOGLE_CLIENT_SECRET,
// Önce Google ID ile kullanıcı ara callbackURL: process.env.GOOGLE_CALLBACK_URL || "/api/auth/google/callback"
let user = await prisma.user.findUnique({ }, async (accessToken, refreshToken, profile, done) => {
where: { googleId: profile.id } try {
}); // Önce Google ID ile kullanıcı ara
let user = await prisma.user.findUnique({
if (user) { where: { googleId: profile.id }
// Kullanıcı zaten var, son giriş tarihini güncelle
user = await prisma.user.update({
where: { id: user.id },
data: { lastLoginAt: new Date() }
}); });
return done(null, user);
}
// Email ile kullanıcı ara (mevcut hesap varsa bağla) if (user) {
user = await prisma.user.findUnique({ // Kullanıcı zaten var, son giriş tarihini güncelle
where: { email: profile.emails[0].value } user = await prisma.user.update({
}); where: { id: user.id },
data: { lastLoginAt: new Date() }
});
return done(null, user);
}
if (user) { // Email ile kullanıcı ara (mevcut hesap varsa bağla)
// Mevcut hesabı Google ile bağla user = await prisma.user.findUnique({
user = await prisma.user.update({ where: { email: profile.emails[0].value }
where: { id: user.id }, });
if (user) {
// Mevcut hesabı Google ile bağla
user = await prisma.user.update({
where: { id: user.id },
data: {
googleId: profile.id,
authProvider: 'google',
avatar: profile.photos[0]?.value || user.avatar,
lastLoginAt: new Date()
}
});
return done(null, user);
}
// Yeni kullanıcı oluştur
const username = profile.emails[0].value.split('@')[0] + '_' + Math.random().toString(36).substr(2, 4);
user = await prisma.user.create({
data: { data: {
email: profile.emails[0].value,
username: username,
firstName: profile.name.givenName || '',
lastName: profile.name.familyName || '',
googleId: profile.id, googleId: profile.id,
authProvider: 'google', authProvider: 'google',
avatar: profile.photos[0]?.value || user.avatar, avatar: profile.photos[0]?.value,
lastLoginAt: new Date() lastLoginAt: new Date()
} }
}); });
return done(null, user); return done(null, user);
} catch (error) {
console.error('Google OAuth Error:', error);
return done(error, null);
} }
}));
// Yeni kullanıcı oluştur }
const username = profile.emails[0].value.split('@')[0] + '_' + Math.random().toString(36).substr(2, 4);
user = await prisma.user.create({
data: {
email: profile.emails[0].value,
username: username,
firstName: profile.name.givenName || '',
lastName: profile.name.familyName || '',
googleId: profile.id,
authProvider: 'google',
avatar: profile.photos[0]?.value,
lastLoginAt: new Date()
}
});
return done(null, user);
} catch (error) {
console.error('Google OAuth Error:', error);
return done(error, null);
}
}));
module.exports = passport; module.exports = passport;

View File

@@ -1,5 +1,4 @@
const express = require('express'); const express = require('express');
const { PrismaClient } = require('@prisma/client');
const { authenticateToken, checkListMembership, requireListEditPermission } = require('../middleware/auth'); const { authenticateToken, checkListMembership, requireListEditPermission } = require('../middleware/auth');
const { asyncHandler } = require('../middleware/errorHandler'); const { asyncHandler } = require('../middleware/errorHandler');
const { const {
@@ -15,7 +14,6 @@ const { successResponse, errorResponse, calculatePagination, createPaginationMet
const notificationService = require('../services/notificationService'); const notificationService = require('../services/notificationService');
const router = express.Router(); const router = express.Router();
const prisma = new PrismaClient();
/** /**
* Liste öğelerini getir * Liste öğelerini getir
@@ -68,8 +66,8 @@ router.get('/:listId',
// Toplam sayı ve öğeleri getir // Toplam sayı ve öğeleri getir
const [total, items] = await Promise.all([ const [total, items] = await Promise.all([
prisma.listItem.count({ where }), req.prisma.listItem.count({ where }),
prisma.listItem.findMany({ req.prisma.listItem.findMany({
where, where,
skip, skip,
take, take,
@@ -116,7 +114,7 @@ router.get('/:listId/:itemId',
const { listId, itemId } = req.params; const { listId, itemId } = req.params;
const item = await prisma.listItem.findFirst({ const item = await req.prisma.listItem.findFirst({
where: { where: {
id: itemId, id: itemId,
listId listId
@@ -179,7 +177,7 @@ router.post('/:listId',
// Eğer productId verilmişse, ürünün var olduğunu kontrol et // Eğer productId verilmişse, ürünün var olduğunu kontrol et
let product = null; let product = null;
if (productId) { if (productId) {
product = await prisma.product.findUnique({ product = await req.prisma.product.findUnique({
where: { id: productId } where: { id: productId }
}); });
@@ -189,7 +187,7 @@ router.post('/:listId',
} }
// Aynı öğenin listede zaten var olup olmadığını kontrol et // Aynı öğenin listede zaten var olup olmadığını kontrol et
const existingItem = await prisma.listItem.findFirst({ const existingItem = await req.prisma.listItem.findFirst({
where: { where: {
listId, listId,
OR: [ OR: [
@@ -204,7 +202,7 @@ router.post('/:listId',
} }
// Yeni öğe oluştur // Yeni öğe oluştur
const newItem = await prisma.listItem.create({ const newItem = await req.prisma.listItem.create({
data: { data: {
customName: productId ? product.name : name, customName: productId ? product.name : name,
quantity, quantity,
@@ -226,26 +224,26 @@ router.post('/:listId',
// Ürün kullanım sayısını artır (Product modelinde usageCount alanı yok, bu özellik kaldırıldı) // Ürün kullanım sayısını artır (Product modelinde usageCount alanı yok, bu özellik kaldırıldı)
// Liste güncelleme tarihini güncelle // Liste güncelleme tarihini güncelle
await prisma.shoppingList.update({ await req.prisma.shoppingList.update({
where: { id: listId }, where: { id: listId },
data: { updatedAt: new Date() } data: { updatedAt: new Date() }
}); });
// Aktivite kaydı oluştur // Aktivite kaydı oluştur (geçici olarak devre dışı)
await prisma.activity.create({ // await req.prisma.activity.create({
data: { // data: {
action: 'item_added', // action: 'item_added',
details: { // details: {
itemId: newItem.id, // itemId: newItem.id,
itemName: newItem.customName || newItem.product?.name || 'Öğe', // itemName: newItem.customName || newItem.product?.name || 'Öğe',
userName: `${req.user.firstName} ${req.user.lastName}` // userName: `${req.user.firstName} ${req.user.lastName}`
}, // },
userId, // userId,
listId // listId
} // }
}); // });
// Liste üyelerine bildirim gönder (geçici olarak devre dışı - notifyListMembers fonksiyonu mevcut değil) // Liste üyelerine bildirim gönder (geçici olarak devre dışı)
// await notificationService.notifyListMembers( // await notificationService.notifyListMembers(
// listId, // listId,
// userId, // userId,
@@ -254,14 +252,14 @@ router.post('/:listId',
// { itemId: newItem.id, itemName: newItem.customName || newItem.product?.name } // { itemId: newItem.id, itemName: newItem.customName || newItem.product?.name }
// ); // );
// Socket.IO ile gerçek zamanlı güncelleme // Socket.IO ile gerçek zamanlı güncelleme (geçici olarak devre dışı)
const io = req.app.get('io'); // const io = req.app.get('io');
if (io) { // if (io) {
io.to(`list_${listId}`).emit('itemAdded', { // io.to(`list_${listId}`).emit('itemAdded', {
item: newItem, // item: newItem,
addedBy: req.user // addedBy: req.user
}); // });
} // }
// Priority değerini string'e çevir // Priority değerini string'e çevir
const newItemWithStringPriority = { const newItemWithStringPriority = {
@@ -321,7 +319,7 @@ router.put('/:listId/:itemId',
// Öğenin var olduğunu kontrol et // Öğenin var olduğunu kontrol et
console.log('🔍 Öğe aranıyor:', { itemId, listId }); console.log('🔍 Öğe aranıyor:', { itemId, listId });
const existingItem = await prisma.listItem.findFirst({ const existingItem = await req.prisma.listItem.findFirst({
where: { where: {
id: itemId, id: itemId,
listId listId
@@ -364,7 +362,7 @@ router.put('/:listId/:itemId',
} }
// Öğeyi güncelle // Öğeyi güncelle
const updatedItem = await prisma.listItem.update({ const updatedItem = await req.prisma.listItem.update({
where: { id: itemId }, where: { id: itemId },
data: updateData, data: updateData,
include: { include: {
@@ -378,7 +376,7 @@ router.put('/:listId/:itemId',
// Fiyat geçmişi ekle (eğer fiyat girilmişse ve ürün varsa) // Fiyat geçmişi ekle (eğer fiyat girilmişse ve ürün varsa)
if (price && existingItem.productId && isPurchased) { if (price && existingItem.productId && isPurchased) {
await prisma.priceHistory.create({ await req.prisma.priceHistory.create({
data: { data: {
price: price, price: price,
productId: existingItem.productId, productId: existingItem.productId,
@@ -389,7 +387,7 @@ router.put('/:listId/:itemId',
} }
// Liste güncelleme tarihini güncelle // Liste güncelleme tarihini güncelle
await prisma.shoppingList.update({ await req.prisma.shoppingList.update({
where: { id: listId }, where: { id: listId },
data: { updatedAt: new Date() } data: { updatedAt: new Date() }
}); });
@@ -402,7 +400,7 @@ router.put('/:listId/:itemId',
: `${req.user.firstName} ${req.user.lastName} "${updatedItem.name}" öğesinin satın alma durumunu iptal etti`; : `${req.user.firstName} ${req.user.lastName} "${updatedItem.name}" öğesinin satın alma durumunu iptal etti`;
} }
await prisma.activity.create({ await req.prisma.activity.create({
data: { data: {
action: isPurchased !== undefined ? (isPurchased ? 'ITEM_PURCHASED' : 'ITEM_UNPURCHASED') : 'ITEM_UPDATED', action: isPurchased !== undefined ? (isPurchased ? 'ITEM_PURCHASED' : 'ITEM_UNPURCHASED') : 'ITEM_UPDATED',
details: { details: {
@@ -467,7 +465,7 @@ router.delete('/:listId/:itemId',
const userId = req.user.id; const userId = req.user.id;
// Öğenin var olduğunu kontrol et // Öğenin var olduğunu kontrol et
const existingItem = await prisma.listItem.findFirst({ const existingItem = await req.prisma.listItem.findFirst({
where: { where: {
id: itemId, id: itemId,
listId listId
@@ -479,19 +477,19 @@ router.delete('/:listId/:itemId',
} }
// Öğeyi sil // Öğeyi sil
await prisma.listItem.delete({ await req.prisma.listItem.delete({
where: { id: itemId } where: { id: itemId }
}); });
// Liste güncelleme tarihini güncelle // Liste güncelleme tarihini güncelle
await prisma.shoppingList.update({ await req.prisma.shoppingList.update({
where: { id: listId }, where: { id: listId },
data: { updatedAt: new Date() } data: { updatedAt: new Date() }
}); });
// Aktivite kaydı oluştur (Prisma şemasına uygun) // Aktivite kaydı oluştur (Prisma şemasına uygun)
const itemName = existingItem.customName || existingItem.product?.name || 'Öğe'; const itemName = existingItem.customName || existingItem.product?.name || 'Öğe';
await prisma.activity.create({ await req.prisma.activity.create({
data: { data: {
action: 'ITEM_REMOVED', action: 'ITEM_REMOVED',
details: { details: {
@@ -551,7 +549,7 @@ router.patch('/:listId/bulk',
} }
// Öğelerin var olduğunu kontrol et // Öğelerin var olduğunu kontrol et
const existingItems = await prisma.listItem.findMany({ const existingItems = await req.prisma.listItem.findMany({
where: { where: {
id: { in: items }, id: { in: items },
listId listId
@@ -593,14 +591,14 @@ router.patch('/:listId/bulk',
// Toplu güncelleme veya silme // Toplu güncelleme veya silme
if (action === 'delete') { if (action === 'delete') {
await prisma.listItem.deleteMany({ await req.prisma.listItem.deleteMany({
where: { where: {
id: { in: items }, id: { in: items },
listId listId
} }
}); });
} else { } else {
await prisma.listItem.updateMany({ await req.prisma.listItem.updateMany({
where: { where: {
id: { in: items }, id: { in: items },
listId listId
@@ -610,13 +608,13 @@ router.patch('/:listId/bulk',
} }
// Liste güncelleme tarihini güncelle // Liste güncelleme tarihini güncelle
await prisma.shoppingList.update({ await req.prisma.shoppingList.update({
where: { id: listId }, where: { id: listId },
data: { updatedAt: new Date() } data: { updatedAt: new Date() }
}); });
// Aktivite kaydı oluştur // Aktivite kaydı oluştur
await prisma.activity.create({ await req.prisma.activity.create({
data: { data: {
type: activityType, type: activityType,
description: activityDescription, description: activityDescription,

View File

@@ -198,23 +198,25 @@ router.post('/', authenticateToken, [
} }
}); });
// Aktivite kaydı oluştur // Aktivite kaydı oluştur (geçici olarak devre dışı)
await req.prisma.activity.create({ // await req.prisma.activity.create({
data: { // data: {
listId: list.id, // listId: list.id,
userId: req.user.id, // userId: req.user.id,
action: 'list_created', // action: 'list_created',
details: { // details: {
listName: list.name // listName: list.name
} // }
} // }
}); // });
// Socket.IO ile gerçek zamanlı bildirim gönder // Socket.IO ile gerçek zamanlı bildirim gönder (geçici olarak devre dışı)
req.io.emit('list_created', { // if (req.io) {
list: { ...list, userRole: 'owner' }, // req.io.emit('list_created', {
user: req.user // list: { ...list, userRole: 'owner' },
}); // user: req.user
// });
// }
res.status(201).json({ res.status(201).json({
success: true, success: true,

View File

@@ -148,7 +148,7 @@ process.on('SIGINT', async () => {
}); });
// Sunucuyu başlat // Sunucuyu başlat
const PORT = process.env.PORT || 5000; const PORT = process.env.PORT || 7001;
server.listen(PORT, () => { server.listen(PORT, () => {
console.log(`🚀 Server ${PORT} portunda çalışıyor - port 7001`); console.log(`🚀 Server ${PORT} portunda çalışıyor - port 7001`);

View File

@@ -9,6 +9,16 @@ class NotificationService {
initializeFirebase() { initializeFirebase() {
try { try {
// Firebase credentials kontrolü
const hasCredentials = process.env.FIREBASE_PROJECT_ID &&
process.env.FIREBASE_PRIVATE_KEY &&
process.env.FIREBASE_CLIENT_EMAIL;
if (!hasCredentials) {
console.log('⚠️ Firebase credentials not configured. Push notifications disabled.');
return;
}
if (!admin.apps.length) { if (!admin.apps.length) {
const serviceAccount = { const serviceAccount = {
type: process.env.FIREBASE_TYPE, type: process.env.FIREBASE_TYPE,
@@ -27,10 +37,11 @@ class NotificationService {
credential: admin.credential.cert(serviceAccount) credential: admin.credential.cert(serviceAccount)
}); });
console.log('Firebase Admin SDK initialized successfully'); console.log('Firebase Admin SDK initialized successfully');
} }
} catch (error) { } catch (error) {
console.error('Firebase initialization error:', error); console.error('Firebase initialization error:', error.message);
console.warn('Push notifications will be disabled.');
} }
} }

View File

@@ -16,13 +16,20 @@ function getDatabaseName(databaseUrl) {
async function setupUtf8mb4(prisma) { async function setupUtf8mb4(prisma) {
const databaseUrl = process.env.DATABASE_URL || ''; const databaseUrl = process.env.DATABASE_URL || '';
// SQLite için bu fonksiyonu atla
if (databaseUrl.includes('sqlite') || databaseUrl.includes('.db')) {
console.log(' SQLite kullanılıyor. UTF8MB4 kurulumu atlandı.');
return;
}
const dbName = getDatabaseName(databaseUrl); const dbName = getDatabaseName(databaseUrl);
if (!dbName) { if (!dbName) {
console.warn('⚠️ DATABASE_URL bulunamadı veya veritabanı adı çözümlenemedi. UTF8MB4 kurulumu atlandı.'); console.warn('⚠️ DATABASE_URL bulunamadı veya veritabanı adı çözümlenemedi. UTF8MB4 kurulumu atlandı.');
return; return;
} }
// Try altering database charset/collation // Only run for MySQL/MariaDB
try { try {
await prisma.$executeRawUnsafe(`ALTER DATABASE \`${dbName}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`); await prisma.$executeRawUnsafe(`ALTER DATABASE \`${dbName}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`);
console.log('✅ Veritabanı varsayılan karakter seti/collation utf8mb4 olarak ayarlandı.'); console.log('✅ Veritabanı varsayılan karakter seti/collation utf8mb4 olarak ayarlandı.');
@@ -30,7 +37,6 @@ async function setupUtf8mb4(prisma) {
console.warn('⚠️ Veritabanı charset ayarlanırken hata oluştu:', err?.message || err); console.warn('⚠️ Veritabanı charset ayarlanırken hata oluştu:', err?.message || err);
} }
// Try converting categories table
try { try {
await prisma.$executeRawUnsafe('ALTER TABLE `categories` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci'); await prisma.$executeRawUnsafe('ALTER TABLE `categories` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci');
console.log('✅ `categories` tablosu utf8mb4 olarak dönüştürüldü.'); console.log('✅ `categories` tablosu utf8mb4 olarak dönüştürüldü.');

View File

@@ -15610,19 +15610,6 @@
} }
} }
}, },
"node_modules/tailwindcss/node_modules/yaml": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
"integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
"optional": true,
"peer": true,
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14.6"
}
},
"node_modules/tapable": { "node_modules/tapable": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",

View File

@@ -1,63 +0,0 @@
from PIL import Image, ImageDraw, ImageFilter
def create_hmarket_logo(path, size=512):
# Create image with transparent background
img = Image.new('RGBA', (size, size), (255, 255, 255, 0))
draw = ImageDraw.Draw(img)
# Modern Blue/Teal Gradient simulation
# Let's draw a rounded rectangle background for the icon
padding = size // 8
rect_shape = [padding, padding, size - padding, size - padding]
corner_radius = size // 6
# Draw shadow
shadow_offset = size // 40
draw.rounded_rectangle(
[padding + shadow_offset, padding + shadow_offset, size - padding + shadow_offset, size - padding + shadow_offset],
radius=corner_radius,
fill=(0, 0, 0, 40)
)
# Draw main background circle/rounded rect with gradient
for i in range(size - 2*padding):
# Color from #3a7bd5 to #00d2ff
r = int(58 + (0 - 58) * (i / (size - 2*padding)))
g = int(123 + (210 - 123) * (i / (size - 2*padding)))
b = int(213 + (255 - 213) * (i / (size - 2*padding)))
draw.line([padding + i, padding, padding + i, size - padding], fill=(r, g, b, 255))
# Redraw rounded corners mask (to make it look like a rounded rect icon)
mask = Image.new('L', (size, size), 0)
mask_draw = ImageDraw.Draw(mask)
mask_draw.rounded_rectangle(rect_shape, radius=corner_radius, fill=255)
# Apply mask to gradient
output = Image.new('RGBA', (size, size), (255, 255, 255, 0))
output.paste(img, (0, 0), mask=mask)
# Draw Shopping Cart Icon (Simplified white vector style)
draw_icon = ImageDraw.Draw(output)
s = size // 10 # scale factor
# Cart body
cart_color = (255, 255, 255, 255)
# Handle and frame
draw_icon.line([3*s, 3*s, 3.5*s, 3*s, 4*s, 6*s, 7.5*s, 6*s], fill=cart_color, width=s//3)
# Basket
draw_icon.polygon([4*s, 4*s, 7.5*s, 4*s, 7*s, 5.5*s, 4.5*s, 5.5*s], fill=cart_color)
# Wheels
draw_icon.ellipse([4.2*s, 6.2*s, 4.8*s, 6.8*s], fill=cart_color)
draw_icon.ellipse([6.7*s, 6.2*s, 7.3*s, 6.8*s], fill=cart_color)
# Save
output.save(path)
return output
# Generate both sizes
logo512 = create_hmarket_logo("/home/hololu/calismalar/hMarket/frontend/public/logo512.png", 512)
logo192 = logo512.resize((192, 192), Image.LANCZOS)
logo192.save("/home/hololu/calismalar/hMarket/frontend/public/logo192.png")
logo512.save("/home/hololu/calismalar/hmarket-logo.png") # Extra copy for OAuth screen
print("Logolar başarıyla oluşturuldu.")

View File

@@ -1,60 +0,0 @@
from PIL import Image, ImageDraw
def create_orange_logo(path, size=512):
# Base image
img = Image.new('RGBA', (size, size), (255, 255, 255, 0))
draw = ImageDraw.Draw(img)
# Background color #FF5722
bg_color = (255, 87, 34, 255)
padding = size // 10
corner_radius = size // 6
draw.rounded_rectangle(
[padding, padding, size - padding, size - padding],
radius=corner_radius,
fill=bg_color
)
# Scale for the 24x24 SVG path
# We want the icon to fit in the center, say 60% of the box
icon_size = size * 0.55
offset = (size - icon_size) / 2
scale = icon_size / 24
def scale_pt(x, y):
return (offset + x * scale, offset + y * scale)
# Drawing the cart manually based on the SVG path logic
# Wheels
r_wheel = 1 * scale
w1_c = scale_pt(7, 20)
draw.ellipse([w1_c[0]-r_wheel, w1_c[1]-r_wheel, w1_c[0]+r_wheel, w1_c[1]+r_wheel], fill="white")
w2_c = scale_pt(17, 20)
draw.ellipse([w2_c[0]-r_wheel, w2_c[1]-r_wheel, w2_c[0]+r_wheel, w2_c[1]+r_wheel], fill="white")
# The main body path
# M1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.58-6.49c.08-.14.12-.31.12-.48 0-.55-.45-1-1-1H5.21l-.94-2z
# Simplified polygon for the cart body
points = [
scale_pt(1, 2), scale_pt(1, 4), scale_pt(3, 4),
scale_pt(6.6, 11.59), scale_pt(5.25, 14.04),
scale_pt(5.25, 15), scale_pt(7, 17), scale_pt(19, 17),
scale_pt(19, 15), scale_pt(7.42, 15), scale_pt(8.35, 13.37),
scale_pt(15.8, 13.37), scale_pt(17.55, 12.34), scale_pt(21.13, 5.85),
scale_pt(21.25, 5.37), scale_pt(20.25, 4.37), scale_pt(5.21, 4.37),
scale_pt(4.27, 2.37)
]
draw.polygon(points, fill="white")
# Save
img.save(path)
create_orange_logo("/home/hololu/calismalar/hMarket/frontend/public/logo512.png", 512)
create_orange_logo("/home/hololu/calismalar/hmarket-logo.png", 512)
img_512 = Image.open("/home/hololu/calismalar/hMarket/frontend/public/logo512.png")
img_192 = img_512.resize((192, 192), Image.LANCZOS)
img_192.save("/home/hololu/calismalar/hMarket/frontend/public/logo192.png")
print("Yeni turuncu logolar oluşturuldu.")

View File

@@ -1 +0,0 @@
{"email":"admin@hmarket.com","password":"admin123"}

View File

@@ -1,39 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
width: 512px;
height: 512px;
background: transparent;
}
.container {
width: 440px;
height: 440px;
background: #FF5722;
border-radius: 80px;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 20px 40px rgba(255, 87, 34, 0.3);
}
svg {
width: 280px;
height: 280px;
fill: white;
}
</style>
</head>
<body>
<div class="container">
<svg viewBox="0 0 24 24">
<path d="M7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2M1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.58-6.49c.08-.14.12-.31.12-.48 0-.55-.45-1-1-1H5.21l-.94-2zm16 16c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2"></path>
</svg>
</div>
</body>
</html>

View File

@@ -1,4 +0,0 @@
{
"login": "ahmet@test.com",
"password": "test123"
}