Some checks are pending
Veza CI / Backend (Go) (push) Waiting to run
Veza CI / Frontend (Web) (push) Waiting to run
Veza CI / Rust (Stream Server) (push) Waiting to run
Veza CI / Notify on failure (push) Blocked by required conditions
E2E Playwright / e2e (full) (push) Waiting to run
Security Scan / Secret Scanning (gitleaks) (push) Waiting to run
The soft-launch report doc (SOFT_LAUNCH_BETA_2026.md) had the
narrative — cohort table, email body inline, monitoring list,
acceptance gate. But the operational pieces were notes-to-self :
"add migration if missing", "Typeform to-do", "schema TBD". The
operator was supposed to assemble them on the day, which on a soft-
launch day is the worst possible time.
Added the missing 6 pieces so the day-of work is "tick boxes",
not "build the tooling" :
* migrations/990_beta_invites.sql — schema with code (16-char
base32-ish), email, cohort label, used_at, expires_at + 30d
default, sent_by FK with ON DELETE SET NULL. Three indexes :
unique on code (signup-path lookup), cohort (post-launch
attribution report), partial expires_at WHERE used_at IS NULL
(cleanup cron).
* scripts/soft-launch/validate-cohort.sh — sanity check on the
operator's CSV : header form, malformed emails, duplicates,
cohort distribution (≥50 total / ≥5 creators / ≥3 distinct
labels), optional collision check against existing users.
Exit codes 0 / 1 (block) / 2 (warn-but-proceed). Hard checks
block, soft checks let the operator override with FORCE=1.
* scripts/soft-launch/send-invitations.sh — split-phase :
step 1 (default) inserts beta_invites rows + renders one .eml
per recipient under scripts/soft-launch/out-<date>/
step 2 (SEND=1) dispatches via $SEND_CMD (msmtp by default)
so the operator can review the rendered emls before sending
100 emails. Per-recipient transactional INSERT so a partial
failure doesn't poison the table. Failed inserts logged with
the offending email so the operator can rerun on the subset.
* templates/email/beta_invite.eml.template — proper MIME multipart
(text + HTML) eml ready for sendmail-compatible piping. French
copy aligned with the éthique brand (no FOMO, no urgency
manipulation, no "limited spots" framing).
* scripts/soft-launch/monitor-checks.sh — polls the 6 acceptance-
gate signals defined in SOFT_LAUNCH_BETA_2026.md §"Acceptance
gate" : testers signed up, Sentry P1 events, status page,
synthetic parcours, k6 nightly age, HIGH issues. Each gate
independently emits ✅ / 🔴 / ⚪ (last for "couldn't check").
Verdict on stdout. LOOP=1 keeps polling every CHECK_INTERVAL
seconds. Designed for cron + tmux, not for an interactive UI.
* docs/SOFT_LAUNCH_BETA_2026_CHECKLIST.md — pre-flight gate that
must reach 100% green before the first invitation goes out.
T-72h section (database, cohort, email infra, redemption path,
monitoring, comms), D-day section (last-hour, send, hour-1,
every-4h), 18:00 UTC decision call section. Linked back to the
bigger SOFT_LAUNCH_BETA_2026.md so the operator can navigate
between the "what" (report) and the "how / has-everything-
been-checked" (this checklist) without losing context.
What still requires the operator on the day :
- Build the cohort CSV (curate emails from real sources)
- Create the Typeform feedback form ; paste its URL into the
eml template once known
- Configure msmtp / sendmail ($SEND_CMD)
- Press the send button
- Show up at 18:00 UTC for the decision call
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
92 lines
4.2 KiB
Text
92 lines
4.2 KiB
Text
To: {{TO_ADDR}}
|
|
From: Veza <{{FROM_ADDR}}>
|
|
Subject: {{SUBJECT}}
|
|
MIME-Version: 1.0
|
|
Content-Type: multipart/alternative; boundary="--veza-beta-boundary"
|
|
|
|
----veza-beta-boundary
|
|
Content-Type: text/plain; charset="UTF-8"
|
|
Content-Transfer-Encoding: 7bit
|
|
|
|
Bonjour,
|
|
|
|
Vous êtes invité·e à rejoindre la bêta privée de Veza —
|
|
une plateforme de streaming musical éthique faite pour les
|
|
créateur·ices et les auditeur·ices, sans algorithme de
|
|
recommandation comportementale, sans gamification, sans dark
|
|
patterns.
|
|
|
|
Votre code d'invitation : {{INVITE_CODE}}
|
|
|
|
Pour vous inscrire :
|
|
{{INVITE_URL}}
|
|
|
|
Le code expire dans 30 jours.
|
|
|
|
Pendant la bêta, l'idée est simple : utilisez Veza comme vous
|
|
utiliseriez n'importe quelle plateforme musicale. Uploadez,
|
|
écoutez, partagez, achetez. Quand quelque chose vous frustre
|
|
ou vous étonne — en bien comme en mal — dites-le. Le canal
|
|
de retour vous sera communiqué après l'inscription.
|
|
|
|
Cohorte : {{COHORT}}
|
|
(C'est juste un tag interne pour qu'on regroupe les retours
|
|
par contexte d'usage. Ça n'affecte ni votre expérience ni vos
|
|
permissions.)
|
|
|
|
À très vite,
|
|
L'équipe Veza
|
|
|
|
|
|
--
|
|
Si vous n'avez pas demandé cette invitation, ignorez ce
|
|
message. Le code expirera automatiquement après 30 jours.
|
|
|
|
----veza-beta-boundary
|
|
Content-Type: text/html; charset="UTF-8"
|
|
Content-Transfer-Encoding: 7bit
|
|
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Invitation à la bêta Veza</title>
|
|
</head>
|
|
<body style="font-family: Georgia, 'Times New Roman', serif; line-height: 1.6; color: #1a1a1e; margin: 0; padding: 0; background-color: #f8f7f4;">
|
|
<div style="max-width: 600px; margin: 20px auto; padding: 30px; background-color: #ffffff; border: 1px solid #e8e6e0;">
|
|
<h1 style="font-weight: 400; color: #1a1a1e; margin-top: 0; font-size: 28px;">Bienvenue dans la bêta Veza.</h1>
|
|
<p>Bonjour,</p>
|
|
<p>Vous êtes invité·e à rejoindre la <strong>bêta privée</strong> de Veza — une plateforme de streaming musical éthique faite pour les créateur·ices et les auditeur·ices, sans algorithme de recommandation comportementale, sans gamification, sans dark patterns.</p>
|
|
|
|
<div style="text-align: center; margin: 35px 0;">
|
|
<a href="{{INVITE_URL}}" style="background-color: #1a1a1e; color: #f8f7f4; padding: 14px 32px; text-decoration: none; display: inline-block; font-weight: 400; letter-spacing: 0.05em;">
|
|
Activer mon invitation
|
|
</a>
|
|
</div>
|
|
|
|
<p style="color: #555; font-size: 14px;">Ou collez ce lien dans votre navigateur :</p>
|
|
<p style="word-break: break-all; color: #888; background-color: #f8f7f4; padding: 10px; font-family: 'Courier New', monospace; font-size: 12px; border-left: 2px solid #d4a574;">{{INVITE_URL}}</p>
|
|
|
|
<p style="color: #555; font-size: 14px; margin-top: 25px;">Code d'invitation :</p>
|
|
<p style="font-family: 'Courier New', monospace; font-size: 18px; letter-spacing: 0.1em; background-color: #f8f7f4; padding: 12px; text-align: center; color: #1a1a1e;">{{INVITE_CODE}}</p>
|
|
|
|
<hr style="border: none; border-top: 1px solid #e8e6e0; margin: 30px 0;">
|
|
|
|
<p style="font-size: 14px; color: #555;">Pendant la bêta, l'idée est simple : utilisez Veza comme vous utiliseriez n'importe quelle plateforme musicale. Uploadez, écoutez, partagez, achetez. Quand quelque chose vous frustre ou vous étonne — en bien comme en mal — dites-le. Le canal de retour vous sera communiqué après l'inscription.</p>
|
|
|
|
<p style="font-size: 13px; color: #888; margin-top: 25px;">Cohorte : <strong>{{COHORT}}</strong> — c'est juste un tag interne pour qu'on regroupe les retours par contexte d'usage.</p>
|
|
|
|
<p style="margin-top: 30px; color: #888; font-size: 12px;">
|
|
Le code expire dans 30 jours. Si vous n'avez pas demandé cette invitation, ignorez ce message.
|
|
</p>
|
|
|
|
<hr style="border: none; border-top: 1px solid #e8e6e0; margin: 25px 0;">
|
|
<p style="color: #aaa; font-size: 11px; text-align: center; font-family: 'Courier New', monospace; letter-spacing: 0.1em;">
|
|
VEZA · v2.0.0 BETA · {{FRONTEND_URL}}
|
|
</p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
|
|
----veza-beta-boundary--
|