feat: Add organization member support with memberType field
Implements support for both individual persons and organizations as members. Changes: - Added MemberType enum (INDIVIDUAL, ORGANIZATION) to distinguish member types - Added member_type column to database (defaults to INDIVIDUAL for backward compatibility) - Added company_name field for organizations - Made first_name nullable (required for individuals, optional for organizations) - Implemented conditional validation: - INDIVIDUAL members require first_name - ORGANIZATION members require company_name - Updated GraphQL schema with new memberType and companyName fields - Updated all resolvers to handle new fields and validation - Added comprehensive unit tests for validation logic - Updated existing tests to work with new fields - All 53 tests passing Technical notes: - Using memberType instead of 'kind' to avoid GraphQL introspection conflicts - Using native_enum=False for SQLite compatibility - Using batch_alter_table for SQLite ALTER COLUMN compatibility - Backward compatible: existing members automatically become INDIVIDUAL type 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# Spec: Organization Support
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Distinguish member kind
|
||||
|
||||
The system MUST allow defining a member as either an individual or an organization.
|
||||
|
||||
#### Scenario: Create individual member
|
||||
**Given** client provides kind="INDIVIDUAL"
|
||||
**And** first_name="John"
|
||||
**When** createMember mutation executes
|
||||
**Then** member is created with kind INDIVIDUAL
|
||||
**And** first_name is "John"
|
||||
|
||||
#### Scenario: Create organization member
|
||||
**Given** client provides kind="ORGANIZATION"
|
||||
**And** company_name="Acme Corp"
|
||||
**When** createMember mutation executes
|
||||
**Then** member is created with kind ORGANIZATION
|
||||
**And** company_name is "Acme Corp"
|
||||
|
||||
### Requirement: Conditional mandatory fields
|
||||
|
||||
The system MUST enforce different mandatory fields based on member kind.
|
||||
|
||||
#### Scenario: Organization requires company name
|
||||
**Given** client provides kind="ORGANIZATION"
|
||||
**And** company_name is missing or empty
|
||||
**When** createMember mutation executes
|
||||
**Then** validation error is raised
|
||||
**And** error message indicates company_name is required for organizations
|
||||
|
||||
#### Scenario: Organization allows missing first name
|
||||
**Given** client provides kind="ORGANIZATION"
|
||||
**And** company_name="Acme Corp"
|
||||
**And** first_name is missing
|
||||
**When** createMember mutation executes
|
||||
**Then** member is created successfully
|
||||
**And** first_name is null
|
||||
|
||||
#### Scenario: Individual requires first name
|
||||
**Given** client provides kind="INDIVIDUAL"
|
||||
**And** first_name is missing
|
||||
**When** createMember mutation executes
|
||||
**Then** validation error is raised
|
||||
**And** error message indicates first_name is required for individuals
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Member data structure
|
||||
|
||||
The Member data structure MUST be modified to include kind and company_name, and allow nullable first_name.
|
||||
|
||||
#### Scenario: Query member includes new fields
|
||||
**Given** member exists with kind="ORGANIZATION" and company_name="Acme Corp"
|
||||
**When** member query executes requesting kind and companyName
|
||||
**Then** kind is returned as "ORGANIZATION"
|
||||
**And** companyName is returned as "Acme Corp"
|
||||
Reference in New Issue
Block a user