62 lines
1.7 KiB
Go
62 lines
1.7 KiB
Go
package files
|
|
|
|
import (
|
|
"time"
|
|
|
|
"git.apinb.com/bsm-sdk/core/infra"
|
|
fileerrors "git.apinb.com/ops/files/internal/errors"
|
|
"git.apinb.com/ops/files/internal/impl"
|
|
"git.apinb.com/ops/files/internal/models"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func CompleteUpload(ctx *gin.Context) {
|
|
fileObject, ok := loadOwnedFile(ctx)
|
|
if !ok {
|
|
return
|
|
}
|
|
if fileObject.Status != models.FileStatusPending {
|
|
infra.Response.Error(ctx, fileerrors.ErrUploadStatusConflict)
|
|
return
|
|
}
|
|
|
|
if fileObject.ExpiresAt == nil || !fileObject.ExpiresAt.After(time.Now()) {
|
|
infra.Response.Error(ctx, fileerrors.ErrUploadExpired)
|
|
return
|
|
}
|
|
|
|
objectInfo, err := impl.StorageService.Stat(ctx.Request.Context(), fileObject.ObjectKey)
|
|
if err != nil {
|
|
infra.Response.Error(ctx, fileerrors.ErrObjectStorageOperation)
|
|
return
|
|
}
|
|
if objectInfo.Size != fileObject.ExpectedSize {
|
|
infra.Response.Error(ctx, fileerrors.ErrObjectInfoMismatch)
|
|
return
|
|
}
|
|
|
|
completedAt := time.Now()
|
|
result := impl.DBService.Model(&models.FileObject{}).
|
|
Where("id = ? AND status = ? AND expires_at > ?", fileObject.ID, models.FileStatusPending, completedAt).
|
|
Updates(map[string]any{
|
|
"status": models.FileStatusReady,
|
|
"actual_size": objectInfo.Size,
|
|
"e_tag": objectInfo.ETag,
|
|
"completed_at": completedAt,
|
|
})
|
|
if result.Error != nil {
|
|
infra.Response.Error(ctx, fileerrors.ErrDatabaseOperation)
|
|
return
|
|
}
|
|
if result.RowsAffected != 1 {
|
|
infra.Response.Error(ctx, fileerrors.ErrUploadStatusConflict)
|
|
return
|
|
}
|
|
|
|
fileObject.Status = models.FileStatusReady
|
|
fileObject.ActualSize = objectInfo.Size
|
|
fileObject.ETag = objectInfo.ETag
|
|
fileObject.CompletedAt = &completedAt
|
|
infra.Response.Success(ctx, newFileResponse(fileObject))
|
|
}
|