feat: improved duplicate (#927)

* feat: improved duplicate

* feat: enhance item duplication process with transaction handling and error logging for attachments and fields

* feat: add error logging during transaction rollback in item duplication process for better debugging

* feat: don't try and rollback is the commit succeeded

* feat: add customizable duplication options for items, including prefix and field copying settings in API and UI

* fix: simplify duplication checks for custom fields, attachments, and maintenance entries in ItemsRepository duplication method

* refactor: import DuplicateSettings type from composables and sort import issues
This commit is contained in:
Tonya
2025-08-23 16:17:15 +01:00
committed by GitHub
parent 8b711eda99
commit 788d0b1c7e
18 changed files with 643 additions and 29 deletions

View File

@@ -254,6 +254,25 @@ func (ctrl *V1Controller) HandleItemPatch() errchain.HandlerFunc {
return adapters.ActionID("id", fn, http.StatusOK)
}
// HandleItemDuplicate godocs
//
// @Summary Duplicate Item
// @Tags Items
// @Produce json
// @Param id path string true "Item ID"
// @Param payload body repo.DuplicateOptions true "Duplicate Options"
// @Success 201 {object} repo.ItemOut
// @Router /v1/items/{id}/duplicate [POST]
// @Security Bearer
func (ctrl *V1Controller) HandleItemDuplicate() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID, options repo.DuplicateOptions) (repo.ItemOut, error) {
ctx := services.NewContext(r.Context())
return ctrl.svc.Items.Duplicate(ctx, ctx.GID, ID, options)
}
return adapters.ActionID("id", fn, http.StatusCreated)
}
// HandleGetAllCustomFieldNames godocs
//
// @Summary Get All Custom Field Names

View File

@@ -129,6 +129,7 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR
r.Put("/items/{id}", chain.ToHandlerFunc(v1Ctrl.HandleItemUpdate(), userMW...))
r.Patch("/items/{id}", chain.ToHandlerFunc(v1Ctrl.HandleItemPatch(), userMW...))
r.Delete("/items/{id}", chain.ToHandlerFunc(v1Ctrl.HandleItemDelete(), userMW...))
r.Post("/items/{id}/duplicate", chain.ToHandlerFunc(v1Ctrl.HandleItemDuplicate(), userMW...))
r.Post("/items/{id}/attachments", chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentCreate(), userMW...))
r.Put("/items/{id}/attachments/{attachment_id}", chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentUpdate(), userMW...))

View File

@@ -943,6 +943,48 @@ const docTemplate = `{
}
}
},
"/v1/items/{id}/duplicate": {
"post": {
"security": [
{
"Bearer": []
}
],
"produces": [
"application/json"
],
"tags": [
"Items"
],
"summary": "Duplicate Item",
"parameters": [
{
"type": "string",
"description": "Item ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Duplicate Options",
"name": "payload",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/repo.DuplicateOptions"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/repo.ItemOut"
}
}
}
}
},
"/v1/items/{id}/maintenance": {
"get": {
"security": [
@@ -3129,6 +3171,23 @@ const docTemplate = `{
}
}
},
"repo.DuplicateOptions": {
"type": "object",
"properties": {
"copyAttachments": {
"type": "boolean"
},
"copyCustomFields": {
"type": "boolean"
},
"copyMaintenance": {
"type": "boolean"
},
"copyPrefix": {
"type": "string"
}
}
},
"repo.Group": {
"type": "object",
"properties": {

View File

@@ -941,6 +941,48 @@
}
}
},
"/v1/items/{id}/duplicate": {
"post": {
"security": [
{
"Bearer": []
}
],
"produces": [
"application/json"
],
"tags": [
"Items"
],
"summary": "Duplicate Item",
"parameters": [
{
"type": "string",
"description": "Item ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Duplicate Options",
"name": "payload",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/repo.DuplicateOptions"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/repo.ItemOut"
}
}
}
}
},
"/v1/items/{id}/maintenance": {
"get": {
"security": [
@@ -3127,6 +3169,23 @@
}
}
},
"repo.DuplicateOptions": {
"type": "object",
"properties": {
"copyAttachments": {
"type": "boolean"
},
"copyCustomFields": {
"type": "boolean"
},
"copyMaintenance": {
"type": "boolean"
},
"copyPrefix": {
"type": "string"
}
}
},
"repo.Group": {
"type": "object",
"properties": {

View File

@@ -667,6 +667,17 @@ definitions:
search_engine_name:
type: string
type: object
repo.DuplicateOptions:
properties:
copyAttachments:
type: boolean
copyCustomFields:
type: boolean
copyMaintenance:
type: boolean
copyPrefix:
type: string
type: object
repo.Group:
properties:
createdAt:
@@ -1968,6 +1979,32 @@ paths:
summary: Update Item Attachment
tags:
- Items Attachments
/v1/items/{id}/duplicate:
post:
parameters:
- description: Item ID
in: path
name: id
required: true
type: string
- description: Duplicate Options
in: body
name: payload
required: true
schema:
$ref: '#/definitions/repo.DuplicateOptions'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/repo.ItemOut'
security:
- Bearer: []
summary: Duplicate Item
tags:
- Items
/v1/items/{id}/maintenance:
get:
parameters: