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.4 kB Ruw bestand
-- Promotieteam: de vrienden die vrijwillig mond-tot-mondreclame maken.
--
-- Eigen database, met opzet los van de app. Het schema van de app wordt bij elke wijziging
-- opnieuw aangemaakt en zijn gegevens zijn wegwerpbaar (zie db/setup.js); deze lijst is dat
-- niet. Daarom staat er hier ook nergens een `drop table`: dit bestand mag zo vaak uitgevoerd
-- worden als je wilt en raakt nooit een bestaande rij aan.
--
-- Er is geen quotum en geen controle. Dit schema telt daarom niets: geen aanbrengcodes, geen
-- verwijzing naar de gebruikers van de app, geen score per persoon. Zou zoiets er staan, dan
-- gaat iemand ernaar kijken, en dan is het alsnog een quotum. Het beantwoordt één vraag:
-- wie doet er mee, en hoe bereik ik diegene als het feest er is.

create table if not exists promoters (
  id        bigint primary key generated always as identity,
  name      text not null check (length(trim(name)) between 1 and 80),
  -- Contact: e-mail, telefoon, of allebei. Minstens één van de twee, want zonder contact kun
  -- je iemand niet uitnodigen en is de rij een naam zonder feest.
  email     text check (email is null or (email = lower(email) and email like '%@%')),
  phone     text check (phone is null or length(trim(phone)) > 0),
  joined_on date not null default current_date,
  -- Gestopt. De rij blijft staan: "wie was er vorig jaar bij" blijft zo te beantwoorden, en
  -- wie weer meedoet is één klik terug. Echt weg wil hebben kan ook — dan wordt de rij gewist.
  left_on   date,
  note      text not null default '',
  check (email is not null or phone is not null),
  check (left_on is null or left_on >= joined_on)
);

create index if not exists promoters_name on promoters (lower(name));

/*
 * Vanaf hier de post. Deze database blijft staan (anders dan die van de app), dus wat er later
 * bij komt, komt er met `alter ... if not exists` bij: dit bestand blijft één keer draaien én
 * herhaalbaar, zonder een migratiestapel en zonder ooit een naam te wissen.
 */
alter table promoters add column if not exists welcomed_at timestamptz;   -- wanneer de welkomstmail eruit ging
/*
 * Gezet als het vertrek van de afmeldknop in de mail kwam, en niet van de knop Gestopt hier. Dat
 * onderscheid is nodig omdat Postmark op zijn afmeldpagina meteen een "toch weer aanmelden" biedt
 * voor wie zich vergist: verdwijnt iemand daardoor weer van hun afmeldlijst, dan hoort hij hier
 * ook terug te komen. Wie jij met de hand op Gestopt zet, staat nooit op die lijst en wordt door
 * die terugweg dus met rust gelaten.
 */
alter table promoters add column if not exists unsubscribed_at timestamptz;
/*
 * Hier stond een `unsub_token` voor een eigen afmeldlink. Die is er niet meer: bij een
 * broadcast-stream doet Postmark het afmelden zelf en is dat niet uit te zetten zonder hun
 * toestemming voor "custom unsubscribe handling". Wie afmeldt komt op hun onderdrukkingslijst, en
 * server/promotie.js haalt die op en zet diezelfde persoon hier op `left_on`. Eén afmeldweg, en
 * de kolom hoort dan ook weg te zijn in plaats van ongebruikt te blijven staan.
 */
alter table promoters drop column if exists unsub_token;

/*
 * De vaste tekst van de welkomstmail: één rij, te bewerken op /promotieteam. Hier en niet in de
 * repository, want de repository is openbaar en dit zijn jouw woorden aan je vrienden — en omdat
 * schaven aan een zin geen uitrol hoort te kosten. `{naam}` wordt de aanhef.
 */
create table if not exists welcome (
  singleton boolean primary key default true check (singleton),
  subject   text not null default 'Welkom bij het promotieteam',
  body      text not null default
'Hoi {naam},

Fijn dat je meedoet. Je hoeft niets bij te houden en er is geen quotum — vertel het gewoon door
aan wie je denkt dat er iets aan heeft.

Als dank geef ik een feestje. Je hoort van me wanneer.

Groet,
Bram'
);
insert into welcome default values on conflict do nothing;

/*
 * Wat er naar de groep is gegaan. Geen prestatiemeting van wie dan ook — het is het doorslagvel:
 * wat schreef ik, wanneer, aan hoeveel mensen, en bij wie liep het mis.
 */
create table if not exists mailings (
  id      bigint primary key generated always as identity,
  subject text        not null,
  body    text        not null,
  sent_at timestamptz not null default now(),
  aantal  int         not null default 0,   -- hoeveel er daadwerkelijk uitgingen
  mislukt text        not null default ''   -- adressen die Postmark weigerde, met de reden
);