merge trails function added (#627)
* merge trails function added * fix conflict resolve issues * avoid incorrect authorship when merging trail comments * require edit access for all selected trails before merge * fix likes checkbox binding in trail merge modal * improve error handling * require editable target and deletable sources for merge * avoid duplicate trail fetch during merge * prevent duplicate likes when merging trails * check photo download responses during trail merge * add merge completion toast notifications * cleanup * small fixes * move merge code to backend, option to merge single trail selection with similar one, automatic merge for integrations add as option, maintenance page to find and merge similar trails added * fix build error * fix * docu, beautifying, refactoring --------- Co-authored-by: Flomp <Flomp@users.noreply.github.com>
This commit is contained in:
@@ -764,6 +764,125 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/trail-merge": {
|
||||
"post": {
|
||||
"summary": "Merge trails",
|
||||
"description": "Merges a source trail into a target trail using the backend merge logic.",
|
||||
"tags": [
|
||||
"Trail Merge"
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TrailMergeExecuteRequest"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Merge acknowledged",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TrailMergeExecuteResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/trail-merge/suggest": {
|
||||
"post": {
|
||||
"summary": "Suggest merge target or duplicate groups",
|
||||
"description": "Returns merge target suggestions for manual selection or auto-discovery, or temporary duplicate groups for maintenance workflows.",
|
||||
"tags": [
|
||||
"Trail Merge"
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TrailMergeSuggestRequest"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Suggestion response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/TrailMergeSuggestResponse"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/TrailMergeSuggestGroupsResponse"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/trail-link-share": {
|
||||
"get": {
|
||||
"summary": "List trail link shares",
|
||||
@@ -6571,6 +6690,201 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"TrailMergeSettings": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"summitLog",
|
||||
"photos",
|
||||
"comments",
|
||||
"delete",
|
||||
"tags",
|
||||
"likes"
|
||||
],
|
||||
"properties": {
|
||||
"summitLog": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"photos": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"comments": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"delete": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tags": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"likes": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"TrailMergeSuggestRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"mode"
|
||||
],
|
||||
"properties": {
|
||||
"mode": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"manual-selection",
|
||||
"auto-discovery",
|
||||
"maintenance-groups"
|
||||
]
|
||||
},
|
||||
"trailIds": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Required for manual-selection"
|
||||
},
|
||||
"sourceTrailId": {
|
||||
"type": "string",
|
||||
"description": "Required for auto-discovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"TrailMergeSuggestCandidate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"trailId",
|
||||
"score",
|
||||
"reason",
|
||||
"warnings",
|
||||
"selectable"
|
||||
],
|
||||
"properties": {
|
||||
"trailId": {
|
||||
"type": "string"
|
||||
},
|
||||
"score": {
|
||||
"type": "number"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string"
|
||||
},
|
||||
"warnings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"selectable": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"TrailMergeSuggestResponse": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"targetTrailId",
|
||||
"reason",
|
||||
"warnings",
|
||||
"candidates"
|
||||
],
|
||||
"properties": {
|
||||
"targetTrailId": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string"
|
||||
},
|
||||
"warnings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"candidates": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/TrailMergeSuggestCandidate"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"TrailMergeSuggestGroup": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupId",
|
||||
"trailIds",
|
||||
"targetTrailId",
|
||||
"reason",
|
||||
"score",
|
||||
"indirect"
|
||||
],
|
||||
"properties": {
|
||||
"groupId": {
|
||||
"type": "string"
|
||||
},
|
||||
"trailIds": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"targetTrailId": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string"
|
||||
},
|
||||
"score": {
|
||||
"type": "number"
|
||||
},
|
||||
"indirect": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"TrailMergeSuggestGroupsResponse": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groups"
|
||||
],
|
||||
"properties": {
|
||||
"groups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/TrailMergeSuggestGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"TrailMergeExecuteRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"sourceTrailId",
|
||||
"targetTrailId",
|
||||
"settings"
|
||||
],
|
||||
"properties": {
|
||||
"sourceTrailId": {
|
||||
"type": "string"
|
||||
},
|
||||
"targetTrailId": {
|
||||
"type": "string"
|
||||
},
|
||||
"settings": {
|
||||
"$ref": "#/components/schemas/TrailMergeSettings"
|
||||
}
|
||||
}
|
||||
},
|
||||
"TrailMergeExecuteResponse": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"acknowledged"
|
||||
],
|
||||
"properties": {
|
||||
"acknowledged": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ListResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
Reference in New Issue
Block a user