https://github.com/zh/redmine_extended_api
Adds missing REST API endpoints: custom fields CRUD, queries CRUD, time entries bulk operations (globally available)
https://github.com/zh/redmine_extended_api
Last synced: 2 months ago
JSON representation
Adds missing REST API endpoints: custom fields CRUD, queries CRUD, time entries bulk operations (globally available)
- Host: GitHub
- URL: https://github.com/zh/redmine_extended_api
- Owner: zh
- Created: 2025-11-17T06:12:13.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-11-17T06:20:30.000Z (8 months ago)
- Last Synced: 2026-05-24T01:33:36.744Z (2 months ago)
- Language: Ruby
- Size: 20.5 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# Redmine Extended API
Adds missing REST API endpoints to Redmine 6.1.x (globally available):
- **Custom Fields CRUD**: Full management of custom fields
- **Queries CRUD**: Create, update, and delete queries (saved filters)
- **Time Entries Bulk**: Create multiple time entries in one request
## Requirements
- Redmine 6.1.0 or higher
## Installation
```bash
cd /path/to/redmine/plugins
git clone https://github.com/zh/redmine_extended_api.git
cd /path/to/redmine
bundle install
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
systemctl restart redmine
```
## API Endpoints
### 1. Custom Fields CRUD
**POST /custom_fields.json** - Create custom field
**PUT /custom_fields/:id.json** - Update custom field
**DELETE /custom_fields/:id.json** - Delete custom field
**Requires**: Admin privileges
**Create Example**:
```bash
curl -X POST \
-H "X-Redmine-API-Key: ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"custom_field": {
"type": "IssueCustomField",
"name": "Priority Level",
"field_format": "list",
"possible_values": ["Low", "Medium", "High"],
"is_required": false,
"is_for_all": true
}
}' \
https://redmine.example.com/custom_fields.json
```
**Update Example**:
```bash
curl -X PUT \
-H "X-Redmine-API-Key": ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"custom_field":{"name":"Updated Name","is_required":true}}' \
https://redmine.example.com/custom_fields/5.json
```
**Delete Example**:
```bash
curl -X DELETE \
-H "X-Redmine-API-Key: ADMIN_KEY" \
https://redmine.example.com/custom_fields/5.json
```
### 2. Queries CRUD
**POST /extended_api/queries.json** - Create query
**PUT /extended_api/queries/:id.json** - Update query
**DELETE /extended_api/queries/:id.json** - Delete query
**Permissions**: Users can create/update/delete their own private queries. Users with `manage_public_queries` permission can manage public project queries. Only admins can manage global public queries.
**Create Private Query Example**:
```bash
curl -X POST \
-H "X-Redmine-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": {
"name": "Late Issues Before May",
"type": "IssueQuery",
"visibility": 0,
"filters": {
"due_date": {"operator": "<=", "values": ["2025-05-01"]},
"status_id": {"operator": "o"}
}
}
}' \
https://redmine.example.com/extended_api/queries.json
```
**Create Public Project Query Example**:
```bash
curl -X POST \
-H "X-Redmine-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": {
"name": "My Team Issues",
"type": "IssueQuery",
"project_id": 5,
"visibility": 2,
"filters": {
"assigned_to_id": {"operator": "=", "values": ["me"]}
},
"column_names": ["id", "subject", "status", "assigned_to", "due_date"],
"sort_criteria": [["due_date", "asc"]]
}
}' \
https://redmine.example.com/extended_api/queries.json
```
**Update Query Example**:
```bash
curl -X PUT \
-H "X-Redmine-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": {
"name": "Updated Query Name",
"filters": {
"priority_id": {"operator": "=", "values": ["4", "5"]}
}
}
}' \
https://redmine.example.com/extended_api/queries/10.json
```
**Delete Query Example**:
```bash
curl -X DELETE \
-H "X-Redmine-API-Key: YOUR_KEY" \
https://redmine.example.com/extended_api/queries/10.json
```
**Query Parameters**:
- `name` (required): Query name
- `type`: Query type (default: "IssueQuery"). Options: IssueQuery, ProjectQuery, TimeEntryQuery
- `project_id`: Project ID (null = global query)
- `visibility`: 0=Private, 1=Roles, 2=Public
- `filters`: Hash of filters with operators and values
- `column_names`: Array of column names to display
- `sort_criteria`: Array of [field, order] pairs
- `role_ids`: Array of role IDs (required when visibility=1)
**Common Filter Operators**:
- `=`, `!`: Equals, not equals
- `>=`, `<=`: Greater/less than or equal
- `~`, `!~`: Contains, doesn't contain
- `o`, `c`: Open, closed (for status)
- `t`: Today, `w`: This week, `m`: This month
- `t-N`: More than N days ago
### 3. Time Entries Bulk Create
**POST /time_entries/bulk_create.json**
Create multiple time entries at once.
**Request Body**:
```json
{
"time_entries": [
{
"issue_id": 123,
"spent_on": "2025-01-15",
"hours": 2.5,
"activity_id": 9,
"comments": "Development work"
},
{
"project_id": 5,
"spent_on": "2025-01-15",
"hours": 1.0,
"activity_id": 9,
"comments": "Meeting"
}
]
}
```
**Response (201 Created)** - All succeeded:
```json
{
"created": [
{"id": 456, "hours": 2.5, "issue_id": 123},
{"id": 457, "hours": 1.0, "project_id": 5}
],
"failed": [],
"summary": {
"total": 2,
"created": 2,
"failed": 0
}
}
```
**Response (207 Multi-Status)** - Partial success:
```json
{
"created": [{"id": 456, "hours": 2.5}],
"failed": [
{
"index": 1,
"errors": ["Project or issue required"]
}
],
"summary": {
"total": 2,
"created": 1,
"failed": 1
}
}
```
**Example**:
```bash
curl -X POST \
-H "X-Redmine-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"time_entries": [
{"issue_id": 123, "spent_on": "2025-01-15", "hours": 2.5, "activity_id": 9, "comments": "Coding"},
{"issue_id": 124, "spent_on": "2025-01-15", "hours": 1.0, "activity_id": 9, "comments": "Review"}
]
}' \
https://redmine.example.com/time_entries/bulk_create.json
```
## Permissions
Configure these permissions in Administration → Roles and permissions:
- **manage_custom_fields_via_api**: Create/update/delete custom fields (requires admin status)
- **manage_queries_via_api**: Create/update/delete queries (global permission)
- **bulk_create_time_entries**: Create multiple time entries in one request (global permission)
All permissions are global and do not require per-project module enabling.
## HTTP Status Codes
- **200 OK**: Successful update
- **201 Created**: Resource created successfully
- **204 No Content**: Successful deletion
- **207 Multi-Status**: Partial success (some items succeeded, some failed)
- **401 Unauthorized**: Missing or invalid API key
- **403 Forbidden**: Insufficient permissions
- **404 Not Found**: Resource not found
- **406 Not Acceptable**: Endpoint only accepts API requests
- **422 Unprocessable Entity**: Validation errors
## Development
### Testing
This plugin uses RSpec for testing. All tests are located in the `spec/` directory.
**Run all tests:**
```bash
cd /path/to/redmine
bundle exec rspec plugins/redmine_extended_api/spec
```
**Run specific test file:**
```bash
bundle exec rspec plugins/redmine_extended_api/spec/controllers/extended_projects_controller_spec.rb
```
**Run specific test:**
```bash
bundle exec rspec plugins/redmine_extended_api/spec/controllers/extended_projects_controller_spec.rb:16
```
### Test Structure
- **spec/controllers/** - Controller specs for API endpoints
- `extended_custom_fields_controller_spec.rb` - Custom fields CRUD tests (16 examples)
- `extended_queries_controller_spec.rb` - Queries CRUD tests (23 examples)
- `extended_time_entries_controller_spec.rb` - Bulk time entries tests (12 examples)
- **spec/factories/** - FactoryBot factories for test data
- **spec/support/** - Test helpers and configuration
**Test Coverage:** 51 examples, 100% passing
### Testing Features
- ✅ HTTP Basic authentication testing
- ✅ Permission and authorization testing
- ✅ Validation error handling
- ✅ Success and failure scenarios
- ✅ Multi-status responses (207)
- ✅ Edge cases and boundary conditions
- ✅ FactoryBot for consistent test data
- ✅ Isolated test environment
## License
MIT License
## Author
Stoyan Zhekov
## Support
Report issues at: https://github.com/zh/redmine_extended_api/issues