mirror of
https://github.com/hay-kot/homebox.git
synced 2024-11-25 18:15:40 +00:00
fix: refactoring errors (#359)
* #352 - require one date to be set to save * fix many type regressions
This commit is contained in:
parent
4a8ba6231d
commit
97fb94d231
22 changed files with 164 additions and 289 deletions
|
@ -9,6 +9,14 @@ import (
|
||||||
"github.com/hay-kot/safeserve/server"
|
"github.com/hay-kot/safeserve/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Results[T any] struct {
|
||||||
|
Items []T `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func WrapResults[T any](items []T) Results[T] {
|
||||||
|
return Results[T]{Items: items}
|
||||||
|
}
|
||||||
|
|
||||||
type Wrapped struct {
|
type Wrapped struct {
|
||||||
Item interface{} `json:"item"`
|
Item interface{} `json:"item"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
// @Summary Get All Labels
|
// @Summary Get All Labels
|
||||||
// @Tags Labels
|
// @Tags Labels
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} Wrapped{items=[]repo.LabelOut}
|
// @Success 200 {object} []repo.LabelOut
|
||||||
// @Router /v1/labels [GET]
|
// @Router /v1/labels [GET]
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func (ctrl *V1Controller) HandleLabelsGetAll() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLabelsGetAll() errchain.HandlerFunc {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
// @Tags Locations
|
// @Tags Locations
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param withItems query bool false "include items in response tree"
|
// @Param withItems query bool false "include items in response tree"
|
||||||
// @Success 200 {object} Wrapped{items=[]repo.TreeItem}
|
// @Success 200 {object} []repo.TreeItem
|
||||||
// @Router /v1/locations/tree [GET]
|
// @Router /v1/locations/tree [GET]
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func (ctrl *V1Controller) HandleLocationTreeQuery() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLocationTreeQuery() errchain.HandlerFunc {
|
||||||
|
@ -34,7 +34,7 @@ func (ctrl *V1Controller) HandleLocationTreeQuery() errchain.HandlerFunc {
|
||||||
// @Tags Locations
|
// @Tags Locations
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param filterChildren query bool false "Filter locations with parents"
|
// @Param filterChildren query bool false "Filter locations with parents"
|
||||||
// @Success 200 {object} Wrapped{items=[]repo.LocationOutCount}
|
// @Success 200 {object} []repo.LocationOutCount
|
||||||
// @Router /v1/locations [GET]
|
// @Router /v1/locations [GET]
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func (ctrl *V1Controller) HandleLocationGetAll() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLocationGetAll() errchain.HandlerFunc {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
// @Summary Get Notifiers
|
// @Summary Get Notifiers
|
||||||
// @Tags Notifiers
|
// @Tags Notifiers
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} Wrapped{items=[]repo.NotifierOut}
|
// @Success 200 {object} []repo.NotifierOut
|
||||||
// @Router /v1/notifiers [GET]
|
// @Router /v1/notifiers [GET]
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func (ctrl *V1Controller) HandleGetUserNotifiers() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleGetUserNotifiers() errchain.HandlerFunc {
|
||||||
|
|
|
@ -945,14 +945,6 @@ const docTemplate = `{
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.LabelOut"
|
"$ref": "#/definitions/repo.LabelOut"
|
||||||
|
@ -960,10 +952,6 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -1117,14 +1105,6 @@ const docTemplate = `{
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.LocationOutCount"
|
"$ref": "#/definitions/repo.LocationOutCount"
|
||||||
|
@ -1132,10 +1112,6 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -1197,14 +1173,6 @@ const docTemplate = `{
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.TreeItem"
|
"$ref": "#/definitions/repo.TreeItem"
|
||||||
|
@ -1212,10 +1180,6 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/v1/locations/{id}": {
|
"/v1/locations/{id}": {
|
||||||
|
@ -1337,14 +1301,6 @@ const docTemplate = `{
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.NotifierOut"
|
"$ref": "#/definitions/repo.NotifierOut"
|
||||||
|
@ -1352,10 +1308,6 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -1917,14 +1869,12 @@ const docTemplate = `{
|
||||||
"repo.ItemCreate": {
|
"repo.ItemCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
"description",
|
|
||||||
"name"
|
"name"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 1000,
|
"maxLength": 1000
|
||||||
"minLength": 1
|
|
||||||
},
|
},
|
||||||
"labelIds": {
|
"labelIds": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
@ -2433,6 +2383,9 @@ const docTemplate = `{
|
||||||
},
|
},
|
||||||
"repo.MaintenanceEntryCreate": {
|
"repo.MaintenanceEntryCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"completedDate": {
|
"completedDate": {
|
||||||
"description": "Sold",
|
"description": "Sold",
|
||||||
|
|
|
@ -937,14 +937,6 @@
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.LabelOut"
|
"$ref": "#/definitions/repo.LabelOut"
|
||||||
|
@ -952,10 +944,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -1109,14 +1097,6 @@
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.LocationOutCount"
|
"$ref": "#/definitions/repo.LocationOutCount"
|
||||||
|
@ -1124,10 +1104,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -1189,14 +1165,6 @@
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.TreeItem"
|
"$ref": "#/definitions/repo.TreeItem"
|
||||||
|
@ -1204,10 +1172,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/v1/locations/{id}": {
|
"/v1/locations/{id}": {
|
||||||
|
@ -1329,14 +1293,6 @@
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.NotifierOut"
|
"$ref": "#/definitions/repo.NotifierOut"
|
||||||
|
@ -1344,10 +1300,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -1909,14 +1861,12 @@
|
||||||
"repo.ItemCreate": {
|
"repo.ItemCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
"description",
|
|
||||||
"name"
|
"name"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 1000,
|
"maxLength": 1000
|
||||||
"minLength": 1
|
|
||||||
},
|
},
|
||||||
"labelIds": {
|
"labelIds": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
@ -2425,6 +2375,9 @@
|
||||||
},
|
},
|
||||||
"repo.MaintenanceEntryCreate": {
|
"repo.MaintenanceEntryCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"completedDate": {
|
"completedDate": {
|
||||||
"description": "Sold",
|
"description": "Sold",
|
||||||
|
|
|
@ -77,7 +77,6 @@ definitions:
|
||||||
properties:
|
properties:
|
||||||
description:
|
description:
|
||||||
maxLength: 1000
|
maxLength: 1000
|
||||||
minLength: 1
|
|
||||||
type: string
|
type: string
|
||||||
labelIds:
|
labelIds:
|
||||||
items:
|
items:
|
||||||
|
@ -94,7 +93,6 @@ definitions:
|
||||||
type: string
|
type: string
|
||||||
x-nullable: true
|
x-nullable: true
|
||||||
required:
|
required:
|
||||||
- description
|
|
||||||
- name
|
- name
|
||||||
type: object
|
type: object
|
||||||
repo.ItemField:
|
repo.ItemField:
|
||||||
|
@ -442,6 +440,8 @@ definitions:
|
||||||
scheduledDate:
|
scheduledDate:
|
||||||
description: Sold
|
description: Sold
|
||||||
type: string
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
type: object
|
type: object
|
||||||
repo.MaintenanceEntryUpdate:
|
repo.MaintenanceEntryUpdate:
|
||||||
properties:
|
properties:
|
||||||
|
@ -1258,14 +1258,9 @@ paths:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
allOf:
|
|
||||||
- $ref: '#/definitions/v1.Wrapped'
|
|
||||||
- properties:
|
|
||||||
items:
|
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/repo.LabelOut'
|
$ref: '#/definitions/repo.LabelOut'
|
||||||
type: array
|
type: array
|
||||||
type: object
|
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get All Labels
|
summary: Get All Labels
|
||||||
|
@ -1360,14 +1355,9 @@ paths:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
allOf:
|
|
||||||
- $ref: '#/definitions/v1.Wrapped'
|
|
||||||
- properties:
|
|
||||||
items:
|
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/repo.LocationOutCount'
|
$ref: '#/definitions/repo.LocationOutCount'
|
||||||
type: array
|
type: array
|
||||||
type: object
|
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get All Locations
|
summary: Get All Locations
|
||||||
|
@ -1468,14 +1458,9 @@ paths:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
allOf:
|
|
||||||
- $ref: '#/definitions/v1.Wrapped'
|
|
||||||
- properties:
|
|
||||||
items:
|
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/repo.TreeItem'
|
$ref: '#/definitions/repo.TreeItem'
|
||||||
type: array
|
type: array
|
||||||
type: object
|
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get Locations Tree
|
summary: Get Locations Tree
|
||||||
|
@ -1489,14 +1474,9 @@ paths:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
allOf:
|
|
||||||
- $ref: '#/definitions/v1.Wrapped'
|
|
||||||
- properties:
|
|
||||||
items:
|
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/repo.NotifierOut'
|
$ref: '#/definitions/repo.NotifierOut'
|
||||||
type: array
|
type: array
|
||||||
type: object
|
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get Notifiers
|
summary: Get Notifiers
|
||||||
|
|
|
@ -61,6 +61,7 @@ func (svc *UserService) RegisterUser(ctx context.Context, data UserRegistration)
|
||||||
|
|
||||||
switch data.GroupToken {
|
switch data.GroupToken {
|
||||||
case "":
|
case "":
|
||||||
|
log.Debug().Msg("creating new group")
|
||||||
creatingGroup = true
|
creatingGroup = true
|
||||||
group, err = svc.repos.Groups.GroupCreate(ctx, "Home")
|
group, err = svc.repos.Groups.GroupCreate(ctx, "Home")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -68,6 +69,7 @@ func (svc *UserService) RegisterUser(ctx context.Context, data UserRegistration)
|
||||||
return repo.UserOut{}, err
|
return repo.UserOut{}, err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
log.Debug().Msg("joining existing group")
|
||||||
token, err = svc.repos.Groups.InvitationGet(ctx, hasher.HashToken(data.GroupToken))
|
token, err = svc.repos.Groups.InvitationGet(ctx, hasher.HashToken(data.GroupToken))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("Failed to get invitation token")
|
log.Err(err).Msg("Failed to get invitation token")
|
||||||
|
@ -94,14 +96,14 @@ func (svc *UserService) RegisterUser(ctx context.Context, data UserRegistration)
|
||||||
// Create the default labels and locations for the group.
|
// Create the default labels and locations for the group.
|
||||||
if creatingGroup {
|
if creatingGroup {
|
||||||
for _, label := range defaultLabels() {
|
for _, label := range defaultLabels() {
|
||||||
_, err := svc.repos.Labels.Create(ctx, group.ID, label)
|
_, err := svc.repos.Labels.Create(ctx, usr.GroupID, label)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return repo.UserOut{}, err
|
return repo.UserOut{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, location := range defaultLocations() {
|
for _, location := range defaultLocations() {
|
||||||
_, err := svc.repos.Locations.Create(ctx, group.ID, location)
|
_, err := svc.repos.Locations.Create(ctx, usr.GroupID, location)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return repo.UserOut{}, err
|
return repo.UserOut{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,11 +234,17 @@ func (r *GroupRepository) StatsGroup(ctx context.Context, GID uuid.UUID) (GroupS
|
||||||
var stats GroupStatistics
|
var stats GroupStatistics
|
||||||
row := r.db.Sql().QueryRowContext(ctx, q, GID, GID, GID, GID, GID, GID)
|
row := r.db.Sql().QueryRowContext(ctx, q, GID, GID, GID, GID, GID, GID)
|
||||||
|
|
||||||
err := row.Scan(&stats.TotalUsers, &stats.TotalItems, &stats.TotalLocations, &stats.TotalLabels, &stats.TotalItemPrice, &stats.TotalWithWarranty)
|
var maybeTotalItemPrice *float64
|
||||||
|
var maybeTotalWithWarranty *int
|
||||||
|
|
||||||
|
err := row.Scan(&stats.TotalUsers, &stats.TotalItems, &stats.TotalLocations, &stats.TotalLabels, &maybeTotalItemPrice, &maybeTotalWithWarranty)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GroupStatistics{}, err
|
return GroupStatistics{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stats.TotalItemPrice = orDefault(maybeTotalItemPrice, 0)
|
||||||
|
stats.TotalWithWarranty = orDefault(maybeTotalWithWarranty, 0)
|
||||||
|
|
||||||
return stats, nil
|
return stats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ type (
|
||||||
ImportRef string `json:"-"`
|
ImportRef string `json:"-"`
|
||||||
ParentID uuid.UUID `json:"parentId" extensions:"x-nullable"`
|
ParentID uuid.UUID `json:"parentId" extensions:"x-nullable"`
|
||||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||||
Description string `json:"description" validate:"required,min=1,max=1000"`
|
Description string `json:"description" validate:"max=1000"`
|
||||||
AssetID AssetID `json:"-"`
|
AssetID AssetID `json:"-"`
|
||||||
|
|
||||||
// Edges
|
// Edges
|
||||||
|
|
|
@ -2,6 +2,7 @@ package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
@ -18,15 +19,38 @@ import (
|
||||||
type MaintenanceEntryRepository struct {
|
type MaintenanceEntryRepository struct {
|
||||||
db *ent.Client
|
db *ent.Client
|
||||||
}
|
}
|
||||||
type (
|
|
||||||
MaintenanceEntryCreate struct {
|
type MaintenanceEntryCreate struct {
|
||||||
|
CompletedDate types.Date `json:"completedDate"`
|
||||||
|
ScheduledDate types.Date `json:"scheduledDate"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Cost float64 `json:"cost,string"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc MaintenanceEntryCreate) Validate() error {
|
||||||
|
if mc.CompletedDate.Time().IsZero() && mc.ScheduledDate.Time().IsZero() {
|
||||||
|
return errors.New("either completedDate or scheduledDate must be set")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type MaintenanceEntryUpdate struct {
|
||||||
CompletedDate types.Date `json:"completedDate"`
|
CompletedDate types.Date `json:"completedDate"`
|
||||||
ScheduledDate types.Date `json:"scheduledDate"`
|
ScheduledDate types.Date `json:"scheduledDate"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Cost float64 `json:"cost,string"`
|
Cost float64 `json:"cost,string"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mu MaintenanceEntryUpdate) Validate() error {
|
||||||
|
if mu.CompletedDate.Time().IsZero() && mu.ScheduledDate.Time().IsZero() {
|
||||||
|
return errors.New("either completedDate or scheduledDate must be set")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
MaintenanceEntry struct {
|
MaintenanceEntry struct {
|
||||||
ID uuid.UUID `json:"id"`
|
ID uuid.UUID `json:"id"`
|
||||||
CompletedDate types.Date `json:"completedDate"`
|
CompletedDate types.Date `json:"completedDate"`
|
||||||
|
@ -36,14 +60,6 @@ type (
|
||||||
Cost float64 `json:"cost,string"`
|
Cost float64 `json:"cost,string"`
|
||||||
}
|
}
|
||||||
|
|
||||||
MaintenanceEntryUpdate struct {
|
|
||||||
CompletedDate types.Date `json:"completedDate"`
|
|
||||||
ScheduledDate types.Date `json:"scheduledDate"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Cost float64 `json:"cost,string"`
|
|
||||||
}
|
|
||||||
|
|
||||||
MaintenanceLog struct {
|
MaintenanceLog struct {
|
||||||
ItemID uuid.UUID `json:"itemId"`
|
ItemID uuid.UUID `json:"itemId"`
|
||||||
CostAverage float64 `json:"costAverage"`
|
CostAverage float64 `json:"costAverage"`
|
||||||
|
|
|
@ -29,20 +29,31 @@ func DecodeQuery[T any](r *http.Request) (T, error) {
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Validator interface {
|
||||||
|
Validate() error
|
||||||
|
}
|
||||||
|
|
||||||
func DecodeBody[T any](r *http.Request) (T, error) {
|
func DecodeBody[T any](r *http.Request) (T, error) {
|
||||||
var v T
|
var val T
|
||||||
|
|
||||||
err := server.Decode(r, &v)
|
err := server.Decode(r, &val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v, errors.Wrap(err, "body decoding error")
|
return val, errors.Wrap(err, "body decoding error")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = validate.Check(v)
|
err = validate.Check(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v, errors.Wrap(err, "validation error")
|
return val, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return v, nil
|
if v, ok := any(val).(Validator); ok {
|
||||||
|
err = v.Validate()
|
||||||
|
if err != nil {
|
||||||
|
return val, errors.Wrap(err, "validation error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return val, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RouteUUID(r *http.Request, key string) (uuid.UUID, error) {
|
func RouteUUID(r *http.Request, key string) (uuid.UUID, error) {
|
||||||
|
|
|
@ -937,14 +937,6 @@
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.LabelOut"
|
"$ref": "#/definitions/repo.LabelOut"
|
||||||
|
@ -952,10 +944,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -1109,14 +1097,6 @@
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.LocationOutCount"
|
"$ref": "#/definitions/repo.LocationOutCount"
|
||||||
|
@ -1124,10 +1104,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -1189,14 +1165,6 @@
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.TreeItem"
|
"$ref": "#/definitions/repo.TreeItem"
|
||||||
|
@ -1204,10 +1172,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/v1/locations/{id}": {
|
"/v1/locations/{id}": {
|
||||||
|
@ -1329,14 +1293,6 @@
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/v1.Wrapped"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/repo.NotifierOut"
|
"$ref": "#/definitions/repo.NotifierOut"
|
||||||
|
@ -1344,10 +1300,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -1909,14 +1861,12 @@
|
||||||
"repo.ItemCreate": {
|
"repo.ItemCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
"description",
|
|
||||||
"name"
|
"name"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 1000,
|
"maxLength": 1000
|
||||||
"minLength": 1
|
|
||||||
},
|
},
|
||||||
"labelIds": {
|
"labelIds": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
@ -2425,6 +2375,9 @@
|
||||||
},
|
},
|
||||||
"repo.MaintenanceEntryCreate": {
|
"repo.MaintenanceEntryCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"completedDate": {
|
"completedDate": {
|
||||||
"description": "Sold",
|
"description": "Sold",
|
||||||
|
|
|
@ -15,12 +15,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const api = useUserApi();
|
|
||||||
|
|
||||||
function getQRCodeUrl(): string {
|
function getQRCodeUrl(): string {
|
||||||
const currentURL = window.location.href;
|
const currentURL = window.location.href;
|
||||||
|
|
||||||
return `/api/v1/qrcode?data=${encodeURIComponent(currentURL)}&access_token=${api.items.attachmentToken}`;
|
return `/api/v1/qrcode?data=${encodeURIComponent(currentURL)}`;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,10 @@ export function flatTree(tree: TreeItem[]): Ref<FlatTreeItem[]> {
|
||||||
// the display is a string of the tree hierarchy separated by breadcrumbs
|
// the display is a string of the tree hierarchy separated by breadcrumbs
|
||||||
|
|
||||||
function flatten(items: TreeItem[], display: string) {
|
function flatten(items: TreeItem[], display: string) {
|
||||||
|
if (!items) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
v.value.push({
|
v.value.push({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
|
@ -40,5 +44,5 @@ export async function useFlatLocations(): Promise<Ref<FlatTreeItem[]>> {
|
||||||
return ref([]);
|
return ref([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return flatTree(locations.data.items);
|
return flatTree(locations.data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { BaseAPI, route } from "../base";
|
import { BaseAPI, route } from "../base";
|
||||||
import { LabelCreate, LabelOut } from "../types/data-contracts";
|
import { LabelCreate, LabelOut } from "../types/data-contracts";
|
||||||
import { Results } from "../types/non-generated";
|
|
||||||
|
|
||||||
export class LabelsApi extends BaseAPI {
|
export class LabelsApi extends BaseAPI {
|
||||||
getAll() {
|
getAll() {
|
||||||
return this.http.get<Results<LabelOut>>({ url: route("/labels") });
|
return this.http.get<LabelOut[]>({ url: route("/labels") });
|
||||||
}
|
}
|
||||||
|
|
||||||
create(body: LabelCreate) {
|
create(body: LabelCreate) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { BaseAPI, route } from "../base";
|
import { BaseAPI, route } from "../base";
|
||||||
import { LocationOutCount, LocationCreate, LocationOut, LocationUpdate, TreeItem } from "../types/data-contracts";
|
import { LocationOutCount, LocationCreate, LocationOut, LocationUpdate, TreeItem } from "../types/data-contracts";
|
||||||
import { Results } from "../types/non-generated";
|
|
||||||
|
|
||||||
export type LocationsQuery = {
|
export type LocationsQuery = {
|
||||||
filterChildren: boolean;
|
filterChildren: boolean;
|
||||||
|
@ -12,11 +11,11 @@ export type TreeQuery = {
|
||||||
|
|
||||||
export class LocationsApi extends BaseAPI {
|
export class LocationsApi extends BaseAPI {
|
||||||
getAll(q: LocationsQuery = { filterChildren: false }) {
|
getAll(q: LocationsQuery = { filterChildren: false }) {
|
||||||
return this.http.get<Results<LocationOutCount>>({ url: route("/locations", q) });
|
return this.http.get<LocationOutCount[]>({ url: route("/locations", q) });
|
||||||
}
|
}
|
||||||
|
|
||||||
getTree(tq = { withItems: false }) {
|
getTree(tq = { withItems: false }) {
|
||||||
return this.http.get<Results<TreeItem>>({ url: route("/locations/tree", tq) });
|
return this.http.get<TreeItem[]>({ url: route("/locations/tree", tq) });
|
||||||
}
|
}
|
||||||
|
|
||||||
create(body: LocationCreate) {
|
create(body: LocationCreate) {
|
||||||
|
|
|
@ -57,10 +57,7 @@ export interface ItemAttachmentUpdate {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ItemCreate {
|
export interface ItemCreate {
|
||||||
/**
|
/** @maxLength 1000 */
|
||||||
* @minLength 1
|
|
||||||
* @maxLength 1000
|
|
||||||
*/
|
|
||||||
description: string;
|
description: string;
|
||||||
labelIds: string[];
|
labelIds: string[];
|
||||||
/** Edges */
|
/** Edges */
|
||||||
|
|
|
@ -10,10 +10,6 @@ export type Result<T> = {
|
||||||
item: T;
|
item: T;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Results<T> = {
|
|
||||||
items: T[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface PaginationResult<T> {
|
export interface PaginationResult<T> {
|
||||||
items: T[];
|
items: T[];
|
||||||
page: number;
|
page: number;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return data.items;
|
return data;
|
||||||
});
|
});
|
||||||
|
|
||||||
const locationTreeId = "locationTree";
|
const locationTreeId = "locationTree";
|
||||||
|
|
|
@ -19,7 +19,7 @@ export const useLabelStore = defineStore("labels", {
|
||||||
console.error(result.error);
|
console.error(result.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.allLabels = result.data.items;
|
this.allLabels = result.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return state.allLabels ?? [];
|
return state.allLabels ?? [];
|
||||||
|
@ -32,7 +32,7 @@ export const useLabelStore = defineStore("labels", {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.allLabels = result.data.items;
|
this.allLabels = result.data;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,7 +22,7 @@ export const useLocationStore = defineStore("locations", {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.parents = result.data.items;
|
this.parents = result.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return state.parents ?? [];
|
return state.parents ?? [];
|
||||||
|
@ -35,7 +35,7 @@ export const useLocationStore = defineStore("locations", {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Locations = result.data.items;
|
this.Locations = result.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return state.Locations ?? [];
|
return state.Locations ?? [];
|
||||||
|
@ -48,7 +48,7 @@ export const useLocationStore = defineStore("locations", {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.parents = result.data.items;
|
this.parents = result.data;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
async refreshChildren(): ReturnType<LocationsApi["getAll"]> {
|
async refreshChildren(): ReturnType<LocationsApi["getAll"]> {
|
||||||
|
@ -57,7 +57,7 @@ export const useLocationStore = defineStore("locations", {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Locations = result.data.items;
|
this.Locations = result.data;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue