Salta ai contenuti

VimineServer

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

Per i sistemi dell’associazione: un client riservato che si autentica con client_credentials, legge lo stato delle tessere e guida la sua sandbox. Node ≥ 18. Il secret non deve mai raggiungere un browser.

Opzione Tipo Default
clientId string — obbligatorio
clientSecret string — obbligatorio; vms_… o vms_test_…
scopes Scope[] tutti quelli registrati un sottoinsieme da chiedere
apiUrl string https://api.vimine.network
fetch typeof fetch globalThis.fetch

Un access token del client (client_credentials, HTTP Basic), messo in cache fino a 30 secondi prima della scadenza (1 ora); una sola richiesta anche con chiamate concorrenti.

Una chiamata autenticata con Authorization: Bearer; JSON in entrata e in uscita; errori come VimineError. Una risposta 401 (credenziali ruotate o revocate) viene ritentata una volta con un token nuovo.

Stato di una tessera dell’associazione, senza dati personali (memberships:read):

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

Crea un account Vimine per una persona (identity:signup): riceverà la mail per confermare l’indirizzo e scegliere la password. Risponde sempre { status: 'accepted' } — se l’indirizzo aveva già un account non ti viene detto (lo sa il titolare, per posta). opts.idempotencyKey (generata se assente).

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

Invia una richiesta di tesseramento per una persona (enroll:write): un indirizzo nuovo ottiene account e richiesta in attesa; il titolare di un account esistente riceve invece un link di conferma (non viene scritto nulla finché non lo usa). accept_statuto (versione in vigore) è obbligatorio; privacy_notice lo è quando l’associazione pubblica un’informativa ai soci (association(slug).privacy_notice): la persona la legge sul tuo sito e tu passi la versione mostrata. Vedi Integrazioni server.

La persona si identifica con codicefiscale oppure con dob + birthplace + birth_country — mai nessuno dei due (422, voce required su ogni dato mancante). Un codice che non concorda con i dati è una voce codicefiscale_mismatch in err.errors, con mismatches, hints e confirmable: se confirmable è true e la persona conferma, ripeti con codicefiscale_confirmed: true. address (MemberAddress) quando l’associazione raccoglie l’indirizzo dei soci (aps.member_address). Vedi Soci senza codice fiscale.

// con un codice fiscale
await vimineServer.enroll({ ...persona, codicefiscale: 'RSSMRA80A01H501U', accept_statuto: { version: 3 }, privacy_notice: { version: 2 } }, { idempotencyKey: 'ordine-42' });
// senza: data, luogo e Stato di nascita
await vimineServer.enroll({ ...persona, dob: '1985-03-10', birthplace: 'Lyon', birth_country: 'FR', accept_statuto: { version: 3 }, privacy_notice: { version: 2 } });

Registra un accesso dal token letto sul QR (checkins:write). Una tessera risponde { kind: 'card', verdict, status, membership_id, valid_until, valid_from, identity_check, checked_in_at } — identity_check: 'pending' è una nota da mostrare a chi è all’ingresso, non fa parte di verdict e non limita nulla (guida); il QR di un’iscrizione a un evento risponde { kind: 'registration', verdict, registration_id, event, first, membership_verdict, … } (vedi Eventi e iscrizioni).

events.list(params?) · events.get(slug) — gli eventi pubblicati dell’associazione, compresi quelli riservati ai soci (qualsiasi token del client).

registrations.listForEvent(slug, { status?, limit?, cursor? }) le iscrizioni di un evento: id, stato, tipo, tessera, ingresso — senza dati personali (registrations:read, piani con gli elenchi via API)
registrations.guest(slug, { email, first_name, last_name, registration_type, note? }, opts?) iscrive un ospite senza account a un evento pubblico; sempre { status: 'accepted' }; Idempotency-Key generata (vedi ospiti)

Elenco delle tessere dell’associazione (memberships:read, piani con gli elenchi): { items: [{ id, status, verdict, membership_type, issued_at, valid_until, updated_at }], next_cursor }; params: status, updated_since, limit, cursor.

Solo per i client di test: i soci sintetici della sandbox e il reset (nuova password condivisa, restituita una volta). Un client di produzione riceve 403.

Gli endpoint pubblici, senza credenziali: vedi 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('/tessere/:id/stato', 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;
}
});