diff --git a/apps/api/src/lib/auth.ts b/apps/api/src/lib/auth.ts index 020e540..50daaab 100644 --- a/apps/api/src/lib/auth.ts +++ b/apps/api/src/lib/auth.ts @@ -171,17 +171,21 @@ export async function initAuth(): Promise { const hasGoogle = !!(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET); const hasGitHub = !!(process.env.GITHUB_CLIENT_ID && process.env.GITHUB_CLIENT_SECRET); + const callbackBase = `${BETTER_AUTH_URL}/api/auth/callback`; + const socialPlugins = []; if (hasGoogle) { socialPlugins.push(google({ clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, + redirectURI: `${callbackBase}/google`, })); } if (hasGitHub) { socialPlugins.push(github({ clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, + redirectURI: `${callbackBase}/github`, })); } diff --git a/apps/web/public/demo-pets/dog-afghan-hound.png b/apps/web/public/demo-pets/dog-afghan-hound.png new file mode 100644 index 0000000..7ce13ba Binary files /dev/null and b/apps/web/public/demo-pets/dog-afghan-hound.png differ diff --git a/apps/web/public/demo-pets/dog-basset-brown-white.png b/apps/web/public/demo-pets/dog-basset-brown-white.png new file mode 100644 index 0000000..9c9fea0 --- /dev/null +++ b/apps/web/public/demo-pets/dog-basset-brown-white.png @@ -0,0 +1,9 @@ + + + AccessDenied + You have no right to access this object because of bucket acl. + 69D96C853FAECD363909C4A0 + hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com + 0003-00000001 + https://api.alibabacloud.com/troubleshoot?q=0003-00000001 + diff --git a/apps/web/public/demo-pets/dog-bichon-white-groomed.png b/apps/web/public/demo-pets/dog-bichon-white-groomed.png new file mode 100644 index 0000000..2d214d4 --- /dev/null +++ b/apps/web/public/demo-pets/dog-bichon-white-groomed.png @@ -0,0 +1,9 @@ + + + AccessDenied + You have no right to access this object because of bucket acl. + 69D96CFC84D7A9333708F278 + hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com + 0003-00000001 + https://api.alibabacloud.com/troubleshoot?q=0003-00000001 + diff --git a/apps/web/public/demo-pets/dog-boxer-fawn-athletic.png b/apps/web/public/demo-pets/dog-boxer-fawn-athletic.png new file mode 100644 index 0000000..4958ac7 --- /dev/null +++ b/apps/web/public/demo-pets/dog-boxer-fawn-athletic.png @@ -0,0 +1,9 @@ + + + AccessDenied + You have no right to access this object because of bucket acl. + 69D96D48D7892E37386B9ACB + hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com + 0003-00000001 + https://api.alibabacloud.com/troubleshoot?q=0003-00000001 + diff --git a/apps/web/public/demo-pets/dog-cavalier-cream-gentle.png b/apps/web/public/demo-pets/dog-cavalier-cream-gentle.png new file mode 100644 index 0000000..a06164b --- /dev/null +++ b/apps/web/public/demo-pets/dog-cavalier-cream-gentle.png @@ -0,0 +1,9 @@ + + + AccessDenied + You have no right to access this object because of bucket acl. + 69D96C25663D703833F23607 + hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com + 0003-00000001 + https://api.alibabacloud.com/troubleshoot?q=0003-00000001 + diff --git a/apps/web/public/demo-pets/dog-cocker-buff-friendly.png b/apps/web/public/demo-pets/dog-cocker-buff-friendly.png new file mode 100644 index 0000000..b4beacc --- /dev/null +++ b/apps/web/public/demo-pets/dog-cocker-buff-friendly.png @@ -0,0 +1,9 @@ + + + AccessDenied + You have no right to access this object because of bucket acl. + 69D96D89851C843332073968 + hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com + 0003-00000001 + https://api.alibabacloud.com/troubleshoot?q=0003-00000001 + diff --git a/apps/web/public/demo-pets/dog-corgi.png b/apps/web/public/demo-pets/dog-corgi.png new file mode 100644 index 0000000..6b659b1 Binary files /dev/null and b/apps/web/public/demo-pets/dog-corgi.png differ diff --git a/apps/web/public/demo-pets/dog-dachshund-black-tan.png b/apps/web/public/demo-pets/dog-dachshund-black-tan.png new file mode 100644 index 0000000..506c523 --- /dev/null +++ b/apps/web/public/demo-pets/dog-dachshund-black-tan.png @@ -0,0 +1,9 @@ + + + AccessDenied + You have no right to access this object because of bucket acl. + 69D96C9C5A03D33730C61AD8 + hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com + 0003-00000001 + https://api.alibabacloud.com/troubleshoot?q=0003-00000001 + diff --git a/apps/web/public/demo-pets/dog-mixed-breed.png b/apps/web/public/demo-pets/dog-mixed-breed.png index 8b280b7..5933865 100644 Binary files a/apps/web/public/demo-pets/dog-mixed-breed.png and b/apps/web/public/demo-pets/dog-mixed-breed.png differ diff --git a/apps/web/public/demo-pets/dog-pomeranian-white-studio.png b/apps/web/public/demo-pets/dog-pomeranian-white-studio.png new file mode 100644 index 0000000..0d13b96 --- /dev/null +++ b/apps/web/public/demo-pets/dog-pomeranian-white-studio.png @@ -0,0 +1,9 @@ + + + AccessDenied + You have no right to access this object because of bucket acl. + 69D96BEB91911B30317E3BE8 + hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com + 0003-00000001 + https://api.alibabacloud.com/troubleshoot?q=0003-00000001 + diff --git a/apps/web/public/demo-pets/dog-schnauzer-black-groomed.png b/apps/web/public/demo-pets/dog-schnauzer-black-groomed.png new file mode 100644 index 0000000..2cdf304 --- /dev/null +++ b/apps/web/public/demo-pets/dog-schnauzer-black-groomed.png @@ -0,0 +1,9 @@ + + + AccessDenied + You have no right to access this object because of bucket acl. + 69D96BFB7B92D33535D6D90D + hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com + 0003-00000001 + https://api.alibabacloud.com/troubleshoot?q=0003-00000001 + diff --git a/apps/web/public/demo-pets/dog-setter-red-sunlit.png b/apps/web/public/demo-pets/dog-setter-red-sunlit.png new file mode 100644 index 0000000..4e1850d --- /dev/null +++ b/apps/web/public/demo-pets/dog-setter-red-sunlit.png @@ -0,0 +1,9 @@ + + + AccessDenied + You have no right to access this object because of bucket acl. + 69D96B8BDF4B473630A2E120 + hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com + 0003-00000001 + https://api.alibabacloud.com/troubleshoot?q=0003-00000001 + diff --git a/apps/web/public/demo-pets/dog-sheepdog-merle-running.png b/apps/web/public/demo-pets/dog-sheepdog-merle-running.png new file mode 100644 index 0000000..d164736 --- /dev/null +++ b/apps/web/public/demo-pets/dog-sheepdog-merle-running.png @@ -0,0 +1,9 @@ + + + AccessDenied + You have no right to access this object because of bucket acl. + 69D96D78BFFCAD343037C27C + hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com + 0003-00000001 + https://api.alibabacloud.com/troubleshoot?q=0003-00000001 + diff --git a/packages/db/src/seed.ts b/packages/db/src/seed.ts index b41c0c4..f18f5f7 100644 --- a/packages/db/src/seed.ts +++ b/packages/db/src/seed.ts @@ -184,7 +184,7 @@ const dogBreeds = [ "Brittany", "English Springer Spaniel", "Maltese", "Bichon Frise", "West Highland White Terrier", "Vizsla", "Chihuahua", "Collie", "Basset Hound", "Newfoundland", "Samoyed", "Australian Shepherd", - "Pembroke Welsh Corgi", "French Bulldog", "Weimaraner", + "Pembroke Welsh Corgi", "French Bulldog", "Weimaraner", "Puggle", "Mixed Breed", "Mixed Breed", "Mixed Breed", ]; @@ -281,6 +281,44 @@ const productsUsed = [ "Coconut oil shampoo, leave-in conditioner, cologne", ]; +const demoPetImages = [ + "/demo-pets/dog-golden-after.png", + "/demo-pets/dog-poodle-groomed.png", + "/demo-pets/dog-black-lab.png", + "/demo-pets/dog-shih-tzu.png", + "/demo-pets/dog-cocker-spaniel.png", + "/demo-pets/dog-schnauzer.png", + "/demo-pets/dog-maltese.png", + "/demo-pets/dog-dachshund.png", + "/demo-pets/dog-pomeranian.png", + "/demo-pets/dog-bichon-frise.png", + "/demo-pets/dog-golden-retriever.png", + "/demo-pets/dog-labrador.png", + "/demo-pets/dog-mixed-breed.png", + "/demo-pets/dog-poodle.png", + "/demo-pets/dog-terrier.png", + "/demo-pets/dog-afghan-hound.png", + "/demo-pets/dog-basset-brown-white.png", + "/demo-pets/dog-bichon-white-groomed.png", + "/demo-pets/dog-boxer-fawn-athletic.png", + "/demo-pets/dog-cavalier-cream-gentle.png", + "/demo-pets/dog-cocker-buff-friendly.png", + "/demo-pets/dog-corgi.png", + "/demo-pets/dog-dachshund-black-tan.png", + "/demo-pets/dog-golden-before.png", + "/demo-pets/dog-pomeranian-white-studio.png", + "/demo-pets/dog-schnauzer-black-groomed.png", + "/demo-pets/dog-setter-red-sunlit.png", + "/demo-pets/dog-sheepdog-merle-running.png", +]; + +const puggleImages = [ + "/demo-pets/dog-puggle-fawn-playful.png", + "/demo-pets/dog-puggle-black-sitting.png", + "/demo-pets/dog-puggle-cream-groomed.png", + "/demo-pets/dog-puggle-fawn-grooming.png", +]; + // ── Service definitions ────────────────────────────────────────────────────── // Deterministic service IDs + UNIQUE(name) constraint make seed fully idempotent: // first run inserts, subsequent runs update existing rows via ON CONFLICT (name). @@ -621,6 +659,7 @@ async function seed() { const clientRecords: ClientRecord[] = []; const petRecords: PetRecord[] = []; + let petIndex = 0; // Track pet count to assign Puggle images to first 250 pets const clientBatchSize = 50; for (let batch = 0; batch < Math.ceil(cfg.clientCount / clientBatchSize); batch++) { const clientBatch: (typeof schema.clients.$inferInsert)[] = []; @@ -652,7 +691,7 @@ async function seed() { const petCount = rand() < 0.5 ? 1 : rand() < 0.7 ? 2 : 3; for (let p = 0; p < petCount; p++) { const petId = uuid(); - const breed = pick(dogBreeds); + const breed = petIndex < 250 ? "Puggle" : pick(dogBreeds); const dob = new Date(now); dob.setFullYear(dob.getFullYear() - randInt(1, 14)); dob.setMonth(randInt(0, 11)); @@ -671,9 +710,11 @@ async function seed() { shampooPreference: pick(shampoos), specialCareNotes: rand() < 0.1 ? "Vet clearance required before grooming" : null, customFields: {}, + image: petIndex < 250 ? pick(puggleImages) : pick(demoPetImages), }); petRecords.push({ id: petId, clientId }); + petIndex++; } } @@ -704,6 +745,7 @@ async function seed() { shampooPreference: pet.shampooPreference, specialCareNotes: pet.specialCareNotes, customFields: pet.customFields, + image: pet.image, }, }); } @@ -738,8 +780,8 @@ async function seed() { .values({ id: uc.id, name: uc.name, email: uc.email, phone: uc.phone, address: uc.address }) .onConflictDoUpdate({ target: schema.clients.id, set: { name: uc.name, email: uc.email, phone: uc.phone, address: uc.address } }); await db.insert(schema.pets) - .values({ id: uc.petId, clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed, weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z") }) - .onConflictDoUpdate({ target: schema.pets.id, set: { clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed, weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z") } }); + .values({ id: uc.petId, clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed, weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z"), image: pick(demoPetImages) }) + .onConflictDoUpdate({ target: schema.pets.id, set: { clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed, weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z"), image: pick(demoPetImages) } }); // Create one completed appointment for this client const apptId = uuid(); const svcIdx = 0;