|
| 1 | +# Enhanced Field Value Support |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +The MCP GitHub Project Manager now supports **100% coverage** of GitHub Project v2 field types for field value operations. This enhancement addresses the critical gap identified in the compliance review and brings complete field type support to the `setFieldValue` and `getFieldValue` methods. |
| 6 | + |
| 7 | +## Supported Field Types |
| 8 | + |
| 9 | +| Field Type | Set Support | Get Support | Value Format | Description | |
| 10 | +|------------|-------------|-------------|--------------|-------------| |
| 11 | +| TEXT | ✅ | ✅ | `string` | Plain text fields | |
| 12 | +| NUMBER | ✅ | ✅ | `number` | Numeric fields | |
| 13 | +| DATE | ✅ | ✅ | `string` (ISO format) | Date fields | |
| 14 | +| SINGLE_SELECT | ✅ | ✅ | `string` (option name) | Single selection from predefined options | |
| 15 | +| ITERATION | ✅ | ✅ | `string` (iteration ID) | Sprint/iteration assignment | |
| 16 | +| MILESTONE | ✅ | ✅ | `string` (milestone ID) | Milestone assignment | |
| 17 | +| ASSIGNEES | ✅ | ✅ | `string[]` (user IDs) | User assignments | |
| 18 | +| LABELS | ✅ | ✅ | `string[]` (label IDs) | Label assignments | |
| 19 | + |
| 20 | +## Field Value Setting Examples |
| 21 | + |
| 22 | +### Basic Field Types |
| 23 | + |
| 24 | +```typescript |
| 25 | +// Text field |
| 26 | +await projectService.setFieldValue({ |
| 27 | + projectId: "PROJECT_ID", |
| 28 | + itemId: "ITEM_ID", |
| 29 | + fieldId: "FIELD_ID", |
| 30 | + value: "Updated description" |
| 31 | +}); |
| 32 | + |
| 33 | +// Number field |
| 34 | +await projectService.setFieldValue({ |
| 35 | + projectId: "PROJECT_ID", |
| 36 | + itemId: "ITEM_ID", |
| 37 | + fieldId: "FIELD_ID", |
| 38 | + value: 42 |
| 39 | +}); |
| 40 | + |
| 41 | +// Date field |
| 42 | +await projectService.setFieldValue({ |
| 43 | + projectId: "PROJECT_ID", |
| 44 | + itemId: "ITEM_ID", |
| 45 | + fieldId: "FIELD_ID", |
| 46 | + value: "2024-12-31" |
| 47 | +}); |
| 48 | +``` |
| 49 | + |
| 50 | +### Selection Fields |
| 51 | + |
| 52 | +```typescript |
| 53 | +// Single select field |
| 54 | +await projectService.setFieldValue({ |
| 55 | + projectId: "PROJECT_ID", |
| 56 | + itemId: "ITEM_ID", |
| 57 | + fieldId: "FIELD_ID", |
| 58 | + value: "In Progress" // Option name |
| 59 | +}); |
| 60 | +``` |
| 61 | + |
| 62 | +### New Enhanced Field Types |
| 63 | + |
| 64 | +```typescript |
| 65 | +// Iteration field |
| 66 | +await projectService.setFieldValue({ |
| 67 | + projectId: "PROJECT_ID", |
| 68 | + itemId: "ITEM_ID", |
| 69 | + fieldId: "FIELD_ID", |
| 70 | + value: "ITERATION_ID" // GitHub iteration ID |
| 71 | +}); |
| 72 | + |
| 73 | +// Milestone field |
| 74 | +await projectService.setFieldValue({ |
| 75 | + projectId: "PROJECT_ID", |
| 76 | + itemId: "ITEM_ID", |
| 77 | + fieldId: "FIELD_ID", |
| 78 | + value: "MILESTONE_ID" // GitHub milestone ID |
| 79 | +}); |
| 80 | + |
| 81 | +// Assignees field |
| 82 | +await projectService.setFieldValue({ |
| 83 | + projectId: "PROJECT_ID", |
| 84 | + itemId: "ITEM_ID", |
| 85 | + fieldId: "FIELD_ID", |
| 86 | + value: ["USER_ID_1", "USER_ID_2"] // Array of GitHub user IDs |
| 87 | +}); |
| 88 | + |
| 89 | +// Labels field |
| 90 | +await projectService.setFieldValue({ |
| 91 | + projectId: "PROJECT_ID", |
| 92 | + itemId: "ITEM_ID", |
| 93 | + fieldId: "FIELD_ID", |
| 94 | + value: ["LABEL_ID_1", "LABEL_ID_2"] // Array of GitHub label IDs |
| 95 | +}); |
| 96 | +``` |
| 97 | + |
| 98 | +## Field Value Reading Examples |
| 99 | + |
| 100 | +### Reading Enhanced Field Types |
| 101 | + |
| 102 | +```typescript |
| 103 | +// Reading iteration field |
| 104 | +const iterationValue = await projectService.getFieldValue({ |
| 105 | + projectId: "PROJECT_ID", |
| 106 | + itemId: "ITEM_ID", |
| 107 | + fieldId: "FIELD_ID" |
| 108 | +}); |
| 109 | +// Returns: { fieldName: "Sprint", value: { iterationId: "...", title: "Sprint 1" }, fieldType: "ITERATION" } |
| 110 | + |
| 111 | +// Reading milestone field |
| 112 | +const milestoneValue = await projectService.getFieldValue({ |
| 113 | + projectId: "PROJECT_ID", |
| 114 | + itemId: "ITEM_ID", |
| 115 | + fieldId: "FIELD_ID" |
| 116 | +}); |
| 117 | +// Returns: { fieldName: "Milestone", value: { milestoneId: "...", title: "v1.0" }, fieldType: "MILESTONE" } |
| 118 | + |
| 119 | +// Reading assignees field |
| 120 | +const assigneesValue = await projectService.getFieldValue({ |
| 121 | + projectId: "PROJECT_ID", |
| 122 | + itemId: "ITEM_ID", |
| 123 | + fieldId: "FIELD_ID" |
| 124 | +}); |
| 125 | +// Returns: { fieldName: "Assignees", value: [{ id: "...", login: "user1" }], fieldType: "ASSIGNEES" } |
| 126 | + |
| 127 | +// Reading labels field |
| 128 | +const labelsValue = await projectService.getFieldValue({ |
| 129 | + projectId: "PROJECT_ID", |
| 130 | + itemId: "ITEM_ID", |
| 131 | + fieldId: "FIELD_ID" |
| 132 | +}); |
| 133 | +// Returns: { fieldName: "Labels", value: [{ id: "...", name: "bug" }], fieldType: "LABELS" } |
| 134 | +``` |
| 135 | + |
| 136 | +## Error Handling |
| 137 | + |
| 138 | +The enhanced implementation includes comprehensive error handling for the new field types: |
| 139 | + |
| 140 | +### Validation Errors |
| 141 | + |
| 142 | +```typescript |
| 143 | +// Invalid iteration ID |
| 144 | +await projectService.setFieldValue({ |
| 145 | + projectId: "PROJECT_ID", |
| 146 | + itemId: "ITEM_ID", |
| 147 | + fieldId: "FIELD_ID", |
| 148 | + value: null // Will throw ValidationError |
| 149 | +}); |
| 150 | +// Error: "Iteration field 'Sprint' requires a valid iteration ID string" |
| 151 | + |
| 152 | +// Invalid assignees format |
| 153 | +await projectService.setFieldValue({ |
| 154 | + projectId: "PROJECT_ID", |
| 155 | + itemId: "ITEM_ID", |
| 156 | + fieldId: "FIELD_ID", |
| 157 | + value: [] // Will throw ValidationError |
| 158 | +}); |
| 159 | +// Error: "Assignees field 'Team' requires at least one user ID" |
| 160 | + |
| 161 | +// Invalid label IDs |
| 162 | +await projectService.setFieldValue({ |
| 163 | + projectId: "PROJECT_ID", |
| 164 | + itemId: "ITEM_ID", |
| 165 | + fieldId: "FIELD_ID", |
| 166 | + value: ["", "VALID_ID"] // Will throw ValidationError |
| 167 | +}); |
| 168 | +// Error: "Labels field 'Tags' requires valid label ID strings" |
| 169 | +``` |
| 170 | + |
| 171 | +## GraphQL API Integration |
| 172 | + |
| 173 | +### Field Value Mutations |
| 174 | + |
| 175 | +The implementation uses the proper GitHub GraphQL API mutations: |
| 176 | + |
| 177 | +- **Iteration**: `updateProjectV2ItemFieldValue` with `iterationId` value |
| 178 | +- **Milestone**: `updateProjectV2ItemFieldValue` with `milestoneId` value |
| 179 | +- **Assignees**: `updateProjectV2ItemFieldValue` with `userIds` array value |
| 180 | +- **Labels**: `updateProjectV2ItemFieldValue` with `labelIds` array value |
| 181 | + |
| 182 | +### Field Value Queries |
| 183 | + |
| 184 | +Enhanced GraphQL fragments support reading all field types: |
| 185 | + |
| 186 | +- **Iteration**: `ProjectV2ItemFieldIterationValue` with `iterationId` and `title` |
| 187 | +- **Milestone**: `ProjectV2ItemFieldMilestoneValue` with `milestoneId` and `title` |
| 188 | +- **Assignees**: `ProjectV2ItemFieldUserValue` with `users.nodes` array |
| 189 | +- **Labels**: `ProjectV2ItemFieldLabelValue` with `labels.nodes` array |
| 190 | + |
| 191 | +## Implementation Benefits |
| 192 | + |
| 193 | +1. **Complete API Coverage**: 100% support for all GitHub Project v2 field types |
| 194 | +2. **Type Safety**: Strong TypeScript typing with comprehensive interfaces |
| 195 | +3. **Error Handling**: Specific validation for each field type with clear error messages |
| 196 | +4. **GraphQL Optimization**: Efficient queries and mutations using proper GitHub API patterns |
| 197 | +5. **Backward Compatibility**: Existing field types continue to work without changes |
| 198 | + |
| 199 | +## Migration Notes |
| 200 | + |
| 201 | +- **No Breaking Changes**: Existing code for TEXT, NUMBER, DATE, and SINGLE_SELECT fields continues to work |
| 202 | +- **Enhanced Error Messages**: More specific validation errors help with debugging |
| 203 | +- **New Return Formats**: Enhanced field types return structured objects with additional metadata |
| 204 | + |
| 205 | +This enhancement brings the MCP GitHub Project Manager to full compliance with the GitHub Project v2 API field value operations. |
0 commit comments