Files
PleinR/drizzle/meta/0019_snapshot.json
Claude 8d4443a1a1 Boîte mail de l'association : trois transports, une file d'attente
Le site savait composer de beaux messages et ne savait pas les envoyer :
`email-client.ts` ne proposait que la copie ou le téléchargement d'un
brouillon Outlook, complété à la main. `/backend/boite-mail` branche
désormais la boîte de l'association, sur le modèle exact de l'écran
Réseaux sociaux — secrets chiffrés, jamais renvoyés au navigateur, champ
laissé vide qui conserve la valeur enregistrée, contrôle de santé qui ne
lève jamais.

Trois transports, un seul actif à la fois, désigné par l'administrateur —
pas de cascade automatique : si Google se bloque, la bascule se voit.

- **Google** passe par l'API Gmail plutôt que par SMTP avec XOAUTH2 :
  celui-ci exigerait `https://mail.google.com/`, portée *restreinte* et
  donc audit de sécurité, là où `gmail.send` est simplement *sensible*.
- **Microsoft** passe par Graph : l'authentification basique SMTP est
  désactivée depuis 2024, y compris sur outlook.com et hotmail.com.
- **SMTP** couvre le reste via `nodemailer`, seule dépendance ajoutée.

`from_address` est **lu chez le fournisseur** et non saisi : Gmail expédie
comme l'utilisateur authentifié, Graph comme la boîte. Une adresse d'un
autre domaine ferait tomber SPF et DKIM.

La file `mail_messages` porte un destinataire unique par ligne — la
confidentialité d'une diffusion est structurelle, aucune copie partagée
n'est possible. Elle est vidée par la boucle de fond, avec réclamation en
`FOR UPDATE SKIP LOCKED`, réessais espacés et reprise des verrous laissés
par un conteneur arrêté en plein envoi.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QsLjRAnuLwivqxCbM4WeP
2026-09-14 16:00:11 +00:00

2073 lines
52 KiB
JSON

{
"id": "d119f136-adc6-44a1-a4dc-a77bafa56690",
"prevId": "e80a2f6a-ea01-4d00-ab3d-7472b909ff82",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.activity_log": {
"name": "activity_log",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"dot": {
"name": "dot",
"type": "varchar(16)",
"primaryKey": false,
"notNull": true,
"default": "'#2C6FB3'"
},
"message": {
"name": "message",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.categories": {
"name": "categories",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"slug": {
"name": "slug",
"type": "varchar(80)",
"primaryKey": false,
"notNull": true
},
"label": {
"name": "label",
"type": "varchar(120)",
"primaryKey": false,
"notNull": true
},
"accent": {
"name": "accent",
"type": "varchar(16)",
"primaryKey": false,
"notNull": true,
"default": "'#E0A63C'"
},
"tint": {
"name": "tint",
"type": "varchar(16)",
"primaryKey": false,
"notNull": true,
"default": "'#f6efdc'"
},
"sort": {
"name": "sort",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"categories_slug_unique": {
"name": "categories_slug_unique",
"nullsNotDistinct": false,
"columns": [
"slug"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.contact_messages": {
"name": "contact_messages",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"subject": {
"name": "subject",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"message": {
"name": "message",
"type": "text",
"primaryKey": false,
"notNull": true
},
"status": {
"name": "status",
"type": "contact_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'new'"
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.image_consents": {
"name": "image_consents",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"member_id": {
"name": "member_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"decision": {
"name": "decision",
"type": "varchar(20)",
"primaryKey": false,
"notNull": true
},
"scopes": {
"name": "scopes",
"type": "text",
"primaryKey": false,
"notNull": false
},
"signatory_name": {
"name": "signatory_name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"signature_png": {
"name": "signature_png",
"type": "text",
"primaryKey": false,
"notNull": false
},
"consent_version": {
"name": "consent_version",
"type": "varchar(40)",
"primaryKey": false,
"notNull": true
},
"ip": {
"name": "ip",
"type": "varchar(120)",
"primaryKey": false,
"notNull": false
},
"user_agent": {
"name": "user_agent",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"image_consents_member_id_members_id_fk": {
"name": "image_consents_member_id_members_id_fk",
"tableFrom": "image_consents",
"tableTo": "members",
"columnsFrom": [
"member_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.information_reads": {
"name": "information_reads",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"information_id": {
"name": "information_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"read_at": {
"name": "read_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"information_reads_user_info_idx": {
"name": "information_reads_user_info_idx",
"columns": [
{
"expression": "user_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "information_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"information_reads_information_id_informations_id_fk": {
"name": "information_reads_information_id_informations_id_fk",
"tableFrom": "information_reads",
"tableTo": "informations",
"columnsFrom": [
"information_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"information_reads_user_id_users_id_fk": {
"name": "information_reads_user_id_users_id_fk",
"tableFrom": "information_reads",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.informations": {
"name": "informations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"title": {
"name": "title",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"body": {
"name": "body",
"type": "text",
"primaryKey": false,
"notNull": true
},
"image_url": {
"name": "image_url",
"type": "text",
"primaryKey": false,
"notNull": false
},
"status": {
"name": "status",
"type": "info_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'draft'"
},
"pinned": {
"name": "pinned",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"published_at": {
"name": "published_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"author_id": {
"name": "author_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"email_sent_at": {
"name": "email_sent_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"informations_feed_idx": {
"name": "informations_feed_idx",
"columns": [
{
"expression": "status",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "published_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"informations_author_id_users_id_fk": {
"name": "informations_author_id_users_id_fk",
"tableFrom": "informations",
"tableTo": "users",
"columnsFrom": [
"author_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.mail_accounts": {
"name": "mail_accounts",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"provider": {
"name": "provider",
"type": "mail_provider",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
},
"from_address": {
"name": "from_address",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"from_name": {
"name": "from_name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"is_active": {
"name": "is_active",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"app_id": {
"name": "app_id",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"app_secret": {
"name": "app_secret",
"type": "text",
"primaryKey": false,
"notNull": false
},
"access_token": {
"name": "access_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"refresh_token": {
"name": "refresh_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"smtp_host": {
"name": "smtp_host",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"smtp_port": {
"name": "smtp_port",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"smtp_secure": {
"name": "smtp_secure",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"smtp_user": {
"name": "smtp_user",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"smtp_password": {
"name": "smtp_password",
"type": "text",
"primaryKey": false,
"notNull": false
},
"connected_by_id": {
"name": "connected_by_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"connected_at": {
"name": "connected_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"last_check_at": {
"name": "last_check_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"last_check_ok": {
"name": "last_check_ok",
"type": "boolean",
"primaryKey": false,
"notNull": false
},
"last_check_error": {
"name": "last_check_error",
"type": "text",
"primaryKey": false,
"notNull": false
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"mail_accounts_connected_by_id_users_id_fk": {
"name": "mail_accounts_connected_by_id_users_id_fk",
"tableFrom": "mail_accounts",
"tableTo": "users",
"columnsFrom": [
"connected_by_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"mail_accounts_provider_unique": {
"name": "mail_accounts_provider_unique",
"nullsNotDistinct": false,
"columns": [
"provider"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.mail_messages": {
"name": "mail_messages",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"kind": {
"name": "kind",
"type": "mail_kind",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
},
"status": {
"name": "status",
"type": "mail_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'queued'"
},
"to_address": {
"name": "to_address",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"to_name": {
"name": "to_name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"subject": {
"name": "subject",
"type": "varchar(300)",
"primaryKey": false,
"notNull": true
},
"html": {
"name": "html",
"type": "text",
"primaryKey": false,
"notNull": true
},
"text": {
"name": "text",
"type": "text",
"primaryKey": false,
"notNull": false
},
"reply_to": {
"name": "reply_to",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"information_id": {
"name": "information_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"meeting_id": {
"name": "meeting_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"member_id": {
"name": "member_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"created_by_id": {
"name": "created_by_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"provider": {
"name": "provider",
"type": "mail_provider",
"typeSchema": "public",
"primaryKey": false,
"notNull": false
},
"attempts": {
"name": "attempts",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"next_attempt_at": {
"name": "next_attempt_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"locked_at": {
"name": "locked_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"sent_at": {
"name": "sent_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"error": {
"name": "error",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"mail_messages_due_idx": {
"name": "mail_messages_due_idx",
"columns": [
{
"expression": "status",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "next_attempt_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"mail_messages_information_idx": {
"name": "mail_messages_information_idx",
"columns": [
{
"expression": "information_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"mail_messages_information_id_informations_id_fk": {
"name": "mail_messages_information_id_informations_id_fk",
"tableFrom": "mail_messages",
"tableTo": "informations",
"columnsFrom": [
"information_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
},
"mail_messages_meeting_id_meetings_id_fk": {
"name": "mail_messages_meeting_id_meetings_id_fk",
"tableFrom": "mail_messages",
"tableTo": "meetings",
"columnsFrom": [
"meeting_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
},
"mail_messages_member_id_members_id_fk": {
"name": "mail_messages_member_id_members_id_fk",
"tableFrom": "mail_messages",
"tableTo": "members",
"columnsFrom": [
"member_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
},
"mail_messages_created_by_id_users_id_fk": {
"name": "mail_messages_created_by_id_users_id_fk",
"tableFrom": "mail_messages",
"tableTo": "users",
"columnsFrom": [
"created_by_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.meeting_registrations": {
"name": "meeting_registrations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"meeting_id": {
"name": "meeting_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"member_id": {
"name": "member_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"attendee_name": {
"name": "attendee_name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"attendee_company": {
"name": "attendee_company",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"attendee_email": {
"name": "attendee_email",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"attendee_phone": {
"name": "attendee_phone",
"type": "varchar(40)",
"primaryKey": false,
"notNull": false
},
"status": {
"name": "status",
"type": "varchar(20)",
"primaryKey": false,
"notNull": true,
"default": "'pending'"
},
"image_consent": {
"name": "image_consent",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"meeting_registrations_meeting_idx": {
"name": "meeting_registrations_meeting_idx",
"columns": [
{
"expression": "meeting_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"meeting_registrations_member_meeting_idx": {
"name": "meeting_registrations_member_meeting_idx",
"columns": [
{
"expression": "member_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "meeting_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"meeting_registrations_meeting_id_meetings_id_fk": {
"name": "meeting_registrations_meeting_id_meetings_id_fk",
"tableFrom": "meeting_registrations",
"tableTo": "meetings",
"columnsFrom": [
"meeting_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"meeting_registrations_member_id_members_id_fk": {
"name": "meeting_registrations_member_id_members_id_fk",
"tableFrom": "meeting_registrations",
"tableTo": "members",
"columnsFrom": [
"member_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.meetings": {
"name": "meetings",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"title": {
"name": "title",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"starts_at": {
"name": "starts_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"location": {
"name": "location",
"type": "varchar(240)",
"primaryKey": false,
"notNull": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
},
"capacity": {
"name": "capacity",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 30
},
"participants_per_account": {
"name": "participants_per_account",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 1
},
"image_url": {
"name": "image_url",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.members": {
"name": "members",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"contact_email": {
"name": "contact_email",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"contact_first_name": {
"name": "contact_first_name",
"type": "varchar(120)",
"primaryKey": false,
"notNull": false
},
"contact_last_name": {
"name": "contact_last_name",
"type": "varchar(120)",
"primaryKey": false,
"notNull": false
},
"contact_phone": {
"name": "contact_phone",
"type": "varchar(40)",
"primaryKey": false,
"notNull": false
},
"category_id": {
"name": "category_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"city": {
"name": "city",
"type": "varchar(120)",
"primaryKey": false,
"notNull": false
},
"address": {
"name": "address",
"type": "varchar(240)",
"primaryKey": false,
"notNull": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
},
"status": {
"name": "status",
"type": "member_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'pending'"
},
"highlighted": {
"name": "highlighted",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"logo_url": {
"name": "logo_url",
"type": "text",
"primaryKey": false,
"notNull": false
},
"cover_url": {
"name": "cover_url",
"type": "text",
"primaryKey": false,
"notNull": false
},
"phone": {
"name": "phone",
"type": "varchar(40)",
"primaryKey": false,
"notNull": false
},
"website": {
"name": "website",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"postal_code": {
"name": "postal_code",
"type": "varchar(20)",
"primaryKey": false,
"notNull": false
},
"member_since": {
"name": "member_since",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"hours": {
"name": "hours",
"type": "text",
"primaryKey": false,
"notNull": false
},
"tags": {
"name": "tags",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"members_category_id_categories_id_fk": {
"name": "members_category_id_categories_id_fk",
"tableFrom": "members",
"tableTo": "categories",
"columnsFrom": [
"category_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.membership_requests": {
"name": "membership_requests",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"message": {
"name": "message",
"type": "text",
"primaryKey": false,
"notNull": false
},
"status": {
"name": "status",
"type": "request_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'new'"
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.past_meeting_photos": {
"name": "past_meeting_photos",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"past_meeting_id": {
"name": "past_meeting_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"image_url": {
"name": "image_url",
"type": "text",
"primaryKey": false,
"notNull": true
},
"caption": {
"name": "caption",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"position": {
"name": "position",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"past_meeting_photos_past_meeting_id_past_meetings_id_fk": {
"name": "past_meeting_photos_past_meeting_id_past_meetings_id_fk",
"tableFrom": "past_meeting_photos",
"tableTo": "past_meetings",
"columnsFrom": [
"past_meeting_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.past_meetings": {
"name": "past_meetings",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"title": {
"name": "title",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"event_date": {
"name": "event_date",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"location": {
"name": "location",
"type": "varchar(240)",
"primaryKey": false,
"notNull": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
},
"participants": {
"name": "participants",
"type": "text",
"primaryKey": false,
"notNull": false
},
"meeting_id": {
"name": "meeting_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"past_meetings_meeting_id_meetings_id_fk": {
"name": "past_meetings_meeting_id_meetings_id_fk",
"tableFrom": "past_meetings",
"tableTo": "meetings",
"columnsFrom": [
"meeting_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.promotions": {
"name": "promotions",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"title": {
"name": "title",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"text": {
"name": "text",
"type": "text",
"primaryKey": false,
"notNull": false
},
"category": {
"name": "category",
"type": "varchar(120)",
"primaryKey": false,
"notNull": false
},
"badge": {
"name": "badge",
"type": "varchar(40)",
"primaryKey": false,
"notNull": false
},
"image_url": {
"name": "image_url",
"type": "text",
"primaryKey": false,
"notNull": false
},
"member_id": {
"name": "member_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"status": {
"name": "status",
"type": "promo_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'pending'"
},
"starts_on": {
"name": "starts_on",
"type": "date",
"primaryKey": false,
"notNull": false
},
"ends_on": {
"name": "ends_on",
"type": "date",
"primaryKey": false,
"notNull": false
},
"valid_until": {
"name": "valid_until",
"type": "varchar(120)",
"primaryKey": false,
"notNull": false
},
"share_facebook": {
"name": "share_facebook",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"share_linkedin": {
"name": "share_linkedin",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"publish_at": {
"name": "publish_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"suspended_by": {
"name": "suspended_by",
"type": "promo_suspended_by",
"typeSchema": "public",
"primaryKey": false,
"notNull": false
},
"suspended_by_id": {
"name": "suspended_by_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"suspended_at": {
"name": "suspended_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"promotions_member_id_members_id_fk": {
"name": "promotions_member_id_members_id_fk",
"tableFrom": "promotions",
"tableTo": "members",
"columnsFrom": [
"member_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"promotions_suspended_by_id_users_id_fk": {
"name": "promotions_suspended_by_id_users_id_fk",
"tableFrom": "promotions",
"tableTo": "users",
"columnsFrom": [
"suspended_by_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.site_settings": {
"name": "site_settings",
"schema": "",
"columns": {
"key": {
"name": "key",
"type": "varchar(120)",
"primaryKey": true,
"notNull": true
},
"value": {
"name": "value",
"type": "text",
"primaryKey": false,
"notNull": false
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.social_accounts": {
"name": "social_accounts",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"network": {
"name": "network",
"type": "social_network",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
},
"app_id": {
"name": "app_id",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"app_secret": {
"name": "app_secret",
"type": "text",
"primaryKey": false,
"notNull": true
},
"access_token": {
"name": "access_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"refresh_token": {
"name": "refresh_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"target_id": {
"name": "target_id",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"target_name": {
"name": "target_name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"connected_by_id": {
"name": "connected_by_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"connected_at": {
"name": "connected_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"last_check_at": {
"name": "last_check_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"last_check_ok": {
"name": "last_check_ok",
"type": "boolean",
"primaryKey": false,
"notNull": false
},
"last_check_error": {
"name": "last_check_error",
"type": "text",
"primaryKey": false,
"notNull": false
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"social_accounts_connected_by_id_users_id_fk": {
"name": "social_accounts_connected_by_id_users_id_fk",
"tableFrom": "social_accounts",
"tableTo": "users",
"columnsFrom": [
"connected_by_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"social_accounts_network_unique": {
"name": "social_accounts_network_unique",
"nullsNotDistinct": false,
"columns": [
"network"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.social_posts": {
"name": "social_posts",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"promotion_id": {
"name": "promotion_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"network": {
"name": "network",
"type": "social_network",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
},
"status": {
"name": "status",
"type": "social_post_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
},
"external_id": {
"name": "external_id",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"url": {
"name": "url",
"type": "text",
"primaryKey": false,
"notNull": false
},
"error": {
"name": "error",
"type": "text",
"primaryKey": false,
"notNull": false
},
"posted_by_id": {
"name": "posted_by_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"social_posts_promotion_idx": {
"name": "social_posts_promotion_idx",
"columns": [
{
"expression": "promotion_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"social_posts_promotion_id_promotions_id_fk": {
"name": "social_posts_promotion_id_promotions_id_fk",
"tableFrom": "social_posts",
"tableTo": "promotions",
"columnsFrom": [
"promotion_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"social_posts_posted_by_id_users_id_fk": {
"name": "social_posts_posted_by_id_users_id_fk",
"tableFrom": "social_posts",
"tableTo": "users",
"columnsFrom": [
"posted_by_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"email": {
"name": "email",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"password_hash": {
"name": "password_hash",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"role": {
"name": "role",
"type": "role",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'member'"
},
"member_id": {
"name": "member_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"must_change_password": {
"name": "must_change_password",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"session_version": {
"name": "session_version",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"users_email_idx": {
"name": "users_email_idx",
"columns": [
{
"expression": "email",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"users_member_id_members_id_fk": {
"name": "users_member_id_members_id_fk",
"tableFrom": "users",
"tableTo": "members",
"columnsFrom": [
"member_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {
"public.contact_status": {
"name": "contact_status",
"schema": "public",
"values": [
"new",
"read",
"archived"
]
},
"public.info_status": {
"name": "info_status",
"schema": "public",
"values": [
"draft",
"published"
]
},
"public.mail_kind": {
"name": "mail_kind",
"schema": "public",
"values": [
"credentials",
"information",
"meeting",
"studio",
"test"
]
},
"public.mail_provider": {
"name": "mail_provider",
"schema": "public",
"values": [
"google",
"microsoft",
"smtp"
]
},
"public.mail_status": {
"name": "mail_status",
"schema": "public",
"values": [
"queued",
"sending",
"sent",
"failed",
"cancelled"
]
},
"public.member_status": {
"name": "member_status",
"schema": "public",
"values": [
"active",
"pending"
]
},
"public.promo_status": {
"name": "promo_status",
"schema": "public",
"values": [
"pending",
"live",
"expired",
"rejected",
"suspended",
"scheduled"
]
},
"public.promo_suspended_by": {
"name": "promo_suspended_by",
"schema": "public",
"values": [
"member",
"staff"
]
},
"public.request_status": {
"name": "request_status",
"schema": "public",
"values": [
"new",
"approved",
"rejected"
]
},
"public.role": {
"name": "role",
"schema": "public",
"values": [
"admin",
"moderator",
"editor",
"member"
]
},
"public.social_network": {
"name": "social_network",
"schema": "public",
"values": [
"facebook",
"linkedin"
]
},
"public.social_post_status": {
"name": "social_post_status",
"schema": "public",
"values": [
"posted",
"failed"
]
}
},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}