Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 157 additions & 0 deletions api/.claude/context/api-structure.md
Copy link
Member

@kyle-ssg kyle-ssg Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're adding this, the frontend claude context should point to this as the source of truth. This makes me think this should all be 1 PR with a claude.md in api / frontend.

The backend and frontend contexts maybe shouldn't be in the same folder since I imagine it could cause increased token usage. However, I think the FE should point to files like this where applicable.

Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# API Structure

## URL Patterns

### Features
- **Project Features**: `/api/v1/projects/{project_pk}/features/`
- List/create features for a project
- ViewSet: `FeatureViewSet`

- **Feature Detail**: `/api/v1/projects/{project_pk}/features/{id}/`
- Retrieve/update/delete specific feature
- ViewSet: `FeatureViewSet`

### Feature States

#### Environment Feature States
- **List/Create**: `/api/v1/environments/{api_key}/featurestates/`
- Get feature states for environment (no segment/identity overrides)
- ViewSet: `EnvironmentFeatureStateViewSet`
- Filters: `feature`, `feature_name`, `anyIdentity` (deprecated)
- New: `segment` parameter to filter segment overrides

- **Detail**: `/api/v1/environments/{api_key}/featurestates/{id}/`
- Retrieve/update/delete specific feature state
- ViewSet: `EnvironmentFeatureStateViewSet`

#### Identity Feature States
- **List/Create**: `/api/v1/environments/{api_key}/identities/{identity_pk}/featurestates/`
- Feature states for specific identity
- ViewSet: `IdentityFeatureStateViewSet`

- **All States**: `/api/v1/environments/{api_key}/identities/{identity_pk}/featurestates/all/`
- Get all feature states for identity (including environment defaults)
- ViewSet: `IdentityFeatureStateViewSet.all` action

#### Simple Feature States (Alternative Endpoint)
- **List/Create/Update**: `/api/v1/features/featurestates/`
- Simpler endpoint for creating feature states
- ViewSet: `SimpleFeatureStateViewSet`
- Required param: `environment` (ID)

### Segments

#### Feature Segments (Segment Override Associations)
- **List/Create**: `/api/v1/features/feature-segments/`
- Links segments to features with priority
- ViewSet: `FeatureSegmentViewSet`
- Required params: `environment` (ID), `feature` (ID)

- **Update Priorities**: `/api/v1/features/feature-segments/update-priorities/`
- Batch update segment override priorities
- ViewSet: `FeatureSegmentViewSet.update_priorities` action

#### Segments
- **List/Create**: `/api/v1/projects/{project_pk}/segments/`
- Manage segments for a project

### Segment Overrides (Legacy Endpoint)
- **Create**: `/api/v1/environments/{api_key}/features/{feature_pk}/create-segment-override/`
- Create segment override for a feature
- Function: `create_segment_override`

## Key ViewSets

### FeatureViewSet
- **Location**: `api/features/views.py`
- **Purpose**: Manage features at project level
- **Permissions**: `FeaturePermissions`
- **Filters**: `environment`, `search`, `tags`, `is_archived`, `owners`, `group_owners`, `value_search`, `is_enabled`

### EnvironmentFeatureStateViewSet
- **Location**: `api/features/views.py`
- **Base Class**: `BaseFeatureStateViewSet`
- **Purpose**: Manage environment-level feature states (base states + segment overrides)
- **Permissions**: `EnvironmentFeatureStatePermissions`
- **Default Filter**: `feature_segment=None, identity=None` (base states only)
- **New**: Can filter by `segment` parameter to get segment overrides

### IdentityFeatureStateViewSet
- **Location**: `api/features/views.py`
- **Base Class**: `BaseFeatureStateViewSet`
- **Purpose**: Manage identity-specific feature state overrides
- **Permissions**: `IdentityFeatureStatePermissions`
- **Filter**: `identity__pk={identity_pk}`

### FeatureSegmentViewSet
- **Location**: `api/features/feature_segments/views.py`
- **Purpose**: Manage feature-segment associations (which segments override which features)
- **Permissions**: `FeatureSegmentPermissions`
- **Required Filters**: `environment` (ID), `feature` (ID)

## Feature Versioning

### v1 (Default)
- Feature states directly on environment
- No versioning or scheduling
- Filter: `environment=<env>`

### v2 (Optional)
- Feature states via `EnvironmentFeatureVersion`
- Supports versioning and scheduling of changes
- Enabled per environment: `environment.use_v2_feature_versioning = True`
- Uses `get_current_live_environment_feature_version()` to get active version
- Filter: `environment_feature_version=<version>`

### Checking Version in Views
```python
if environment.use_v2_feature_versioning:
queryset = queryset.filter(
environment_feature_version=get_current_live_environment_feature_version(
environment_id=environment_id,
feature_id=feature_id,
)
)
```

## Common Query Patterns

### Get Environment Feature States (Base States Only)
```python
GET /api/v1/environments/{api_key}/featurestates/
# Returns: Feature states where feature_segment=None and identity=None
```

### Get Segment Override States
```python
GET /api/v1/environments/{api_key}/featurestates/?segment={segment_id}
# Returns: Feature states where feature_segment.segment_id={segment_id}
```

### Get Feature State by Feature
```python
GET /api/v1/environments/{api_key}/featurestates/?feature={feature_id}
# Returns: Feature states for specific feature
```

### Get All Identity States
```python
GET /api/v1/environments/{api_key}/identities/{identity_pk}/featurestates/all/
# Returns: All feature states with identity overrides + environment defaults
```

## Authentication

### User Authentication
- Django session auth
- Token auth
- Required for dashboard/admin endpoints

### Environment Key Authentication
- Header: `X-Environment-Key: {api_key}`
- Used for SDK endpoints
- Limited to environment-specific operations

### Master API Key Authentication
- Full access to organization
- Used for automation/integrations
134 changes: 134 additions & 0 deletions api/.claude/context/models-relationships.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Key Model Relationships

## Core Models

### Feature (`features/models.py`)
- `project`: FK to Project
- `name`: Feature name (unique per project)
- `type`: STANDARD, MULTIVARIATE
- `default_enabled`: Default enabled state
- `is_server_key_only`: Hide from client-side SDKs

### FeatureState (`features/models.py`)
The value/enabled state of a feature in a specific context.

**Key Fields**:
- `feature`: FK to Feature (required)
- `environment`: FK to Environment (required)
- `identity`: FK to Identity (nullable - for identity overrides)
- `feature_segment`: FK to FeatureSegment (nullable - for segment overrides)
- `feature_state_value`: OneToOne to FeatureStateValue
- `enabled`: Boolean enabled state
- `environment_feature_version`: FK to EnvironmentFeatureVersion (nullable - v2 only)

**Three Types**:
1. **Base State**: `identity=None`, `feature_segment=None`
2. **Segment Override**: `feature_segment=<FeatureSegment>`, `identity=None`
3. **Identity Override**: `identity=<Identity>`, `feature_segment=None`

### FeatureStateValue (`features/models.py`)
Stores the actual value (string, int, or boolean).
- `feature_state`: OneToOne to FeatureState
- `type`: STRING, INTEGER, BOOLEAN
- `string_value`, `integer_value`, `boolean_value`

### FeatureSegment (`features/feature_segments/models.py`)
Links Feature + Segment + Environment with priority.

- `feature`: FK to Feature
- `segment`: FK to Segment
- `environment`: FK to Environment
- `priority`: Integer (0 = highest priority)
- `environment_feature_version`: FK to EnvironmentFeatureVersion (nullable - v2 only)

**Important**: The override values are in FeatureState with `feature_segment=<this FeatureSegment>`

### Segment (`segments/models.py`)
- `project`: FK to Project
- `name`: Segment name
- `rules`: JSON field with segment rules

### Environment (`environments/models.py`)
- `project`: FK to Project
- `api_key`: Unique API key for SDK access
- `use_v2_feature_versioning`: Boolean (enables v2 versioning)

## Segment Override Structure

```
FeatureSegment (links Feature + Segment + Environment)
└─> FeatureState (the actual override)
├─> feature_segment = <FeatureSegment>
├─> identity = None
└─> FeatureStateValue (actual value)
```

## Common Query Patterns

### Base Environment Feature States
```python
FeatureState.objects.filter(
environment=environment,
feature_segment=None,
identity=None
)
```

### Segment Override Feature States
```python
FeatureState.objects.filter(
environment=environment,
feature_segment__segment=segment,
identity=None
)
```

### Identity Override Feature States
```python
FeatureState.objects.filter(
environment=environment,
identity=identity
)
```

## Versioning (v2)

### EnvironmentFeatureVersion (`features/versioning/models.py`)
Version container for feature states (enables scheduling/versioning).
- `environment`: FK to Environment
- `feature`: FK to Feature
- `published_at`: DateTime (when version went live)

### Querying with v2
```python
from features.versioning.versioning_service import (
get_current_live_environment_feature_version
)

if environment.use_v2_feature_versioning:
version = get_current_live_environment_feature_version(
environment_id=environment.id,
feature_id=feature.id
)
feature_states = FeatureState.objects.filter(
environment_feature_version=version
)
else:
feature_states = FeatureState.objects.filter(
environment=environment,
environment_feature_version=None
)
```

## Useful Select Related

```python
# Feature State with full context
FeatureState.objects.select_related(
'feature',
'environment',
'feature_state_value',
'identity',
'feature_segment__segment'
)
```
Loading
Loading