Zum Inhalt springen

VimineServer

Als Markdown anzeigen
import { VimineServer } from '@vimine/sdk/server';
const vimineServer = new VimineServer({ clientId: 'vmc_…', clientSecret: process.env.VIMINE_SECRET });

Für die eigenen Systeme des Vereins: ein vertraulicher Client, der sich mit client_credentials authentifiziert, Ausweisstatus liest und seine Sandbox steuert. Node ≥ 18. Das Secret darf nie in einen Browser gelangen.

Option Typ Standard
clientId string — Pflicht
clientSecret string — Pflicht; vms_… oder vms_test_…
scopes Scope[] alle registrierten eine anzufordernde Teilmenge
apiUrl string https://api.vimine.network
fetch typeof fetch globalThis.fetch

Ein Client-Access-Token (client_credentials, HTTP Basic), zwischengespeichert bis 30 Sekunden vor seinem Ablauf (1 Stunde); eine einzige Anfrage, auch bei gleichzeitigen Aufrufen.

Ein authentifizierter Aufruf mit Authorization: Bearer; JSON hin und zurück; Fehler als VimineError. Ein 401 (rotierte oder widerrufene Zugangsdaten) wird einmal mit einem frischen Token wiederholt.

Status einer Mitgliedschaft des Vereins, ohne personenbezogene Daten (memberships:read):

const s = await vimineServer.memberships.status('membership-uuid');
// { id, status: 'active', verdict: 'valid', valid_until: '2027-03-31T22:59:59.000Z', membership_type: { cod: 'ORD' } }

Legt ein Vimine-Konto für eine Person an (identity:signup): Sie erhält die E-Mail, um die Adresse zu bestätigen und ein Passwort zu wählen. Antwortet immer { status: 'accepted' } — ob die Adresse schon ein Konto hatte, wird Ihnen nicht verraten (ihr Inhaber erfährt es, per E-Mail). opts.idempotencyKey (wird erzeugt, wenn er fehlt).

await vimineServer.signup({ email: 'mario.rossi@example.org', first_name: 'Mario', last_name: 'Rossi', phone: '+39 …' });

Stellt einen Beitrittsantrag für eine Person (enroll:write): Eine neue Adresse erhält ein Konto und einen ausstehenden Antrag; der Inhaber eines bestehenden Kontos erhält stattdessen einen Bestätigungslink (nichts wird geschrieben, bis er ihn verwendet). accept_statuto (die geltende Version) ist Pflicht; ebenso privacy_notice, wenn der Verein Datenschutzhinweise für seine Mitglieder veröffentlicht (association(slug).privacy_notice): Die Person liest sie auf Ihrer Website, und Sie übergeben die gezeigte Version. Siehe Server-Integrationen.

Die Person wird über codicefiscale oder über dob + birthplace + birth_country identifiziert — nie über keins von beidem (422, ein Eintrag required für jede fehlende Geburtsangabe). Eine Steuernummer, die nicht zu den Geburtsdaten passt, ist ein Eintrag codicefiscale_mismatch in err.errors, mit mismatches, hints und confirmable: Ist confirmable gleich true und bestätigt die Person, wiederholen Sie mit codicefiscale_confirmed: true. address (MemberAddress), wenn der Verein die Adresse seiner Mitglieder erfasst (aps.member_address). Siehe Mitglieder ohne Steuernummer.

// mit einer Steuernummer
await vimineServer.enroll({ ...person, codicefiscale: 'RSSMRA80A01H501U', accept_statuto: { version: 3 }, privacy_notice: { version: 2 } }, { idempotencyKey: 'order-42' });
// ohne: Geburtsdatum, Geburtsort und Geburtsland
await vimineServer.enroll({ ...person, dob: '1985-03-10', birthplace: 'Lyon', birth_country: 'FR', accept_statuto: { version: 3 }, privacy_notice: { version: 2 } });

Erfasst einen Check-in am Einlass aus dem vom QR-Code gelesenen Token (checkins:write). Ein Ausweis antwortet { kind: 'card', verdict, status, membership_id, valid_until, valid_from, identity_check, checked_in_at } — identity_check: 'pending' ist ein Hinweis für die Person am Einlass, nicht Teil von verdict, und schränkt nichts ein (Anleitung); der QR-Code einer Veranstaltungsanmeldung antwortet { kind: 'registration', verdict, registration_id, event, first, membership_verdict, … } (siehe Veranstaltungen und Anmeldungen).

events.list(params?) · events.get(slug) — die veröffentlichten Veranstaltungen des Vereins, einschließlich derer nur für Mitglieder (jedes Client-Token).

registrations.listForEvent(slug, { status?, limit?, cursor? }) die Anmeldungen einer Veranstaltung: ID, Status, Art, Mitgliedschaft, Check-in — keine personenbezogenen Daten (registrations:read, Tarife mit API-Listen)
registrations.guest(slug, { email, first_name, last_name, registration_type, note? }, opts?) meldet einen Gast ohne Konto zu einer öffentlichen Veranstaltung an; immer { status: 'accepted' }; Idempotency-Key wird erzeugt (siehe Gäste)

Die Mitgliedschaften des Vereins (memberships:read, Tarife mit Listen): { items: [{ id, status, verdict, membership_type, issued_at, valid_until, updated_at }], next_cursor }; params: status, updated_since, limit, cursor.

Nur für Test-Clients: die synthetischen Mitglieder der Sandbox und das Zurücksetzen (neues gemeinsames Passwort, einmal zurückgegeben). Ein Production-Client erhält 403.

Die öffentlichen Endpunkte ohne Zugangsdaten: siehe publicApi.

express.js
import express from 'express';
import { VimineServer, VimineError } from '@vimine/sdk/server';
const vimineServer = new VimineServer({ clientId: process.env.VIMINE_CLIENT_ID, clientSecret: process.env.VIMINE_SECRET });
const app = express();
app.get('/cards/:id/status', async (req, res) => {
try {
const { status, verdict, valid_until } = await vimineServer.memberships.status(req.params.id);
res.json({ status, verdict, valid_until });
} catch (err) {
if (err instanceof VimineError && err.code === 'not_found') return res.status(404).end();
throw err;
}
});