diff --git a/backend/alembic/versions/2026_04_24_1000-d91a3c7f8b02_add_mandate_origin.py b/backend/alembic/versions/2026_04_24_1000-d91a3c7f8b02_add_mandate_origin.py
new file mode 100644
index 0000000..fde9331
--- /dev/null
+++ b/backend/alembic/versions/2026_04_24_1000-d91a3c7f8b02_add_mandate_origin.py
@@ -0,0 +1,24 @@
+"""Add origin column to mandates table.
+
+Revision ID: d91a3c7f8b02
+Revises: c4e812fb3a01
+Create Date: 2026-04-24 10:00:00.000000
+"""
+
+from __future__ import annotations
+
+import sqlalchemy as sa
+from alembic import op
+
+revision = "d91a3c7f8b02"
+down_revision = "c4e812fb3a01"
+branch_labels = None
+depends_on = None
+
+
+def upgrade() -> None:
+ op.add_column("mandates", sa.Column("origin", sa.Text(), nullable=True))
+
+
+def downgrade() -> None:
+ op.drop_column("mandates", "origin")
diff --git a/backend/app/models/mandate.py b/backend/app/models/mandate.py
index 3afbf88..c3c677b 100644
--- a/backend/app/models/mandate.py
+++ b/backend/app/models/mandate.py
@@ -12,6 +12,7 @@ class Mandate(Base):
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
title: Mapped[str] = mapped_column(String(256), nullable=False)
+ origin: Mapped[str | None] = mapped_column(Text) # contexte / déclencheur du mandat
description: Mapped[str | None] = mapped_column(Text)
mandate_type: Mapped[str] = mapped_column(String(64), nullable=False) # techcomm, smith, custom
status: Mapped[str] = mapped_column(String(32), default="draft") # draft, candidacy, voting, active, reporting, completed, revoked
diff --git a/backend/app/schemas/mandate.py b/backend/app/schemas/mandate.py
index dac3881..e801f6e 100644
--- a/backend/app/schemas/mandate.py
+++ b/backend/app/schemas/mandate.py
@@ -46,9 +46,12 @@ class MandateCreate(BaseModel):
"""Payload for creating a new mandate."""
title: str = Field(..., min_length=1, max_length=256)
+ origin: str | None = None
description: str | None = None
mandate_type: str = Field(..., max_length=64, description="techcomm, smith, custom")
decision_id: UUID | None = None
+ starts_at: datetime | None = None
+ ends_at: datetime | None = None
class MandateUpdate(BaseModel):
@@ -73,6 +76,7 @@ class MandateOut(BaseModel):
id: UUID
title: str
+ origin: str | None = None
description: str | None = None
mandate_type: str
status: str
@@ -92,6 +96,7 @@ class MandateAdvanceOut(BaseModel):
id: UUID
title: str
+ origin: str | None = None
description: str | None = None
mandate_type: str
status: str
diff --git a/frontend/app/pages/decisions/new.vue b/frontend/app/pages/decisions/new.vue
index b658d91..cefdec8 100644
--- a/frontend/app/pages/decisions/new.vue
+++ b/frontend/app/pages/decisions/new.vue
@@ -353,7 +353,7 @@ const confidenceLabel: Record
Définissez le périmètre et la durée du mandat
+Type de mandat
+Durée du mandat
+Ce mandat est-il demandé par son futur titulaire, ou faut-il désigner quelqu'un ?
+Paramètres du vote de ratification
+Choisissez le mode de désignation et configurez les paramètres
+{{ m.title }}
+{{ m.desc }}
+{{ m.recommendedReason }}
+ + +Vérifiez avant de créer le mandat
+Mandat
+{{ title }}
+ + + + +Nomination
++ {{ nominationCase === 'self' ? 'Auto-désignation avec ratification' : `Élection — ${MODALITIES.find(m => m.id === selectedModalityId)?.title ?? ''}` }} +
+ +Étapes générées ({{ stepsToCreate.length }})
+{{ s.title }}
+{{ s.description }}
+{{ submitError }}
+ +