"""Engagement membership DTOs (sprint 2). `role` is a free-form label per D-017 — not a permission gate. Application- level RBAC stays the responsibility of the F11 `group` membership; per- engagement role is informational (e.g. "lead", "shadow", "binôme A"). """ from __future__ import annotations from datetime import datetime from uuid import UUID from pydantic import BaseModel, ConfigDict, Field class EngagementMemberRead(BaseModel): model_config = ConfigDict(from_attributes=True) engagement_id: UUID user_id: UUID role: str added_at: datetime class EngagementMemberCreate(BaseModel): user_id: UUID role: str = Field(default="member", min_length=1, max_length=40)