16fb29cc12
Ingredienser: fyllde luckan från 101 till 362 för da/de/es/fi/fr/it/nb/nl/pl/pt (engelska hade redan alla 362). Nu 3982 översättningar, 11 språk kompletta – en spansk/tysk/fransk användare ser ingrediensnamn på sitt språk, inte svenska. Författat av språkexperter per språk, verifierat mot 362-listan + kvalitetskoll. Recept: 407 recept har 0 översättningar (svensk källa visas). Lade till två körbara skript för AI-pipelinen (kräver din Gemini-nyckel i workern): - scripts/translate-recipes.ts [språk|all] – köar TRANSLATE_RECIPE för alla publicerade recept × språk, idempotent (hoppar redan gjorda). - scripts/publish-translations.ts [språk|all] – publicerar de utkast som klarat den inbyggda verifieringen (numbersPreserved/stegantal/confidence); övriga stannar som utkast för granskning. Verifierat mot testdatabas: ingredient_translations 3982 rader/11 språk kompletta; enqueue köar 405 jobb; processor skapar draft_ai+ok; publish publicerar; steg- översättningar följer med och serveras.
51 lines
1.8 KiB
TypeScript
51 lines
1.8 KiB
TypeScript
/**
|
||
* Publicera AI-receptöversättningar som klarat den inbyggda verifieringen
|
||
* (verification.ok = true). Endast PUBLICERADE översättningar visas för
|
||
* användare. Utkast som föll på verifieringen lämnas kvar för manuell
|
||
* granskning i admin (så inget felöversatt går live automatiskt).
|
||
*
|
||
* Kör EFTER att translate-recipes.ts-kön har tömts:
|
||
* pnpm --filter @app/worker exec tsx scripts/publish-translations.ts es
|
||
* pnpm --filter @app/worker exec tsx scripts/publish-translations.ts all
|
||
*
|
||
* Kräver DATABASE_URL i miljön.
|
||
*/
|
||
import { and, eq, sql } from "drizzle-orm";
|
||
import { createDatabase, schema } from "@app/database";
|
||
|
||
async function main() {
|
||
if (!process.env.DATABASE_URL) throw new Error("Sätt DATABASE_URL.");
|
||
const arg = (process.argv[2] ?? "all").toLowerCase();
|
||
const { db, pool } = createDatabase(process.env.DATABASE_URL);
|
||
|
||
const cond = [
|
||
eq(schema.recipeTranslations.status, "draft_ai"),
|
||
sql`${schema.recipeTranslations.verification}->>'ok' = 'true'`,
|
||
];
|
||
if (arg !== "all") cond.push(eq(schema.recipeTranslations.languageTag, arg));
|
||
|
||
const published = await db
|
||
.update(schema.recipeTranslations)
|
||
.set({ status: "published", updatedAt: new Date() })
|
||
.where(and(...cond))
|
||
.returning({ id: schema.recipeTranslations.id });
|
||
|
||
const [remaining] = await db
|
||
.select({ n: sql<number>`count(*)::int` })
|
||
.from(schema.recipeTranslations)
|
||
.where(eq(schema.recipeTranslations.status, "draft_ai"));
|
||
|
||
console.log(`Publicerade ${published.length} verifierade översättningar (${arg}).`);
|
||
console.log(
|
||
`Kvar som utkast (föll på verifieringen – granska i admin vid behov): ${remaining?.n ?? 0}.`,
|
||
);
|
||
await pool.end();
|
||
}
|
||
main().then(
|
||
() => process.exit(0),
|
||
(e) => {
|
||
console.error(e);
|
||
process.exit(1);
|
||
},
|
||
);
|