# Design: Organization Member Support ## Data Model Changes ### Member Table - Add `member_type` column: Enum (`INDIVIDUAL`, `ORGANIZATION`). Default to `INDIVIDUAL` for existing records. - Add `company_name` column: String, nullable. - Alter `first_name`: Change from `nullable=False` to `nullable=True`. ### Constraints - **Application Level**: - If `member_type` is `INDIVIDUAL`: `first_name` must be present. - If `member_type` is `ORGANIZATION`: `company_name` must be present. - **Database Level**: - We can't easily enforce conditional not-null constraints in standard SQL without triggers or check constraints. For simplicity and portability (SQLite/Postgres), we will enforce this at the application level (Pydantic/SQLAlchemy validators) and potentially add a CHECK constraint if supported by both dialects easily. - `first_name` will become nullable in the DB schema. ## API Changes ### GraphQL Schema - Update `Member` type to include `memberType` and `companyName`. - Update `createMember` and `updateMember` inputs. - Add validation logic in resolvers to enforce the conditional requirements. ## Migration Strategy 1. Add `member_type` column with default 'INDIVIDUAL'. 2. Add `company_name` column. 3. Alter `first_name` to be nullable. ## Technical Note - Using `memberType` instead of `kind` to avoid conflicts with GraphQL introspection queries which use `kind` as a metadata field.