Een dating-app op basis van brieven, niet van gezichten!

main

Deze repository wordt als momentopname gepubliceerd: een clone bevat de volledige inhoud, maar geen commitgeschiedenis.

4.0 kB Ruw bestand
/*
 * Voert db/schema.sql en db/seed.sql uit tegen DATABASE_URL.
 * Maakt de database aan als die nog niet bestaat.
 *
 *   npm run db:setup            # schema + seed
 *   npm run db:setup -- --no-seed
 *
 * Twee van de seed-accounts — de bouwer en het account voor de beoordelaar van de app-store — krijgen
 * hun échte adres en wachtwoord uit de omgeving (SEED_BRAM_* en SEED_REVIEW_*). Staan die er niet, dan
 * blijven ze wat ze in de seed zijn: @voorbeeld.nl met het gewone seed-wachtwoord. Zo staat er geen
 * enkel bruikbaar inloggegeven in deze repository, die openbaar is, terwijl een echte installatie toch
 * met één opdracht klaarstaat voor een review.
 */
import { readFile, readdir } from "node:fs/promises";
import { fileURLToPath } from "node:url";
import path from "node:path";
import pg from "pg";

const here = path.dirname(fileURLToPath(import.meta.url));
const url = new URL(process.env.DATABASE_URL ?? "postgres://postgres@localhost:5432/liefdesbrieven");
const dbName = url.pathname.slice(1);
const withSeed = !process.argv.includes("--no-seed");

/* 1. Database aanmaken indien nodig (via de standaard 'postgres'-database) */
{
  const admin = new pg.Client({ connectionString: new URL("/postgres", url).toString() });
  await admin.connect();
  const { rowCount } = await admin.query("select 1 from pg_database where datname = $1", [dbName]);
  if (rowCount === 0) {
    await admin.query(`create database "${dbName.replace(/"/g, '""')}"`);
    console.log(`database ${dbName} aangemaakt`);
  }
  await admin.end();
}

/* 2. Schema en seed uitvoeren */
{
  const client = new pg.Client({ connectionString: url.toString() });
  await client.connect();
  const files = ["schema.sql", ...(withSeed ? ["seed.sql"] : [])];
  for (const f of files) {
    await client.query(await readFile(path.join(here, f), "utf8"));
    console.log(`${f} uitgevoerd`);
  }

  /*
   * Een bestáánde database verandert via db/migrations/ (npm run db:migrate); dit script is er
   * alleen nog voor een verse. schema.sql heeft elke migratie al verwerkt, dus een verse opbouw
   * registreert ze meteen als uitgevoerd — anders zou db:migrate hierna toevoegen wat er al staat.
   */
  let migraties = [];
  try {
    migraties = (await readdir(path.join(here, "migrations"))).filter((f) => f.endsWith(".sql")).sort();
  } catch (err) {
    if (err.code !== "ENOENT") throw err;
  }
  for (const f of migraties) await client.query("insert into schema_migrations (filename) values ($1)", [f]);
  if (migraties.length)
    console.log(`${migraties.length} migratie(s) als uitgevoerd geregistreerd — schema.sql is al de nieuwste stand`);

  /*
   * De echte inloggegevens erover, als de omgeving ze aandraagt. Per veld: wie alleen een wachtwoord
   * zet houdt het adres uit de seed, en andersom. Zwijgt de omgeving, dan gebeurt er niets — dat is
   * het gewone geval op een ontwikkelmachine.
   */
  if (withSeed) {
    const { hashPassword } = await import("../server/auth.js");
    const echte = [
      { naam: "Bram", email: process.env.SEED_BRAM_EMAIL, wachtwoord: process.env.SEED_BRAM_PASSWORD },
      { naam: "Nina", email: process.env.SEED_REVIEW_EMAIL, wachtwoord: process.env.SEED_REVIEW_PASSWORD },
    ];
    for (const p of echte) {
      if (!p.email && !p.wachtwoord) continue;
      const waarden = [p.naam];
      const zetten = [];
      if (p.email) {
        waarden.push(p.email.trim().toLowerCase());
        zetten.push(`email = $${waarden.length}`);
      }
      if (p.wachtwoord) {
        waarden.push(await hashPassword(p.wachtwoord));
        zetten.push(`password_hash = $${waarden.length}`);
      }
      const { rowCount } = await client.query(`update users set ${zetten.join(", ")} where name = $1`, waarden);
      /* Het wachtwoord zelf komt hier niet in beeld, en het adres alleen als het gezet is. */
      console.log(rowCount
        ? `${p.naam}: eigen inloggegevens gezet (${zetten.length === 2 ? "adres en wachtwoord" : p.email ? "adres" : "wachtwoord"})`
        : `${p.naam}: niet gevonden in de seed — inloggegevens niet gezet`);
    }
  }

  await client.end();
}