@dpesch/mantisbt-mcp-server 1.10.3 → 1.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/package.json +1 -1
- package/server.json +2 -2
- package/.gitea/PULL_REQUEST_TEMPLATE.md +0 -17
- package/.gitea/workflows/ci.yml +0 -95
- package/.github/workflows/ci.yml +0 -32
- package/scripts/hooks/pre-push.mjs +0 -220
- package/scripts/init.mjs +0 -95
- package/scripts/record-fixtures.ts +0 -160
- package/tests/cache.test.ts +0 -265
- package/tests/client.test.ts +0 -372
- package/tests/config.test.ts +0 -263
- package/tests/fixtures/get_current_user.json +0 -40
- package/tests/fixtures/get_issue.json +0 -133
- package/tests/fixtures/get_issue_enums.json +0 -67
- package/tests/fixtures/get_issue_fields_sample.json +0 -76
- package/tests/fixtures/get_project_categories.json +0 -157
- package/tests/fixtures/get_project_versions.json +0 -3
- package/tests/fixtures/get_project_versions_with_data.json +0 -52
- package/tests/fixtures/list_issues.json +0 -95
- package/tests/fixtures/list_projects.json +0 -65
- package/tests/helpers/mock-server.ts +0 -166
- package/tests/helpers/search-mocks.ts +0 -84
- package/tests/prompts/prompts.test.ts +0 -242
- package/tests/resources/resources.test.ts +0 -309
- package/tests/search/embedder.test.ts +0 -81
- package/tests/search/highlight.test.ts +0 -129
- package/tests/search/store.test.ts +0 -193
- package/tests/search/sync.test.ts +0 -249
- package/tests/search/tools.test.ts +0 -661
- package/tests/tools/config.test.ts +0 -212
- package/tests/tools/files.test.ts +0 -343
- package/tests/tools/issues.test.ts +0 -1180
- package/tests/tools/metadata.test.ts +0 -509
- package/tests/tools/monitors.test.ts +0 -101
- package/tests/tools/projects.test.ts +0 -338
- package/tests/tools/relationships.test.ts +0 -177
- package/tests/tools/string-coercion.test.ts +0 -317
- package/tests/tools/users.test.ts +0 -62
- package/tests/utils/date-filter.test.ts +0 -169
- package/tests/version-hint.test.ts +0 -230
- package/tsconfig.build.json +0 -8
- package/vitest.config.ts +0 -8
package/tests/config.test.ts
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
|
|
3
|
-
// vi.mock is hoisted — must be at module top level
|
|
4
|
-
vi.mock('node:fs/promises');
|
|
5
|
-
|
|
6
|
-
import { readFile } from 'node:fs/promises';
|
|
7
|
-
|
|
8
|
-
// ---------------------------------------------------------------------------
|
|
9
|
-
// Helpers
|
|
10
|
-
// ---------------------------------------------------------------------------
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Reset the module registry so that the `cachedConfig` singleton in config.ts
|
|
14
|
-
* is re-initialized for each test. Then import getConfig fresh.
|
|
15
|
-
*/
|
|
16
|
-
async function freshGetConfig(): Promise<(typeof import('../src/config.js'))['getConfig']> {
|
|
17
|
-
vi.resetModules();
|
|
18
|
-
const mod = await import('../src/config.js');
|
|
19
|
-
return mod.getConfig;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async function freshGetStartupConfig(): Promise<(typeof import('../src/config.js'))['getStartupConfig']> {
|
|
23
|
-
vi.resetModules();
|
|
24
|
-
const mod = await import('../src/config.js');
|
|
25
|
-
return mod.getStartupConfig;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// ---------------------------------------------------------------------------
|
|
29
|
-
// Setup
|
|
30
|
-
// ---------------------------------------------------------------------------
|
|
31
|
-
|
|
32
|
-
beforeEach(() => {
|
|
33
|
-
vi.resetAllMocks();
|
|
34
|
-
vi.unstubAllEnvs();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
// ---------------------------------------------------------------------------
|
|
38
|
-
// ENV-based configuration
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
|
-
|
|
41
|
-
describe('getConfig() – ENV variables', () => {
|
|
42
|
-
it('reads baseUrl and apiKey from environment variables', async () => {
|
|
43
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
44
|
-
vi.stubEnv('MANTIS_API_KEY', 'env-api-key');
|
|
45
|
-
|
|
46
|
-
const getConfig = await freshGetConfig();
|
|
47
|
-
const config = await getConfig();
|
|
48
|
-
|
|
49
|
-
expect(config.baseUrl).toBe('https://mantis.example.com');
|
|
50
|
-
expect(config.apiKey).toBe('env-api-key');
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('strips trailing slash from baseUrl', async () => {
|
|
54
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com/');
|
|
55
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
56
|
-
|
|
57
|
-
const getConfig = await freshGetConfig();
|
|
58
|
-
const config = await getConfig();
|
|
59
|
-
|
|
60
|
-
expect(config.baseUrl).toBe('https://mantis.example.com');
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('strips /api/rest suffix from baseUrl when user includes it', async () => {
|
|
64
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com/api/rest');
|
|
65
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
66
|
-
|
|
67
|
-
const getConfig = await freshGetConfig();
|
|
68
|
-
const config = await getConfig();
|
|
69
|
-
|
|
70
|
-
expect(config.baseUrl).toBe('https://mantis.example.com');
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('strips /api/rest/ (with trailing slash) from baseUrl', async () => {
|
|
74
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com/api/rest/');
|
|
75
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
76
|
-
|
|
77
|
-
const getConfig = await freshGetConfig();
|
|
78
|
-
const config = await getConfig();
|
|
79
|
-
|
|
80
|
-
expect(config.baseUrl).toBe('https://mantis.example.com');
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('parses MANTIS_CACHE_TTL as a number', async () => {
|
|
84
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
85
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
86
|
-
vi.stubEnv('MANTIS_CACHE_TTL', '7200');
|
|
87
|
-
|
|
88
|
-
const getConfig = await freshGetConfig();
|
|
89
|
-
const config = await getConfig();
|
|
90
|
-
|
|
91
|
-
expect(config.cacheTtl).toBe(7200);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('uses 3600 as default cacheTtl when MANTIS_CACHE_TTL is not set', async () => {
|
|
95
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
96
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
97
|
-
|
|
98
|
-
const getConfig = await freshGetConfig();
|
|
99
|
-
const config = await getConfig();
|
|
100
|
-
|
|
101
|
-
expect(config.cacheTtl).toBe(3600);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('uses MANTIS_CACHE_DIR when provided', async () => {
|
|
105
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
106
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
107
|
-
vi.stubEnv('MANTIS_CACHE_DIR', '/custom/cache/dir');
|
|
108
|
-
|
|
109
|
-
const getConfig = await freshGetConfig();
|
|
110
|
-
const config = await getConfig();
|
|
111
|
-
|
|
112
|
-
expect(config.cacheDir).toBe('/custom/cache/dir');
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// ---------------------------------------------------------------------------
|
|
117
|
-
// Error cases
|
|
118
|
-
// ---------------------------------------------------------------------------
|
|
119
|
-
|
|
120
|
-
describe('getConfig() – errors', () => {
|
|
121
|
-
it('throws when MANTIS_BASE_URL is not set', async () => {
|
|
122
|
-
vi.stubEnv('MANTIS_API_KEY', 'some-key');
|
|
123
|
-
|
|
124
|
-
const getConfig = await freshGetConfig();
|
|
125
|
-
await expect(getConfig()).rejects.toThrow('MANTIS_BASE_URL');
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('throws when MANTIS_API_KEY is not set', async () => {
|
|
129
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
130
|
-
|
|
131
|
-
const getConfig = await freshGetConfig();
|
|
132
|
-
await expect(getConfig()).rejects.toThrow('MANTIS_API_KEY');
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it('throws when no configuration is provided at all', async () => {
|
|
136
|
-
const getConfig = await freshGetConfig();
|
|
137
|
-
await expect(getConfig()).rejects.toThrow('Missing required MantisBT configuration');
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// ---------------------------------------------------------------------------
|
|
142
|
-
// HTTP transport configuration
|
|
143
|
-
// ---------------------------------------------------------------------------
|
|
144
|
-
|
|
145
|
-
describe('getConfig() – HTTP transport', () => {
|
|
146
|
-
it('uses 127.0.0.1 as default httpHost', async () => {
|
|
147
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
148
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
149
|
-
|
|
150
|
-
const getConfig = await freshGetConfig();
|
|
151
|
-
const config = await getConfig();
|
|
152
|
-
|
|
153
|
-
expect(config.httpHost).toBe('127.0.0.1');
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('uses 3000 as default httpPort', async () => {
|
|
157
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
158
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
159
|
-
|
|
160
|
-
const getConfig = await freshGetConfig();
|
|
161
|
-
const config = await getConfig();
|
|
162
|
-
|
|
163
|
-
expect(config.httpPort).toBe(3000);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('uses PORT when set', async () => {
|
|
167
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
168
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
169
|
-
vi.stubEnv('PORT', '8080');
|
|
170
|
-
|
|
171
|
-
const getConfig = await freshGetConfig();
|
|
172
|
-
const config = await getConfig();
|
|
173
|
-
|
|
174
|
-
expect(config.httpPort).toBe(8080);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it('uses MCP_HTTP_HOST when set', async () => {
|
|
178
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
179
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
180
|
-
vi.stubEnv('MCP_HTTP_HOST', '0.0.0.0');
|
|
181
|
-
|
|
182
|
-
const getConfig = await freshGetConfig();
|
|
183
|
-
const config = await getConfig();
|
|
184
|
-
|
|
185
|
-
expect(config.httpHost).toBe('0.0.0.0');
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('leaves httpToken undefined when MCP_HTTP_TOKEN is not set', async () => {
|
|
189
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
190
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
191
|
-
|
|
192
|
-
const getConfig = await freshGetConfig();
|
|
193
|
-
const config = await getConfig();
|
|
194
|
-
|
|
195
|
-
expect(config.httpToken).toBeUndefined();
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it('reads httpToken from MCP_HTTP_TOKEN', async () => {
|
|
199
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
200
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
201
|
-
vi.stubEnv('MCP_HTTP_TOKEN', 'secret-token');
|
|
202
|
-
|
|
203
|
-
const getConfig = await freshGetConfig();
|
|
204
|
-
const config = await getConfig();
|
|
205
|
-
|
|
206
|
-
expect(config.httpToken).toBe('secret-token');
|
|
207
|
-
});
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
// ---------------------------------------------------------------------------
|
|
211
|
-
// getStartupConfig — never throws without credentials
|
|
212
|
-
// ---------------------------------------------------------------------------
|
|
213
|
-
|
|
214
|
-
describe('getStartupConfig()', () => {
|
|
215
|
-
it('succeeds without MANTIS_BASE_URL and MANTIS_API_KEY', async () => {
|
|
216
|
-
vi.mocked(readFile).mockRejectedValue(new Error('ENOENT'));
|
|
217
|
-
|
|
218
|
-
const getStartupConfig = await freshGetStartupConfig();
|
|
219
|
-
const config = await getStartupConfig();
|
|
220
|
-
|
|
221
|
-
expect(config).toBeDefined();
|
|
222
|
-
expect(config.cacheTtl).toBe(3600);
|
|
223
|
-
expect(config.httpHost).toBe('127.0.0.1');
|
|
224
|
-
expect(config.httpPort).toBe(3000);
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it('does not include baseUrl or apiKey', async () => {
|
|
228
|
-
vi.mocked(readFile).mockRejectedValue(new Error('ENOENT'));
|
|
229
|
-
|
|
230
|
-
const getStartupConfig = await freshGetStartupConfig();
|
|
231
|
-
const config = await getStartupConfig();
|
|
232
|
-
|
|
233
|
-
expect(config).not.toHaveProperty('baseUrl');
|
|
234
|
-
expect(config).not.toHaveProperty('apiKey');
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
it('reads MANTIS_CACHE_DIR from environment', async () => {
|
|
238
|
-
vi.stubEnv('MANTIS_CACHE_DIR', '/tmp/test-cache');
|
|
239
|
-
vi.mocked(readFile).mockRejectedValue(new Error('ENOENT'));
|
|
240
|
-
|
|
241
|
-
const getStartupConfig = await freshGetStartupConfig();
|
|
242
|
-
const config = await getStartupConfig();
|
|
243
|
-
|
|
244
|
-
expect(config.cacheDir).toBe('/tmp/test-cache');
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
// ---------------------------------------------------------------------------
|
|
249
|
-
// Singleton caching
|
|
250
|
-
// ---------------------------------------------------------------------------
|
|
251
|
-
|
|
252
|
-
describe('getConfig() – singleton', () => {
|
|
253
|
-
it('returns the same object on repeated calls within the same module instance', async () => {
|
|
254
|
-
vi.stubEnv('MANTIS_BASE_URL', 'https://mantis.example.com');
|
|
255
|
-
vi.stubEnv('MANTIS_API_KEY', 'key');
|
|
256
|
-
|
|
257
|
-
const getConfig = await freshGetConfig();
|
|
258
|
-
const first = await getConfig();
|
|
259
|
-
const second = await getConfig();
|
|
260
|
-
|
|
261
|
-
expect(first).toBe(second);
|
|
262
|
-
});
|
|
263
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": 51,
|
|
3
|
-
"name": "user_1",
|
|
4
|
-
"real_name": "User One",
|
|
5
|
-
"email": "user1@example.com",
|
|
6
|
-
"language": "german",
|
|
7
|
-
"timezone": "Europe/Berlin",
|
|
8
|
-
"access_level": {
|
|
9
|
-
"id": 70,
|
|
10
|
-
"name": "manager",
|
|
11
|
-
"label": "Manager"
|
|
12
|
-
},
|
|
13
|
-
"created_at": "2026-02-28T09:08:30+01:00",
|
|
14
|
-
"projects": [
|
|
15
|
-
{ "id": 30, "name": "Project 1" },
|
|
16
|
-
{ "id": 54, "name": "Project 2" },
|
|
17
|
-
{ "id": 2, "name": "Project 3" },
|
|
18
|
-
{ "id": 48, "name": "Project 4" },
|
|
19
|
-
{ "id": 25, "name": "Project 5" },
|
|
20
|
-
{ "id": 39, "name": "Project 6" },
|
|
21
|
-
{ "id": 44, "name": "Project 7" },
|
|
22
|
-
{ "id": 52, "name": "Project 8" },
|
|
23
|
-
{ "id": 5, "name": "Project 9" },
|
|
24
|
-
{ "id": 27, "name": "Project 10" },
|
|
25
|
-
{ "id": 3, "name": "Project 11" },
|
|
26
|
-
{ "id": 11, "name": "Project 12" },
|
|
27
|
-
{ "id": 38, "name": "Project 13" },
|
|
28
|
-
{ "id": 28, "name": "Project 14" },
|
|
29
|
-
{ "id": 45, "name": "Project 15" },
|
|
30
|
-
{ "id": 40, "name": "Project 16" },
|
|
31
|
-
{ "id": 26, "name": "Project 17" },
|
|
32
|
-
{ "id": 8, "name": "Project 18" },
|
|
33
|
-
{ "id": 14, "name": "Project 19" },
|
|
34
|
-
{ "id": 42, "name": "Project 20" },
|
|
35
|
-
{ "id": 49, "name": "Project 21" },
|
|
36
|
-
{ "id": 21, "name": "Project 22" },
|
|
37
|
-
{ "id": 53, "name": "Project 23" },
|
|
38
|
-
{ "id": 47, "name": "Project 24" }
|
|
39
|
-
]
|
|
40
|
-
}
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"issues": [
|
|
3
|
-
{
|
|
4
|
-
"id": 7860,
|
|
5
|
-
"summary": "Issue summary 1",
|
|
6
|
-
"description": "Issue description 1",
|
|
7
|
-
"project": {
|
|
8
|
-
"id": 54,
|
|
9
|
-
"name": "Project 2"
|
|
10
|
-
},
|
|
11
|
-
"category": {
|
|
12
|
-
"id": 393,
|
|
13
|
-
"name": "Skills"
|
|
14
|
-
},
|
|
15
|
-
"reporter": {
|
|
16
|
-
"id": 51,
|
|
17
|
-
"name": "user_1",
|
|
18
|
-
"real_name": "User One",
|
|
19
|
-
"email": "user1@example.com"
|
|
20
|
-
},
|
|
21
|
-
"handler": {
|
|
22
|
-
"id": 51,
|
|
23
|
-
"name": "user_1",
|
|
24
|
-
"real_name": "User One",
|
|
25
|
-
"email": "user1@example.com"
|
|
26
|
-
},
|
|
27
|
-
"status": {
|
|
28
|
-
"id": 50,
|
|
29
|
-
"name": "assigned",
|
|
30
|
-
"label": "zugewiesen",
|
|
31
|
-
"color": "#afbed5"
|
|
32
|
-
},
|
|
33
|
-
"resolution": {
|
|
34
|
-
"id": 10,
|
|
35
|
-
"name": "open",
|
|
36
|
-
"label": "offen"
|
|
37
|
-
},
|
|
38
|
-
"view_state": {
|
|
39
|
-
"id": 10,
|
|
40
|
-
"name": "public",
|
|
41
|
-
"label": "öffentlich"
|
|
42
|
-
},
|
|
43
|
-
"priority": {
|
|
44
|
-
"id": 30,
|
|
45
|
-
"name": "normal",
|
|
46
|
-
"label": "normal"
|
|
47
|
-
},
|
|
48
|
-
"severity": {
|
|
49
|
-
"id": 200,
|
|
50
|
-
"name": "Technische Schuld",
|
|
51
|
-
"label": "Technische Schuld"
|
|
52
|
-
},
|
|
53
|
-
"reproducibility": {
|
|
54
|
-
"id": 70,
|
|
55
|
-
"name": "have not tried",
|
|
56
|
-
"label": "nicht getestet"
|
|
57
|
-
},
|
|
58
|
-
"sticky": false,
|
|
59
|
-
"created_at": "2026-03-16T15:40:38+01:00",
|
|
60
|
-
"updated_at": "2026-03-16T15:40:38+01:00",
|
|
61
|
-
"notes": [
|
|
62
|
-
{
|
|
63
|
-
"id": 1001,
|
|
64
|
-
"reporter": { "id": 51, "name": "user_1" },
|
|
65
|
-
"text": "First note on this issue.",
|
|
66
|
-
"view_state": { "id": 10, "name": "public", "label": "öffentlich" },
|
|
67
|
-
"attachments": [],
|
|
68
|
-
"type": "note",
|
|
69
|
-
"created_at": "2026-03-16T16:00:00+01:00",
|
|
70
|
-
"updated_at": "2026-03-16T16:00:00+01:00"
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"id": 1002,
|
|
74
|
-
"reporter": { "id": 51, "name": "user_1" },
|
|
75
|
-
"text": "Second note on this issue.",
|
|
76
|
-
"view_state": { "id": 10, "name": "public", "label": "öffentlich" },
|
|
77
|
-
"attachments": [],
|
|
78
|
-
"type": "note",
|
|
79
|
-
"created_at": "2026-03-16T17:00:00+01:00",
|
|
80
|
-
"updated_at": "2026-03-16T17:00:00+01:00"
|
|
81
|
-
}
|
|
82
|
-
],
|
|
83
|
-
"history": [
|
|
84
|
-
{
|
|
85
|
-
"created_at": "2026-03-16T15:40:38+01:00",
|
|
86
|
-
"user": {
|
|
87
|
-
"id": 51,
|
|
88
|
-
"name": "user_1",
|
|
89
|
-
"real_name": "User One",
|
|
90
|
-
"email": "user1@example.com"
|
|
91
|
-
},
|
|
92
|
-
"type": { "id": 1, "name": "issue-new" },
|
|
93
|
-
"message": "Neuer Eintrag"
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"created_at": "2026-03-16T15:40:38+01:00",
|
|
97
|
-
"user": {
|
|
98
|
-
"id": 51,
|
|
99
|
-
"name": "user_1",
|
|
100
|
-
"real_name": "User One",
|
|
101
|
-
"email": "user1@example.com"
|
|
102
|
-
},
|
|
103
|
-
"field": { "name": "status", "label": "Status" },
|
|
104
|
-
"type": { "id": 0, "name": "field-updated" },
|
|
105
|
-
"old_value": { "id": 10, "name": "new", "label": "neu", "color": "#eeb3aa" },
|
|
106
|
-
"new_value": { "id": 50, "name": "assigned", "label": "zugewiesen", "color": "#afbed5" },
|
|
107
|
-
"message": "Status",
|
|
108
|
-
"change": "neu => zugewiesen"
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
"created_at": "2026-03-16T15:40:38+01:00",
|
|
112
|
-
"user": {
|
|
113
|
-
"id": 51,
|
|
114
|
-
"name": "user_1",
|
|
115
|
-
"real_name": "User One",
|
|
116
|
-
"email": "user1@example.com"
|
|
117
|
-
},
|
|
118
|
-
"field": { "name": "handler", "label": "Bearbeitung durch" },
|
|
119
|
-
"type": { "id": 0, "name": "field-updated" },
|
|
120
|
-
"old_value": { "id": 0 },
|
|
121
|
-
"new_value": {
|
|
122
|
-
"id": 51,
|
|
123
|
-
"name": "user_1",
|
|
124
|
-
"real_name": "User One",
|
|
125
|
-
"email": "user1@example.com"
|
|
126
|
-
},
|
|
127
|
-
"message": "Bearbeitung durch",
|
|
128
|
-
"change": " => user_1"
|
|
129
|
-
}
|
|
130
|
-
]
|
|
131
|
-
}
|
|
132
|
-
]
|
|
133
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"configs": [
|
|
3
|
-
{
|
|
4
|
-
"option": "severity_enum_string",
|
|
5
|
-
"value": [
|
|
6
|
-
{ "id": 10, "name": "Feature-Wunsch", "label": "Feature-Wunsch" },
|
|
7
|
-
{ "id": 20, "name": "Trivial", "label": "Trivial" },
|
|
8
|
-
{ "id": 30, "name": "Fehler im Text", "label": "Fehler im Text" },
|
|
9
|
-
{ "id": 40, "name": "Unschönheit", "label": "Unschönheit" },
|
|
10
|
-
{ "id": 50, "name": "kleinerer Fehler", "label": "kleinerer Fehler" },
|
|
11
|
-
{ "id": 60, "name": "schwerer Fehler", "label": "schwerer Fehler" },
|
|
12
|
-
{ "id": 70, "name": "Absturz", "label": "Absturz" },
|
|
13
|
-
{ "id": 80, "name": "Blocker", "label": "Blocker" },
|
|
14
|
-
{ "id": 200, "name": "Technische Schuld", "label": "Technische Schuld" },
|
|
15
|
-
{ "id": 210, "name": "Wartung", "label": "Wartung" }
|
|
16
|
-
]
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"option": "status_enum_string",
|
|
20
|
-
"value": [
|
|
21
|
-
{ "id": 10, "name": "new", "label": "neu" },
|
|
22
|
-
{ "id": 20, "name": "feedback", "label": "Rückmeldung" },
|
|
23
|
-
{ "id": 30, "name": "acknowledged", "label": "anerkannt" },
|
|
24
|
-
{ "id": 40, "name": "confirmed", "label": "bestätigt" },
|
|
25
|
-
{ "id": 50, "name": "assigned", "label": "zugewiesen" },
|
|
26
|
-
{ "id": 80, "name": "resolved", "label": "erledigt" },
|
|
27
|
-
{ "id": 90, "name": "closed", "label": "geschlossen" }
|
|
28
|
-
]
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"option": "priority_enum_string",
|
|
32
|
-
"value": [
|
|
33
|
-
{ "id": 10, "name": "none", "label": "keine" },
|
|
34
|
-
{ "id": 20, "name": "low", "label": "niedrig" },
|
|
35
|
-
{ "id": 30, "name": "normal", "label": "normal" },
|
|
36
|
-
{ "id": 40, "name": "high", "label": "hoch" },
|
|
37
|
-
{ "id": 50, "name": "urgent", "label": "dringend" },
|
|
38
|
-
{ "id": 60, "name": "immediate", "label": "sofort" }
|
|
39
|
-
]
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"option": "resolution_enum_string",
|
|
43
|
-
"value": [
|
|
44
|
-
{ "id": 10, "name": "open", "label": "offen" },
|
|
45
|
-
{ "id": 20, "name": "fixed", "label": "erledigt" },
|
|
46
|
-
{ "id": 30, "name": "reopened", "label": "wiedereröffnet" },
|
|
47
|
-
{ "id": 40, "name": "unable to duplicate", "label": "nicht reproduzierbar" },
|
|
48
|
-
{ "id": 50, "name": "not fixable", "label": "unlösbar" },
|
|
49
|
-
{ "id": 60, "name": "duplicate", "label": "doppelt" },
|
|
50
|
-
{ "id": 70, "name": "not a bug", "label": "keine Änderung notwendig" },
|
|
51
|
-
{ "id": 80, "name": "suspended", "label": "aufgeschoben" },
|
|
52
|
-
{ "id": 90, "name": "wont fix", "label": "wird nicht behoben" }
|
|
53
|
-
]
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"option": "reproducibility_enum_string",
|
|
57
|
-
"value": [
|
|
58
|
-
{ "id": 10, "name": "always", "label": "immer" },
|
|
59
|
-
{ "id": 30, "name": "sometimes", "label": "manchmal" },
|
|
60
|
-
{ "id": 50, "name": "random", "label": "zufällig" },
|
|
61
|
-
{ "id": 70, "name": "have not tried", "label": "nicht getestet" },
|
|
62
|
-
{ "id": 90, "name": "unable to duplicate", "label": "nicht reproduzierbar" },
|
|
63
|
-
{ "id": 100, "name": "N/A", "label": "N/A" }
|
|
64
|
-
]
|
|
65
|
-
}
|
|
66
|
-
]
|
|
67
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"issues": [
|
|
3
|
-
{
|
|
4
|
-
"id": 7860,
|
|
5
|
-
"summary": "Issue summary 1",
|
|
6
|
-
"description": "Issue description 1",
|
|
7
|
-
"project": {
|
|
8
|
-
"id": 54,
|
|
9
|
-
"name": "Project 2"
|
|
10
|
-
},
|
|
11
|
-
"category": {
|
|
12
|
-
"id": 393,
|
|
13
|
-
"name": "Skills"
|
|
14
|
-
},
|
|
15
|
-
"reporter": {
|
|
16
|
-
"id": 51,
|
|
17
|
-
"name": "user_1",
|
|
18
|
-
"real_name": "User One",
|
|
19
|
-
"email": "user1@example.com"
|
|
20
|
-
},
|
|
21
|
-
"handler": {
|
|
22
|
-
"id": 51,
|
|
23
|
-
"name": "user_1",
|
|
24
|
-
"real_name": "User One",
|
|
25
|
-
"email": "user1@example.com"
|
|
26
|
-
},
|
|
27
|
-
"status": {
|
|
28
|
-
"id": 50,
|
|
29
|
-
"name": "assigned",
|
|
30
|
-
"label": "zugewiesen",
|
|
31
|
-
"color": "#afbed5"
|
|
32
|
-
},
|
|
33
|
-
"resolution": {
|
|
34
|
-
"id": 10,
|
|
35
|
-
"name": "open",
|
|
36
|
-
"label": "offen"
|
|
37
|
-
},
|
|
38
|
-
"view_state": {
|
|
39
|
-
"id": 10,
|
|
40
|
-
"name": "public",
|
|
41
|
-
"label": "öffentlich"
|
|
42
|
-
},
|
|
43
|
-
"priority": {
|
|
44
|
-
"id": 30,
|
|
45
|
-
"name": "normal",
|
|
46
|
-
"label": "normal"
|
|
47
|
-
},
|
|
48
|
-
"severity": {
|
|
49
|
-
"id": 200,
|
|
50
|
-
"name": "Technische Schuld",
|
|
51
|
-
"label": "Technische Schuld"
|
|
52
|
-
},
|
|
53
|
-
"reproducibility": {
|
|
54
|
-
"id": 70,
|
|
55
|
-
"name": "have not tried",
|
|
56
|
-
"label": "nicht getestet"
|
|
57
|
-
},
|
|
58
|
-
"sticky": false,
|
|
59
|
-
"created_at": "2026-03-16T15:40:38+01:00",
|
|
60
|
-
"updated_at": "2026-03-16T15:40:38+01:00",
|
|
61
|
-
"history": [
|
|
62
|
-
{
|
|
63
|
-
"created_at": "2026-03-16T15:40:38+01:00",
|
|
64
|
-
"user": {
|
|
65
|
-
"id": 51,
|
|
66
|
-
"name": "user_1",
|
|
67
|
-
"real_name": "User One",
|
|
68
|
-
"email": "user1@example.com"
|
|
69
|
-
},
|
|
70
|
-
"type": { "id": 1, "name": "issue-new" },
|
|
71
|
-
"message": "Neuer Eintrag"
|
|
72
|
-
}
|
|
73
|
-
]
|
|
74
|
-
}
|
|
75
|
-
]
|
|
76
|
-
}
|