feat: Patenschafts-Honig automatisch waehlen (nie cremig, neueste Ernte)
Docker Image bauen und veroeffentlichen / typecheck (push) Successful in 2m18s
Docker Image bauen und veroeffentlichen / test (push) Successful in 5m32s
Docker Image bauen und veroeffentlichen / lint (push) Successful in 3m41s
Docker Image bauen und veroeffentlichen / build-and-push (push) Canceled after 20m38s
Docker Image bauen und veroeffentlichen / typecheck (push) Successful in 2m18s
Docker Image bauen und veroeffentlichen / test (push) Successful in 5m32s
Docker Image bauen und veroeffentlichen / lint (push) Successful in 3m41s
Docker Image bauen und veroeffentlichen / build-and-push (push) Canceled after 20m38s
Pakete, Abo-Reservierung und Abo-Lieferungen nehmen immer den aktiven, nicht cremigen Honig der neuesten Ernte mit genug freiem Bestand, bei gleichem Jahrgang den mit dem meisten Bestand. Feste Honig-Zuordnung im Admin entfaellt (Spalte bleibt, wird nicht mehr genutzt). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
3ddf0bfa73
commit
1d88bac52e
30 files changed
+1152
-394
No files matched your search
@@ -4,17 +4,24 @@
|
||||
* Wiederholbar: legt nur an, was fehlt, und aendert nie ein Angebot, das der
|
||||
* Inhaber schon bearbeitet hat (Felder werden nur gesetzt, wenn sie leer sind).
|
||||
*
|
||||
* - verknuepft die physischen Einmal-Pakete mit einem Honigprodukt,
|
||||
* - legt die beiden Abo-Angebote INAKTIV an (Testpreise, im Admin pruefen),
|
||||
* - legt fuer jedes Abo-Angebot Stripe-Produkt, Monatspreis und
|
||||
* Traegerprodukt an (syncOfferStripePrice).
|
||||
*
|
||||
* Einen Honig verknuepft das Skript nicht mehr (frueher --honey=<slug>):
|
||||
* Pakete und Abos bekommen ihren Honig automatisch — nie cremig, neueste
|
||||
* Ernte, genug Bestand (lib/sponsorship/honey-selection.ts). Die Spalte
|
||||
* honeyProductId bleibt ungenutzt im Schema; der Probelauf zeigt zur
|
||||
* Kontrolle, welchen Honig die Regel gerade waehlen wuerde.
|
||||
*
|
||||
* Aufruf (Werkzeug-Image, Umgebung wie die App):
|
||||
* tsx scripts/sponsorship-bootstrap.ts --honey=<produkt-slug> (Probelauf)
|
||||
* tsx scripts/sponsorship-bootstrap.ts --honey=<produkt-slug> --apply (ausfuehren)
|
||||
* tsx scripts/sponsorship-bootstrap.ts (Probelauf)
|
||||
* tsx scripts/sponsorship-bootstrap.ts --apply (ausfuehren)
|
||||
*/
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { syncOfferStripePrice } from "@/lib/sponsorship-subscription/stripe-prices";
|
||||
import { loadHoneyCandidates } from "@/lib/sponsorship/honey-candidates";
|
||||
import { honeyLabel, pickHoneyProduct } from "@/lib/sponsorship/honey-selection";
|
||||
|
||||
interface AboTemplate {
|
||||
slug: string;
|
||||
@@ -70,30 +77,12 @@ const ABO_TEMPLATES: AboTemplate[] = [
|
||||
},
|
||||
];
|
||||
|
||||
function arg(name: string): string | undefined {
|
||||
const hit = process.argv.find((value) => value.startsWith(`--${name}=`));
|
||||
return hit ? hit.slice(name.length + 3) : undefined;
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const apply = process.argv.includes("--apply");
|
||||
const honeySlug = arg("honey");
|
||||
if (!honeySlug) throw new Error("--honey=<produkt-slug> fehlt.");
|
||||
|
||||
const honey = await prisma.product.findUnique({ where: { slug: honeySlug }, select: { id: true, name: true, category: true, isActive: true } });
|
||||
if (!honey || honey.category !== "HONIG" || !honey.isActive) {
|
||||
throw new Error(`Honigprodukt "${honeySlug}" nicht gefunden, nicht HONIG oder nicht aktiv.`);
|
||||
}
|
||||
console.log(`${apply ? "AUSFUEHREN" : "PROBELAUF"} — Honig: ${honey.name}`);
|
||||
|
||||
const physical = await prisma.sponsorshipOffer.findMany({
|
||||
where: { kind: "EINMALIG", isPhysical: true, honeyProductId: null },
|
||||
select: { id: true, slug: true },
|
||||
});
|
||||
for (const offer of physical) {
|
||||
console.log(` Paket ${offer.slug}: Honig verknuepfen`);
|
||||
if (apply) await prisma.sponsorshipOffer.update({ where: { id: offer.id }, data: { honeyProductId: honey.id } });
|
||||
}
|
||||
const honey = pickHoneyProduct(await loadHoneyCandidates(), 1);
|
||||
console.log(
|
||||
`${apply ? "AUSFUEHREN" : "PROBELAUF"} — Honig automatisch, derzeit: ${honey ? honeyLabel(honey) : "kein nicht-cremiger Honig mit freiem Bestand"}`
|
||||
);
|
||||
|
||||
for (const template of ABO_TEMPLATES) {
|
||||
const existing = await prisma.sponsorshipOffer.findUnique({ where: { slug: template.slug }, select: { id: true, stripePriceId: true } });
|
||||
@@ -110,7 +99,6 @@ async function main(): Promise<void> {
|
||||
kind: "ABO",
|
||||
isActive: false,
|
||||
isPhysical: true,
|
||||
honeyProductId: honey.id,
|
||||
medalTier: "ABO",
|
||||
},
|
||||
});
|
||||
@@ -119,7 +107,7 @@ async function main(): Promise<void> {
|
||||
|
||||
const offers = await prisma.sponsorshipOffer.findMany({
|
||||
orderBy: { sortOrder: "asc" },
|
||||
select: { slug: true, kind: true, isActive: true, priceCents: true, honeyProductId: true, stripePriceId: true, productId: true },
|
||||
select: { slug: true, kind: true, isActive: true, priceCents: true, honeyJars: true, stripePriceId: true, productId: true },
|
||||
});
|
||||
console.table(offers);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user