forked from mirrors/homebox
Compare commits
141 commits
feat/new-n
...
main
Author | SHA1 | Date | |
---|---|---|---|
92b4c63792 | |||
|
0995478cc0 | ||
|
ae4b95301f | ||
|
d8482f3a13 | ||
|
1365bdfd46 | ||
|
2cd3c15215 | ||
|
0dc4fa5d98 | ||
|
318b8be192 | ||
|
63a966c526 | ||
|
db16d3fb23 | ||
|
1952b9f1cb | ||
|
2b31d46ab3 | ||
|
f3f96723b2 | ||
|
b28bb2c4a8 | ||
|
a33cf54a33 | ||
|
f13bf2958d | ||
|
a9712c48af | ||
|
e68b7cf500 | ||
|
744a5bbb47 | ||
|
fc5698410b | ||
|
455163d637 | ||
|
fbc7e6e33a | ||
|
5739b2005a | ||
|
5f41960c0a | ||
|
c89aa738cf | ||
|
94fd9c314d | ||
|
0876deb1e9 | ||
|
5438898b49 | ||
|
9fa17bec90 | ||
|
b5987f2e8d | ||
|
2cbcc8bb1d | ||
|
cceec06148 | ||
|
2e2eed143d | ||
|
272cc5a370 | ||
|
275e106d72 | ||
|
3f0e65a2ad | ||
|
22bbaae08f | ||
|
8c7d91ea52 | ||
|
5a219f6a9c | ||
|
895017b28e | ||
|
02ce52dbe3 | ||
|
c5ae6b17f9 | ||
|
371fc0a6af | ||
|
016780920d | ||
|
06eb6c1f91 | ||
|
27dad0e118 | ||
|
dc9446516a | ||
|
a042496c71 | ||
|
feab9f4c46 | ||
|
fe5622d62a | ||
|
e759f2817e | ||
|
60cc5c2710 | ||
|
25ccd678c9 | ||
|
a77b4cbe71 | ||
|
aae32b0d74 | ||
|
a94b43a19e | ||
|
9a4c2df552 | ||
|
d5b89a755e | ||
|
a9acf62d93 | ||
|
c896e198dd | ||
|
c538518b4b | ||
|
f66d14eeea | ||
|
bc8feac83c | ||
|
40a98bcf30 | ||
|
045e91d9ac | ||
|
a80ab0f3e9 | ||
|
e5d209d407 | ||
|
ef1531e561 | ||
|
4dd036abb2 | ||
|
81e909ccfb | ||
|
0cb9d2a8e4 | ||
|
cb16c0e829 | ||
|
9e067ee230 | ||
|
8b53d40a2a | ||
|
4c0ad7a5d8 | ||
|
66e25ba068 | ||
|
56c98e6e3a | ||
|
01f305a98e | ||
|
e14cdaccdd | ||
|
4ece25b58d | ||
|
c1957bb927 | ||
|
636ca155e5 | ||
|
17a5b43609 | ||
|
b2b3ccf923 | ||
|
2272c7eb6b | ||
|
181c324dd4 | ||
|
89912b18d7 | ||
|
85f2af4bc3 | ||
|
21ad5a32c1 | ||
|
4b51a4ad9a | ||
|
dd7e634b69 | ||
|
351ec64bbc | ||
|
3a758e012f | ||
|
c16084d99f | ||
|
5591267124 | ||
|
d46c16f01f | ||
|
18c22e8a68 | ||
|
64b3ac3e94 | ||
|
c36b9dcf5d | ||
|
d3b6c93b63 | ||
|
3b862e36c8 | ||
|
f3bb86d905 | ||
|
4dd925caf0 | ||
|
ced5aef6d1 | ||
|
6a853c07a0 | ||
|
f0b9a0fce4 | ||
|
00f09fec2f | ||
|
6e1863b515 | ||
|
dfe2084c74 | ||
|
0825f055a7 | ||
|
e1e04d49aa | ||
|
9020587c9e | ||
|
bd0db1ea37 | ||
|
d2985ff72c | ||
|
8c57ff841e | ||
|
0264bfb8c1 | ||
|
5dd6844536 | ||
|
0f8db862b4 | ||
|
be6b5c9c56 | ||
|
faed343eda | ||
|
ed1230e17d | ||
|
2d768e2b9c | ||
|
40e76bac0c | ||
|
840d220d4f | ||
|
975e636fb6 | ||
|
d1076baf84 | ||
|
40fcef4e9b | ||
|
97fb94d231 | ||
|
4a8ba6231d | ||
|
db80f8a159 | ||
|
184b494fc3 | ||
|
5a3fa23332 | ||
|
ef0690d511 | ||
|
9e55c880f6 | ||
|
cb9b20e2d2 | ||
|
a79e780b4e | ||
|
90cbb9bfd1 | ||
|
dc08dbbd7a | ||
|
1f47d96e4c | ||
|
23b5892aef | ||
|
2665b666f1 |
287 changed files with 21356 additions and 8570 deletions
|
@ -35,6 +35,6 @@
|
||||||
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||||
"remoteUser": "node",
|
"remoteUser": "node",
|
||||||
"features": {
|
"features": {
|
||||||
"golang": "1.19"
|
"golang": "1.20"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,3 +22,4 @@
|
||||||
**/secrets.dev.yaml
|
**/secrets.dev.yaml
|
||||||
**/values.dev.yaml
|
**/values.dev.yaml
|
||||||
README.md
|
README.md
|
||||||
|
!Dockerfile.rootless
|
||||||
|
|
4
.github/workflows/partial-backend.yaml
vendored
4
.github/workflows/partial-backend.yaml
vendored
|
@ -10,9 +10,9 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: 1.19
|
go-version: "1.20"
|
||||||
|
|
||||||
- name: Install Task
|
- name: Install Task
|
||||||
uses: arduino/setup-task@v1
|
uses: arduino/setup-task@v1
|
||||||
|
|
4
.github/workflows/partial-frontend.yaml
vendored
4
.github/workflows/partial-frontend.yaml
vendored
|
@ -44,9 +44,9 @@ jobs:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: 1.19
|
go-version: "1.20"
|
||||||
|
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
|
|
29
.github/workflows/partial-publish.yaml
vendored
29
.github/workflows/partial-publish.yaml
vendored
|
@ -22,9 +22,9 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: 1.19
|
go-version: "1.20"
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
id: qemu
|
id: qemu
|
||||||
|
@ -44,7 +44,7 @@ jobs:
|
||||||
env:
|
env:
|
||||||
CR_PAT: ${{ secrets.GH_TOKEN }}
|
CR_PAT: ${{ secrets.GH_TOKEN }}
|
||||||
|
|
||||||
- name: build nightly the image
|
- name: build nightly image
|
||||||
if: ${{ inputs.release == false }}
|
if: ${{ inputs.release == false }}
|
||||||
run: |
|
run: |
|
||||||
docker build --push --no-cache \
|
docker build --push --no-cache \
|
||||||
|
@ -53,6 +53,16 @@ jobs:
|
||||||
--build-arg=BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
|
--build-arg=BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
|
||||||
--platform=linux/amd64,linux/arm64,linux/arm/v7 .
|
--platform=linux/amd64,linux/arm64,linux/arm/v7 .
|
||||||
|
|
||||||
|
- name: build nightly-rootless image
|
||||||
|
if: ${{ inputs.release == false }}
|
||||||
|
run: |
|
||||||
|
docker build --push --no-cache \
|
||||||
|
--tag=ghcr.io/hay-kot/homebox:${{ inputs.tag }}-rootless \
|
||||||
|
--build-arg=COMMIT=$(git rev-parse HEAD) \
|
||||||
|
--build-arg=BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
|
||||||
|
--file Dockerfile.rootless \
|
||||||
|
--platform=linux/amd64,linux/arm64,linux/arm/v7 .
|
||||||
|
|
||||||
- name: build release tagged the image
|
- name: build release tagged the image
|
||||||
if: ${{ inputs.release == true }}
|
if: ${{ inputs.release == true }}
|
||||||
run: |
|
run: |
|
||||||
|
@ -64,3 +74,16 @@ jobs:
|
||||||
--build-arg COMMIT=$(git rev-parse HEAD) \
|
--build-arg COMMIT=$(git rev-parse HEAD) \
|
||||||
--build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
|
--build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
|
||||||
--platform linux/amd64,linux/arm64,linux/arm/v7 .
|
--platform linux/amd64,linux/arm64,linux/arm/v7 .
|
||||||
|
|
||||||
|
- name: build release tagged the rootless image
|
||||||
|
if: ${{ inputs.release == true }}
|
||||||
|
run: |
|
||||||
|
docker build --push --no-cache \
|
||||||
|
--tag ghcr.io/hay-kot/homebox:nightly-rootless \
|
||||||
|
--tag ghcr.io/hay-kot/homebox:latest-rootless \
|
||||||
|
--tag ghcr.io/hay-kot/homebox:${{ inputs.tag }}-rootless \
|
||||||
|
--build-arg VERSION=${{ inputs.tag }} \
|
||||||
|
--build-arg COMMIT=$(git rev-parse HEAD) \
|
||||||
|
--build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
|
||||||
|
--platform linux/amd64,linux/arm64,linux/arm/v7 \
|
||||||
|
--file Dockerfile.rootless .
|
||||||
|
|
46
.github/workflows/publish.yaml
vendored
46
.github/workflows/publish.yaml
vendored
|
@ -1,31 +1,17 @@
|
||||||
name: Build Nightly
|
name: Publish Dockers
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
release:
|
|
||||||
types:
|
|
||||||
- published
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
|
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
backend-tests:
|
|
||||||
name: "Backend Server Tests"
|
|
||||||
uses: hay-kot/homebox/.github/workflows/partial-backend.yaml@main
|
|
||||||
|
|
||||||
frontend-tests:
|
|
||||||
name: "Frontend and End-to-End Tests"
|
|
||||||
uses: hay-kot/homebox/.github/workflows/partial-frontend.yaml@main
|
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
name: "Deploy Nightly to Fly.io"
|
name: "Deploy Nightly to Fly.io"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs:
|
|
||||||
- backend-tests
|
|
||||||
- frontend-tests
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: superfly/flyctl-actions/setup-flyctl@master
|
- uses: superfly/flyctl-actions/setup-flyctl@master
|
||||||
|
@ -34,40 +20,10 @@ jobs:
|
||||||
publish-nightly:
|
publish-nightly:
|
||||||
name: "Publish Nightly"
|
name: "Publish Nightly"
|
||||||
if: github.event_name != 'release'
|
if: github.event_name != 'release'
|
||||||
needs:
|
|
||||||
- backend-tests
|
|
||||||
- frontend-tests
|
|
||||||
uses: hay-kot/homebox/.github/workflows/partial-publish.yaml@main
|
uses: hay-kot/homebox/.github/workflows/partial-publish.yaml@main
|
||||||
with:
|
with:
|
||||||
tag: nightly
|
tag: nightly
|
||||||
secrets:
|
secrets:
|
||||||
GH_TOKEN: ${{ secrets.CR_PAT }}
|
GH_TOKEN: ${{ secrets.CR_PAT }}
|
||||||
|
|
||||||
publish-tag:
|
|
||||||
name: "Publish Tag"
|
|
||||||
if: github.event_name == 'release'
|
|
||||||
needs:
|
|
||||||
- backend-tests
|
|
||||||
- frontend-tests
|
|
||||||
uses: hay-kot/homebox/.github/workflows/partial-publish.yaml@main
|
|
||||||
with:
|
|
||||||
release: true
|
|
||||||
tag: ${{ github.event.release.tag_name }}
|
|
||||||
secrets:
|
|
||||||
GH_TOKEN: ${{ secrets.CR_PAT }}
|
|
||||||
|
|
||||||
deploy-docs:
|
|
||||||
name: Deploy docs
|
|
||||||
needs:
|
|
||||||
- publish-tag
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout main
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Deploy docs
|
|
||||||
uses: mhausenblas/mkdocs-deploy-gh-pages@master
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
CONFIG_FILE: docs/mkdocs.yml
|
|
||||||
EXTRA_PACKAGES: build-base
|
|
||||||
|
|
2
.github/workflows/pull-requests.yaml
vendored
2
.github/workflows/pull-requests.yaml
vendored
|
@ -12,4 +12,4 @@ jobs:
|
||||||
|
|
||||||
frontend-tests:
|
frontend-tests:
|
||||||
name: "Frontend and End-to-End Tests"
|
name: "Frontend and End-to-End Tests"
|
||||||
uses: ./.github/workflows/partial-frontend.yaml
|
uses: ./.github/workflows/partial-frontend.yaml
|
77
.github/workflows/tag.yaml
vendored
Normal file
77
.github/workflows/tag.yaml
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
name: Publish Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- v*
|
||||||
|
|
||||||
|
env:
|
||||||
|
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
backend-tests:
|
||||||
|
name: "Backend Server Tests"
|
||||||
|
uses: hay-kot/homebox/.github/workflows/partial-backend.yaml@main
|
||||||
|
|
||||||
|
frontend-tests:
|
||||||
|
name: "Frontend and End-to-End Tests"
|
||||||
|
uses: hay-kot/homebox/.github/workflows/partial-frontend.yaml@main
|
||||||
|
|
||||||
|
goreleaser:
|
||||||
|
name: goreleaser
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v4
|
||||||
|
|
||||||
|
- uses: pnpm/action-setup@v2
|
||||||
|
with:
|
||||||
|
version: 7.30.1
|
||||||
|
|
||||||
|
- name: Build Frontend and Copy to Backend
|
||||||
|
working-directory: frontend
|
||||||
|
run: |
|
||||||
|
pnpm install --shamefully-hoist
|
||||||
|
pnpm run build
|
||||||
|
cp -r ./.output/public ../backend/app/api/static/
|
||||||
|
|
||||||
|
- name: Run GoReleaser
|
||||||
|
uses: goreleaser/goreleaser-action@v4
|
||||||
|
with:
|
||||||
|
workdir: "backend"
|
||||||
|
distribution: goreleaser
|
||||||
|
version: latest
|
||||||
|
args: release --clean
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
publish-tag:
|
||||||
|
name: "Publish Tag"
|
||||||
|
uses: hay-kot/homebox/.github/workflows/partial-publish.yaml@main
|
||||||
|
with:
|
||||||
|
release: true
|
||||||
|
tag: ${{ github.ref_name }}
|
||||||
|
secrets:
|
||||||
|
GH_TOKEN: ${{ secrets.CR_PAT }}
|
||||||
|
|
||||||
|
deploy-docs:
|
||||||
|
name: Deploy docs
|
||||||
|
needs:
|
||||||
|
- publish-tag
|
||||||
|
- goreleaser
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout main
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Deploy docs
|
||||||
|
uses: mhausenblas/mkdocs-deploy-gh-pages@master
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
CONFIG_FILE: docs/mkdocs.yml
|
||||||
|
EXTRA_PACKAGES: build-base
|
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -48,4 +48,9 @@ dist
|
||||||
|
|
||||||
.pnpm-store
|
.pnpm-store
|
||||||
backend/app/api/app
|
backend/app/api/app
|
||||||
backend/app/api/__debug_bin
|
backend/app/api/__debug_bin
|
||||||
|
dist/
|
||||||
|
|
||||||
|
# Nuxt Publish Dir
|
||||||
|
backend/app/api/static/public/*
|
||||||
|
!backend/app/api/static/public/.gitkeep
|
33
.scaffold/model/scaffold.yaml
Normal file
33
.scaffold/model/scaffold.yaml
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
# yaml-language-server: $schema=https://hay-kot.github.io/scaffold/schema.json
|
||||||
|
messages:
|
||||||
|
pre: |
|
||||||
|
# Ent Model Generation
|
||||||
|
|
||||||
|
With Boilerplate!
|
||||||
|
post: |
|
||||||
|
Complete!
|
||||||
|
|
||||||
|
questions:
|
||||||
|
- name: "model"
|
||||||
|
prompt:
|
||||||
|
message: "What is the name of the model? (PascalCase)"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- name: "by_group"
|
||||||
|
prompt:
|
||||||
|
confirm: "Include a Group Edge? (group_id -> id)"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
rewrites:
|
||||||
|
- from: 'templates/model.go'
|
||||||
|
to: 'backend/internal/data/ent/schema/{{ lower .Scaffold.model }}.go'
|
||||||
|
|
||||||
|
inject:
|
||||||
|
- name: "Insert Groups Edge"
|
||||||
|
path: 'backend/internal/data/ent/schema/group.go'
|
||||||
|
at: // $scaffold_edge
|
||||||
|
template: |
|
||||||
|
{{- if .Scaffold.by_group -}}
|
||||||
|
owned("{{ lower .Scaffold.model }}s", {{ .Scaffold.model }}.Type),
|
||||||
|
{{- end -}}
|
40
.scaffold/model/templates/model.go
Normal file
40
.scaffold/model/templates/model.go
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
package schema
|
||||||
|
|
||||||
|
import (
|
||||||
|
"entgo.io/ent"
|
||||||
|
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins"
|
||||||
|
)
|
||||||
|
|
||||||
|
type {{ .Scaffold.model }} struct {
|
||||||
|
ent.Schema
|
||||||
|
}
|
||||||
|
|
||||||
|
func ({{ .Scaffold.model }}) Mixin() []ent.Mixin {
|
||||||
|
return []ent.Mixin{
|
||||||
|
mixins.BaseMixin{},
|
||||||
|
{{- if .Scaffold.by_group }}
|
||||||
|
GroupMixin{ref: "{{ snakecase .Scaffold.model }}s"},
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fields of the {{ .Scaffold.model }}.
|
||||||
|
func ({{ .Scaffold.model }}) Fields() []ent.Field {
|
||||||
|
return []ent.Field{
|
||||||
|
// field.String("name").
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edges of the {{ .Scaffold.model }}.
|
||||||
|
func ({{ .Scaffold.model }}) Edges() []ent.Edge {
|
||||||
|
return []ent.Edge{
|
||||||
|
// edge.From("group", Group.Type).
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ({{ .Scaffold.model }}) Indexes() []ent.Index {
|
||||||
|
return []ent.Index{
|
||||||
|
// index.Fields("token"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,4 +48,10 @@ start command `task: ui:dev`
|
||||||
|
|
||||||
1. The frontend is a Vue 3 app with Nuxt.js that uses Tailwind and DaisyUI for styling.
|
1. The frontend is a Vue 3 app with Nuxt.js that uses Tailwind and DaisyUI for styling.
|
||||||
2. We're using Vitest for our automated testing. you can run these with `task ui:watch`.
|
2. We're using Vitest for our automated testing. you can run these with `task ui:watch`.
|
||||||
3. Tests require the API server to be running and in some cases the first run will fail due to a race condition. If this happens just run the tests again and they should pass.
|
3. Tests require the API server to be running and in some cases the first run will fail due to a race condition. If this happens just run the tests again and they should pass.
|
||||||
|
|
||||||
|
## Publishing Release
|
||||||
|
|
||||||
|
Create a new tag in github with the version number vX.X.X. This will trigger a new release to be created.
|
||||||
|
|
||||||
|
Test -> Goreleaser -> Publish Release -> Trigger Docker Builds -> Deploy Docs + Fly.io Demo
|
14
Dockerfile
14
Dockerfile
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
# Build Nuxt
|
# Build Nuxt
|
||||||
FROM node:17-alpine as frontend-builder
|
FROM r.batts.cloud/node:18 as frontend-builder
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN npm install -g pnpm
|
RUN npm install -g pnpm
|
||||||
COPY frontend/package.json frontend/pnpm-lock.yaml ./
|
COPY frontend/package.json frontend/pnpm-lock.yaml ./
|
||||||
|
@ -9,32 +9,30 @@ COPY frontend .
|
||||||
RUN pnpm build
|
RUN pnpm build
|
||||||
|
|
||||||
# Build API
|
# Build API
|
||||||
FROM golang:alpine AS builder
|
FROM r.batts.cloud/golang:1.21 AS builder
|
||||||
ARG BUILD_TIME
|
ARG BUILD_TIME
|
||||||
ARG COMMIT
|
ARG COMMIT
|
||||||
ARG VERSION
|
ARG VERSION
|
||||||
RUN apk update && \
|
RUN apt update && \
|
||||||
apk upgrade && \
|
apt install -y git build-essential gcc g++
|
||||||
apk add --update git build-base gcc g++
|
|
||||||
|
|
||||||
WORKDIR /go/src/app
|
WORKDIR /go/src/app
|
||||||
COPY ./backend .
|
COPY ./backend .
|
||||||
RUN go get -d -v ./...
|
RUN go get -d -v ./...
|
||||||
RUN rm -rf ./app/api/public
|
RUN rm -rf ./app/api/public
|
||||||
COPY --from=frontend-builder /app/.output/public ./app/api/static/public
|
COPY --from=frontend-builder /app/.output/public ./app/api/static/public
|
||||||
RUN CGO_ENABLED=1 GOOS=linux go build \
|
RUN CGO_ENABLED=0 GOOS=linux go build \
|
||||||
-ldflags "-s -w -X main.commit=$COMMIT -X main.buildTime=$BUILD_TIME -X main.version=$VERSION" \
|
-ldflags "-s -w -X main.commit=$COMMIT -X main.buildTime=$BUILD_TIME -X main.version=$VERSION" \
|
||||||
-o /go/bin/api \
|
-o /go/bin/api \
|
||||||
-v ./app/api/*.go
|
-v ./app/api/*.go
|
||||||
|
|
||||||
# Production Stage
|
# Production Stage
|
||||||
FROM alpine:latest
|
FROM r.batts.cloud/debian:bookworm
|
||||||
|
|
||||||
ENV HBOX_MODE=production
|
ENV HBOX_MODE=production
|
||||||
ENV HBOX_STORAGE_DATA=/data/
|
ENV HBOX_STORAGE_DATA=/data/
|
||||||
ENV HBOX_STORAGE_SQLITE_URL=/data/homebox.db?_fk=1
|
ENV HBOX_STORAGE_SQLITE_URL=/data/homebox.db?_fk=1
|
||||||
|
|
||||||
RUN apk --no-cache add ca-certificates
|
|
||||||
RUN mkdir /app
|
RUN mkdir /app
|
||||||
COPY --from=builder /go/bin/api /app
|
COPY --from=builder /go/bin/api /app
|
||||||
|
|
||||||
|
|
53
Dockerfile.rootless
Normal file
53
Dockerfile.rootless
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
# Build Nuxt
|
||||||
|
FROM node:17-alpine as frontend-builder
|
||||||
|
WORKDIR /app
|
||||||
|
RUN npm install -g pnpm
|
||||||
|
COPY frontend/package.json frontend/pnpm-lock.yaml ./
|
||||||
|
RUN pnpm install --frozen-lockfile --shamefully-hoist
|
||||||
|
COPY frontend .
|
||||||
|
RUN pnpm build
|
||||||
|
|
||||||
|
# Build API
|
||||||
|
FROM golang:alpine AS builder
|
||||||
|
ARG BUILD_TIME
|
||||||
|
ARG COMMIT
|
||||||
|
ARG VERSION
|
||||||
|
RUN apk update && \
|
||||||
|
apk upgrade && \
|
||||||
|
apk add --update git build-base gcc g++
|
||||||
|
|
||||||
|
WORKDIR /go/src/app
|
||||||
|
COPY ./backend .
|
||||||
|
RUN go get -d -v ./...
|
||||||
|
RUN rm -rf ./app/api/public
|
||||||
|
COPY --from=frontend-builder /app/.output/public ./app/api/static/public
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux go build \
|
||||||
|
-ldflags "-s -w -X main.commit=$COMMIT -X main.buildTime=$BUILD_TIME -X main.version=$VERSION" \
|
||||||
|
-o /go/bin/api \
|
||||||
|
-v ./app/api/*.go && \
|
||||||
|
chmod +x /go/bin/api && \
|
||||||
|
# create a directory so that we can copy it in the next stage
|
||||||
|
mkdir /data
|
||||||
|
|
||||||
|
# Production Stage
|
||||||
|
FROM gcr.io/distroless/static
|
||||||
|
|
||||||
|
ENV HBOX_MODE=production
|
||||||
|
ENV HBOX_STORAGE_DATA=/data/
|
||||||
|
ENV HBOX_STORAGE_SQLITE_URL=/data/homebox.db?_fk=1
|
||||||
|
|
||||||
|
# Copy the binary and the (empty) /data dir and
|
||||||
|
# change the ownership to the low-privileged user
|
||||||
|
COPY --from=builder --chown=nonroot /go/bin/api /app
|
||||||
|
COPY --from=builder --chown=nonroot /data /data
|
||||||
|
|
||||||
|
LABEL Name=homebox Version=0.0.1
|
||||||
|
LABEL org.opencontainers.image.source="https://github.com/hay-kot/homebox"
|
||||||
|
EXPOSE 7745
|
||||||
|
VOLUME [ "/data" ]
|
||||||
|
|
||||||
|
# Drop root and run as low-privileged user
|
||||||
|
USER nonroot
|
||||||
|
ENTRYPOINT [ "/app" ]
|
||||||
|
CMD [ "/data/config.yml" ]
|
16
README.md
16
README.md
|
@ -16,10 +16,18 @@
|
||||||
[Configuration & Docker Compose](https://hay-kot.github.io/homebox/quick-start)
|
[Configuration & Docker Compose](https://hay-kot.github.io/homebox/quick-start)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run --name=homebox \
|
# If using the rootless image, ensure data
|
||||||
--restart=always \
|
# folder has correct permissions
|
||||||
--publish=3100:7745 \
|
mkdir -p /path/to/data/folder
|
||||||
ghcr.io/hay-kot/homebox:latest
|
chown 65532:65532 -R /path/to/data/folder
|
||||||
|
docker run -d \
|
||||||
|
--name homebox \
|
||||||
|
--restart unless-stopped \
|
||||||
|
--publish 3100:7745 \
|
||||||
|
--env TZ=Europe/Bucharest \
|
||||||
|
--volume /path/to/data/folder/:/data \
|
||||||
|
ghcr.io/hay-kot/homebox:latest
|
||||||
|
# ghcr.io/hay-kot/homebox:latest-rootless
|
||||||
```
|
```
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
51
Taskfile.yml
51
Taskfile.yml
|
@ -1,7 +1,7 @@
|
||||||
version: "3"
|
version: "3"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
HBOX_STORAGE_SQLITE_URL: .data/homebox.db?_fk=1
|
HBOX_STORAGE_SQLITE_URL: .data/homebox.db?_pragma=busy_timeout=1000&_pragma=journal_mode=WAL&_fk=1
|
||||||
HBOX_OPTIONS_ALLOW_REGISTRATION: true
|
HBOX_OPTIONS_ALLOW_REGISTRATION: true
|
||||||
UNSAFE_DISABLE_PASSWORD_PROJECTION: "yes_i_am_sure"
|
UNSAFE_DISABLE_PASSWORD_PROJECTION: "yes_i_am_sure"
|
||||||
tasks:
|
tasks:
|
||||||
|
@ -27,46 +27,47 @@ tasks:
|
||||||
--modular \
|
--modular \
|
||||||
--path ./backend/app/api/static/docs/swagger.json \
|
--path ./backend/app/api/static/docs/swagger.json \
|
||||||
--output ./frontend/lib/api/types
|
--output ./frontend/lib/api/types
|
||||||
- go run ./scripts/process-types/*.go ./frontend/lib/api/types/data-contracts.ts
|
- go run ./backend/app/tools/typegen/main.go ./frontend/lib/api/types/data-contracts.ts
|
||||||
|
- cp ./backend/app/api/static/docs/swagger.json docs/docs/api/openapi-2.0.json
|
||||||
sources:
|
sources:
|
||||||
- "./backend/app/api/**/*"
|
- "./backend/app/api/**/*"
|
||||||
- "./backend/internal/data/**"
|
- "./backend/internal/data/**"
|
||||||
- "./backend/internal/services/**/*"
|
- "./backend/internal/core/services/**/*"
|
||||||
- "./scripts/process-types.py"
|
- "./backend/app/tools/typegen/main.go"
|
||||||
generates:
|
|
||||||
- "./frontend/lib/api/types/data-contracts.ts"
|
|
||||||
- "./backend/internal/data/ent/schema"
|
|
||||||
- "./backend/app/api/static/docs/swagger.json"
|
|
||||||
- "./backend/app/api/static/docs/swagger.yaml"
|
|
||||||
|
|
||||||
go:run:
|
go:run:
|
||||||
desc: Starts the backend api server (depends on generate task)
|
desc: Starts the backend api server (depends on generate task)
|
||||||
|
dir: backend
|
||||||
deps:
|
deps:
|
||||||
- generate
|
- generate
|
||||||
cmds:
|
cmds:
|
||||||
- cd backend && go run ./app/api/ {{ .CLI_ARGS }}
|
- go run ./app/api/ {{ .CLI_ARGS }}
|
||||||
silent: false
|
silent: false
|
||||||
|
|
||||||
go:test:
|
go:test:
|
||||||
desc: Runs all go tests using gotestsum - supports passing gotestsum args
|
desc: Runs all go tests using gotestsum - supports passing gotestsum args
|
||||||
|
dir: backend
|
||||||
cmds:
|
cmds:
|
||||||
- cd backend && gotestsum {{ .CLI_ARGS }} ./...
|
- gotestsum {{ .CLI_ARGS }} ./...
|
||||||
|
|
||||||
go:coverage:
|
go:coverage:
|
||||||
desc: Runs all go tests with -race flag and generates a coverage report
|
desc: Runs all go tests with -race flag and generates a coverage report
|
||||||
|
dir: backend
|
||||||
cmds:
|
cmds:
|
||||||
- cd backend && go test -race -coverprofile=coverage.out -covermode=atomic ./app/... ./internal/... ./pkgs/... -v -cover
|
- go test -race -coverprofile=coverage.out -covermode=atomic ./app/... ./internal/... ./pkgs/... -v -cover
|
||||||
silent: true
|
silent: true
|
||||||
|
|
||||||
go:tidy:
|
go:tidy:
|
||||||
desc: Runs go mod tidy on the backend
|
desc: Runs go mod tidy on the backend
|
||||||
|
dir: backend
|
||||||
cmds:
|
cmds:
|
||||||
- cd backend && go mod tidy
|
- go mod tidy
|
||||||
|
|
||||||
go:lint:
|
go:lint:
|
||||||
desc: Runs golangci-lint
|
desc: Runs golangci-lint
|
||||||
|
dir: backend
|
||||||
cmds:
|
cmds:
|
||||||
- cd backend && golangci-lint run ./...
|
- golangci-lint run ./...
|
||||||
|
|
||||||
go:all:
|
go:all:
|
||||||
desc: Runs all go test and lint related tasks
|
desc: Runs all go test and lint related tasks
|
||||||
|
@ -77,19 +78,19 @@ tasks:
|
||||||
|
|
||||||
go:build:
|
go:build:
|
||||||
desc: Builds the backend binary
|
desc: Builds the backend binary
|
||||||
|
dir: backend
|
||||||
cmds:
|
cmds:
|
||||||
- cd backend && go build -o ../build/backend ./app/api
|
- go build -o ../build/backend ./app/api
|
||||||
|
|
||||||
db:generate:
|
db:generate:
|
||||||
desc: Run Entgo.io Code Generation
|
desc: Run Entgo.io Code Generation
|
||||||
|
dir: backend/internal/
|
||||||
cmds:
|
cmds:
|
||||||
- |
|
- |
|
||||||
cd backend/internal/ && go generate ./... \
|
go generate ./... \
|
||||||
--template=./data/ent/schema/templates/has_id.tmpl
|
--template=./data/ent/schema/templates/has_id.tmpl
|
||||||
sources:
|
sources:
|
||||||
- "./backend/internal/data/ent/schema/**/*"
|
- "./backend/internal/data/ent/schema/**/*"
|
||||||
generates:
|
|
||||||
- "./backend/internal/ent/"
|
|
||||||
|
|
||||||
db:migration:
|
db:migration:
|
||||||
desc: Runs the database diff engine to generate a SQL migration files
|
desc: Runs the database diff engine to generate a SQL migration files
|
||||||
|
@ -100,23 +101,27 @@ tasks:
|
||||||
|
|
||||||
ui:watch:
|
ui:watch:
|
||||||
desc: Starts the vitest test runner in watch mode
|
desc: Starts the vitest test runner in watch mode
|
||||||
|
dir: frontend
|
||||||
cmds:
|
cmds:
|
||||||
- cd frontend && pnpm run test:watch
|
- pnpm run test:watch
|
||||||
|
|
||||||
ui:dev:
|
ui:dev:
|
||||||
desc: Run frontend development server
|
desc: Run frontend development server
|
||||||
|
dir: frontend
|
||||||
cmds:
|
cmds:
|
||||||
- cd frontend && pnpm dev
|
- pnpm dev
|
||||||
|
|
||||||
ui:fix:
|
ui:fix:
|
||||||
desc: Runs prettier and eslint on the frontend
|
desc: Runs prettier and eslint on the frontend
|
||||||
|
dir: frontend
|
||||||
cmds:
|
cmds:
|
||||||
- cd frontend && pnpm run lint:fix
|
- pnpm run lint:fix
|
||||||
|
|
||||||
ui:check:
|
ui:check:
|
||||||
desc: Runs type checking
|
desc: Runs type checking
|
||||||
|
dir: frontend
|
||||||
cmds:
|
cmds:
|
||||||
- cd frontend && pnpm run typecheck
|
- pnpm run typecheck
|
||||||
|
|
||||||
test:ci:
|
test:ci:
|
||||||
desc: Runs end-to-end test on a live server (only for use in CI)
|
desc: Runs end-to-end test on a live server (only for use in CI)
|
||||||
|
@ -134,4 +139,4 @@ tasks:
|
||||||
- task: go:all
|
- task: go:all
|
||||||
- task: ui:check
|
- task: ui:check
|
||||||
- task: ui:fix
|
- task: ui:fix
|
||||||
- task: test:ci
|
- task: test:ci
|
||||||
|
|
2
backend/.gitignore
vendored
Normal file
2
backend/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
dist/
|
54
backend/.goreleaser.yaml
Normal file
54
backend/.goreleaser.yaml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# This is an example .goreleaser.yml file with some sensible defaults.
|
||||||
|
# Make sure to check the documentation at https://goreleaser.com
|
||||||
|
before:
|
||||||
|
hooks:
|
||||||
|
# you may remove this if you don't need go generate
|
||||||
|
- go generate ./...
|
||||||
|
builds:
|
||||||
|
- main: ./app/api
|
||||||
|
env:
|
||||||
|
- CGO_ENABLED=0
|
||||||
|
goos:
|
||||||
|
- linux
|
||||||
|
- windows
|
||||||
|
- darwin
|
||||||
|
goarch:
|
||||||
|
- amd64
|
||||||
|
- "386"
|
||||||
|
- arm
|
||||||
|
- arm64
|
||||||
|
ignore:
|
||||||
|
- goos: windows
|
||||||
|
goarch: arm
|
||||||
|
- goos: windows
|
||||||
|
goarch: "386"
|
||||||
|
|
||||||
|
archives:
|
||||||
|
- format: tar.gz
|
||||||
|
# this name template makes the OS and Arch compatible with the results of uname.
|
||||||
|
name_template: >-
|
||||||
|
{{ .ProjectName }}_
|
||||||
|
{{- title .Os }}_
|
||||||
|
{{- if eq .Arch "amd64" }}x86_64
|
||||||
|
{{- else if eq .Arch "386" }}i386
|
||||||
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
|
{{- if .Arm }}v{{ .Arm }}{{ end }}
|
||||||
|
# use zip for windows archives
|
||||||
|
format_overrides:
|
||||||
|
- goos: windows
|
||||||
|
format: zip
|
||||||
|
checksum:
|
||||||
|
name_template: 'checksums.txt'
|
||||||
|
snapshot:
|
||||||
|
name_template: "{{ incpatch .Version }}-next"
|
||||||
|
changelog:
|
||||||
|
sort: asc
|
||||||
|
filters:
|
||||||
|
exclude:
|
||||||
|
- '^docs:'
|
||||||
|
- '^test:'
|
||||||
|
|
||||||
|
# The lines beneath this are called `modelines`. See `:help modeline`
|
||||||
|
# Feel free to remove those if you don't want/use them.
|
||||||
|
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
||||||
|
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
|
BIN
backend/api
Executable file
BIN
backend/api
Executable file
Binary file not shown.
|
@ -4,11 +4,12 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/config"
|
"github.com/hay-kot/homebox/backend/internal/sys/config"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/mailer"
|
"github.com/hay-kot/homebox/backend/pkgs/mailer"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
type app struct {
|
type app struct {
|
||||||
|
@ -18,6 +19,7 @@ type app struct {
|
||||||
server *server.Server
|
server *server.Server
|
||||||
repos *repo.AllRepos
|
repos *repo.AllRepos
|
||||||
services *services.AllServices
|
services *services.AllServices
|
||||||
|
bus *eventbus.EventBus
|
||||||
}
|
}
|
||||||
|
|
||||||
func new(conf *config.Config) *app {
|
func new(conf *config.Config) *app {
|
||||||
|
@ -37,8 +39,11 @@ func new(conf *config.Config) *app {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *app) startBgTask(t time.Duration, fn func()) {
|
func (a *app) startBgTask(t time.Duration, fn func()) {
|
||||||
|
timer := time.NewTimer(t)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
timer.Reset(t)
|
||||||
a.server.Background(fn)
|
a.server.Background(fn)
|
||||||
time.Sleep(t)
|
<-timer.C
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ func (a *app) SetupDemo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// First check if we've already setup a demo user and skip if so
|
// First check if we've already setup a demo user and skip if so
|
||||||
_, err := a.services.User.Login(context.Background(), registration.Email, registration.Password)
|
_, err := a.services.User.Login(context.Background(), registration.Email, registration.Password, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ func (a *app) SetupDemo() {
|
||||||
log.Fatal().Msg("Failed to setup demo")
|
log.Fatal().Msg("Failed to setup demo")
|
||||||
}
|
}
|
||||||
|
|
||||||
token, _ := a.services.User.Login(context.Background(), registration.Email, registration.Password)
|
token, _ := a.services.User.Login(context.Background(), registration.Email, registration.Password, false)
|
||||||
self, _ := a.services.User.GetSelf(context.Background(), token.Raw)
|
self, _ := a.services.User.GetSelf(context.Background(), token.Raw)
|
||||||
|
|
||||||
_, err = a.services.Items.CsvImport(context.Background(), self.GroupID, strings.NewReader(csvText))
|
_, err = a.services.Items.CsvImport(context.Background(), self.GroupID, strings.NewReader(csvText))
|
||||||
|
|
|
@ -1,13 +1,36 @@
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
|
"github.com/hay-kot/httpkit/server"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
|
"github.com/olahol/melody"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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 {
|
||||||
|
Item interface{} `json:"item"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Wrap(v any) Wrapped {
|
||||||
|
return Wrapped{Item: v}
|
||||||
|
}
|
||||||
|
|
||||||
func WithMaxUploadSize(maxUploadSize int64) func(*V1Controller) {
|
func WithMaxUploadSize(maxUploadSize int64) func(*V1Controller) {
|
||||||
return func(ctrl *V1Controller) {
|
return func(ctrl *V1Controller) {
|
||||||
ctrl.maxUploadSize = maxUploadSize
|
ctrl.maxUploadSize = maxUploadSize
|
||||||
|
@ -26,12 +49,20 @@ func WithRegistration(allowRegistration bool) func(*V1Controller) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithSecureCookies(secure bool) func(*V1Controller) {
|
||||||
|
return func(ctrl *V1Controller) {
|
||||||
|
ctrl.cookieSecure = secure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type V1Controller struct {
|
type V1Controller struct {
|
||||||
|
cookieSecure bool
|
||||||
repo *repo.AllRepos
|
repo *repo.AllRepos
|
||||||
svc *services.AllServices
|
svc *services.AllServices
|
||||||
maxUploadSize int64
|
maxUploadSize int64
|
||||||
isDemo bool
|
isDemo bool
|
||||||
allowRegistration bool
|
allowRegistration bool
|
||||||
|
bus *eventbus.EventBus
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -60,11 +91,12 @@ func BaseUrlFunc(prefix string) func(s string) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewControllerV1(svc *services.AllServices, repos *repo.AllRepos, options ...func(*V1Controller)) *V1Controller {
|
func NewControllerV1(svc *services.AllServices, repos *repo.AllRepos, bus *eventbus.EventBus, options ...func(*V1Controller)) *V1Controller {
|
||||||
ctrl := &V1Controller{
|
ctrl := &V1Controller{
|
||||||
repo: repos,
|
repo: repos,
|
||||||
svc: svc,
|
svc: svc,
|
||||||
allowRegistration: true,
|
allowRegistration: true,
|
||||||
|
bus: bus,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range options {
|
for _, opt := range options {
|
||||||
|
@ -75,20 +107,60 @@ func NewControllerV1(svc *services.AllServices, repos *repo.AllRepos, options ..
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleBase godoc
|
// HandleBase godoc
|
||||||
// @Summary Retrieves the basic information about the API
|
//
|
||||||
// @Tags Base
|
// @Summary Application Info
|
||||||
// @Produce json
|
// @Tags Base
|
||||||
// @Success 200 {object} ApiSummary
|
// @Produce json
|
||||||
// @Router /v1/status [GET]
|
// @Success 200 {object} ApiSummary
|
||||||
func (ctrl *V1Controller) HandleBase(ready ReadyFunc, build Build) server.HandlerFunc {
|
// @Router /v1/status [GET]
|
||||||
|
func (ctrl *V1Controller) HandleBase(ready ReadyFunc, build Build) errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
return server.Respond(w, http.StatusOK, ApiSummary{
|
return server.JSON(w, http.StatusOK, ApiSummary{
|
||||||
Healthy: ready(),
|
Healthy: ready(),
|
||||||
Title: "Go API Template",
|
Title: "Homebox",
|
||||||
Message: "Welcome to the Go API Template Application!",
|
Message: "Track, Manage, and Organize your Things",
|
||||||
Build: build,
|
Build: build,
|
||||||
Demo: ctrl.isDemo,
|
Demo: ctrl.isDemo,
|
||||||
AllowRegistration: ctrl.allowRegistration,
|
AllowRegistration: ctrl.allowRegistration,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctrl *V1Controller) HandleCacheWS() errchain.HandlerFunc {
|
||||||
|
m := melody.New()
|
||||||
|
|
||||||
|
m.HandleConnect(func(s *melody.Session) {
|
||||||
|
auth := services.NewContext(s.Request.Context())
|
||||||
|
s.Set("gid", auth.GID)
|
||||||
|
})
|
||||||
|
|
||||||
|
factory := func(e string) func(data any) {
|
||||||
|
return func(data any) {
|
||||||
|
eventData, ok := data.(eventbus.GroupMutationEvent)
|
||||||
|
if !ok {
|
||||||
|
log.Log().Msgf("invalid event data: %v", data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonStr := fmt.Sprintf(`{"event": "%s"}`, e)
|
||||||
|
|
||||||
|
_ = m.BroadcastFilter([]byte(jsonStr), func(s *melody.Session) bool {
|
||||||
|
groupIDStr, ok := s.Get("gid")
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
GID := groupIDStr.(uuid.UUID)
|
||||||
|
return GID == eventData.GID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl.bus.Subscribe(eventbus.EventLabelMutation, factory("label.mutation"))
|
||||||
|
ctrl.bus.Subscribe(eventbus.EventLocationMutation, factory("location.mutation"))
|
||||||
|
ctrl.bus.Subscribe(eventbus.EventItemMutation, factory("item.mutation"))
|
||||||
|
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
return m.HandleRequest(w, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ func (ctrl *V1Controller) routeID(r *http.Request) (uuid.UUID, error) {
|
||||||
func (ctrl *V1Controller) routeUUID(r *http.Request, key string) (uuid.UUID, error) {
|
func (ctrl *V1Controller) routeUUID(r *http.Request, key string) (uuid.UUID, error) {
|
||||||
ID, err := uuid.Parse(chi.URLParam(r, key))
|
ID, err := uuid.Parse(chi.URLParam(r, key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return uuid.Nil, validate.NewInvalidRouteKeyError(key)
|
return uuid.Nil, validate.NewRouteKeyError(key)
|
||||||
}
|
}
|
||||||
return ID, nil
|
return ID, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
|
"github.com/hay-kot/httpkit/server"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ type ActionAmountResult struct {
|
||||||
Completed int `json:"completed"`
|
Completed int `json:"completed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func actionHandlerFactory(ref string, fn func(context.Context, uuid.UUID) (int, error)) server.HandlerFunc {
|
func actionHandlerFactory(ref string, fn func(context.Context, uuid.UUID) (int, error)) errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
ctx := services.NewContext(r.Context())
|
ctx := services.NewContext(r.Context())
|
||||||
|
|
||||||
|
@ -25,39 +26,58 @@ func actionHandlerFactory(ref string, fn func(context.Context, uuid.UUID) (int,
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, ActionAmountResult{Completed: totalCompleted})
|
return server.JSON(w, http.StatusOK, ActionAmountResult{Completed: totalCompleted})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleGroupInvitationsCreate godoc
|
// HandleEnsureAssetID godoc
|
||||||
// @Summary Ensures all items in the database have an asset id
|
//
|
||||||
// @Tags Group
|
// @Summary Ensure Asset IDs
|
||||||
// @Produce json
|
// @Description Ensures all items in the database have an asset ID
|
||||||
// @Success 200 {object} ActionAmountResult
|
// @Tags Actions
|
||||||
// @Router /v1/actions/ensure-asset-ids [Post]
|
// @Produce json
|
||||||
// @Security Bearer
|
// @Success 200 {object} ActionAmountResult
|
||||||
func (ctrl *V1Controller) HandleEnsureAssetID() server.HandlerFunc {
|
// @Router /v1/actions/ensure-asset-ids [Post]
|
||||||
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleEnsureAssetID() errchain.HandlerFunc {
|
||||||
return actionHandlerFactory("ensure asset IDs", ctrl.svc.Items.EnsureAssetID)
|
return actionHandlerFactory("ensure asset IDs", ctrl.svc.Items.EnsureAssetID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleEnsureImportRefs godoc
|
// HandleEnsureImportRefs godoc
|
||||||
// @Summary Ensures all items in the database have an import ref
|
//
|
||||||
// @Tags Group
|
// @Summary Ensures Import Refs
|
||||||
// @Produce json
|
// @Description Ensures all items in the database have an import ref
|
||||||
// @Success 200 {object} ActionAmountResult
|
// @Tags Actions
|
||||||
// @Router /v1/actions/ensure-import-refs [Post]
|
// @Produce json
|
||||||
// @Security Bearer
|
// @Success 200 {object} ActionAmountResult
|
||||||
func (ctrl *V1Controller) HandleEnsureImportRefs() server.HandlerFunc {
|
// @Router /v1/actions/ensure-import-refs [Post]
|
||||||
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleEnsureImportRefs() errchain.HandlerFunc {
|
||||||
return actionHandlerFactory("ensure import refs", ctrl.svc.Items.EnsureImportRef)
|
return actionHandlerFactory("ensure import refs", ctrl.svc.Items.EnsureImportRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleItemDateZeroOut godoc
|
// HandleItemDateZeroOut godoc
|
||||||
// @Summary Resets all item date fields to the beginning of the day
|
//
|
||||||
// @Tags Group
|
// @Summary Zero Out Time Fields
|
||||||
// @Produce json
|
// @Description Resets all item date fields to the beginning of the day
|
||||||
// @Success 200 {object} ActionAmountResult
|
// @Tags Actions
|
||||||
// @Router /v1/actions/zero-item-time-fields [Post]
|
// @Produce json
|
||||||
// @Security Bearer
|
// @Success 200 {object} ActionAmountResult
|
||||||
func (ctrl *V1Controller) HandleItemDateZeroOut() server.HandlerFunc {
|
// @Router /v1/actions/zero-item-time-fields [Post]
|
||||||
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleItemDateZeroOut() errchain.HandlerFunc {
|
||||||
return actionHandlerFactory("zero out date time", ctrl.repo.Items.ZeroOutTimeFields)
|
return actionHandlerFactory("zero out date time", ctrl.repo.Items.ZeroOutTimeFields)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleSetPrimaryPhotos godoc
|
||||||
|
//
|
||||||
|
// @Summary Set Primary Photos
|
||||||
|
// @Description Sets the first photo of each item as the primary photo
|
||||||
|
// @Tags Actions
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} ActionAmountResult
|
||||||
|
// @Router /v1/actions/set-primary-photos [Post]
|
||||||
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleSetPrimaryPhotos() errchain.HandlerFunc {
|
||||||
|
return actionHandlerFactory("ensure asset IDs", ctrl.repo.Items.SetPrimaryPhotos)
|
||||||
|
}
|
||||||
|
|
|
@ -9,20 +9,22 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
|
"github.com/hay-kot/httpkit/server"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleItemGet godocs
|
// HandleAssetGet godocs
|
||||||
// @Summary Gets an item by Asset ID
|
//
|
||||||
// @Tags Assets
|
// @Summary Get Item by Asset ID
|
||||||
// @Produce json
|
// @Tags Items
|
||||||
// @Param id path string true "Asset ID"
|
// @Produce json
|
||||||
// @Success 200 {object} repo.PaginationResult[repo.ItemSummary]{}
|
// @Param id path string true "Asset ID"
|
||||||
// @Router /v1/assets/{id} [GET]
|
// @Success 200 {object} repo.PaginationResult[repo.ItemSummary]{}
|
||||||
// @Security Bearer
|
// @Router /v1/assets/{id} [GET]
|
||||||
func (ctrl *V1Controller) HandleAssetGet() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleAssetGet() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
ctx := services.NewContext(r.Context())
|
ctx := services.NewContext(r.Context())
|
||||||
assetIdParam := chi.URLParam(r, "id")
|
assetIdParam := chi.URLParam(r, "id")
|
||||||
|
@ -37,7 +39,7 @@ func (ctrl *V1Controller) HandleAssetGet() server.HandlerFunc {
|
||||||
if pageParam != "" {
|
if pageParam != "" {
|
||||||
page, err = strconv.ParseInt(pageParam, 10, 64)
|
page, err = strconv.ParseInt(pageParam, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return server.Respond(w, http.StatusBadRequest, "Invalid page number")
|
return server.JSON(w, http.StatusBadRequest, "Invalid page number")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +48,7 @@ func (ctrl *V1Controller) HandleAssetGet() server.HandlerFunc {
|
||||||
if pageSizeParam != "" {
|
if pageSizeParam != "" {
|
||||||
pageSize, err = strconv.ParseInt(pageSizeParam, 10, 64)
|
pageSize, err = strconv.ParseInt(pageSizeParam, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return server.Respond(w, http.StatusBadRequest, "Invalid page size")
|
return server.JSON(w, http.StatusBadRequest, "Invalid page size")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +57,6 @@ func (ctrl *V1Controller) HandleAssetGet() server.HandlerFunc {
|
||||||
log.Err(err).Msg("failed to get item")
|
log.Err(err).Msg("failed to get item")
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
return server.Respond(w, http.StatusOK, items)
|
return server.JSON(w, http.StatusOK, items)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,23 @@ package v1
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
|
"github.com/hay-kot/httpkit/server"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
cookieNameToken = "hb.auth.token"
|
||||||
|
cookieNameRemember = "hb.auth.remember"
|
||||||
|
cookieNameSession = "hb.auth.session"
|
||||||
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
TokenResponse struct {
|
TokenResponse struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
|
@ -20,41 +28,70 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
LoginForm struct {
|
LoginForm struct {
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
|
StayLoggedIn bool `json:"stayLoggedIn"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CookieContents struct {
|
||||||
|
Token string
|
||||||
|
ExpiresAt time.Time
|
||||||
|
Remember bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCookies(r *http.Request) (*CookieContents, error) {
|
||||||
|
cookie, err := r.Cookie(cookieNameToken)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("authorization cookie is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
rememberCookie, err := r.Cookie(cookieNameRemember)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("remember cookie is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &CookieContents{
|
||||||
|
Token: cookie.Value,
|
||||||
|
ExpiresAt: cookie.Expires,
|
||||||
|
Remember: rememberCookie.Value == "true",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// HandleAuthLogin godoc
|
// HandleAuthLogin godoc
|
||||||
// @Summary User Login
|
//
|
||||||
// @Tags Authentication
|
// @Summary User Login
|
||||||
// @Accept x-www-form-urlencoded
|
// @Tags Authentication
|
||||||
// @Accept application/json
|
// @Accept x-www-form-urlencoded
|
||||||
// @Param username formData string false "string" example(admin@admin.com)
|
// @Accept application/json
|
||||||
// @Param password formData string false "string" example(admin)
|
// @Param username formData string false "string" example(admin@admin.com)
|
||||||
// @Produce json
|
// @Param password formData string false "string" example(admin)
|
||||||
// @Success 200 {object} TokenResponse
|
// @Param payload body LoginForm true "Login Data"
|
||||||
// @Router /v1/users/login [POST]
|
// @Produce json
|
||||||
func (ctrl *V1Controller) HandleAuthLogin() server.HandlerFunc {
|
// @Success 200 {object} TokenResponse
|
||||||
|
// @Router /v1/users/login [POST]
|
||||||
|
func (ctrl *V1Controller) HandleAuthLogin() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
loginForm := &LoginForm{}
|
loginForm := &LoginForm{}
|
||||||
|
|
||||||
switch r.Header.Get("Content-Type") {
|
switch r.Header.Get("Content-Type") {
|
||||||
case server.ContentFormUrlEncoded:
|
case "application/x-www-form-urlencoded":
|
||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return server.Respond(w, http.StatusBadRequest, server.Wrap(err))
|
return errors.New("failed to parse form")
|
||||||
}
|
}
|
||||||
|
|
||||||
loginForm.Username = r.PostFormValue("username")
|
loginForm.Username = r.PostFormValue("username")
|
||||||
loginForm.Password = r.PostFormValue("password")
|
loginForm.Password = r.PostFormValue("password")
|
||||||
case server.ContentJSON:
|
loginForm.StayLoggedIn = r.PostFormValue("stayLoggedIn") == "true"
|
||||||
|
case "application/json":
|
||||||
err := server.Decode(r, loginForm)
|
err := server.Decode(r, loginForm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("failed to decode login form")
|
log.Err(err).Msg("failed to decode login form")
|
||||||
|
return errors.New("failed to decode login form")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return server.Respond(w, http.StatusBadRequest, errors.New("invalid content type"))
|
return server.JSON(w, http.StatusBadRequest, errors.New("invalid content type"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if loginForm.Username == "" || loginForm.Password == "" {
|
if loginForm.Username == "" || loginForm.Password == "" {
|
||||||
|
@ -70,12 +107,13 @@ func (ctrl *V1Controller) HandleAuthLogin() server.HandlerFunc {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
newToken, err := ctrl.svc.User.Login(r.Context(), strings.ToLower(loginForm.Username), loginForm.Password)
|
newToken, err := ctrl.svc.User.Login(r.Context(), strings.ToLower(loginForm.Username), loginForm.Password, loginForm.StayLoggedIn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return validate.NewRequestError(errors.New("authentication failed"), http.StatusInternalServerError)
|
return validate.NewRequestError(errors.New("authentication failed"), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, TokenResponse{
|
ctrl.setCookies(w, noPort(r.Host), newToken.Raw, newToken.ExpiresAt, loginForm.StayLoggedIn)
|
||||||
|
return server.JSON(w, http.StatusOK, TokenResponse{
|
||||||
Token: "Bearer " + newToken.Raw,
|
Token: "Bearer " + newToken.Raw,
|
||||||
ExpiresAt: newToken.ExpiresAt,
|
ExpiresAt: newToken.ExpiresAt,
|
||||||
AttachmentToken: newToken.AttachmentToken,
|
AttachmentToken: newToken.AttachmentToken,
|
||||||
|
@ -84,12 +122,13 @@ func (ctrl *V1Controller) HandleAuthLogin() server.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleAuthLogout godoc
|
// HandleAuthLogout godoc
|
||||||
// @Summary User Logout
|
//
|
||||||
// @Tags Authentication
|
// @Summary User Logout
|
||||||
// @Success 204
|
// @Tags Authentication
|
||||||
// @Router /v1/users/logout [POST]
|
// @Success 204
|
||||||
// @Security Bearer
|
// @Router /v1/users/logout [POST]
|
||||||
func (ctrl *V1Controller) HandleAuthLogout() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleAuthLogout() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
token := services.UseTokenCtx(r.Context())
|
token := services.UseTokenCtx(r.Context())
|
||||||
if token == "" {
|
if token == "" {
|
||||||
|
@ -101,19 +140,21 @@ func (ctrl *V1Controller) HandleAuthLogout() server.HandlerFunc {
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusNoContent, nil)
|
ctrl.unsetCookies(w, noPort(r.Host))
|
||||||
|
return server.JSON(w, http.StatusNoContent, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleAuthLogout godoc
|
// HandleAuthLogout godoc
|
||||||
// @Summary User Token Refresh
|
//
|
||||||
// @Description handleAuthRefresh returns a handler that will issue a new token from an existing token.
|
// @Summary User Token Refresh
|
||||||
// @Description This does not validate that the user still exists within the database.
|
// @Description handleAuthRefresh returns a handler that will issue a new token from an existing token.
|
||||||
// @Tags Authentication
|
// @Description This does not validate that the user still exists within the database.
|
||||||
// @Success 200
|
// @Tags Authentication
|
||||||
// @Router /v1/users/refresh [GET]
|
// @Success 200
|
||||||
// @Security Bearer
|
// @Router /v1/users/refresh [GET]
|
||||||
func (ctrl *V1Controller) HandleAuthRefresh() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleAuthRefresh() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
requestToken := services.UseTokenCtx(r.Context())
|
requestToken := services.UseTokenCtx(r.Context())
|
||||||
if requestToken == "" {
|
if requestToken == "" {
|
||||||
|
@ -125,6 +166,78 @@ func (ctrl *V1Controller) HandleAuthRefresh() server.HandlerFunc {
|
||||||
return validate.NewUnauthorizedError()
|
return validate.NewUnauthorizedError()
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, newToken)
|
ctrl.setCookies(w, noPort(r.Host), newToken.Raw, newToken.ExpiresAt, false)
|
||||||
|
return server.JSON(w, http.StatusOK, newToken)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func noPort(host string) string {
|
||||||
|
return strings.Split(host, ":")[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctrl *V1Controller) setCookies(w http.ResponseWriter, domain, token string, expires time.Time, remember bool) {
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: cookieNameRemember,
|
||||||
|
Value: strconv.FormatBool(remember),
|
||||||
|
Expires: expires,
|
||||||
|
Domain: domain,
|
||||||
|
Secure: ctrl.cookieSecure,
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
})
|
||||||
|
|
||||||
|
// Set HTTP only cookie
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: cookieNameToken,
|
||||||
|
Value: token,
|
||||||
|
Expires: expires,
|
||||||
|
Domain: domain,
|
||||||
|
Secure: ctrl.cookieSecure,
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
})
|
||||||
|
|
||||||
|
// Set Fake Session cookie
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: cookieNameSession,
|
||||||
|
Value: "true",
|
||||||
|
Expires: expires,
|
||||||
|
Domain: domain,
|
||||||
|
Secure: ctrl.cookieSecure,
|
||||||
|
HttpOnly: false,
|
||||||
|
Path: "/",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctrl *V1Controller) unsetCookies(w http.ResponseWriter, domain string) {
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: cookieNameToken,
|
||||||
|
Value: "",
|
||||||
|
Expires: time.Unix(0, 0),
|
||||||
|
Domain: domain,
|
||||||
|
Secure: ctrl.cookieSecure,
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
})
|
||||||
|
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: cookieNameRemember,
|
||||||
|
Value: "false",
|
||||||
|
Expires: time.Unix(0, 0),
|
||||||
|
Domain: domain,
|
||||||
|
Secure: ctrl.cookieSecure,
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
})
|
||||||
|
|
||||||
|
// Set Fake Session cookie
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: cookieNameSession,
|
||||||
|
Value: "false",
|
||||||
|
Expires: time.Unix(0, 0),
|
||||||
|
Domain: domain,
|
||||||
|
Secure: ctrl.cookieSecure,
|
||||||
|
HttpOnly: false,
|
||||||
|
Path: "/",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -6,14 +6,13 @@ import (
|
||||||
|
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/web/adapters"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
GroupInvitationCreate struct {
|
GroupInvitationCreate struct {
|
||||||
Uses int `json:"uses"`
|
Uses int `json:"uses" validate:"required,min=1,max=100"`
|
||||||
ExpiresAt time.Time `json:"expiresAt"`
|
ExpiresAt time.Time `json:"expiresAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,93 +24,65 @@ type (
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleGroupGet godoc
|
// HandleGroupGet godoc
|
||||||
// @Summary Get the current user's group
|
//
|
||||||
// @Tags Group
|
// @Summary Get Group
|
||||||
// @Produce json
|
// @Tags Group
|
||||||
// @Success 200 {object} repo.Group
|
// @Produce json
|
||||||
// @Router /v1/groups [Get]
|
// @Success 200 {object} repo.Group
|
||||||
// @Security Bearer
|
// @Router /v1/groups [Get]
|
||||||
func (ctrl *V1Controller) HandleGroupGet() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleGroupGeneral()
|
func (ctrl *V1Controller) HandleGroupGet() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request) (repo.Group, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
return ctrl.repo.Groups.GroupByID(auth, auth.GID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.Command(fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleGroupUpdate godoc
|
// HandleGroupUpdate godoc
|
||||||
// @Summary Updates some fields of the current users group
|
//
|
||||||
// @Tags Group
|
// @Summary Update Group
|
||||||
// @Produce json
|
// @Tags Group
|
||||||
// @Param payload body repo.GroupUpdate true "User Data"
|
// @Produce json
|
||||||
// @Success 200 {object} repo.Group
|
// @Param payload body repo.GroupUpdate true "User Data"
|
||||||
// @Router /v1/groups [Put]
|
// @Success 200 {object} repo.Group
|
||||||
// @Security Bearer
|
// @Router /v1/groups [Put]
|
||||||
func (ctrl *V1Controller) HandleGroupUpdate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleGroupGeneral()
|
func (ctrl *V1Controller) HandleGroupUpdate() errchain.HandlerFunc {
|
||||||
}
|
fn := func(r *http.Request, body repo.GroupUpdate) (repo.Group, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
func (ctrl *V1Controller) handleGroupGeneral() server.HandlerFunc {
|
return ctrl.svc.Group.UpdateGroup(auth, body)
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
|
||||||
ctx := services.NewContext(r.Context())
|
|
||||||
|
|
||||||
switch r.Method {
|
|
||||||
case http.MethodGet:
|
|
||||||
group, err := ctrl.repo.Groups.GroupByID(ctx, ctx.GID)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to get group")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, group)
|
|
||||||
|
|
||||||
case http.MethodPut:
|
|
||||||
data := repo.GroupUpdate{}
|
|
||||||
if err := server.Decode(r, &data); err != nil {
|
|
||||||
return validate.NewRequestError(err, http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
group, err := ctrl.svc.Group.UpdateGroup(ctx, data)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to update group")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, group)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Action(fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleGroupInvitationsCreate godoc
|
// HandleGroupInvitationsCreate godoc
|
||||||
// @Summary Get the current user
|
//
|
||||||
// @Tags Group
|
// @Summary Create Group Invitation
|
||||||
// @Produce json
|
// @Tags Group
|
||||||
// @Param payload body GroupInvitationCreate true "User Data"
|
// @Produce json
|
||||||
// @Success 200 {object} GroupInvitation
|
// @Param payload body GroupInvitationCreate true "User Data"
|
||||||
// @Router /v1/groups/invitations [Post]
|
// @Success 200 {object} GroupInvitation
|
||||||
// @Security Bearer
|
// @Router /v1/groups/invitations [Post]
|
||||||
func (ctrl *V1Controller) HandleGroupInvitationsCreate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleGroupInvitationsCreate() errchain.HandlerFunc {
|
||||||
data := GroupInvitationCreate{}
|
fn := func(r *http.Request, body GroupInvitationCreate) (GroupInvitation, error) {
|
||||||
if err := server.Decode(r, &data); err != nil {
|
if body.ExpiresAt.IsZero() {
|
||||||
log.Err(err).Msg("failed to decode user registration data")
|
body.ExpiresAt = time.Now().Add(time.Hour * 24)
|
||||||
return validate.NewRequestError(err, http.StatusBadRequest)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if data.ExpiresAt.IsZero() {
|
auth := services.NewContext(r.Context())
|
||||||
data.ExpiresAt = time.Now().Add(time.Hour * 24)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := services.NewContext(r.Context())
|
token, err := ctrl.svc.Group.NewInvitation(auth, body.Uses, body.ExpiresAt)
|
||||||
|
|
||||||
token, err := ctrl.svc.Group.NewInvitation(ctx, data.Uses, data.ExpiresAt)
|
return GroupInvitation{
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to create new token")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusCreated, GroupInvitation{
|
|
||||||
Token: token,
|
Token: token,
|
||||||
ExpiresAt: data.ExpiresAt,
|
ExpiresAt: body.ExpiresAt,
|
||||||
Uses: data.Uses,
|
Uses: body.Uses,
|
||||||
})
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Action(fn, http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,26 +7,30 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/homebox/backend/internal/web/adapters"
|
||||||
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
|
"github.com/hay-kot/httpkit/server"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleItemsGetAll godoc
|
// HandleItemsGetAll godoc
|
||||||
// @Summary Get All Items
|
//
|
||||||
// @Tags Items
|
// @Summary Query All Items
|
||||||
// @Produce json
|
// @Tags Items
|
||||||
// @Param q query string false "search string"
|
// @Produce json
|
||||||
// @Param page query int false "page number"
|
// @Param q query string false "search string"
|
||||||
// @Param pageSize query int false "items per page"
|
// @Param page query int false "page number"
|
||||||
// @Param labels query []string false "label Ids" collectionFormat(multi)
|
// @Param pageSize query int false "items per page"
|
||||||
// @Param locations query []string false "location Ids" collectionFormat(multi)
|
// @Param labels query []string false "label Ids" collectionFormat(multi)
|
||||||
// @Success 200 {object} repo.PaginationResult[repo.ItemSummary]{}
|
// @Param locations query []string false "location Ids" collectionFormat(multi)
|
||||||
// @Router /v1/items [GET]
|
// @Success 200 {object} repo.PaginationResult[repo.ItemSummary]{}
|
||||||
// @Security Bearer
|
// @Router /v1/items [GET]
|
||||||
func (ctrl *V1Controller) HandleItemsGetAll() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleItemsGetAll() errchain.HandlerFunc {
|
||||||
extractQuery := func(r *http.Request) repo.ItemQuery {
|
extractQuery := func(r *http.Request) repo.ItemQuery {
|
||||||
params := r.URL.Query()
|
params := r.URL.Query()
|
||||||
|
|
||||||
|
@ -54,6 +58,7 @@ func (ctrl *V1Controller) HandleItemsGetAll() server.HandlerFunc {
|
||||||
LabelIDs: queryUUIDList(params, "labels"),
|
LabelIDs: queryUUIDList(params, "labels"),
|
||||||
IncludeArchived: queryBool(params.Get("includeArchived")),
|
IncludeArchived: queryBool(params.Get("includeArchived")),
|
||||||
Fields: filterFieldItems(params["fields"]),
|
Fields: filterFieldItems(params["fields"]),
|
||||||
|
OrderBy: params.Get("orderBy"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(v.Search, "#") {
|
if strings.HasPrefix(v.Search, "#") {
|
||||||
|
@ -75,174 +80,171 @@ func (ctrl *V1Controller) HandleItemsGetAll() server.HandlerFunc {
|
||||||
items, err := ctrl.repo.Items.QueryByGroup(ctx, ctx.GID, extractQuery(r))
|
items, err := ctrl.repo.Items.QueryByGroup(ctx, ctx.GID, extractQuery(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
return server.Respond(w, http.StatusOK, repo.PaginationResult[repo.ItemSummary]{
|
return server.JSON(w, http.StatusOK, repo.PaginationResult[repo.ItemSummary]{
|
||||||
Items: []repo.ItemSummary{},
|
Items: []repo.ItemSummary{},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
log.Err(err).Msg("failed to get items")
|
log.Err(err).Msg("failed to get items")
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
return server.Respond(w, http.StatusOK, items)
|
return server.JSON(w, http.StatusOK, items)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleItemsCreate godoc
|
// HandleItemsCreate godoc
|
||||||
// @Summary Create a new item
|
//
|
||||||
// @Tags Items
|
// @Summary Create Item
|
||||||
// @Produce json
|
// @Tags Items
|
||||||
// @Param payload body repo.ItemCreate true "Item Data"
|
// @Produce json
|
||||||
// @Success 200 {object} repo.ItemSummary
|
// @Param payload body repo.ItemCreate true "Item Data"
|
||||||
// @Router /v1/items [POST]
|
// @Success 201 {object} repo.ItemSummary
|
||||||
// @Security Bearer
|
// @Router /v1/items [POST]
|
||||||
func (ctrl *V1Controller) HandleItemsCreate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleItemsCreate() errchain.HandlerFunc {
|
||||||
createData := repo.ItemCreate{}
|
fn := func(r *http.Request, body repo.ItemCreate) (repo.ItemOut, error) {
|
||||||
if err := server.Decode(r, &createData); err != nil {
|
return ctrl.svc.Items.Create(services.NewContext(r.Context()), body)
|
||||||
log.Err(err).Msg("failed to decode request body")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := services.NewContext(r.Context())
|
|
||||||
item, err := ctrl.svc.Items.Create(ctx, createData)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to create item")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusCreated, item)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Action(fn, http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleItemGet godocs
|
// HandleItemGet godocs
|
||||||
// @Summary Gets a item and fields
|
//
|
||||||
// @Tags Items
|
// @Summary Get Item
|
||||||
// @Produce json
|
// @Tags Items
|
||||||
// @Param id path string true "Item ID"
|
// @Produce json
|
||||||
// @Success 200 {object} repo.ItemOut
|
// @Param id path string true "Item ID"
|
||||||
// @Router /v1/items/{id} [GET]
|
// @Success 200 {object} repo.ItemOut
|
||||||
// @Security Bearer
|
// @Router /v1/items/{id} [GET]
|
||||||
func (ctrl *V1Controller) HandleItemGet() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleItemsGeneral()
|
func (ctrl *V1Controller) HandleItemGet() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, ID uuid.UUID) (repo.ItemOut, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
|
||||||
|
return ctrl.repo.Items.GetOneByGroup(auth, auth.GID, ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.CommandID("id", fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleItemDelete godocs
|
// HandleItemDelete godocs
|
||||||
// @Summary deletes a item
|
//
|
||||||
// @Tags Items
|
// @Summary Delete Item
|
||||||
// @Produce json
|
// @Tags Items
|
||||||
// @Param id path string true "Item ID"
|
// @Produce json
|
||||||
// @Success 204
|
// @Param id path string true "Item ID"
|
||||||
// @Router /v1/items/{id} [DELETE]
|
// @Success 204
|
||||||
// @Security Bearer
|
// @Router /v1/items/{id} [DELETE]
|
||||||
func (ctrl *V1Controller) HandleItemDelete() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleItemsGeneral()
|
func (ctrl *V1Controller) HandleItemDelete() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
err := ctrl.repo.Items.DeleteByGroup(auth, auth.GID, ID)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.CommandID("id", fn, http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleItemUpdate godocs
|
// HandleItemUpdate godocs
|
||||||
// @Summary updates a item
|
//
|
||||||
// @Tags Items
|
// @Summary Update Item
|
||||||
// @Produce json
|
// @Tags Items
|
||||||
// @Param id path string true "Item ID"
|
// @Produce json
|
||||||
// @Param payload body repo.ItemUpdate true "Item Data"
|
// @Param id path string true "Item ID"
|
||||||
// @Success 200 {object} repo.ItemOut
|
// @Param payload body repo.ItemUpdate true "Item Data"
|
||||||
// @Router /v1/items/{id} [PUT]
|
// @Success 200 {object} repo.ItemOut
|
||||||
// @Security Bearer
|
// @Router /v1/items/{id} [PUT]
|
||||||
func (ctrl *V1Controller) HandleItemUpdate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleItemsGeneral()
|
func (ctrl *V1Controller) HandleItemUpdate() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, ID uuid.UUID, body repo.ItemUpdate) (repo.ItemOut, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
|
||||||
|
body.ID = ID
|
||||||
|
return ctrl.repo.Items.UpdateByGroup(auth, auth.GID, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.ActionID("id", fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctrl *V1Controller) handleItemsGeneral() server.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
|
||||||
ctx := services.NewContext(r.Context())
|
|
||||||
ID, err := ctrl.routeID(r)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch r.Method {
|
// HandleItemPatch godocs
|
||||||
case http.MethodGet:
|
//
|
||||||
items, err := ctrl.repo.Items.GetOneByGroup(r.Context(), ctx.GID, ID)
|
// @Summary Update Item
|
||||||
if err != nil {
|
// @Tags Items
|
||||||
log.Err(err).Msg("failed to get item")
|
// @Produce json
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
// @Param id path string true "Item ID"
|
||||||
}
|
// @Param payload body repo.ItemPatch true "Item Data"
|
||||||
return server.Respond(w, http.StatusOK, items)
|
// @Success 200 {object} repo.ItemOut
|
||||||
case http.MethodDelete:
|
// @Router /v1/items/{id} [Patch]
|
||||||
err = ctrl.repo.Items.DeleteByGroup(r.Context(), ctx.GID, ID)
|
// @Security Bearer
|
||||||
if err != nil {
|
func (ctrl *V1Controller) HandleItemPatch() errchain.HandlerFunc {
|
||||||
log.Err(err).Msg("failed to delete item")
|
fn := func(r *http.Request, ID uuid.UUID, body repo.ItemPatch) (repo.ItemOut, error) {
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
auth := services.NewContext(r.Context())
|
||||||
}
|
|
||||||
return server.Respond(w, http.StatusNoContent, nil)
|
|
||||||
case http.MethodPut:
|
|
||||||
body := repo.ItemUpdate{}
|
|
||||||
if err := server.Decode(r, &body); err != nil {
|
|
||||||
log.Err(err).Msg("failed to decode request body")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
body.ID = ID
|
|
||||||
result, err := ctrl.repo.Items.UpdateByGroup(r.Context(), ctx.GID, body)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to update item")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
return server.Respond(w, http.StatusOK, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
body.ID = ID
|
||||||
|
err := ctrl.repo.Items.Patch(auth, auth.GID, ID, body)
|
||||||
|
if err != nil {
|
||||||
|
return repo.ItemOut{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctrl.repo.Items.GetOneByGroup(auth, auth.GID, ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.ActionID("id", fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleGetAllCustomFieldNames godocs
|
// HandleGetAllCustomFieldNames godocs
|
||||||
// @Summary imports items into the database
|
//
|
||||||
// @Tags Items
|
// @Summary Get All Custom Field Names
|
||||||
// @Produce json
|
// @Tags Items
|
||||||
// @Success 200
|
// @Produce json
|
||||||
// @Router /v1/items/fields [GET]
|
// @Success 200
|
||||||
// @Success 200 {object} []string
|
// @Router /v1/items/fields [GET]
|
||||||
// @Security Bearer
|
// @Success 200 {object} []string
|
||||||
func (ctrl *V1Controller) HandleGetAllCustomFieldNames() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleGetAllCustomFieldNames() errchain.HandlerFunc {
|
||||||
ctx := services.NewContext(r.Context())
|
fn := func(r *http.Request) ([]string, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
v, err := ctrl.repo.Items.GetAllCustomFieldNames(r.Context(), ctx.GID)
|
return ctrl.repo.Items.GetAllCustomFieldNames(auth, auth.GID)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Command(fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleGetAllCustomFieldValues godocs
|
// HandleGetAllCustomFieldValues godocs
|
||||||
// @Summary imports items into the database
|
//
|
||||||
// @Tags Items
|
// @Summary Get All Custom Field Values
|
||||||
// @Produce json
|
// @Tags Items
|
||||||
// @Success 200
|
// @Produce json
|
||||||
// @Router /v1/items/fields/values [GET]
|
// @Success 200
|
||||||
// @Success 200 {object} []string
|
// @Router /v1/items/fields/values [GET]
|
||||||
// @Security Bearer
|
// @Success 200 {object} []string
|
||||||
func (ctrl *V1Controller) HandleGetAllCustomFieldValues() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleGetAllCustomFieldValues() errchain.HandlerFunc {
|
||||||
ctx := services.NewContext(r.Context())
|
type query struct {
|
||||||
|
Field string `schema:"field" validate:"required"`
|
||||||
v, err := ctrl.repo.Items.GetAllCustomFieldValues(r.Context(), ctx.GID, r.URL.Query().Get("field"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn := func(r *http.Request, q query) ([]string, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
return ctrl.repo.Items.GetAllCustomFieldValues(auth, auth.GID, q.Field)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.Query(fn, http.StatusOK)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleItemsImport godocs
|
// HandleItemsImport godocs
|
||||||
// @Summary imports items into the database
|
//
|
||||||
// @Tags Items
|
// @Summary Import Items
|
||||||
// @Produce json
|
// @Tags Items
|
||||||
// @Success 204
|
// @Produce json
|
||||||
// @Param csv formData file true "Image to upload"
|
// @Success 204
|
||||||
// @Router /v1/items/import [Post]
|
// @Param csv formData file true "Image to upload"
|
||||||
// @Security Bearer
|
// @Router /v1/items/import [Post]
|
||||||
func (ctrl *V1Controller) HandleItemsImport() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleItemsImport() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
err := r.ParseMultipartForm(ctrl.maxUploadSize << 20)
|
err := r.ParseMultipartForm(ctrl.maxUploadSize << 20)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -264,17 +266,18 @@ func (ctrl *V1Controller) HandleItemsImport() server.HandlerFunc {
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusNoContent, nil)
|
return server.JSON(w, http.StatusNoContent, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleItemsImport godocs
|
// HandleItemsExport godocs
|
||||||
// @Summary exports items into the database
|
//
|
||||||
// @Tags Items
|
// @Summary Export Items
|
||||||
// @Success 200 {string} string "text/csv"
|
// @Tags Items
|
||||||
// @Router /v1/items/export [GET]
|
// @Success 200 {string} string "text/csv"
|
||||||
// @Security Bearer
|
// @Router /v1/items/export [GET]
|
||||||
func (ctrl *V1Controller) HandleItemsExport() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleItemsExport() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
ctx := services.NewContext(r.Context())
|
ctx := services.NewContext(r.Context())
|
||||||
|
|
||||||
|
@ -286,7 +289,9 @@ func (ctrl *V1Controller) HandleItemsExport() server.HandlerFunc {
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "text/tsv")
|
w.Header().Set("Content-Type", "text/tsv")
|
||||||
w.Header().Set("Content-Disposition", "attachment;filename=homebox-items.tsv")
|
w.Header().Set("Content-Disposition", "attachment;filename=homebox-items.tsv")
|
||||||
|
|
||||||
writer := csv.NewWriter(w)
|
writer := csv.NewWriter(w)
|
||||||
|
writer.Comma = '\t'
|
||||||
return writer.WriteAll(csvData)
|
return writer.WriteAll(csvData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
|
"github.com/hay-kot/httpkit/server"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,19 +19,20 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleItemsImport godocs
|
// HandleItemAttachmentCreate godocs
|
||||||
// @Summary imports items into the database
|
//
|
||||||
// @Tags Items Attachments
|
// @Summary Create Item Attachment
|
||||||
// @Produce json
|
// @Tags Items Attachments
|
||||||
// @Param id path string true "Item ID"
|
// @Produce json
|
||||||
// @Param file formData file true "File attachment"
|
// @Param id path string true "Item ID"
|
||||||
// @Param type formData string true "Type of file"
|
// @Param file formData file true "File attachment"
|
||||||
// @Param name formData string true "name of the file including extension"
|
// @Param type formData string true "Type of file"
|
||||||
// @Success 200 {object} repo.ItemOut
|
// @Param name formData string true "name of the file including extension"
|
||||||
// @Failure 422 {object} server.ErrorResponse
|
// @Success 200 {object} repo.ItemOut
|
||||||
// @Router /v1/items/{id}/attachments [POST]
|
// @Failure 422 {object} validate.ErrorResponse
|
||||||
// @Security Bearer
|
// @Router /v1/items/{id}/attachments [POST]
|
||||||
func (ctrl *V1Controller) HandleItemAttachmentCreate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleItemAttachmentCreate() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
err := r.ParseMultipartForm(ctrl.maxUploadSize << 20)
|
err := r.ParseMultipartForm(ctrl.maxUploadSize << 20)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -60,7 +62,7 @@ func (ctrl *V1Controller) HandleItemAttachmentCreate() server.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !errs.Nil() {
|
if !errs.Nil() {
|
||||||
return server.Respond(w, http.StatusUnprocessableEntity, errs)
|
return server.JSON(w, http.StatusUnprocessableEntity, errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
attachmentType := r.FormValue("type")
|
attachmentType := r.FormValue("type")
|
||||||
|
@ -87,45 +89,48 @@ func (ctrl *V1Controller) HandleItemAttachmentCreate() server.HandlerFunc {
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusCreated, item)
|
return server.JSON(w, http.StatusCreated, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleItemAttachmentGet godocs
|
// HandleItemAttachmentGet godocs
|
||||||
// @Summary retrieves an attachment for an item
|
//
|
||||||
// @Tags Items Attachments
|
// @Summary Get Item Attachment
|
||||||
// @Produce application/octet-stream
|
// @Tags Items Attachments
|
||||||
// @Param id path string true "Item ID"
|
// @Produce application/octet-stream
|
||||||
// @Param attachment_id path string true "Attachment ID"
|
// @Param id path string true "Item ID"
|
||||||
// @Success 200 {object} ItemAttachmentToken
|
// @Param attachment_id path string true "Attachment ID"
|
||||||
// @Router /v1/items/{id}/attachments/{attachment_id} [GET]
|
// @Success 200 {object} ItemAttachmentToken
|
||||||
// @Security Bearer
|
// @Router /v1/items/{id}/attachments/{attachment_id} [GET]
|
||||||
func (ctrl *V1Controller) HandleItemAttachmentGet() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleItemAttachmentGet() errchain.HandlerFunc {
|
||||||
return ctrl.handleItemAttachmentsHandler
|
return ctrl.handleItemAttachmentsHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleItemAttachmentDelete godocs
|
// HandleItemAttachmentDelete godocs
|
||||||
// @Summary retrieves an attachment for an item
|
//
|
||||||
// @Tags Items Attachments
|
// @Summary Delete Item Attachment
|
||||||
// @Param id path string true "Item ID"
|
// @Tags Items Attachments
|
||||||
// @Param attachment_id path string true "Attachment ID"
|
// @Param id path string true "Item ID"
|
||||||
// @Success 204
|
// @Param attachment_id path string true "Attachment ID"
|
||||||
// @Router /v1/items/{id}/attachments/{attachment_id} [DELETE]
|
// @Success 204
|
||||||
// @Security Bearer
|
// @Router /v1/items/{id}/attachments/{attachment_id} [DELETE]
|
||||||
func (ctrl *V1Controller) HandleItemAttachmentDelete() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleItemAttachmentDelete() errchain.HandlerFunc {
|
||||||
return ctrl.handleItemAttachmentsHandler
|
return ctrl.handleItemAttachmentsHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleItemAttachmentUpdate godocs
|
// HandleItemAttachmentUpdate godocs
|
||||||
// @Summary retrieves an attachment for an item
|
//
|
||||||
// @Tags Items Attachments
|
// @Summary Update Item Attachment
|
||||||
// @Param id path string true "Item ID"
|
// @Tags Items Attachments
|
||||||
// @Param attachment_id path string true "Attachment ID"
|
// @Param id path string true "Item ID"
|
||||||
// @Param payload body repo.ItemAttachmentUpdate true "Attachment Update"
|
// @Param attachment_id path string true "Attachment ID"
|
||||||
// @Success 200 {object} repo.ItemOut
|
// @Param payload body repo.ItemAttachmentUpdate true "Attachment Update"
|
||||||
// @Router /v1/items/{id}/attachments/{attachment_id} [PUT]
|
// @Success 200 {object} repo.ItemOut
|
||||||
// @Security Bearer
|
// @Router /v1/items/{id}/attachments/{attachment_id} [PUT]
|
||||||
func (ctrl *V1Controller) HandleItemAttachmentUpdate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleItemAttachmentUpdate() errchain.HandlerFunc {
|
||||||
return ctrl.handleItemAttachmentsHandler
|
return ctrl.handleItemAttachmentsHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +165,7 @@ func (ctrl *V1Controller) handleItemAttachmentsHandler(w http.ResponseWriter, r
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusNoContent, nil)
|
return server.JSON(w, http.StatusNoContent, nil)
|
||||||
|
|
||||||
// Update Attachment Handler
|
// Update Attachment Handler
|
||||||
case http.MethodPut:
|
case http.MethodPut:
|
||||||
|
@ -178,7 +183,7 @@ func (ctrl *V1Controller) handleItemAttachmentsHandler(w http.ResponseWriter, r
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, val)
|
return server.JSON(w, http.StatusOK, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -3,141 +3,100 @@ package v1
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/web/adapters"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleLabelsGetAll godoc
|
// HandleLabelsGetAll godoc
|
||||||
// @Summary Get All Labels
|
//
|
||||||
// @Tags Labels
|
// @Summary Get All Labels
|
||||||
// @Produce json
|
// @Tags Labels
|
||||||
// @Success 200 {object} server.Results{items=[]repo.LabelOut}
|
// @Produce json
|
||||||
// @Router /v1/labels [GET]
|
// @Success 200 {object} []repo.LabelOut
|
||||||
// @Security Bearer
|
// @Router /v1/labels [GET]
|
||||||
func (ctrl *V1Controller) HandleLabelsGetAll() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleLabelsGetAll() errchain.HandlerFunc {
|
||||||
user := services.UseUserCtx(r.Context())
|
fn := func(r *http.Request) ([]repo.LabelSummary, error) {
|
||||||
labels, err := ctrl.repo.Labels.GetAll(r.Context(), user.GroupID)
|
auth := services.NewContext(r.Context())
|
||||||
if err != nil {
|
return ctrl.repo.Labels.GetAll(auth, auth.GID)
|
||||||
log.Err(err).Msg("error getting labels")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
return server.Respond(w, http.StatusOK, server.Results{Items: labels})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Command(fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleLabelsCreate godoc
|
// HandleLabelsCreate godoc
|
||||||
// @Summary Create a new label
|
//
|
||||||
// @Tags Labels
|
// @Summary Create Label
|
||||||
// @Produce json
|
// @Tags Labels
|
||||||
// @Param payload body repo.LabelCreate true "Label Data"
|
// @Produce json
|
||||||
// @Success 200 {object} repo.LabelSummary
|
// @Param payload body repo.LabelCreate true "Label Data"
|
||||||
// @Router /v1/labels [POST]
|
// @Success 200 {object} repo.LabelSummary
|
||||||
// @Security Bearer
|
// @Router /v1/labels [POST]
|
||||||
func (ctrl *V1Controller) HandleLabelsCreate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleLabelsCreate() errchain.HandlerFunc {
|
||||||
createData := repo.LabelCreate{}
|
fn := func(r *http.Request, data repo.LabelCreate) (repo.LabelOut, error) {
|
||||||
if err := server.Decode(r, &createData); err != nil {
|
auth := services.NewContext(r.Context())
|
||||||
log.Err(err).Msg("error decoding label create data")
|
return ctrl.repo.Labels.Create(auth, auth.GID, data)
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
user := services.UseUserCtx(r.Context())
|
|
||||||
label, err := ctrl.repo.Labels.Create(r.Context(), user.GroupID, createData)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("error creating label")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusCreated, label)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Action(fn, http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleLabelDelete godocs
|
// HandleLabelDelete godocs
|
||||||
// @Summary deletes a label
|
//
|
||||||
// @Tags Labels
|
// @Summary Delete Label
|
||||||
// @Produce json
|
// @Tags Labels
|
||||||
// @Param id path string true "Label ID"
|
// @Produce json
|
||||||
// @Success 204
|
// @Param id path string true "Label ID"
|
||||||
// @Router /v1/labels/{id} [DELETE]
|
// @Success 204
|
||||||
// @Security Bearer
|
// @Router /v1/labels/{id} [DELETE]
|
||||||
func (ctrl *V1Controller) HandleLabelDelete() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleLabelsGeneral()
|
func (ctrl *V1Controller) HandleLabelDelete() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
err := ctrl.repo.Labels.DeleteByGroup(auth, auth.GID, ID)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.CommandID("id", fn, http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleLabelGet godocs
|
// HandleLabelGet godocs
|
||||||
// @Summary Gets a label and fields
|
//
|
||||||
// @Tags Labels
|
// @Summary Get Label
|
||||||
// @Produce json
|
// @Tags Labels
|
||||||
// @Param id path string true "Label ID"
|
// @Produce json
|
||||||
// @Success 200 {object} repo.LabelOut
|
// @Param id path string true "Label ID"
|
||||||
// @Router /v1/labels/{id} [GET]
|
// @Success 200 {object} repo.LabelOut
|
||||||
// @Security Bearer
|
// @Router /v1/labels/{id} [GET]
|
||||||
func (ctrl *V1Controller) HandleLabelGet() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleLabelsGeneral()
|
func (ctrl *V1Controller) HandleLabelGet() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, ID uuid.UUID) (repo.LabelOut, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
return ctrl.repo.Labels.GetOneByGroup(auth, auth.GID, ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.CommandID("id", fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleLabelUpdate godocs
|
// HandleLabelUpdate godocs
|
||||||
// @Summary updates a label
|
//
|
||||||
// @Tags Labels
|
// @Summary Update Label
|
||||||
// @Produce json
|
// @Tags Labels
|
||||||
// @Param id path string true "Label ID"
|
// @Produce json
|
||||||
// @Success 200 {object} repo.LabelOut
|
// @Param id path string true "Label ID"
|
||||||
// @Router /v1/labels/{id} [PUT]
|
// @Success 200 {object} repo.LabelOut
|
||||||
// @Security Bearer
|
// @Router /v1/labels/{id} [PUT]
|
||||||
func (ctrl *V1Controller) HandleLabelUpdate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleLabelsGeneral()
|
func (ctrl *V1Controller) HandleLabelUpdate() errchain.HandlerFunc {
|
||||||
}
|
fn := func(r *http.Request, ID uuid.UUID, data repo.LabelUpdate) (repo.LabelOut, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
func (ctrl *V1Controller) handleLabelsGeneral() server.HandlerFunc {
|
data.ID = ID
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return ctrl.repo.Labels.UpdateByGroup(auth, auth.GID, data)
|
||||||
ctx := services.NewContext(r.Context())
|
|
||||||
ID, err := ctrl.routeID(r)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch r.Method {
|
|
||||||
case http.MethodGet:
|
|
||||||
labels, err := ctrl.repo.Labels.GetOneByGroup(r.Context(), ctx.GID, ID)
|
|
||||||
if err != nil {
|
|
||||||
if ent.IsNotFound(err) {
|
|
||||||
log.Err(err).
|
|
||||||
Str("id", ID.String()).
|
|
||||||
Msg("label not found")
|
|
||||||
return validate.NewRequestError(err, http.StatusNotFound)
|
|
||||||
}
|
|
||||||
log.Err(err).Msg("error getting label")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
return server.Respond(w, http.StatusOK, labels)
|
|
||||||
|
|
||||||
case http.MethodDelete:
|
|
||||||
err = ctrl.repo.Labels.DeleteByGroup(ctx, ctx.GID, ID)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("error deleting label")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
return server.Respond(w, http.StatusNoContent, nil)
|
|
||||||
|
|
||||||
case http.MethodPut:
|
|
||||||
body := repo.LabelUpdate{}
|
|
||||||
if err := server.Decode(r, &body); err != nil {
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
body.ID = ID
|
|
||||||
result, err := ctrl.repo.Labels.UpdateByGroup(ctx, ctx.GID, body)
|
|
||||||
if err != nil {
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
return server.Respond(w, http.StatusOK, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.ActionID("id", fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,186 +3,120 @@ package v1
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/web/adapters"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleLocationTreeQuery godoc
|
// HandleLocationTreeQuery
|
||||||
// @Summary Get All Locations
|
//
|
||||||
// @Tags Locations
|
// @Summary Get Locations Tree
|
||||||
// @Produce json
|
// @Tags Locations
|
||||||
// @Param withItems query bool false "include items in response tree"
|
// @Produce json
|
||||||
// @Success 200 {object} server.Results{items=[]repo.TreeItem}
|
// @Param withItems query bool false "include items in response tree"
|
||||||
// @Router /v1/locations/tree [GET]
|
// @Success 200 {object} []repo.TreeItem
|
||||||
// @Security Bearer
|
// @Router /v1/locations/tree [GET]
|
||||||
func (ctrl *V1Controller) HandleLocationTreeQuery() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleLocationTreeQuery() errchain.HandlerFunc {
|
||||||
user := services.UseUserCtx(r.Context())
|
fn := func(r *http.Request, query repo.TreeQuery) ([]repo.TreeItem, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
q := r.URL.Query()
|
return ctrl.repo.Locations.Tree(auth, auth.GID, query)
|
||||||
|
|
||||||
withItems := queryBool(q.Get("withItems"))
|
|
||||||
|
|
||||||
locTree, err := ctrl.repo.Locations.Tree(
|
|
||||||
r.Context(),
|
|
||||||
user.GroupID,
|
|
||||||
repo.TreeQuery{
|
|
||||||
WithItems: withItems,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to get locations tree")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, server.Results{Items: locTree})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Query(fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleLocationGetAll godoc
|
// HandleLocationGetAll
|
||||||
// @Summary Get All Locations
|
//
|
||||||
// @Tags Locations
|
// @Summary Get All Locations
|
||||||
// @Produce json
|
// @Tags Locations
|
||||||
// @Param filterChildren query bool false "Filter locations with parents"
|
// @Produce json
|
||||||
// @Success 200 {object} server.Results{items=[]repo.LocationOutCount}
|
// @Param filterChildren query bool false "Filter locations with parents"
|
||||||
// @Router /v1/locations [GET]
|
// @Success 200 {object} []repo.LocationOutCount
|
||||||
// @Security Bearer
|
// @Router /v1/locations [GET]
|
||||||
func (ctrl *V1Controller) HandleLocationGetAll() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleLocationGetAll() errchain.HandlerFunc {
|
||||||
user := services.UseUserCtx(r.Context())
|
fn := func(r *http.Request, q repo.LocationQuery) ([]repo.LocationOutCount, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
q := r.URL.Query()
|
return ctrl.repo.Locations.GetAll(auth, auth.GID, q)
|
||||||
|
|
||||||
filter := repo.LocationQuery{
|
|
||||||
FilterChildren: queryBool(q.Get("filterChildren")),
|
|
||||||
}
|
|
||||||
|
|
||||||
locations, err := ctrl.repo.Locations.GetAll(r.Context(), user.GroupID, filter)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to get locations")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, server.Results{Items: locations})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Query(fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleLocationCreate godoc
|
// HandleLocationCreate
|
||||||
// @Summary Create a new location
|
//
|
||||||
// @Tags Locations
|
// @Summary Create Location
|
||||||
// @Produce json
|
// @Tags Locations
|
||||||
// @Param payload body repo.LocationCreate true "Location Data"
|
// @Produce json
|
||||||
// @Success 200 {object} repo.LocationSummary
|
// @Param payload body repo.LocationCreate true "Location Data"
|
||||||
// @Router /v1/locations [POST]
|
// @Success 200 {object} repo.LocationSummary
|
||||||
// @Security Bearer
|
// @Router /v1/locations [POST]
|
||||||
func (ctrl *V1Controller) HandleLocationCreate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleLocationCreate() errchain.HandlerFunc {
|
||||||
createData := repo.LocationCreate{}
|
fn := func(r *http.Request, createData repo.LocationCreate) (repo.LocationOut, error) {
|
||||||
if err := server.Decode(r, &createData); err != nil {
|
auth := services.NewContext(r.Context())
|
||||||
log.Err(err).Msg("failed to decode location create data")
|
return ctrl.repo.Locations.Create(auth, auth.GID, createData)
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
user := services.UseUserCtx(r.Context())
|
|
||||||
location, err := ctrl.repo.Locations.Create(r.Context(), user.GroupID, createData)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to create location")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusCreated, location)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Action(fn, http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleLocationDelete godocs
|
// HandleLocationDelete
|
||||||
// @Summary deletes a location
|
//
|
||||||
// @Tags Locations
|
// @Summary Delete Location
|
||||||
// @Produce json
|
// @Tags Locations
|
||||||
// @Param id path string true "Location ID"
|
// @Produce json
|
||||||
// @Success 204
|
// @Param id path string true "Location ID"
|
||||||
// @Router /v1/locations/{id} [DELETE]
|
// @Success 204
|
||||||
// @Security Bearer
|
// @Router /v1/locations/{id} [DELETE]
|
||||||
func (ctrl *V1Controller) HandleLocationDelete() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleLocationGeneral()
|
func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc {
|
||||||
}
|
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
// HandleLocationGet godocs
|
err := ctrl.repo.Locations.DeleteByGroup(auth, auth.GID, ID)
|
||||||
// @Summary Gets a location and fields
|
return nil, err
|
||||||
// @Tags Locations
|
|
||||||
// @Produce json
|
|
||||||
// @Param id path string true "Location ID"
|
|
||||||
// @Success 200 {object} repo.LocationOut
|
|
||||||
// @Router /v1/locations/{id} [GET]
|
|
||||||
// @Security Bearer
|
|
||||||
func (ctrl *V1Controller) HandleLocationGet() server.HandlerFunc {
|
|
||||||
return ctrl.handleLocationGeneral()
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleLocationUpdate godocs
|
|
||||||
// @Summary updates a location
|
|
||||||
// @Tags Locations
|
|
||||||
// @Produce json
|
|
||||||
// @Param id path string true "Location ID"
|
|
||||||
// @Param payload body repo.LocationUpdate true "Location Data"
|
|
||||||
// @Success 200 {object} repo.LocationOut
|
|
||||||
// @Router /v1/locations/{id} [PUT]
|
|
||||||
// @Security Bearer
|
|
||||||
func (ctrl *V1Controller) HandleLocationUpdate() server.HandlerFunc {
|
|
||||||
return ctrl.handleLocationGeneral()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctrl *V1Controller) handleLocationGeneral() server.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
|
||||||
ctx := services.NewContext(r.Context())
|
|
||||||
ID, err := ctrl.routeID(r)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch r.Method {
|
|
||||||
case http.MethodGet:
|
|
||||||
location, err := ctrl.repo.Locations.GetOneByGroup(r.Context(), ctx.GID, ID)
|
|
||||||
if err != nil {
|
|
||||||
l := log.Err(err).
|
|
||||||
Str("ID", ID.String()).
|
|
||||||
Str("GID", ctx.GID.String())
|
|
||||||
|
|
||||||
if ent.IsNotFound(err) {
|
|
||||||
l.Msg("location not found")
|
|
||||||
return validate.NewRequestError(err, http.StatusNotFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
l.Msg("failed to get location")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
return server.Respond(w, http.StatusOK, location)
|
|
||||||
case http.MethodPut:
|
|
||||||
body := repo.LocationUpdate{}
|
|
||||||
if err := server.Decode(r, &body); err != nil {
|
|
||||||
log.Err(err).Msg("failed to decode location update data")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
body.ID = ID
|
|
||||||
|
|
||||||
result, err := ctrl.repo.Locations.UpdateOneByGroup(r.Context(), ctx.GID, ID, body)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to update location")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
return server.Respond(w, http.StatusOK, result)
|
|
||||||
case http.MethodDelete:
|
|
||||||
err = ctrl.repo.Locations.DeleteByGroup(r.Context(), ctx.GID, ID)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to delete location")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
return server.Respond(w, http.StatusNoContent, nil)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.CommandID("id", fn, http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleLocationGet
|
||||||
|
//
|
||||||
|
// @Summary Get Location
|
||||||
|
// @Tags Locations
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "Location ID"
|
||||||
|
// @Success 200 {object} repo.LocationOut
|
||||||
|
// @Router /v1/locations/{id} [GET]
|
||||||
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleLocationGet() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, ID uuid.UUID) (repo.LocationOut, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
return ctrl.repo.Locations.GetOneByGroup(auth, auth.GID, ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.CommandID("id", fn, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleLocationUpdate
|
||||||
|
//
|
||||||
|
// @Summary Update Location
|
||||||
|
// @Tags Locations
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "Location ID"
|
||||||
|
// @Param payload body repo.LocationUpdate true "Location Data"
|
||||||
|
// @Success 200 {object} repo.LocationOut
|
||||||
|
// @Router /v1/locations/{id} [PUT]
|
||||||
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleLocationUpdate() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, ID uuid.UUID, body repo.LocationUpdate) (repo.LocationOut, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
body.ID = ID
|
||||||
|
return ctrl.repo.Locations.UpdateByGroup(auth, auth.GID, ID, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.ActionID("id", fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,132 +2,81 @@ package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/web/adapters"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleMaintenanceGetLog godoc
|
// HandleMaintenanceGetLog godoc
|
||||||
// @Summary Get Maintenance Log
|
//
|
||||||
// @Tags Maintenance
|
// @Summary Get Maintenance Log
|
||||||
// @Produce json
|
// @Tags Maintenance
|
||||||
// @Success 200 {object} repo.MaintenanceLog
|
// @Produce json
|
||||||
// @Router /v1/items/{id}/maintenance [GET]
|
// @Success 200 {object} repo.MaintenanceLog
|
||||||
// @Security Bearer
|
// @Router /v1/items/{id}/maintenance [GET]
|
||||||
func (ctrl *V1Controller) HandleMaintenanceLogGet() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleMaintenanceLog()
|
func (ctrl *V1Controller) HandleMaintenanceLogGet() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, ID uuid.UUID, q repo.MaintenanceLogQuery) (repo.MaintenanceLog, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
return ctrl.repo.MaintEntry.GetLog(auth, auth.GID, ID, q)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.QueryID("id", fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleMaintenanceEntryCreate godoc
|
// HandleMaintenanceEntryCreate godoc
|
||||||
// @Summary Create Maintenance Entry
|
//
|
||||||
// @Tags Maintenance
|
// @Summary Create Maintenance Entry
|
||||||
// @Produce json
|
// @Tags Maintenance
|
||||||
// @Param payload body repo.MaintenanceEntryCreate true "Entry Data"
|
// @Produce json
|
||||||
// @Success 200 {object} repo.MaintenanceEntry
|
// @Param payload body repo.MaintenanceEntryCreate true "Entry Data"
|
||||||
// @Router /v1/items/{id}/maintenance [POST]
|
// @Success 201 {object} repo.MaintenanceEntry
|
||||||
// @Security Bearer
|
// @Router /v1/items/{id}/maintenance [POST]
|
||||||
func (ctrl *V1Controller) HandleMaintenanceEntryCreate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleMaintenanceLog()
|
func (ctrl *V1Controller) HandleMaintenanceEntryCreate() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, itemID uuid.UUID, body repo.MaintenanceEntryCreate) (repo.MaintenanceEntry, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
return ctrl.repo.MaintEntry.Create(auth, itemID, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.ActionID("id", fn, http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleMaintenanceEntryDelete godoc
|
// HandleMaintenanceEntryDelete godoc
|
||||||
// @Summary Delete Maintenance Entry
|
//
|
||||||
// @Tags Maintenance
|
// @Summary Delete Maintenance Entry
|
||||||
// @Produce json
|
// @Tags Maintenance
|
||||||
// @Success 204
|
// @Produce json
|
||||||
// @Router /v1/items/{id}/maintenance/{entry_id} [DELETE]
|
// @Success 204
|
||||||
// @Security Bearer
|
// @Router /v1/items/{id}/maintenance/{entry_id} [DELETE]
|
||||||
func (ctrl *V1Controller) HandleMaintenanceEntryDelete() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleMaintenanceLog()
|
func (ctrl *V1Controller) HandleMaintenanceEntryDelete() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, entryID uuid.UUID) (any, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
err := ctrl.repo.MaintEntry.Delete(auth, entryID)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.CommandID("entry_id", fn, http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleMaintenanceEntryUpdate godoc
|
// HandleMaintenanceEntryUpdate godoc
|
||||||
// @Summary Update Maintenance Entry
|
//
|
||||||
// @Tags Maintenance
|
// @Summary Update Maintenance Entry
|
||||||
// @Produce json
|
// @Tags Maintenance
|
||||||
// @Param payload body repo.MaintenanceEntryUpdate true "Entry Data"
|
// @Produce json
|
||||||
// @Success 200 {object} repo.MaintenanceEntry
|
// @Param payload body repo.MaintenanceEntryUpdate true "Entry Data"
|
||||||
// @Router /v1/items/{id}/maintenance/{entry_id} [PUT]
|
// @Success 200 {object} repo.MaintenanceEntry
|
||||||
// @Security Bearer
|
// @Router /v1/items/{id}/maintenance/{entry_id} [PUT]
|
||||||
func (ctrl *V1Controller) HandleMaintenanceEntryUpdate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return ctrl.handleMaintenanceLog()
|
func (ctrl *V1Controller) HandleMaintenanceEntryUpdate() errchain.HandlerFunc {
|
||||||
}
|
fn := func(r *http.Request, entryID uuid.UUID, body repo.MaintenanceEntryUpdate) (repo.MaintenanceEntry, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
func (ctrl *V1Controller) handleMaintenanceLog() server.HandlerFunc {
|
return ctrl.repo.MaintEntry.Update(auth, entryID, body)
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
|
||||||
ctx := services.NewContext(r.Context())
|
|
||||||
itemID, err := ctrl.routeID(r)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch r.Method {
|
|
||||||
case http.MethodGet:
|
|
||||||
completed, _ := strconv.ParseBool(r.URL.Query().Get("completed"))
|
|
||||||
scheduled, _ := strconv.ParseBool(r.URL.Query().Get("scheduled"))
|
|
||||||
query := repo.MaintenanceLogQuery{
|
|
||||||
Completed: completed,
|
|
||||||
Scheduled: scheduled,
|
|
||||||
}
|
|
||||||
|
|
||||||
mlog, err := ctrl.repo.MaintEntry.GetLog(ctx, itemID, query)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to get items")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
return server.Respond(w, http.StatusOK, mlog)
|
|
||||||
case http.MethodPost:
|
|
||||||
var create repo.MaintenanceEntryCreate
|
|
||||||
err := server.Decode(r, &create)
|
|
||||||
if err != nil {
|
|
||||||
return validate.NewRequestError(err, http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
entry, err := ctrl.repo.MaintEntry.Create(ctx, itemID, create)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to create item")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusCreated, entry)
|
|
||||||
case http.MethodPut:
|
|
||||||
entryID, err := ctrl.routeUUID(r, "entry_id")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var update repo.MaintenanceEntryUpdate
|
|
||||||
err = server.Decode(r, &update)
|
|
||||||
if err != nil {
|
|
||||||
return validate.NewRequestError(err, http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
entry, err := ctrl.repo.MaintEntry.Update(ctx, entryID, update)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to update item")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, entry)
|
|
||||||
case http.MethodDelete:
|
|
||||||
entryID, err := ctrl.routeUUID(r, "entry_id")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ctrl.repo.MaintEntry.Delete(ctx, entryID)
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg("failed to delete item")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusNoContent, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.ActionID("entry_id", fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
105
backend/app/api/handlers/v1/v1_ctrl_notifiers.go
Normal file
105
backend/app/api/handlers/v1/v1_ctrl_notifiers.go
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/containrrr/shoutrrr"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/web/adapters"
|
||||||
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HandleGetUserNotifiers godoc
|
||||||
|
//
|
||||||
|
// @Summary Get Notifiers
|
||||||
|
// @Tags Notifiers
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} []repo.NotifierOut
|
||||||
|
// @Router /v1/notifiers [GET]
|
||||||
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleGetUserNotifiers() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, _ struct{}) ([]repo.NotifierOut, error) {
|
||||||
|
user := services.UseUserCtx(r.Context())
|
||||||
|
return ctrl.repo.Notifiers.GetByUser(r.Context(), user.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.Query(fn, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCreateNotifier godoc
|
||||||
|
//
|
||||||
|
// @Summary Create Notifier
|
||||||
|
// @Tags Notifiers
|
||||||
|
// @Produce json
|
||||||
|
// @Param payload body repo.NotifierCreate true "Notifier Data"
|
||||||
|
// @Success 200 {object} repo.NotifierOut
|
||||||
|
// @Router /v1/notifiers [POST]
|
||||||
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleCreateNotifier() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, in repo.NotifierCreate) (repo.NotifierOut, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
return ctrl.repo.Notifiers.Create(auth, auth.GID, auth.UID, in)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.Action(fn, http.StatusCreated)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleDeleteNotifier godocs
|
||||||
|
//
|
||||||
|
// @Summary Delete a Notifier
|
||||||
|
// @Tags Notifiers
|
||||||
|
// @Param id path string true "Notifier ID"
|
||||||
|
// @Success 204
|
||||||
|
// @Router /v1/notifiers/{id} [DELETE]
|
||||||
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleDeleteNotifier() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
return nil, ctrl.repo.Notifiers.Delete(auth, auth.UID, ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.CommandID("id", fn, http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleUpdateNotifier godocs
|
||||||
|
//
|
||||||
|
// @Summary Update Notifier
|
||||||
|
// @Tags Notifiers
|
||||||
|
// @Param id path string true "Notifier ID"
|
||||||
|
// @Param payload body repo.NotifierUpdate true "Notifier Data"
|
||||||
|
// @Success 200 {object} repo.NotifierOut
|
||||||
|
// @Router /v1/notifiers/{id} [PUT]
|
||||||
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleUpdateNotifier() errchain.HandlerFunc {
|
||||||
|
fn := func(r *http.Request, ID uuid.UUID, in repo.NotifierUpdate) (repo.NotifierOut, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
|
return ctrl.repo.Notifiers.Update(auth, auth.UID, ID, in)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.ActionID("id", fn, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandlerNotifierTest godoc
|
||||||
|
//
|
||||||
|
// @Summary Test Notifier
|
||||||
|
// @Tags Notifiers
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "Notifier ID"
|
||||||
|
// @Param url query string true "URL"
|
||||||
|
// @Success 204
|
||||||
|
// @Router /v1/notifiers/test [POST]
|
||||||
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandlerNotifierTest() errchain.HandlerFunc {
|
||||||
|
type body struct {
|
||||||
|
URL string `json:"url" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn := func(r *http.Request, q body) (any, error) {
|
||||||
|
err := shoutrrr.Send(q.URL, "Test message from Homebox")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapters.Action(fn, http.StatusOK)
|
||||||
|
}
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/web/adapters"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
"github.com/yeqown/go-qrcode/v2"
|
"github.com/yeqown/go-qrcode/v2"
|
||||||
"github.com/yeqown/go-qrcode/writer/standard"
|
"github.com/yeqown/go-qrcode/writer/standard"
|
||||||
|
|
||||||
|
@ -19,32 +19,31 @@ var qrcodeLogo []byte
|
||||||
|
|
||||||
// HandleGenerateQRCode godoc
|
// HandleGenerateQRCode godoc
|
||||||
//
|
//
|
||||||
// @Summary Encode data into QRCode
|
// @Summary Create QR Code
|
||||||
// @Tags Items
|
// @Tags Items
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param data query string false "data to be encoded into qrcode"
|
// @Param data query string false "data to be encoded into qrcode"
|
||||||
// @Success 200 {string} string "image/jpeg"
|
// @Success 200 {string} string "image/jpeg"
|
||||||
// @Router /v1/qrcode [GET]
|
// @Router /v1/qrcode [GET]
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func (ctrl *V1Controller) HandleGenerateQRCode() server.HandlerFunc {
|
func (ctrl *V1Controller) HandleGenerateQRCode() errchain.HandlerFunc {
|
||||||
const MaxLength = 4_296 // assume alphanumeric characters only
|
type query struct {
|
||||||
|
// 4,296 characters is the maximum length of a QR code
|
||||||
|
Data string `schema:"data" validate:"required,max=4296"`
|
||||||
|
}
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
data := r.URL.Query().Get("data")
|
q, err := adapters.DecodeQuery[query](r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
image, err := png.Decode(bytes.NewReader(qrcodeLogo))
|
image, err := png.Decode(bytes.NewReader(qrcodeLogo))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(data) > MaxLength {
|
qrc, err := qrcode.New(q.Data)
|
||||||
return validate.NewFieldErrors(validate.FieldError{
|
|
||||||
Field: "data",
|
|
||||||
Error: "max length is 4,296 characters exceeded",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
qrc, err := qrcode.New(data)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,18 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleBillOfMaterialsExport godoc
|
// HandleBillOfMaterialsExport godoc
|
||||||
//
|
//
|
||||||
// @Summary Generates a Bill of Materials CSV
|
// @Summary Export Bill of Materials
|
||||||
// @Tags Reporting
|
// @Tags Reporting
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {string} string "text/csv"
|
// @Success 200 {string} string "text/csv"
|
||||||
// @Router /v1/reporting/bill-of-materials [GET]
|
// @Router /v1/reporting/bill-of-materials [GET]
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func (ctrl *V1Controller) HandleBillOfMaterialsExport() server.HandlerFunc {
|
func (ctrl *V1Controller) HandleBillOfMaterialsExport() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
actor := services.UseUserCtx(r.Context())
|
actor := services.UseUserCtx(r.Context())
|
||||||
|
|
||||||
|
|
|
@ -5,80 +5,75 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/homebox/backend/internal/web/adapters"
|
||||||
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
|
"github.com/hay-kot/httpkit/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleGroupGet godoc
|
// HandleGroupGet godoc
|
||||||
// @Summary Get the current user's group statistics
|
//
|
||||||
// @Tags Statistics
|
// @Summary Get Location Statistics
|
||||||
// @Produce json
|
// @Tags Statistics
|
||||||
// @Success 200 {object} []repo.TotalsByOrganizer
|
// @Produce json
|
||||||
// @Router /v1/groups/statistics/locations [GET]
|
// @Success 200 {object} []repo.TotalsByOrganizer
|
||||||
// @Security Bearer
|
// @Router /v1/groups/statistics/locations [GET]
|
||||||
func (ctrl *V1Controller) HandleGroupStatisticsLocations() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleGroupStatisticsLocations() errchain.HandlerFunc {
|
||||||
ctx := services.NewContext(r.Context())
|
fn := func(r *http.Request) ([]repo.TotalsByOrganizer, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
stats, err := ctrl.repo.Groups.StatsLocationsByPurchasePrice(ctx, ctx.GID)
|
return ctrl.repo.Groups.StatsLocationsByPurchasePrice(auth, auth.GID)
|
||||||
if err != nil {
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, stats)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Command(fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleGroupGet godoc
|
// HandleGroupStatisticsLabels godoc
|
||||||
// @Summary Get the current user's group statistics
|
//
|
||||||
// @Tags Statistics
|
// @Summary Get Label Statistics
|
||||||
// @Produce json
|
// @Tags Statistics
|
||||||
// @Success 200 {object} []repo.TotalsByOrganizer
|
// @Produce json
|
||||||
// @Router /v1/groups/statistics/labels [GET]
|
// @Success 200 {object} []repo.TotalsByOrganizer
|
||||||
// @Security Bearer
|
// @Router /v1/groups/statistics/labels [GET]
|
||||||
func (ctrl *V1Controller) HandleGroupStatisticsLabels() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleGroupStatisticsLabels() errchain.HandlerFunc {
|
||||||
ctx := services.NewContext(r.Context())
|
fn := func(r *http.Request) ([]repo.TotalsByOrganizer, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
stats, err := ctrl.repo.Groups.StatsLabelsByPurchasePrice(ctx, ctx.GID)
|
return ctrl.repo.Groups.StatsLabelsByPurchasePrice(auth, auth.GID)
|
||||||
if err != nil {
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, stats)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Command(fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleGroupGet godoc
|
// HandleGroupStatistics godoc
|
||||||
// @Summary Get the current user's group statistics
|
//
|
||||||
// @Tags Statistics
|
// @Summary Get Group Statistics
|
||||||
// @Produce json
|
// @Tags Statistics
|
||||||
// @Success 200 {object} repo.GroupStatistics
|
// @Produce json
|
||||||
// @Router /v1/groups/statistics [GET]
|
// @Success 200 {object} repo.GroupStatistics
|
||||||
// @Security Bearer
|
// @Router /v1/groups/statistics [GET]
|
||||||
func (ctrl *V1Controller) HandleGroupStatistics() server.HandlerFunc {
|
// @Security Bearer
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
func (ctrl *V1Controller) HandleGroupStatistics() errchain.HandlerFunc {
|
||||||
ctx := services.NewContext(r.Context())
|
fn := func(r *http.Request) (repo.GroupStatistics, error) {
|
||||||
|
auth := services.NewContext(r.Context())
|
||||||
stats, err := ctrl.repo.Groups.StatsGroup(ctx, ctx.GID)
|
return ctrl.repo.Groups.StatsGroup(auth, auth.GID)
|
||||||
if err != nil {
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, stats)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return adapters.Command(fn, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleGroupGet godoc
|
// HandleGroupStatisticsPriceOverTime godoc
|
||||||
// @Summary Queries the changes overtime of the purchase price over time
|
//
|
||||||
// @Tags Statistics
|
// @Summary Get Purchase Price Statistics
|
||||||
// @Produce json
|
// @Tags Statistics
|
||||||
// @Success 200 {object} repo.ValueOverTime
|
// @Produce json
|
||||||
// @Param start query string false "start date"
|
// @Success 200 {object} repo.ValueOverTime
|
||||||
// @Param end query string false "end date"
|
// @Param start query string false "start date"
|
||||||
// @Router /v1/groups/statistics/purchase-price [GET]
|
// @Param end query string false "end date"
|
||||||
// @Security Bearer
|
// @Router /v1/groups/statistics/purchase-price [GET]
|
||||||
func (ctrl *V1Controller) HandleGroupStatisticsPriceOverTime() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleGroupStatisticsPriceOverTime() errchain.HandlerFunc {
|
||||||
parseDate := func(datestr string, defaultDate time.Time) (time.Time, error) {
|
parseDate := func(datestr string, defaultDate time.Time) (time.Time, error) {
|
||||||
if datestr == "" {
|
if datestr == "" {
|
||||||
return defaultDate, nil
|
return defaultDate, nil
|
||||||
|
@ -104,6 +99,6 @@ func (ctrl *V1Controller) HandleGroupStatisticsPriceOverTime() server.HandlerFun
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, stats)
|
return server.JSON(w, http.StatusOK, stats)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,20 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
|
"github.com/hay-kot/httpkit/server"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleUserSelf godoc
|
// HandleUserRegistration godoc
|
||||||
// @Summary Get the current user
|
//
|
||||||
// @Tags User
|
// @Summary Register New User
|
||||||
// @Produce json
|
// @Tags User
|
||||||
// @Param payload body services.UserRegistration true "User Data"
|
// @Produce json
|
||||||
// @Success 204
|
// @Param payload body services.UserRegistration true "User Data"
|
||||||
// @Router /v1/users/register [Post]
|
// @Success 204
|
||||||
func (ctrl *V1Controller) HandleUserRegistration() server.HandlerFunc {
|
// @Router /v1/users/register [Post]
|
||||||
|
func (ctrl *V1Controller) HandleUserRegistration() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
regData := services.UserRegistration{}
|
regData := services.UserRegistration{}
|
||||||
|
|
||||||
|
@ -38,18 +40,19 @@ func (ctrl *V1Controller) HandleUserRegistration() server.HandlerFunc {
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusNoContent, nil)
|
return server.JSON(w, http.StatusNoContent, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleUserSelf godoc
|
// HandleUserSelf godoc
|
||||||
// @Summary Get the current user
|
//
|
||||||
// @Tags User
|
// @Summary Get User Self
|
||||||
// @Produce json
|
// @Tags User
|
||||||
// @Success 200 {object} server.Result{item=repo.UserOut}
|
// @Produce json
|
||||||
// @Router /v1/users/self [GET]
|
// @Success 200 {object} Wrapped{item=repo.UserOut}
|
||||||
// @Security Bearer
|
// @Router /v1/users/self [GET]
|
||||||
func (ctrl *V1Controller) HandleUserSelf() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleUserSelf() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
token := services.UseTokenCtx(r.Context())
|
token := services.UseTokenCtx(r.Context())
|
||||||
usr, err := ctrl.svc.User.GetSelf(r.Context(), token)
|
usr, err := ctrl.svc.User.GetSelf(r.Context(), token)
|
||||||
|
@ -58,19 +61,20 @@ func (ctrl *V1Controller) HandleUserSelf() server.HandlerFunc {
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, server.Wrap(usr))
|
return server.JSON(w, http.StatusOK, Wrap(usr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleUserSelfUpdate godoc
|
// HandleUserSelfUpdate godoc
|
||||||
// @Summary Update the current user
|
//
|
||||||
// @Tags User
|
// @Summary Update Account
|
||||||
// @Produce json
|
// @Tags User
|
||||||
// @Param payload body repo.UserUpdate true "User Data"
|
// @Produce json
|
||||||
// @Success 200 {object} server.Result{item=repo.UserUpdate}
|
// @Param payload body repo.UserUpdate true "User Data"
|
||||||
// @Router /v1/users/self [PUT]
|
// @Success 200 {object} Wrapped{item=repo.UserUpdate}
|
||||||
// @Security Bearer
|
// @Router /v1/users/self [PUT]
|
||||||
func (ctrl *V1Controller) HandleUserSelfUpdate() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleUserSelfUpdate() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
updateData := repo.UserUpdate{}
|
updateData := repo.UserUpdate{}
|
||||||
if err := server.Decode(r, &updateData); err != nil {
|
if err := server.Decode(r, &updateData); err != nil {
|
||||||
|
@ -84,18 +88,19 @@ func (ctrl *V1Controller) HandleUserSelfUpdate() server.HandlerFunc {
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, server.Wrap(newData))
|
return server.JSON(w, http.StatusOK, Wrap(newData))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleUserSelfDelete godoc
|
// HandleUserSelfDelete godoc
|
||||||
// @Summary Deletes the user account
|
//
|
||||||
// @Tags User
|
// @Summary Delete Account
|
||||||
// @Produce json
|
// @Tags User
|
||||||
// @Success 204
|
// @Produce json
|
||||||
// @Router /v1/users/self [DELETE]
|
// @Success 204
|
||||||
// @Security Bearer
|
// @Router /v1/users/self [DELETE]
|
||||||
func (ctrl *V1Controller) HandleUserSelfDelete() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleUserSelfDelete() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
if ctrl.isDemo {
|
if ctrl.isDemo {
|
||||||
return validate.NewRequestError(nil, http.StatusForbidden)
|
return validate.NewRequestError(nil, http.StatusForbidden)
|
||||||
|
@ -106,7 +111,7 @@ func (ctrl *V1Controller) HandleUserSelfDelete() server.HandlerFunc {
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusNoContent, nil)
|
return server.JSON(w, http.StatusNoContent, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,13 +123,14 @@ type (
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleUserSelfChangePassword godoc
|
// HandleUserSelfChangePassword godoc
|
||||||
// @Summary Updates the users password
|
//
|
||||||
// @Tags User
|
// @Summary Change Password
|
||||||
// @Success 204
|
// @Tags User
|
||||||
// @Param payload body ChangePassword true "Password Payload"
|
// @Success 204
|
||||||
// @Router /v1/users/change-password [PUT]
|
// @Param payload body ChangePassword true "Password Payload"
|
||||||
// @Security Bearer
|
// @Router /v1/users/change-password [PUT]
|
||||||
func (ctrl *V1Controller) HandleUserSelfChangePassword() server.HandlerFunc {
|
// @Security Bearer
|
||||||
|
func (ctrl *V1Controller) HandleUserSelfChangePassword() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
if ctrl.isDemo {
|
if ctrl.isDemo {
|
||||||
return validate.NewRequestError(nil, http.StatusForbidden)
|
return validate.NewRequestError(nil, http.StatusForbidden)
|
||||||
|
@ -143,6 +149,6 @@ func (ctrl *V1Controller) HandleUserSelfChangePassword() server.HandlerFunc {
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusNoContent, nil)
|
return server.JSON(w, http.StatusNoContent, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -9,16 +10,23 @@ import (
|
||||||
|
|
||||||
atlas "ariga.io/atlas/sql/migrate"
|
atlas "ariga.io/atlas/sql/migrate"
|
||||||
"entgo.io/ent/dialect/sql/schema"
|
"entgo.io/ent/dialect/sql/schema"
|
||||||
"github.com/hay-kot/homebox/backend/app/api/static/docs"
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
|
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/migrations"
|
"github.com/hay-kot/homebox/backend/internal/data/migrations"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/config"
|
"github.com/hay-kot/homebox/backend/internal/sys/config"
|
||||||
"github.com/hay-kot/homebox/backend/internal/web/mid"
|
"github.com/hay-kot/homebox/backend/internal/web/mid"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
"github.com/hay-kot/httpkit/server"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/rs/zerolog/pkgerrors"
|
||||||
|
|
||||||
|
_ "github.com/hay-kot/homebox/backend/pkgs/cgofreesqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -27,24 +35,23 @@ var (
|
||||||
buildTime = "now"
|
buildTime = "now"
|
||||||
)
|
)
|
||||||
|
|
||||||
// @title Go API Templates
|
// @title Homebox API
|
||||||
// @version 1.0
|
// @version 1.0
|
||||||
// @description This is a simple Rest API Server Template that implements some basic User and Authentication patterns to help you get started and bootstrap your next project!.
|
// @description Track, Manage, and Organize your Things.
|
||||||
// @contact.name Don't
|
// @contact.name Don't
|
||||||
// @license.name MIT
|
|
||||||
// @BasePath /api
|
// @BasePath /api
|
||||||
// @securityDefinitions.apikey Bearer
|
// @securityDefinitions.apikey Bearer
|
||||||
// @in header
|
// @in header
|
||||||
// @name Authorization
|
// @name Authorization
|
||||||
// @description "Type 'Bearer TOKEN' to correctly set the API Key"
|
// @description "Type 'Bearer TOKEN' to correctly set the API Key"
|
||||||
func main() {
|
func main() {
|
||||||
|
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
|
||||||
|
|
||||||
cfg, err := config.New()
|
cfg, err := config.New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
docs.SwaggerInfo.Host = cfg.Swagger.Host
|
|
||||||
|
|
||||||
if err := run(cfg); err != nil {
|
if err := run(cfg); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -110,39 +117,43 @@ func run(cfg *config.Config) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.bus = eventbus.New()
|
||||||
app.db = c
|
app.db = c
|
||||||
app.repos = repo.New(c, cfg.Storage.Data)
|
app.repos = repo.New(c, app.bus, cfg.Storage.Data)
|
||||||
app.services = services.New(
|
app.services = services.New(
|
||||||
app.repos,
|
app.repos,
|
||||||
services.WithAutoIncrementAssetID(cfg.Options.AutoIncrementAssetID),
|
services.WithAutoIncrementAssetID(cfg.Options.AutoIncrementAssetID),
|
||||||
)
|
)
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// Start Server\
|
// Start Server
|
||||||
|
|
||||||
logger := log.With().Caller().Logger()
|
logger := log.With().Caller().Logger()
|
||||||
|
|
||||||
mwLogger := mid.Logger(logger)
|
router := chi.NewMux()
|
||||||
if app.conf.Mode == config.ModeDevelopment {
|
router.Use(
|
||||||
mwLogger = mid.SugarLogger(logger)
|
middleware.RequestID,
|
||||||
}
|
middleware.RealIP,
|
||||||
|
mid.Logger(logger),
|
||||||
|
middleware.Recoverer,
|
||||||
|
middleware.StripSlashes,
|
||||||
|
)
|
||||||
|
|
||||||
|
chain := errchain.New(mid.Errors(app.server, logger))
|
||||||
|
|
||||||
|
app.mountRoutes(router, chain, app.repos)
|
||||||
|
|
||||||
app.server = server.NewServer(
|
app.server = server.NewServer(
|
||||||
server.WithHost(app.conf.Web.Host),
|
server.WithHost(app.conf.Web.Host),
|
||||||
server.WithPort(app.conf.Web.Port),
|
server.WithPort(app.conf.Web.Port),
|
||||||
server.WithMiddleware(
|
|
||||||
mwLogger,
|
|
||||||
mid.Errors(logger),
|
|
||||||
mid.Panic(app.conf.Mode == config.ModeDevelopment),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
app.mountRoutes(app.repos)
|
|
||||||
|
|
||||||
log.Info().Msgf("Starting HTTP Server on %s:%s", app.server.Host, app.server.Port)
|
log.Info().Msgf("Starting HTTP Server on %s:%s", app.server.Host, app.server.Port)
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// Start Reoccurring Tasks
|
// Start Reoccurring Tasks
|
||||||
|
|
||||||
|
go app.bus.Run()
|
||||||
|
|
||||||
go app.startBgTask(time.Duration(24)*time.Hour, func() {
|
go app.startBgTask(time.Duration(24)*time.Hour, func() {
|
||||||
_, err := app.repos.AuthTokens.PurgeExpiredTokens(context.Background())
|
_, err := app.repos.AuthTokens.PurgeExpiredTokens(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -159,6 +170,19 @@ func run(cfg *config.Config) error {
|
||||||
Msg("failed to purge expired invitations")
|
Msg("failed to purge expired invitations")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
go app.startBgTask(time.Duration(1)*time.Hour, func() {
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
if now.Hour() == 8 {
|
||||||
|
fmt.Println("run notifiers")
|
||||||
|
err := app.services.BackgroundService.SendNotifiersToday(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
log.Error().
|
||||||
|
Err(err).
|
||||||
|
Msg("failed to send notifiers")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// TODO: Remove through external API that does setup
|
// TODO: Remove through external API that does setup
|
||||||
if cfg.Demo {
|
if cfg.Demo {
|
||||||
|
@ -175,5 +199,5 @@ func run(cfg *config.Config) error {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
return app.server.Start()
|
return app.server.Start(router)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,10 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
v1 "github.com/hay-kot/homebox/backend/app/api/handlers/v1"
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
)
|
)
|
||||||
|
|
||||||
type tokenHasKey struct {
|
type tokenHasKey struct {
|
||||||
|
@ -30,9 +31,9 @@ const (
|
||||||
// the required roles, a 403 Forbidden will be returned.
|
// the required roles, a 403 Forbidden will be returned.
|
||||||
//
|
//
|
||||||
// WARNING: This middleware _MUST_ be called after mwAuthToken or else it will panic
|
// WARNING: This middleware _MUST_ be called after mwAuthToken or else it will panic
|
||||||
func (a *app) mwRoles(rm RoleMode, required ...string) server.Middleware {
|
func (a *app) mwRoles(rm RoleMode, required ...string) errchain.Middleware {
|
||||||
return func(next server.Handler) server.Handler {
|
return func(next errchain.Handler) errchain.Handler {
|
||||||
return server.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
return errchain.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
maybeToken := ctx.Value(hashedToken)
|
maybeToken := ctx.Value(hashedToken)
|
||||||
|
@ -94,20 +95,6 @@ func getQuery(r *http.Request) (string, error) {
|
||||||
return token, nil
|
return token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCookie(r *http.Request) (string, error) {
|
|
||||||
cookie, err := r.Cookie("hb.auth.token")
|
|
||||||
if err != nil {
|
|
||||||
return "", errors.New("access_token cookie is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
token, err := url.QueryUnescape(cookie.Value)
|
|
||||||
if err != nil {
|
|
||||||
return "", errors.New("access_token cookie is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
return token, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// mwAuthToken is a middleware that will check the database for a stateful token
|
// mwAuthToken is a middleware that will check the database for a stateful token
|
||||||
// and attach it's user to the request context, or return an appropriate error.
|
// and attach it's user to the request context, or return an appropriate error.
|
||||||
// Authorization support is by token via Headers or Query Parameter
|
// Authorization support is by token via Headers or Query Parameter
|
||||||
|
@ -115,21 +102,30 @@ func getCookie(r *http.Request) (string, error) {
|
||||||
// Example:
|
// Example:
|
||||||
// - header = "Bearer 1234567890"
|
// - header = "Bearer 1234567890"
|
||||||
// - query = "?access_token=1234567890"
|
// - query = "?access_token=1234567890"
|
||||||
// - cookie = hb.auth.token = 1234567890
|
func (a *app) mwAuthToken(next errchain.Handler) errchain.Handler {
|
||||||
func (a *app) mwAuthToken(next server.Handler) server.Handler {
|
return errchain.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||||
return server.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
var requestToken string
|
||||||
keyFuncs := [...]KeyFunc{
|
|
||||||
getBearer,
|
// We ignore the error to allow the next strategy to be attempted
|
||||||
getCookie,
|
{
|
||||||
getQuery,
|
cookies, _ := v1.GetCookies(r)
|
||||||
|
if cookies != nil {
|
||||||
|
requestToken = cookies.Token
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var requestToken string
|
if requestToken == "" {
|
||||||
for _, keyFunc := range keyFuncs {
|
keyFuncs := [...]KeyFunc{
|
||||||
token, err := keyFunc(r)
|
getBearer,
|
||||||
if err == nil {
|
getQuery,
|
||||||
requestToken = token
|
}
|
||||||
break
|
|
||||||
|
for _, keyFunc := range keyFuncs {
|
||||||
|
token, err := keyFunc(r)
|
||||||
|
if err == nil {
|
||||||
|
requestToken = token
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,19 +3,19 @@ package main
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/hay-kot/homebox/backend/app/api/handlers/debughandlers"
|
"github.com/hay-kot/homebox/backend/app/api/handlers/debughandlers"
|
||||||
v1 "github.com/hay-kot/homebox/backend/app/api/handlers/v1"
|
v1 "github.com/hay-kot/homebox/backend/app/api/handlers/v1"
|
||||||
_ "github.com/hay-kot/homebox/backend/app/api/static/docs"
|
_ "github.com/hay-kot/homebox/backend/app/api/static/docs"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
httpSwagger "github.com/swaggo/http-swagger" // http-swagger middleware
|
httpSwagger "github.com/swaggo/http-swagger" // http-swagger middleware
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,12 +36,12 @@ func (a *app) debugRouter() *http.ServeMux {
|
||||||
}
|
}
|
||||||
|
|
||||||
// registerRoutes registers all the routes for the API
|
// registerRoutes registers all the routes for the API
|
||||||
func (a *app) mountRoutes(repos *repo.AllRepos) {
|
func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllRepos) {
|
||||||
registerMimes()
|
registerMimes()
|
||||||
|
|
||||||
a.server.Get("/swagger/*", server.ToHandler(httpSwagger.Handler(
|
r.Get("/swagger/*", httpSwagger.Handler(
|
||||||
httpSwagger.URL(fmt.Sprintf("%s://%s/swagger/doc.json", a.conf.Swagger.Scheme, a.conf.Swagger.Host)),
|
httpSwagger.URL("/swagger/doc.json"),
|
||||||
)))
|
))
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// API Version 1
|
// API Version 1
|
||||||
|
@ -51,97 +51,111 @@ func (a *app) mountRoutes(repos *repo.AllRepos) {
|
||||||
v1Ctrl := v1.NewControllerV1(
|
v1Ctrl := v1.NewControllerV1(
|
||||||
a.services,
|
a.services,
|
||||||
a.repos,
|
a.repos,
|
||||||
|
a.bus,
|
||||||
v1.WithMaxUploadSize(a.conf.Web.MaxUploadSize),
|
v1.WithMaxUploadSize(a.conf.Web.MaxUploadSize),
|
||||||
v1.WithRegistration(a.conf.Options.AllowRegistration),
|
v1.WithRegistration(a.conf.Options.AllowRegistration),
|
||||||
v1.WithDemoStatus(a.conf.Demo), // Disable Password Change in Demo Mode
|
v1.WithDemoStatus(a.conf.Demo), // Disable Password Change in Demo Mode
|
||||||
)
|
)
|
||||||
|
|
||||||
a.server.Get(v1Base("/status"), v1Ctrl.HandleBase(func() bool { return true }, v1.Build{
|
r.Get(v1Base("/status"), chain.ToHandlerFunc(v1Ctrl.HandleBase(func() bool { return true }, v1.Build{
|
||||||
Version: version,
|
Version: version,
|
||||||
Commit: commit,
|
Commit: commit,
|
||||||
BuildTime: buildTime,
|
BuildTime: buildTime,
|
||||||
}))
|
})))
|
||||||
|
|
||||||
a.server.Post(v1Base("/users/register"), v1Ctrl.HandleUserRegistration())
|
r.Post(v1Base("/users/register"), chain.ToHandlerFunc(v1Ctrl.HandleUserRegistration()))
|
||||||
a.server.Post(v1Base("/users/login"), v1Ctrl.HandleAuthLogin())
|
r.Post(v1Base("/users/login"), chain.ToHandlerFunc(v1Ctrl.HandleAuthLogin()))
|
||||||
|
|
||||||
userMW := []server.Middleware{
|
userMW := []errchain.Middleware{
|
||||||
a.mwAuthToken,
|
a.mwAuthToken,
|
||||||
a.mwRoles(RoleModeOr, authroles.RoleUser.String()),
|
a.mwRoles(RoleModeOr, authroles.RoleUser.String()),
|
||||||
}
|
}
|
||||||
|
|
||||||
a.server.Get(v1Base("/users/self"), v1Ctrl.HandleUserSelf(), userMW...)
|
r.Get(v1Base("/ws/events"), chain.ToHandlerFunc(v1Ctrl.HandleCacheWS(), userMW...))
|
||||||
a.server.Put(v1Base("/users/self"), v1Ctrl.HandleUserSelfUpdate(), userMW...)
|
r.Get(v1Base("/users/self"), chain.ToHandlerFunc(v1Ctrl.HandleUserSelf(), userMW...))
|
||||||
a.server.Delete(v1Base("/users/self"), v1Ctrl.HandleUserSelfDelete(), userMW...)
|
r.Put(v1Base("/users/self"), chain.ToHandlerFunc(v1Ctrl.HandleUserSelfUpdate(), userMW...))
|
||||||
a.server.Post(v1Base("/users/logout"), v1Ctrl.HandleAuthLogout(), userMW...)
|
r.Delete(v1Base("/users/self"), chain.ToHandlerFunc(v1Ctrl.HandleUserSelfDelete(), userMW...))
|
||||||
a.server.Get(v1Base("/users/refresh"), v1Ctrl.HandleAuthRefresh(), userMW...)
|
r.Post(v1Base("/users/logout"), chain.ToHandlerFunc(v1Ctrl.HandleAuthLogout(), userMW...))
|
||||||
a.server.Put(v1Base("/users/self/change-password"), v1Ctrl.HandleUserSelfChangePassword(), userMW...)
|
r.Get(v1Base("/users/refresh"), chain.ToHandlerFunc(v1Ctrl.HandleAuthRefresh(), userMW...))
|
||||||
|
r.Put(v1Base("/users/self/change-password"), chain.ToHandlerFunc(v1Ctrl.HandleUserSelfChangePassword(), userMW...))
|
||||||
|
|
||||||
a.server.Post(v1Base("/groups/invitations"), v1Ctrl.HandleGroupInvitationsCreate(), userMW...)
|
r.Post(v1Base("/groups/invitations"), chain.ToHandlerFunc(v1Ctrl.HandleGroupInvitationsCreate(), userMW...))
|
||||||
a.server.Get(v1Base("/groups/statistics"), v1Ctrl.HandleGroupStatistics(), userMW...)
|
r.Get(v1Base("/groups/statistics"), chain.ToHandlerFunc(v1Ctrl.HandleGroupStatistics(), userMW...))
|
||||||
a.server.Get(v1Base("/groups/statistics/purchase-price"), v1Ctrl.HandleGroupStatisticsPriceOverTime(), userMW...)
|
r.Get(v1Base("/groups/statistics/purchase-price"), chain.ToHandlerFunc(v1Ctrl.HandleGroupStatisticsPriceOverTime(), userMW...))
|
||||||
a.server.Get(v1Base("/groups/statistics/locations"), v1Ctrl.HandleGroupStatisticsLocations(), userMW...)
|
r.Get(v1Base("/groups/statistics/locations"), chain.ToHandlerFunc(v1Ctrl.HandleGroupStatisticsLocations(), userMW...))
|
||||||
a.server.Get(v1Base("/groups/statistics/labels"), v1Ctrl.HandleGroupStatisticsLabels(), userMW...)
|
r.Get(v1Base("/groups/statistics/labels"), chain.ToHandlerFunc(v1Ctrl.HandleGroupStatisticsLabels(), userMW...))
|
||||||
|
|
||||||
// TODO: I don't like /groups being the URL for users
|
// TODO: I don't like /groups being the URL for users
|
||||||
a.server.Get(v1Base("/groups"), v1Ctrl.HandleGroupGet(), userMW...)
|
r.Get(v1Base("/groups"), chain.ToHandlerFunc(v1Ctrl.HandleGroupGet(), userMW...))
|
||||||
a.server.Put(v1Base("/groups"), v1Ctrl.HandleGroupUpdate(), userMW...)
|
r.Put(v1Base("/groups"), chain.ToHandlerFunc(v1Ctrl.HandleGroupUpdate(), userMW...))
|
||||||
|
|
||||||
a.server.Post(v1Base("/actions/ensure-asset-ids"), v1Ctrl.HandleEnsureAssetID(), userMW...)
|
r.Post(v1Base("/actions/ensure-asset-ids"), chain.ToHandlerFunc(v1Ctrl.HandleEnsureAssetID(), userMW...))
|
||||||
a.server.Post(v1Base("/actions/zero-item-time-fields"), v1Ctrl.HandleItemDateZeroOut(), userMW...)
|
r.Post(v1Base("/actions/zero-item-time-fields"), chain.ToHandlerFunc(v1Ctrl.HandleItemDateZeroOut(), userMW...))
|
||||||
a.server.Post(v1Base("/actions/ensure-import-refs"), v1Ctrl.HandleEnsureImportRefs(), userMW...)
|
r.Post(v1Base("/actions/ensure-import-refs"), chain.ToHandlerFunc(v1Ctrl.HandleEnsureImportRefs(), userMW...))
|
||||||
|
r.Post(v1Base("/actions/set-primary-photos"), chain.ToHandlerFunc(v1Ctrl.HandleSetPrimaryPhotos(), userMW...))
|
||||||
|
|
||||||
a.server.Get(v1Base("/locations"), v1Ctrl.HandleLocationGetAll(), userMW...)
|
r.Get(v1Base("/locations"), chain.ToHandlerFunc(v1Ctrl.HandleLocationGetAll(), userMW...))
|
||||||
a.server.Post(v1Base("/locations"), v1Ctrl.HandleLocationCreate(), userMW...)
|
r.Post(v1Base("/locations"), chain.ToHandlerFunc(v1Ctrl.HandleLocationCreate(), userMW...))
|
||||||
a.server.Get(v1Base("/locations/tree"), v1Ctrl.HandleLocationTreeQuery(), userMW...)
|
r.Get(v1Base("/locations/tree"), chain.ToHandlerFunc(v1Ctrl.HandleLocationTreeQuery(), userMW...))
|
||||||
a.server.Get(v1Base("/locations/{id}"), v1Ctrl.HandleLocationGet(), userMW...)
|
r.Get(v1Base("/locations/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLocationGet(), userMW...))
|
||||||
a.server.Put(v1Base("/locations/{id}"), v1Ctrl.HandleLocationUpdate(), userMW...)
|
r.Put(v1Base("/locations/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLocationUpdate(), userMW...))
|
||||||
a.server.Delete(v1Base("/locations/{id}"), v1Ctrl.HandleLocationDelete(), userMW...)
|
r.Delete(v1Base("/locations/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLocationDelete(), userMW...))
|
||||||
|
|
||||||
a.server.Get(v1Base("/labels"), v1Ctrl.HandleLabelsGetAll(), userMW...)
|
r.Get(v1Base("/labels"), chain.ToHandlerFunc(v1Ctrl.HandleLabelsGetAll(), userMW...))
|
||||||
a.server.Post(v1Base("/labels"), v1Ctrl.HandleLabelsCreate(), userMW...)
|
r.Post(v1Base("/labels"), chain.ToHandlerFunc(v1Ctrl.HandleLabelsCreate(), userMW...))
|
||||||
a.server.Get(v1Base("/labels/{id}"), v1Ctrl.HandleLabelGet(), userMW...)
|
r.Get(v1Base("/labels/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLabelGet(), userMW...))
|
||||||
a.server.Put(v1Base("/labels/{id}"), v1Ctrl.HandleLabelUpdate(), userMW...)
|
r.Put(v1Base("/labels/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLabelUpdate(), userMW...))
|
||||||
a.server.Delete(v1Base("/labels/{id}"), v1Ctrl.HandleLabelDelete(), userMW...)
|
r.Delete(v1Base("/labels/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLabelDelete(), userMW...))
|
||||||
|
|
||||||
a.server.Get(v1Base("/items"), v1Ctrl.HandleItemsGetAll(), userMW...)
|
r.Get(v1Base("/items"), chain.ToHandlerFunc(v1Ctrl.HandleItemsGetAll(), userMW...))
|
||||||
a.server.Post(v1Base("/items"), v1Ctrl.HandleItemsCreate(), userMW...)
|
r.Post(v1Base("/items"), chain.ToHandlerFunc(v1Ctrl.HandleItemsCreate(), userMW...))
|
||||||
a.server.Post(v1Base("/items/import"), v1Ctrl.HandleItemsImport(), userMW...)
|
r.Post(v1Base("/items/import"), chain.ToHandlerFunc(v1Ctrl.HandleItemsImport(), userMW...))
|
||||||
a.server.Get(v1Base("/items/export"), v1Ctrl.HandleItemsExport(), userMW...)
|
r.Get(v1Base("/items/export"), chain.ToHandlerFunc(v1Ctrl.HandleItemsExport(), userMW...))
|
||||||
a.server.Get(v1Base("/items/fields"), v1Ctrl.HandleGetAllCustomFieldNames(), userMW...)
|
r.Get(v1Base("/items/fields"), chain.ToHandlerFunc(v1Ctrl.HandleGetAllCustomFieldNames(), userMW...))
|
||||||
a.server.Get(v1Base("/items/fields/values"), v1Ctrl.HandleGetAllCustomFieldValues(), userMW...)
|
r.Get(v1Base("/items/fields/values"), chain.ToHandlerFunc(v1Ctrl.HandleGetAllCustomFieldValues(), userMW...))
|
||||||
|
|
||||||
a.server.Get(v1Base("/items/{id}"), v1Ctrl.HandleItemGet(), userMW...)
|
r.Get(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemGet(), userMW...))
|
||||||
a.server.Put(v1Base("/items/{id}"), v1Ctrl.HandleItemUpdate(), userMW...)
|
r.Put(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemUpdate(), userMW...))
|
||||||
a.server.Delete(v1Base("/items/{id}"), v1Ctrl.HandleItemDelete(), userMW...)
|
r.Patch(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemPatch(), userMW...))
|
||||||
|
r.Delete(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemDelete(), userMW...))
|
||||||
|
|
||||||
a.server.Post(v1Base("/items/{id}/attachments"), v1Ctrl.HandleItemAttachmentCreate(), userMW...)
|
r.Post(v1Base("/items/{id}/attachments"), chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentCreate(), userMW...))
|
||||||
a.server.Put(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentUpdate(), userMW...)
|
r.Put(v1Base("/items/{id}/attachments/{attachment_id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentUpdate(), userMW...))
|
||||||
a.server.Delete(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentDelete(), userMW...)
|
r.Delete(v1Base("/items/{id}/attachments/{attachment_id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentDelete(), userMW...))
|
||||||
|
|
||||||
a.server.Get(v1Base("/items/{id}/maintenance"), v1Ctrl.HandleMaintenanceEntryCreate(), userMW...)
|
r.Get(v1Base("/items/{id}/maintenance"), chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceLogGet(), userMW...))
|
||||||
a.server.Post(v1Base("/items/{id}/maintenance"), v1Ctrl.HandleMaintenanceEntryCreate(), userMW...)
|
r.Post(v1Base("/items/{id}/maintenance"), chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryCreate(), userMW...))
|
||||||
a.server.Put(v1Base("/items/{id}/maintenance/{entry_id}"), v1Ctrl.HandleMaintenanceEntryUpdate(), userMW...)
|
r.Put(v1Base("/items/{id}/maintenance/{entry_id}"), chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryUpdate(), userMW...))
|
||||||
a.server.Delete(v1Base("/items/{id}/maintenance/{entry_id}"), v1Ctrl.HandleMaintenanceEntryDelete(), userMW...)
|
r.Delete(v1Base("/items/{id}/maintenance/{entry_id}"), chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryDelete(), userMW...))
|
||||||
|
|
||||||
a.server.Get(v1Base("/asset/{id}"), v1Ctrl.HandleAssetGet(), userMW...)
|
r.Get(v1Base("/assets/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleAssetGet(), userMW...))
|
||||||
|
|
||||||
|
// Notifiers
|
||||||
|
r.Get(v1Base("/notifiers"), chain.ToHandlerFunc(v1Ctrl.HandleGetUserNotifiers(), userMW...))
|
||||||
|
r.Post(v1Base("/notifiers"), chain.ToHandlerFunc(v1Ctrl.HandleCreateNotifier(), userMW...))
|
||||||
|
r.Put(v1Base("/notifiers/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleUpdateNotifier(), userMW...))
|
||||||
|
r.Delete(v1Base("/notifiers/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleDeleteNotifier(), userMW...))
|
||||||
|
r.Post(v1Base("/notifiers/test"), chain.ToHandlerFunc(v1Ctrl.HandlerNotifierTest(), userMW...))
|
||||||
|
|
||||||
// Asset-Like endpoints
|
// Asset-Like endpoints
|
||||||
a.server.Get(
|
assetMW := []errchain.Middleware{
|
||||||
|
a.mwAuthToken,
|
||||||
|
a.mwRoles(RoleModeOr, authroles.RoleUser.String(), authroles.RoleAttachments.String()),
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Get(
|
||||||
v1Base("/qrcode"),
|
v1Base("/qrcode"),
|
||||||
v1Ctrl.HandleGenerateQRCode(),
|
chain.ToHandlerFunc(v1Ctrl.HandleGenerateQRCode(), assetMW...),
|
||||||
a.mwAuthToken, a.mwRoles(RoleModeOr, authroles.RoleUser.String(), authroles.RoleAttachments.String()),
|
|
||||||
)
|
)
|
||||||
a.server.Get(
|
r.Get(
|
||||||
v1Base("/items/{id}/attachments/{attachment_id}"),
|
v1Base("/items/{id}/attachments/{attachment_id}"),
|
||||||
v1Ctrl.HandleItemAttachmentGet(),
|
chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentGet(), assetMW...),
|
||||||
a.mwAuthToken, a.mwRoles(RoleModeOr, authroles.RoleUser.String(), authroles.RoleAttachments.String()),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reporting Services
|
// Reporting Services
|
||||||
a.server.Get(v1Base("/reporting/bill-of-materials"), v1Ctrl.HandleBillOfMaterialsExport(), userMW...)
|
r.Get(v1Base("/reporting/bill-of-materials"), chain.ToHandlerFunc(v1Ctrl.HandleBillOfMaterialsExport(), userMW...))
|
||||||
|
|
||||||
a.server.NotFound(notFoundHandler())
|
r.NotFound(chain.ToHandlerFunc(notFoundHandler()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerMimes() {
|
func registerMimes() {
|
||||||
|
@ -158,7 +172,7 @@ func registerMimes() {
|
||||||
|
|
||||||
// notFoundHandler perform the main logic around handling the internal SPA embed and ensuring that
|
// notFoundHandler perform the main logic around handling the internal SPA embed and ensuring that
|
||||||
// the client side routing is handled correctly.
|
// the client side routing is handled correctly.
|
||||||
func notFoundHandler() server.HandlerFunc {
|
func notFoundHandler() errchain.HandlerFunc {
|
||||||
tryRead := func(fs embed.FS, prefix, requestedPath string, w http.ResponseWriter) error {
|
tryRead := func(fs embed.FS, prefix, requestedPath string, w http.ResponseWriter) error {
|
||||||
f, err := fs.Open(path.Join(prefix, requestedPath))
|
f, err := fs.Open(path.Join(prefix, requestedPath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -52,6 +52,8 @@ definitions:
|
||||||
$ref: '#/definitions/repo.DocumentOut'
|
$ref: '#/definitions/repo.DocumentOut'
|
||||||
id:
|
id:
|
||||||
type: string
|
type: string
|
||||||
|
primary:
|
||||||
|
type: boolean
|
||||||
type:
|
type:
|
||||||
type: string
|
type: string
|
||||||
updatedAt:
|
updatedAt:
|
||||||
|
@ -59,6 +61,8 @@ definitions:
|
||||||
type: object
|
type: object
|
||||||
repo.ItemAttachmentUpdate:
|
repo.ItemAttachmentUpdate:
|
||||||
properties:
|
properties:
|
||||||
|
primary:
|
||||||
|
type: boolean
|
||||||
title:
|
title:
|
||||||
type: string
|
type: string
|
||||||
type:
|
type:
|
||||||
|
@ -67,6 +71,7 @@ definitions:
|
||||||
repo.ItemCreate:
|
repo.ItemCreate:
|
||||||
properties:
|
properties:
|
||||||
description:
|
description:
|
||||||
|
maxLength: 1000
|
||||||
type: string
|
type: string
|
||||||
labelIds:
|
labelIds:
|
||||||
items:
|
items:
|
||||||
|
@ -76,10 +81,14 @@ definitions:
|
||||||
description: Edges
|
description: Edges
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
|
maxLength: 255
|
||||||
|
minLength: 1
|
||||||
type: string
|
type: string
|
||||||
parentId:
|
parentId:
|
||||||
type: string
|
type: string
|
||||||
x-nullable: true
|
x-nullable: true
|
||||||
|
required:
|
||||||
|
- name
|
||||||
type: object
|
type: object
|
||||||
repo.ItemField:
|
repo.ItemField:
|
||||||
properties:
|
properties:
|
||||||
|
@ -121,6 +130,8 @@ definitions:
|
||||||
type: array
|
type: array
|
||||||
id:
|
id:
|
||||||
type: string
|
type: string
|
||||||
|
imageId:
|
||||||
|
type: string
|
||||||
insured:
|
insured:
|
||||||
type: boolean
|
type: boolean
|
||||||
labels:
|
labels:
|
||||||
|
@ -177,6 +188,15 @@ definitions:
|
||||||
warrantyExpires:
|
warrantyExpires:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
repo.ItemPatch:
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
quantity:
|
||||||
|
type: integer
|
||||||
|
x-nullable: true
|
||||||
|
x-omitempty: true
|
||||||
|
type: object
|
||||||
repo.ItemSummary:
|
repo.ItemSummary:
|
||||||
properties:
|
properties:
|
||||||
archived:
|
archived:
|
||||||
|
@ -187,6 +207,8 @@ definitions:
|
||||||
type: string
|
type: string
|
||||||
id:
|
id:
|
||||||
type: string
|
type: string
|
||||||
|
imageId:
|
||||||
|
type: string
|
||||||
insured:
|
insured:
|
||||||
type: boolean
|
type: boolean
|
||||||
labels:
|
labels:
|
||||||
|
@ -281,9 +303,14 @@ definitions:
|
||||||
color:
|
color:
|
||||||
type: string
|
type: string
|
||||||
description:
|
description:
|
||||||
|
maxLength: 255
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
|
maxLength: 255
|
||||||
|
minLength: 1
|
||||||
type: string
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
type: object
|
type: object
|
||||||
repo.LabelOut:
|
repo.LabelOut:
|
||||||
properties:
|
properties:
|
||||||
|
@ -293,10 +320,6 @@ definitions:
|
||||||
type: string
|
type: string
|
||||||
id:
|
id:
|
||||||
type: string
|
type: string
|
||||||
items:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/repo.ItemSummary'
|
|
||||||
type: array
|
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
updatedAt:
|
updatedAt:
|
||||||
|
@ -337,10 +360,6 @@ definitions:
|
||||||
type: string
|
type: string
|
||||||
id:
|
id:
|
||||||
type: string
|
type: string
|
||||||
items:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/repo.ItemSummary'
|
|
||||||
type: array
|
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
parent:
|
parent:
|
||||||
|
@ -421,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:
|
||||||
|
@ -451,6 +472,51 @@ definitions:
|
||||||
itemId:
|
itemId:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
repo.NotifierCreate:
|
||||||
|
properties:
|
||||||
|
isActive:
|
||||||
|
type: boolean
|
||||||
|
name:
|
||||||
|
maxLength: 255
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
|
url:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- url
|
||||||
|
type: object
|
||||||
|
repo.NotifierOut:
|
||||||
|
properties:
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
groupId:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
isActive:
|
||||||
|
type: boolean
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
updatedAt:
|
||||||
|
type: string
|
||||||
|
userId:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
repo.NotifierUpdate:
|
||||||
|
properties:
|
||||||
|
isActive:
|
||||||
|
type: boolean
|
||||||
|
name:
|
||||||
|
maxLength: 255
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
|
url:
|
||||||
|
type: string
|
||||||
|
x-nullable: true
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
repo.PaginationResult-repo_ItemSummary:
|
repo.PaginationResult-repo_ItemSummary:
|
||||||
properties:
|
properties:
|
||||||
items:
|
items:
|
||||||
|
@ -534,28 +600,6 @@ definitions:
|
||||||
value:
|
value:
|
||||||
type: number
|
type: number
|
||||||
type: object
|
type: object
|
||||||
server.ErrorResponse:
|
|
||||||
properties:
|
|
||||||
error:
|
|
||||||
type: string
|
|
||||||
fields:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
type: object
|
|
||||||
server.Result:
|
|
||||||
properties:
|
|
||||||
details: {}
|
|
||||||
error:
|
|
||||||
type: boolean
|
|
||||||
item: {}
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
server.Results:
|
|
||||||
properties:
|
|
||||||
items: {}
|
|
||||||
type: object
|
|
||||||
services.UserRegistration:
|
services.UserRegistration:
|
||||||
properties:
|
properties:
|
||||||
email:
|
email:
|
||||||
|
@ -621,13 +665,26 @@ definitions:
|
||||||
expiresAt:
|
expiresAt:
|
||||||
type: string
|
type: string
|
||||||
uses:
|
uses:
|
||||||
|
maximum: 100
|
||||||
|
minimum: 1
|
||||||
type: integer
|
type: integer
|
||||||
|
required:
|
||||||
|
- uses
|
||||||
type: object
|
type: object
|
||||||
v1.ItemAttachmentToken:
|
v1.ItemAttachmentToken:
|
||||||
properties:
|
properties:
|
||||||
token:
|
token:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
v1.LoginForm:
|
||||||
|
properties:
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
stayLoggedIn:
|
||||||
|
type: boolean
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
v1.TokenResponse:
|
v1.TokenResponse:
|
||||||
properties:
|
properties:
|
||||||
attachmentToken:
|
attachmentToken:
|
||||||
|
@ -637,19 +694,27 @@ definitions:
|
||||||
token:
|
token:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
v1.Wrapped:
|
||||||
|
properties:
|
||||||
|
item: {}
|
||||||
|
type: object
|
||||||
|
validate.ErrorResponse:
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: string
|
||||||
|
fields:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
info:
|
info:
|
||||||
contact:
|
contact:
|
||||||
name: Don't
|
name: Don't
|
||||||
description: This is a simple Rest API Server Template that implements some basic
|
description: Track, Manage, and Organize your Things.
|
||||||
User and Authentication patterns to help you get started and bootstrap your next
|
title: Homebox API
|
||||||
project!.
|
|
||||||
license:
|
|
||||||
name: MIT
|
|
||||||
title: Go API Templates
|
|
||||||
version: "1.0"
|
version: "1.0"
|
||||||
paths:
|
paths:
|
||||||
/v1/actions/ensure-asset-ids:
|
/v1/actions/ensure-asset-ids:
|
||||||
post:
|
post:
|
||||||
|
description: Ensures all items in the database have an asset ID
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
|
@ -659,11 +724,12 @@ paths:
|
||||||
$ref: '#/definitions/v1.ActionAmountResult'
|
$ref: '#/definitions/v1.ActionAmountResult'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Ensures all items in the database have an asset id
|
summary: Ensure Asset IDs
|
||||||
tags:
|
tags:
|
||||||
- Group
|
- Actions
|
||||||
/v1/actions/ensure-import-refs:
|
/v1/actions/ensure-import-refs:
|
||||||
post:
|
post:
|
||||||
|
description: Ensures all items in the database have an import ref
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
|
@ -673,11 +739,27 @@ paths:
|
||||||
$ref: '#/definitions/v1.ActionAmountResult'
|
$ref: '#/definitions/v1.ActionAmountResult'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Ensures all items in the database have an import ref
|
summary: Ensures Import Refs
|
||||||
tags:
|
tags:
|
||||||
- Group
|
- Actions
|
||||||
|
/v1/actions/set-primary-photos:
|
||||||
|
post:
|
||||||
|
description: Sets the first photo of each item as the primary photo
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/v1.ActionAmountResult'
|
||||||
|
security:
|
||||||
|
- Bearer: []
|
||||||
|
summary: Set Primary Photos
|
||||||
|
tags:
|
||||||
|
- Actions
|
||||||
/v1/actions/zero-item-time-fields:
|
/v1/actions/zero-item-time-fields:
|
||||||
post:
|
post:
|
||||||
|
description: Resets all item date fields to the beginning of the day
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
|
@ -687,9 +769,9 @@ paths:
|
||||||
$ref: '#/definitions/v1.ActionAmountResult'
|
$ref: '#/definitions/v1.ActionAmountResult'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Resets all item date fields to the beginning of the day
|
summary: Zero Out Time Fields
|
||||||
tags:
|
tags:
|
||||||
- Group
|
- Actions
|
||||||
/v1/assets/{id}:
|
/v1/assets/{id}:
|
||||||
get:
|
get:
|
||||||
parameters:
|
parameters:
|
||||||
|
@ -707,9 +789,9 @@ paths:
|
||||||
$ref: '#/definitions/repo.PaginationResult-repo_ItemSummary'
|
$ref: '#/definitions/repo.PaginationResult-repo_ItemSummary'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Gets an item by Asset ID
|
summary: Get Item by Asset ID
|
||||||
tags:
|
tags:
|
||||||
- Assets
|
- Items
|
||||||
/v1/groups:
|
/v1/groups:
|
||||||
get:
|
get:
|
||||||
produces:
|
produces:
|
||||||
|
@ -721,7 +803,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.Group'
|
$ref: '#/definitions/repo.Group'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get the current user's group
|
summary: Get Group
|
||||||
tags:
|
tags:
|
||||||
- Group
|
- Group
|
||||||
put:
|
put:
|
||||||
|
@ -741,7 +823,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.Group'
|
$ref: '#/definitions/repo.Group'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Updates some fields of the current users group
|
summary: Update Group
|
||||||
tags:
|
tags:
|
||||||
- Group
|
- Group
|
||||||
/v1/groups/invitations:
|
/v1/groups/invitations:
|
||||||
|
@ -762,7 +844,7 @@ paths:
|
||||||
$ref: '#/definitions/v1.GroupInvitation'
|
$ref: '#/definitions/v1.GroupInvitation'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get the current user
|
summary: Create Group Invitation
|
||||||
tags:
|
tags:
|
||||||
- Group
|
- Group
|
||||||
/v1/groups/statistics:
|
/v1/groups/statistics:
|
||||||
|
@ -776,7 +858,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.GroupStatistics'
|
$ref: '#/definitions/repo.GroupStatistics'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get the current user's group statistics
|
summary: Get Group Statistics
|
||||||
tags:
|
tags:
|
||||||
- Statistics
|
- Statistics
|
||||||
/v1/groups/statistics/labels:
|
/v1/groups/statistics/labels:
|
||||||
|
@ -792,7 +874,7 @@ paths:
|
||||||
type: array
|
type: array
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get the current user's group statistics
|
summary: Get Label Statistics
|
||||||
tags:
|
tags:
|
||||||
- Statistics
|
- Statistics
|
||||||
/v1/groups/statistics/locations:
|
/v1/groups/statistics/locations:
|
||||||
|
@ -808,7 +890,7 @@ paths:
|
||||||
type: array
|
type: array
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get the current user's group statistics
|
summary: Get Location Statistics
|
||||||
tags:
|
tags:
|
||||||
- Statistics
|
- Statistics
|
||||||
/v1/groups/statistics/purchase-price:
|
/v1/groups/statistics/purchase-price:
|
||||||
|
@ -831,7 +913,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.ValueOverTime'
|
$ref: '#/definitions/repo.ValueOverTime'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Queries the changes overtime of the purchase price over time
|
summary: Get Purchase Price Statistics
|
||||||
tags:
|
tags:
|
||||||
- Statistics
|
- Statistics
|
||||||
/v1/items:
|
/v1/items:
|
||||||
|
@ -872,7 +954,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.PaginationResult-repo_ItemSummary'
|
$ref: '#/definitions/repo.PaginationResult-repo_ItemSummary'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get All Items
|
summary: Query All Items
|
||||||
tags:
|
tags:
|
||||||
- Items
|
- Items
|
||||||
post:
|
post:
|
||||||
|
@ -886,13 +968,13 @@ paths:
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"201":
|
||||||
description: OK
|
description: Created
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/repo.ItemSummary'
|
$ref: '#/definitions/repo.ItemSummary'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Create a new item
|
summary: Create Item
|
||||||
tags:
|
tags:
|
||||||
- Items
|
- Items
|
||||||
/v1/items/{id}:
|
/v1/items/{id}:
|
||||||
|
@ -910,7 +992,7 @@ paths:
|
||||||
description: No Content
|
description: No Content
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: deletes a item
|
summary: Delete Item
|
||||||
tags:
|
tags:
|
||||||
- Items
|
- Items
|
||||||
get:
|
get:
|
||||||
|
@ -929,7 +1011,32 @@ paths:
|
||||||
$ref: '#/definitions/repo.ItemOut'
|
$ref: '#/definitions/repo.ItemOut'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Gets a item and fields
|
summary: Get Item
|
||||||
|
tags:
|
||||||
|
- Items
|
||||||
|
patch:
|
||||||
|
parameters:
|
||||||
|
- description: Item ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: Item Data
|
||||||
|
in: body
|
||||||
|
name: payload
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/repo.ItemPatch'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/repo.ItemOut'
|
||||||
|
security:
|
||||||
|
- Bearer: []
|
||||||
|
summary: Update Item
|
||||||
tags:
|
tags:
|
||||||
- Items
|
- Items
|
||||||
put:
|
put:
|
||||||
|
@ -954,7 +1061,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.ItemOut'
|
$ref: '#/definitions/repo.ItemOut'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: updates a item
|
summary: Update Item
|
||||||
tags:
|
tags:
|
||||||
- Items
|
- Items
|
||||||
/v1/items/{id}/attachments:
|
/v1/items/{id}/attachments:
|
||||||
|
@ -990,10 +1097,10 @@ paths:
|
||||||
"422":
|
"422":
|
||||||
description: Unprocessable Entity
|
description: Unprocessable Entity
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/server.ErrorResponse'
|
$ref: '#/definitions/validate.ErrorResponse'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: imports items into the database
|
summary: Create Item Attachment
|
||||||
tags:
|
tags:
|
||||||
- Items Attachments
|
- Items Attachments
|
||||||
/v1/items/{id}/attachments/{attachment_id}:
|
/v1/items/{id}/attachments/{attachment_id}:
|
||||||
|
@ -1014,7 +1121,7 @@ paths:
|
||||||
description: No Content
|
description: No Content
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: retrieves an attachment for an item
|
summary: Delete Item Attachment
|
||||||
tags:
|
tags:
|
||||||
- Items Attachments
|
- Items Attachments
|
||||||
get:
|
get:
|
||||||
|
@ -1038,7 +1145,7 @@ paths:
|
||||||
$ref: '#/definitions/v1.ItemAttachmentToken'
|
$ref: '#/definitions/v1.ItemAttachmentToken'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: retrieves an attachment for an item
|
summary: Get Item Attachment
|
||||||
tags:
|
tags:
|
||||||
- Items Attachments
|
- Items Attachments
|
||||||
put:
|
put:
|
||||||
|
@ -1066,7 +1173,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.ItemOut'
|
$ref: '#/definitions/repo.ItemOut'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: retrieves an attachment for an item
|
summary: Update Item Attachment
|
||||||
tags:
|
tags:
|
||||||
- Items Attachments
|
- Items Attachments
|
||||||
/v1/items/{id}/maintenance:
|
/v1/items/{id}/maintenance:
|
||||||
|
@ -1094,8 +1201,8 @@ paths:
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"201":
|
||||||
description: OK
|
description: Created
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/repo.MaintenanceEntry'
|
$ref: '#/definitions/repo.MaintenanceEntry'
|
||||||
security:
|
security:
|
||||||
|
@ -1144,7 +1251,7 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: exports items into the database
|
summary: Export Items
|
||||||
tags:
|
tags:
|
||||||
- Items
|
- Items
|
||||||
/v1/items/fields:
|
/v1/items/fields:
|
||||||
|
@ -1160,7 +1267,7 @@ paths:
|
||||||
type: array
|
type: array
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: imports items into the database
|
summary: Get All Custom Field Names
|
||||||
tags:
|
tags:
|
||||||
- Items
|
- Items
|
||||||
/v1/items/fields/values:
|
/v1/items/fields/values:
|
||||||
|
@ -1176,7 +1283,7 @@ paths:
|
||||||
type: array
|
type: array
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: imports items into the database
|
summary: Get All Custom Field Values
|
||||||
tags:
|
tags:
|
||||||
- Items
|
- Items
|
||||||
/v1/items/import:
|
/v1/items/import:
|
||||||
|
@ -1194,7 +1301,7 @@ paths:
|
||||||
description: No Content
|
description: No Content
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: imports items into the database
|
summary: Import Items
|
||||||
tags:
|
tags:
|
||||||
- Items
|
- Items
|
||||||
/v1/labels:
|
/v1/labels:
|
||||||
|
@ -1205,14 +1312,9 @@ paths:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
allOf:
|
items:
|
||||||
- $ref: '#/definitions/server.Results'
|
$ref: '#/definitions/repo.LabelOut'
|
||||||
- properties:
|
type: array
|
||||||
items:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/repo.LabelOut'
|
|
||||||
type: array
|
|
||||||
type: object
|
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get All Labels
|
summary: Get All Labels
|
||||||
|
@ -1235,7 +1337,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.LabelSummary'
|
$ref: '#/definitions/repo.LabelSummary'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Create a new label
|
summary: Create Label
|
||||||
tags:
|
tags:
|
||||||
- Labels
|
- Labels
|
||||||
/v1/labels/{id}:
|
/v1/labels/{id}:
|
||||||
|
@ -1253,7 +1355,7 @@ paths:
|
||||||
description: No Content
|
description: No Content
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: deletes a label
|
summary: Delete Label
|
||||||
tags:
|
tags:
|
||||||
- Labels
|
- Labels
|
||||||
get:
|
get:
|
||||||
|
@ -1272,7 +1374,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.LabelOut'
|
$ref: '#/definitions/repo.LabelOut'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Gets a label and fields
|
summary: Get Label
|
||||||
tags:
|
tags:
|
||||||
- Labels
|
- Labels
|
||||||
put:
|
put:
|
||||||
|
@ -1291,7 +1393,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.LabelOut'
|
$ref: '#/definitions/repo.LabelOut'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: updates a label
|
summary: Update Label
|
||||||
tags:
|
tags:
|
||||||
- Labels
|
- Labels
|
||||||
/v1/locations:
|
/v1/locations:
|
||||||
|
@ -1307,14 +1409,9 @@ paths:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
allOf:
|
items:
|
||||||
- $ref: '#/definitions/server.Results'
|
$ref: '#/definitions/repo.LocationOutCount'
|
||||||
- properties:
|
type: array
|
||||||
items:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/repo.LocationOutCount'
|
|
||||||
type: array
|
|
||||||
type: object
|
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get All Locations
|
summary: Get All Locations
|
||||||
|
@ -1337,7 +1434,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.LocationSummary'
|
$ref: '#/definitions/repo.LocationSummary'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Create a new location
|
summary: Create Location
|
||||||
tags:
|
tags:
|
||||||
- Locations
|
- Locations
|
||||||
/v1/locations/{id}:
|
/v1/locations/{id}:
|
||||||
|
@ -1355,7 +1452,7 @@ paths:
|
||||||
description: No Content
|
description: No Content
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: deletes a location
|
summary: Delete Location
|
||||||
tags:
|
tags:
|
||||||
- Locations
|
- Locations
|
||||||
get:
|
get:
|
||||||
|
@ -1374,7 +1471,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.LocationOut'
|
$ref: '#/definitions/repo.LocationOut'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Gets a location and fields
|
summary: Get Location
|
||||||
tags:
|
tags:
|
||||||
- Locations
|
- Locations
|
||||||
put:
|
put:
|
||||||
|
@ -1399,7 +1496,7 @@ paths:
|
||||||
$ref: '#/definitions/repo.LocationOut'
|
$ref: '#/definitions/repo.LocationOut'
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: updates a location
|
summary: Update Location
|
||||||
tags:
|
tags:
|
||||||
- Locations
|
- Locations
|
||||||
/v1/locations/tree:
|
/v1/locations/tree:
|
||||||
|
@ -1415,19 +1512,112 @@ paths:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
allOf:
|
items:
|
||||||
- $ref: '#/definitions/server.Results'
|
$ref: '#/definitions/repo.TreeItem'
|
||||||
- properties:
|
type: array
|
||||||
items:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/repo.TreeItem'
|
|
||||||
type: array
|
|
||||||
type: object
|
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get All Locations
|
summary: Get Locations Tree
|
||||||
tags:
|
tags:
|
||||||
- Locations
|
- Locations
|
||||||
|
/v1/notifiers:
|
||||||
|
get:
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/repo.NotifierOut'
|
||||||
|
type: array
|
||||||
|
security:
|
||||||
|
- Bearer: []
|
||||||
|
summary: Get Notifiers
|
||||||
|
tags:
|
||||||
|
- Notifiers
|
||||||
|
post:
|
||||||
|
parameters:
|
||||||
|
- description: Notifier Data
|
||||||
|
in: body
|
||||||
|
name: payload
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/repo.NotifierCreate'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/repo.NotifierOut'
|
||||||
|
security:
|
||||||
|
- Bearer: []
|
||||||
|
summary: Create Notifier
|
||||||
|
tags:
|
||||||
|
- Notifiers
|
||||||
|
/v1/notifiers/{id}:
|
||||||
|
delete:
|
||||||
|
parameters:
|
||||||
|
- description: Notifier ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: No Content
|
||||||
|
security:
|
||||||
|
- Bearer: []
|
||||||
|
summary: Delete a Notifier
|
||||||
|
tags:
|
||||||
|
- Notifiers
|
||||||
|
put:
|
||||||
|
parameters:
|
||||||
|
- description: Notifier ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: Notifier Data
|
||||||
|
in: body
|
||||||
|
name: payload
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/repo.NotifierUpdate'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/repo.NotifierOut'
|
||||||
|
security:
|
||||||
|
- Bearer: []
|
||||||
|
summary: Update Notifier
|
||||||
|
tags:
|
||||||
|
- Notifiers
|
||||||
|
/v1/notifiers/test:
|
||||||
|
post:
|
||||||
|
parameters:
|
||||||
|
- description: Notifier ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: URL
|
||||||
|
in: query
|
||||||
|
name: url
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: No Content
|
||||||
|
security:
|
||||||
|
- Bearer: []
|
||||||
|
summary: Test Notifier
|
||||||
|
tags:
|
||||||
|
- Notifiers
|
||||||
/v1/qrcode:
|
/v1/qrcode:
|
||||||
get:
|
get:
|
||||||
parameters:
|
parameters:
|
||||||
|
@ -1444,7 +1634,7 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Encode data into QRCode
|
summary: Create QR Code
|
||||||
tags:
|
tags:
|
||||||
- Items
|
- Items
|
||||||
/v1/reporting/bill-of-materials:
|
/v1/reporting/bill-of-materials:
|
||||||
|
@ -1458,7 +1648,7 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Generates a Bill of Materials CSV
|
summary: Export Bill of Materials
|
||||||
tags:
|
tags:
|
||||||
- Reporting
|
- Reporting
|
||||||
/v1/status:
|
/v1/status:
|
||||||
|
@ -1470,7 +1660,7 @@ paths:
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/v1.ApiSummary'
|
$ref: '#/definitions/v1.ApiSummary'
|
||||||
summary: Retrieves the basic information about the API
|
summary: Application Info
|
||||||
tags:
|
tags:
|
||||||
- Base
|
- Base
|
||||||
/v1/users/change-password:
|
/v1/users/change-password:
|
||||||
|
@ -1487,7 +1677,7 @@ paths:
|
||||||
description: No Content
|
description: No Content
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Updates the users password
|
summary: Change Password
|
||||||
tags:
|
tags:
|
||||||
- User
|
- User
|
||||||
/v1/users/login:
|
/v1/users/login:
|
||||||
|
@ -1506,6 +1696,12 @@ paths:
|
||||||
in: formData
|
in: formData
|
||||||
name: password
|
name: password
|
||||||
type: string
|
type: string
|
||||||
|
- description: Login Data
|
||||||
|
in: body
|
||||||
|
name: payload
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/v1.LoginForm'
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
|
@ -1553,7 +1749,7 @@ paths:
|
||||||
responses:
|
responses:
|
||||||
"204":
|
"204":
|
||||||
description: No Content
|
description: No Content
|
||||||
summary: Get the current user
|
summary: Register New User
|
||||||
tags:
|
tags:
|
||||||
- User
|
- User
|
||||||
/v1/users/self:
|
/v1/users/self:
|
||||||
|
@ -1565,7 +1761,7 @@ paths:
|
||||||
description: No Content
|
description: No Content
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Deletes the user account
|
summary: Delete Account
|
||||||
tags:
|
tags:
|
||||||
- User
|
- User
|
||||||
get:
|
get:
|
||||||
|
@ -1576,14 +1772,14 @@ paths:
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/definitions/server.Result'
|
- $ref: '#/definitions/v1.Wrapped'
|
||||||
- properties:
|
- properties:
|
||||||
item:
|
item:
|
||||||
$ref: '#/definitions/repo.UserOut'
|
$ref: '#/definitions/repo.UserOut'
|
||||||
type: object
|
type: object
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Get the current user
|
summary: Get User Self
|
||||||
tags:
|
tags:
|
||||||
- User
|
- User
|
||||||
put:
|
put:
|
||||||
|
@ -1601,14 +1797,14 @@ paths:
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/definitions/server.Result'
|
- $ref: '#/definitions/v1.Wrapped'
|
||||||
- properties:
|
- properties:
|
||||||
item:
|
item:
|
||||||
$ref: '#/definitions/repo.UserUpdate'
|
$ref: '#/definitions/repo.UserUpdate'
|
||||||
type: object
|
type: object
|
||||||
security:
|
security:
|
||||||
- Bearer: []
|
- Bearer: []
|
||||||
summary: Update the current user
|
summary: Update Account
|
||||||
tags:
|
tags:
|
||||||
- User
|
- User
|
||||||
securityDefinitions:
|
securityDefinitions:
|
||||||
|
|
|
@ -54,6 +54,7 @@ func main() {
|
||||||
NewReReplace(` Services`, " "),
|
NewReReplace(` Services`, " "),
|
||||||
NewReReplace(` V1`, " "),
|
NewReReplace(` V1`, " "),
|
||||||
NewReReplace(`\?:`, ":"),
|
NewReReplace(`\?:`, ":"),
|
||||||
|
NewReReplace(`(\w+):\s(.*null.*)`, "$1?: $2"), // make null union types optional
|
||||||
NewReDate("createdAt"),
|
NewReDate("createdAt"),
|
||||||
NewReDate("updatedAt"),
|
NewReDate("updatedAt"),
|
||||||
NewReDate("soldTime"),
|
NewReDate("soldTime"),
|
|
@ -1,23 +1,29 @@
|
||||||
module github.com/hay-kot/homebox/backend
|
module github.com/hay-kot/homebox/backend
|
||||||
|
|
||||||
go 1.19
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
ariga.io/atlas v0.9.1-0.20230119145809-92243f7c55cb
|
ariga.io/atlas v0.12.0
|
||||||
entgo.io/ent v0.11.8
|
entgo.io/ent v0.12.3
|
||||||
github.com/ardanlabs/conf/v3 v3.1.4
|
github.com/ardanlabs/conf/v3 v3.1.6
|
||||||
github.com/go-chi/chi/v5 v5.0.8
|
github.com/containrrr/shoutrrr v0.8.0
|
||||||
github.com/go-playground/validator/v10 v10.11.2
|
github.com/go-chi/chi/v5 v5.0.10
|
||||||
github.com/gocarina/gocsv v0.0.0-20230219202803-bcce7dc8d0bb
|
github.com/go-playground/validator/v10 v10.15.5
|
||||||
github.com/google/uuid v1.3.0
|
github.com/gocarina/gocsv v0.0.0-20230616125104-99d496ca653d
|
||||||
github.com/mattn/go-sqlite3 v1.14.16
|
github.com/google/uuid v1.3.1
|
||||||
github.com/rs/zerolog v1.29.0
|
github.com/gorilla/schema v1.2.0
|
||||||
github.com/stretchr/testify v1.8.2
|
github.com/hay-kot/httpkit v0.0.3
|
||||||
github.com/swaggo/http-swagger v1.3.3
|
github.com/mattn/go-sqlite3 v1.14.17
|
||||||
github.com/swaggo/swag v1.8.10
|
github.com/olahol/melody v1.1.4
|
||||||
github.com/yeqown/go-qrcode/v2 v2.2.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/yeqown/go-qrcode/writer/standard v1.2.1
|
github.com/rs/zerolog v1.31.0
|
||||||
golang.org/x/crypto v0.7.0
|
github.com/stretchr/testify v1.8.4
|
||||||
|
github.com/swaggo/http-swagger v1.3.4
|
||||||
|
github.com/swaggo/swag v1.16.2
|
||||||
|
github.com/yeqown/go-qrcode/v2 v2.2.2
|
||||||
|
github.com/yeqown/go-qrcode/writer/standard v1.2.2
|
||||||
|
golang.org/x/crypto v0.14.0
|
||||||
|
modernc.org/sqlite v1.26.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
@ -25,33 +31,47 @@ require (
|
||||||
github.com/agext/levenshtein v1.2.3 // indirect
|
github.com/agext/levenshtein v1.2.3 // indirect
|
||||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
|
github.com/fatih/color v1.15.0 // indirect
|
||||||
github.com/fogleman/gg v1.3.0 // indirect
|
github.com/fogleman/gg v1.3.0 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
github.com/go-openapi/inflect v0.19.0 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
github.com/go-openapi/jsonpointer v0.20.0 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||||
github.com/go-openapi/spec v0.20.7 // indirect
|
github.com/go-openapi/spec v0.20.9 // indirect
|
||||||
github.com/go-openapi/swag v0.22.3 // indirect
|
github.com/go-openapi/swag v0.22.4 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/go-cmp v0.5.9 // indirect
|
||||||
github.com/hashicorp/hcl/v2 v2.15.0 // indirect
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/hashicorp/hcl/v2 v2.17.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/leodido/go-urn v1.2.1 // indirect
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
|
github.com/leodido/go-urn v1.2.4 // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/swaggo/files v1.0.0 // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
|
github.com/swaggo/files v1.0.1 // indirect
|
||||||
github.com/yeqown/reedsolomon v1.0.0 // indirect
|
github.com/yeqown/reedsolomon v1.0.0 // indirect
|
||||||
github.com/zclconf/go-cty v1.12.1 // indirect
|
github.com/zclconf/go-cty v1.13.2 // indirect
|
||||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect
|
golang.org/x/image v0.9.0 // indirect
|
||||||
golang.org/x/mod v0.8.0 // indirect
|
golang.org/x/mod v0.12.0 // indirect
|
||||||
golang.org/x/net v0.8.0 // indirect
|
golang.org/x/net v0.12.0 // indirect
|
||||||
golang.org/x/sys v0.6.0 // indirect
|
golang.org/x/sys v0.13.0 // indirect
|
||||||
golang.org/x/text v0.8.0 // indirect
|
golang.org/x/text v0.13.0 // indirect
|
||||||
golang.org/x/tools v0.6.0 // indirect
|
golang.org/x/tools v0.11.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
lukechampine.com/uint128 v1.3.0 // indirect
|
||||||
|
modernc.org/cc/v3 v3.41.0 // indirect
|
||||||
|
modernc.org/ccgo/v3 v3.16.14 // indirect
|
||||||
|
modernc.org/libc v1.24.1 // indirect
|
||||||
|
modernc.org/mathutil v1.6.0 // indirect
|
||||||
|
modernc.org/memory v1.6.0 // indirect
|
||||||
|
modernc.org/opt v0.1.3 // indirect
|
||||||
|
modernc.org/strutil v1.1.3 // indirect
|
||||||
|
modernc.org/token v1.1.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
1267
backend/go.sum
1267
backend/go.sum
File diff suppressed because it is too large
Load diff
|
@ -5,9 +5,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type AllServices struct {
|
type AllServices struct {
|
||||||
User *UserService
|
User *UserService
|
||||||
Group *GroupService
|
Group *GroupService
|
||||||
Items *ItemService
|
Items *ItemService
|
||||||
|
BackgroundService *BackgroundService
|
||||||
}
|
}
|
||||||
|
|
||||||
type OptionsFunc func(*options)
|
type OptionsFunc func(*options)
|
||||||
|
@ -42,5 +43,6 @@ func New(repos *repo.AllRepos, opts ...OptionsFunc) *AllServices {
|
||||||
repo: repos,
|
repo: repos,
|
||||||
autoIncrementAssetID: options.autoIncrementAssetID,
|
autoIncrementAssetID: options.autoIncrementAssetID,
|
||||||
},
|
},
|
||||||
|
BackgroundService: &BackgroundService{repos},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,10 @@ package services
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/faker"
|
"github.com/hay-kot/homebox/backend/pkgs/faker"
|
||||||
|
@ -15,7 +14,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
fk = faker.NewFaker()
|
fk = faker.NewFaker()
|
||||||
|
tbus = eventbus.New()
|
||||||
|
|
||||||
tCtx = Context{}
|
tCtx = Context{}
|
||||||
tClient *ent.Client
|
tClient *ent.Client
|
||||||
|
@ -49,8 +49,6 @@ func bootstrap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
rand.Seed(int64(time.Now().Unix()))
|
|
||||||
|
|
||||||
client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
|
client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed opening connection to sqlite: %v", err)
|
log.Fatalf("failed opening connection to sqlite: %v", err)
|
||||||
|
@ -62,7 +60,7 @@ func TestMain(m *testing.M) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tClient = client
|
tClient = client
|
||||||
tRepos = repo.New(tClient, os.TempDir()+"/homebox")
|
tRepos = repo.New(tClient, tbus, os.TempDir()+"/homebox")
|
||||||
tSvc = New(tRepos)
|
tSvc = New(tRepos)
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
Import Ref,Location,Labels,Quantity,Name,Description,Insured,Serial Number,Mode Number,Manufacturer,Notes,Purchase From,Purchased Price,Purchased Time,Lifetime Warranty,Warranty Expires,Warranty Details,Sold To,Sold Price,Sold Time,Sold Notes
|
|
||||||
A,Garage,IOT;Home Assistant; Z-Wave,1,Zooz Universal Relay ZEN17,Description 1,TRUE,,ZEN17,Zooz,,Amazon,39.95,10/13/2021,,10/13/2021,,,,10/13/2021,
|
|
||||||
B,Living Room,IOT;Home Assistant; Z-Wave,1,Zooz Motion Sensor,Description 2,FALSE,,ZSE18,Zooz,,Amazon,29.95,10/15/2021,,10/15/2021,,,,10/15/2021,
|
|
||||||
C,Office,IOT;Home Assistant; Z-Wave,1,Zooz 110v Power Switch,Description 3,TRUE,,ZEN15,Zooz,,Amazon,39.95,10/13/2021,,10/13/2021,,,,10/13/2021,
|
|
||||||
D,Downstairs,IOT;Home Assistant; Z-Wave,1,Ecolink Z-Wave PIR Motion Sensor,Description 4,FALSE,,PIRZWAVE2.5-ECO,Ecolink,,Amazon,35.58,10/21/2020,,10/21/2020,,,,10/21/2020,
|
|
||||||
E,Entry,IOT;Home Assistant; Z-Wave,1,Yale Security Touchscreen Deadbolt,Description 5,TRUE,,YRD226ZW2619,Yale,,Amazon,120.39,10/14/2020,,10/14/2020,,,,10/14/2020,
|
|
||||||
F,Kitchen,IOT;Home Assistant; Z-Wave,1,Smart Rocker Light Dimmer,Description 6,FALSE,,39351,Honeywell,,Amazon,65.98,09/30/2020,,09/30/2020,,,,09/30/2020,
|
|
|
|
@ -1,7 +0,0 @@
|
||||||
Import Ref Location Labels Quantity Name Description Insured Serial Number Mode Number Manufacturer Notes Purchase From Purchased Price Purchased Time Lifetime Warranty Warranty Expires Warranty Details Sold To Sold Price Sold Time Sold Notes
|
|
||||||
A Garage IOT;Home Assistant; Z-Wave 1 Zooz Universal Relay ZEN17 Description 1 TRUE ZEN17 Zooz Amazon 39.95 10/13/2021 10/13/2021 10/13/2021
|
|
||||||
B Living Room IOT;Home Assistant; Z-Wave 1 Zooz Motion Sensor Description 2 FALSE ZSE18 Zooz Amazon 29.95 10/15/2021 10/15/2021 10/15/2021
|
|
||||||
C Office IOT;Home Assistant; Z-Wave 1 Zooz 110v Power Switch Description 3 TRUE ZEN15 Zooz Amazon 39.95 10/13/2021 10/13/2021 10/13/2021
|
|
||||||
D Downstairs IOT;Home Assistant; Z-Wave 1 Ecolink Z-Wave PIR Motion Sensor Description 4 FALSE PIRZWAVE2.5-ECO Ecolink Amazon 35.58 10/21/2020 10/21/2020 10/21/2020
|
|
||||||
E Entry IOT;Home Assistant; Z-Wave 1 Yale Security Touchscreen Deadbolt Description 5 TRUE YRD226ZW2619 Yale Amazon 120.39 10/14/2020 10/14/2020 10/14/2020
|
|
||||||
F Kitchen IOT;Home Assistant; Z-Wave 1 Smart Rocker Light Dimmer Description 6 FALSE 39351 Honeywell Amazon 65.98 09/30/2020 09/30/2020 09/30/2020
|
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
// / Package eventbus provides an interface for event bus.
|
||||||
|
package eventbus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Event string
|
||||||
|
|
||||||
|
const (
|
||||||
|
EventLabelMutation Event = "label.mutation"
|
||||||
|
EventLocationMutation Event = "location.mutation"
|
||||||
|
EventItemMutation Event = "item.mutation"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GroupMutationEvent struct {
|
||||||
|
GID uuid.UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
type eventData struct {
|
||||||
|
event Event
|
||||||
|
data any
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventBus struct {
|
||||||
|
started bool
|
||||||
|
ch chan eventData
|
||||||
|
|
||||||
|
mu sync.RWMutex
|
||||||
|
subscribers map[Event][]func(any)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() *EventBus {
|
||||||
|
return &EventBus{
|
||||||
|
ch: make(chan eventData, 10),
|
||||||
|
subscribers: map[Event][]func(any){
|
||||||
|
EventLabelMutation: {},
|
||||||
|
EventLocationMutation: {},
|
||||||
|
EventItemMutation: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EventBus) Run() {
|
||||||
|
if e.started {
|
||||||
|
panic("event bus already started")
|
||||||
|
}
|
||||||
|
|
||||||
|
e.started = true
|
||||||
|
|
||||||
|
for event := range e.ch {
|
||||||
|
e.mu.RLock()
|
||||||
|
arr, ok := e.subscribers[event.event]
|
||||||
|
e.mu.RUnlock()
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fn := range arr {
|
||||||
|
fn(event.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EventBus) Publish(event Event, data any) {
|
||||||
|
e.ch <- eventData{
|
||||||
|
event: event,
|
||||||
|
data: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EventBus) Subscribe(event Event, fn func(any)) {
|
||||||
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
|
arr, ok := e.subscribers[event]
|
||||||
|
if !ok {
|
||||||
|
panic("event not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
e.subscribers[event] = append(arr, fn)
|
||||||
|
}
|
|
@ -83,3 +83,13 @@ func parseLocationString(s string) LocationString {
|
||||||
func (csf LocationString) String() string {
|
func (csf LocationString) String() string {
|
||||||
return strings.Join(csf, " / ")
|
return strings.Join(csf, " / ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fromPathSlice(s []repo.LocationPath) LocationString {
|
||||||
|
v := make(LocationString, len(s))
|
||||||
|
|
||||||
|
for i := range s {
|
||||||
|
v[i] = s[i].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package reporting
|
package reporting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -8,6 +9,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/types"
|
"github.com/hay-kot/homebox/backend/internal/data/types"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
@ -151,7 +153,7 @@ func (s *IOSheet) Read(data io.Reader) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write writes the sheet to a writer.
|
// Write writes the sheet to a writer.
|
||||||
func (s *IOSheet) ReadItems(items []repo.ItemOut) {
|
func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.UUID, repos *repo.AllRepos) error {
|
||||||
s.Rows = make([]ExportTSVRow, len(items))
|
s.Rows = make([]ExportTSVRow, len(items))
|
||||||
|
|
||||||
extraHeaders := map[string]struct{}{}
|
extraHeaders := map[string]struct{}{}
|
||||||
|
@ -160,7 +162,15 @@ func (s *IOSheet) ReadItems(items []repo.ItemOut) {
|
||||||
item := items[i]
|
item := items[i]
|
||||||
|
|
||||||
// TODO: Support fetching nested locations
|
// TODO: Support fetching nested locations
|
||||||
locString := LocationString{item.Location.Name}
|
locId := item.Location.ID
|
||||||
|
|
||||||
|
locPaths, err := repos.Locations.PathForLoc(context.Background(), GID, locId)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("could not get location path")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
locString := fromPathSlice(locPaths)
|
||||||
|
|
||||||
labelString := make([]string, len(item.Labels))
|
labelString := make([]string, len(item.Labels))
|
||||||
|
|
||||||
|
@ -238,6 +248,8 @@ func (s *IOSheet) ReadItems(items []repo.ItemOut) {
|
||||||
for _, h := range customHeaders {
|
for _, h := range customHeaders {
|
||||||
s.headers = append(s.headers, "HB.field."+h)
|
s.headers = append(s.headers, "HB.field."+h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writes the current sheet to a writer in TSV format.
|
// Writes the current sheet to a writer in TSV format.
|
||||||
|
|
|
@ -20,12 +20,6 @@ var (
|
||||||
|
|
||||||
//go:embed .testdata/import/types.csv
|
//go:embed .testdata/import/types.csv
|
||||||
customTypesImportCSV []byte
|
customTypesImportCSV []byte
|
||||||
|
|
||||||
//go:embed .testdata/import.csv
|
|
||||||
CSVData_Comma []byte
|
|
||||||
|
|
||||||
//go:embed .testdata/import.tsv
|
|
||||||
CSVData_Tab []byte
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSheet_Read(t *testing.T) {
|
func TestSheet_Read(t *testing.T) {
|
||||||
|
@ -189,7 +183,7 @@ func Test_determineSeparator(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "comma",
|
name: "comma",
|
||||||
args: args{
|
args: args{
|
||||||
data: CSVData_Comma,
|
data: []byte("a,b,c"),
|
||||||
},
|
},
|
||||||
want: ',',
|
want: ',',
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
|
@ -197,7 +191,7 @@ func Test_determineSeparator(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "tab",
|
name: "tab",
|
||||||
args: args{
|
args: args{
|
||||||
data: CSVData_Tab,
|
data: []byte("a\tb\tc"),
|
||||||
},
|
},
|
||||||
want: '\t',
|
want: '\t',
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
|
|
81
backend/internal/core/services/service_background.go
Normal file
81
backend/internal/core/services/service_background.go
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/containrrr/shoutrrr"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/types"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BackgroundService struct {
|
||||||
|
repos *repo.AllRepos
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svc *BackgroundService) SendNotifiersToday(ctx context.Context) error {
|
||||||
|
// Get All Groups
|
||||||
|
groups, err := svc.repos.Groups.GetAllGroups(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
today := types.DateFromTime(time.Now())
|
||||||
|
|
||||||
|
for i := range groups {
|
||||||
|
group := groups[i]
|
||||||
|
|
||||||
|
entries, err := svc.repos.MaintEntry.GetScheduled(ctx, group.ID, today)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(entries) == 0 {
|
||||||
|
log.Debug().
|
||||||
|
Str("group_name", group.Name).
|
||||||
|
Str("group_id", group.ID.String()).
|
||||||
|
Msg("No scheduled maintenance for today")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
notifiers, err := svc.repos.Notifiers.GetByGroup(ctx, group.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
urls := make([]string, len(notifiers))
|
||||||
|
for i := range notifiers {
|
||||||
|
urls[i] = notifiers[i].URL
|
||||||
|
}
|
||||||
|
|
||||||
|
bldr := strings.Builder{}
|
||||||
|
|
||||||
|
bldr.WriteString("Homebox Maintenance for (")
|
||||||
|
bldr.WriteString(today.String())
|
||||||
|
bldr.WriteString("):\n")
|
||||||
|
|
||||||
|
for i := range entries {
|
||||||
|
entry := entries[i]
|
||||||
|
bldr.WriteString(" - ")
|
||||||
|
bldr.WriteString(entry.Name)
|
||||||
|
bldr.WriteString("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
var sendErrs []error
|
||||||
|
for i := range urls {
|
||||||
|
err := shoutrrr.Send(urls[i], bldr.String())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
sendErrs = append(sendErrs, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sendErrs) > 0 {
|
||||||
|
return sendErrs[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -337,7 +337,10 @@ func (svc *ItemService) ExportTSV(ctx context.Context, GID uuid.UUID) ([][]strin
|
||||||
|
|
||||||
sheet := reporting.IOSheet{}
|
sheet := reporting.IOSheet{}
|
||||||
|
|
||||||
sheet.ReadItems(items)
|
err = sheet.ReadItems(ctx, items, GID, svc.repo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return sheet.TSV()
|
return sheet.TSV()
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ func (svc *ItemService) AttachmentPath(ctx context.Context, attachmentId uuid.UU
|
||||||
|
|
||||||
func (svc *ItemService) AttachmentUpdate(ctx Context, itemId uuid.UUID, data *repo.ItemAttachmentUpdate) (repo.ItemOut, error) {
|
func (svc *ItemService) AttachmentUpdate(ctx Context, itemId uuid.UUID, data *repo.ItemAttachmentUpdate) (repo.ItemOut, error) {
|
||||||
// Update Attachment
|
// Update Attachment
|
||||||
attachment, err := svc.repo.Attachments.Update(ctx, data.ID, attachment.Type(data.Type))
|
attachment, err := svc.repo.Attachments.Update(ctx, data.ID, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return repo.ItemOut{}, err
|
return repo.ItemOut{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -138,12 +140,18 @@ func (svc *UserService) UpdateSelf(ctx context.Context, ID uuid.UUID, data repo.
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// User Authentication
|
// User Authentication
|
||||||
|
|
||||||
func (svc *UserService) createSessionToken(ctx context.Context, userId uuid.UUID) (UserAuthTokenDetail, error) {
|
func (svc *UserService) createSessionToken(ctx context.Context, userId uuid.UUID, extendedSession bool) (UserAuthTokenDetail, error) {
|
||||||
attachmentToken := hasher.GenerateToken()
|
attachmentToken := hasher.GenerateToken()
|
||||||
|
|
||||||
|
expiresAt := time.Now().Add(oneWeek)
|
||||||
|
if extendedSession {
|
||||||
|
expiresAt = time.Now().Add(oneWeek * 4)
|
||||||
|
}
|
||||||
|
|
||||||
attachmentData := repo.UserAuthTokenCreate{
|
attachmentData := repo.UserAuthTokenCreate{
|
||||||
UserID: userId,
|
UserID: userId,
|
||||||
TokenHash: attachmentToken.Hash,
|
TokenHash: attachmentToken.Hash,
|
||||||
ExpiresAt: time.Now().Add(oneWeek),
|
ExpiresAt: expiresAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := svc.repos.AuthTokens.CreateToken(ctx, attachmentData, authroles.RoleAttachments)
|
_, err := svc.repos.AuthTokens.CreateToken(ctx, attachmentData, authroles.RoleAttachments)
|
||||||
|
@ -155,7 +163,7 @@ func (svc *UserService) createSessionToken(ctx context.Context, userId uuid.UUID
|
||||||
data := repo.UserAuthTokenCreate{
|
data := repo.UserAuthTokenCreate{
|
||||||
UserID: userId,
|
UserID: userId,
|
||||||
TokenHash: userToken.Hash,
|
TokenHash: userToken.Hash,
|
||||||
ExpiresAt: time.Now().Add(oneWeek),
|
ExpiresAt: expiresAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
created, err := svc.repos.AuthTokens.CreateToken(ctx, data, authroles.RoleUser)
|
created, err := svc.repos.AuthTokens.CreateToken(ctx, data, authroles.RoleUser)
|
||||||
|
@ -170,7 +178,7 @@ func (svc *UserService) createSessionToken(ctx context.Context, userId uuid.UUID
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *UserService) Login(ctx context.Context, username, password string) (UserAuthTokenDetail, error) {
|
func (svc *UserService) Login(ctx context.Context, username, password string, extendedSession bool) (UserAuthTokenDetail, error) {
|
||||||
usr, err := svc.repos.Users.GetOneEmail(ctx, username)
|
usr, err := svc.repos.Users.GetOneEmail(ctx, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// SECURITY: Perform hash to ensure response times are the same
|
// SECURITY: Perform hash to ensure response times are the same
|
||||||
|
@ -182,7 +190,7 @@ func (svc *UserService) Login(ctx context.Context, username, password string) (U
|
||||||
return UserAuthTokenDetail{}, ErrorInvalidLogin
|
return UserAuthTokenDetail{}, ErrorInvalidLogin
|
||||||
}
|
}
|
||||||
|
|
||||||
return svc.createSessionToken(ctx, usr.ID)
|
return svc.createSessionToken(ctx, usr.ID, extendedSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *UserService) Logout(ctx context.Context, token string) error {
|
func (svc *UserService) Logout(ctx context.Context, token string) error {
|
||||||
|
@ -199,7 +207,7 @@ func (svc *UserService) RenewToken(ctx context.Context, token string) (UserAuthT
|
||||||
return UserAuthTokenDetail{}, ErrorInvalidToken
|
return UserAuthTokenDetail{}, ErrorInvalidToken
|
||||||
}
|
}
|
||||||
|
|
||||||
return svc.createSessionToken(ctx, dbToken.ID)
|
return svc.createSessionToken(ctx, dbToken.ID, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteSelf deletes the user that is currently logged based of the provided UUID
|
// DeleteSelf deletes the user that is currently logged based of the provided UUID
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||||
|
@ -25,11 +26,14 @@ type Attachment struct {
|
||||||
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
||||||
// Type holds the value of the "type" field.
|
// Type holds the value of the "type" field.
|
||||||
Type attachment.Type `json:"type,omitempty"`
|
Type attachment.Type `json:"type,omitempty"`
|
||||||
|
// Primary holds the value of the "primary" field.
|
||||||
|
Primary bool `json:"primary,omitempty"`
|
||||||
// Edges holds the relations/edges for other nodes in the graph.
|
// Edges holds the relations/edges for other nodes in the graph.
|
||||||
// The values are being populated by the AttachmentQuery when eager-loading is set.
|
// The values are being populated by the AttachmentQuery when eager-loading is set.
|
||||||
Edges AttachmentEdges `json:"edges"`
|
Edges AttachmentEdges `json:"edges"`
|
||||||
document_attachments *uuid.UUID
|
document_attachments *uuid.UUID
|
||||||
item_attachments *uuid.UUID
|
item_attachments *uuid.UUID
|
||||||
|
selectValues sql.SelectValues
|
||||||
}
|
}
|
||||||
|
|
||||||
// AttachmentEdges holds the relations/edges for other nodes in the graph.
|
// AttachmentEdges holds the relations/edges for other nodes in the graph.
|
||||||
|
@ -74,6 +78,8 @@ func (*Attachment) scanValues(columns []string) ([]any, error) {
|
||||||
values := make([]any, len(columns))
|
values := make([]any, len(columns))
|
||||||
for i := range columns {
|
for i := range columns {
|
||||||
switch columns[i] {
|
switch columns[i] {
|
||||||
|
case attachment.FieldPrimary:
|
||||||
|
values[i] = new(sql.NullBool)
|
||||||
case attachment.FieldType:
|
case attachment.FieldType:
|
||||||
values[i] = new(sql.NullString)
|
values[i] = new(sql.NullString)
|
||||||
case attachment.FieldCreatedAt, attachment.FieldUpdatedAt:
|
case attachment.FieldCreatedAt, attachment.FieldUpdatedAt:
|
||||||
|
@ -85,7 +91,7 @@ func (*Attachment) scanValues(columns []string) ([]any, error) {
|
||||||
case attachment.ForeignKeys[1]: // item_attachments
|
case attachment.ForeignKeys[1]: // item_attachments
|
||||||
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected column %q for type Attachment", columns[i])
|
values[i] = new(sql.UnknownType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values, nil
|
return values, nil
|
||||||
|
@ -123,6 +129,12 @@ func (a *Attachment) assignValues(columns []string, values []any) error {
|
||||||
} else if value.Valid {
|
} else if value.Valid {
|
||||||
a.Type = attachment.Type(value.String)
|
a.Type = attachment.Type(value.String)
|
||||||
}
|
}
|
||||||
|
case attachment.FieldPrimary:
|
||||||
|
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field primary", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
a.Primary = value.Bool
|
||||||
|
}
|
||||||
case attachment.ForeignKeys[0]:
|
case attachment.ForeignKeys[0]:
|
||||||
if value, ok := values[i].(*sql.NullScanner); !ok {
|
if value, ok := values[i].(*sql.NullScanner); !ok {
|
||||||
return fmt.Errorf("unexpected type %T for field document_attachments", values[i])
|
return fmt.Errorf("unexpected type %T for field document_attachments", values[i])
|
||||||
|
@ -137,11 +149,19 @@ func (a *Attachment) assignValues(columns []string, values []any) error {
|
||||||
a.item_attachments = new(uuid.UUID)
|
a.item_attachments = new(uuid.UUID)
|
||||||
*a.item_attachments = *value.S.(*uuid.UUID)
|
*a.item_attachments = *value.S.(*uuid.UUID)
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
a.selectValues.Set(columns[i], values[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Value returns the ent.Value that was dynamically selected and assigned to the Attachment.
|
||||||
|
// This includes values selected through modifiers, order, etc.
|
||||||
|
func (a *Attachment) Value(name string) (ent.Value, error) {
|
||||||
|
return a.selectValues.Get(name)
|
||||||
|
}
|
||||||
|
|
||||||
// QueryItem queries the "item" edge of the Attachment entity.
|
// QueryItem queries the "item" edge of the Attachment entity.
|
||||||
func (a *Attachment) QueryItem() *ItemQuery {
|
func (a *Attachment) QueryItem() *ItemQuery {
|
||||||
return NewAttachmentClient(a.config).QueryItem(a)
|
return NewAttachmentClient(a.config).QueryItem(a)
|
||||||
|
@ -183,6 +203,9 @@ func (a *Attachment) String() string {
|
||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
builder.WriteString("type=")
|
builder.WriteString("type=")
|
||||||
builder.WriteString(fmt.Sprintf("%v", a.Type))
|
builder.WriteString(fmt.Sprintf("%v", a.Type))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("primary=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", a.Primary))
|
||||||
builder.WriteByte(')')
|
builder.WriteByte(')')
|
||||||
return builder.String()
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,6 +22,8 @@ const (
|
||||||
FieldUpdatedAt = "updated_at"
|
FieldUpdatedAt = "updated_at"
|
||||||
// FieldType holds the string denoting the type field in the database.
|
// FieldType holds the string denoting the type field in the database.
|
||||||
FieldType = "type"
|
FieldType = "type"
|
||||||
|
// FieldPrimary holds the string denoting the primary field in the database.
|
||||||
|
FieldPrimary = "primary"
|
||||||
// EdgeItem holds the string denoting the item edge name in mutations.
|
// EdgeItem holds the string denoting the item edge name in mutations.
|
||||||
EdgeItem = "item"
|
EdgeItem = "item"
|
||||||
// EdgeDocument holds the string denoting the document edge name in mutations.
|
// EdgeDocument holds the string denoting the document edge name in mutations.
|
||||||
|
@ -48,6 +52,7 @@ var Columns = []string{
|
||||||
FieldCreatedAt,
|
FieldCreatedAt,
|
||||||
FieldUpdatedAt,
|
FieldUpdatedAt,
|
||||||
FieldType,
|
FieldType,
|
||||||
|
FieldPrimary,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForeignKeys holds the SQL foreign-keys that are owned by the "attachments"
|
// ForeignKeys holds the SQL foreign-keys that are owned by the "attachments"
|
||||||
|
@ -79,6 +84,8 @@ var (
|
||||||
DefaultUpdatedAt func() time.Time
|
DefaultUpdatedAt func() time.Time
|
||||||
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
|
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
|
||||||
UpdateDefaultUpdatedAt func() time.Time
|
UpdateDefaultUpdatedAt func() time.Time
|
||||||
|
// DefaultPrimary holds the default value on creation for the "primary" field.
|
||||||
|
DefaultPrimary bool
|
||||||
// DefaultID holds the default value on creation for the "id" field.
|
// DefaultID holds the default value on creation for the "id" field.
|
||||||
DefaultID func() uuid.UUID
|
DefaultID func() uuid.UUID
|
||||||
)
|
)
|
||||||
|
@ -111,3 +118,59 @@ func TypeValidator(_type Type) error {
|
||||||
return fmt.Errorf("attachment: invalid enum value for type field: %q", _type)
|
return fmt.Errorf("attachment: invalid enum value for type field: %q", _type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OrderOption defines the ordering options for the Attachment queries.
|
||||||
|
type OrderOption func(*sql.Selector)
|
||||||
|
|
||||||
|
// ByID orders the results by the id field.
|
||||||
|
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByCreatedAt orders the results by the created_at field.
|
||||||
|
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUpdatedAt orders the results by the updated_at field.
|
||||||
|
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByType orders the results by the type field.
|
||||||
|
func ByType(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldType, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByPrimary orders the results by the primary field.
|
||||||
|
func ByPrimary(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldPrimary, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByItemField orders the results by item field.
|
||||||
|
func ByItemField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newItemStep(), sql.OrderByField(field, opts...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByDocumentField orders the results by document field.
|
||||||
|
func ByDocumentField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newDocumentStep(), sql.OrderByField(field, opts...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func newItemStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(ItemInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, ItemTable, ItemColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func newDocumentStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(DocumentInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, DocumentTable, DocumentColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -66,6 +66,11 @@ func UpdatedAt(v time.Time) predicate.Attachment {
|
||||||
return predicate.Attachment(sql.FieldEQ(FieldUpdatedAt, v))
|
return predicate.Attachment(sql.FieldEQ(FieldUpdatedAt, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Primary applies equality check predicate on the "primary" field. It's identical to PrimaryEQ.
|
||||||
|
func Primary(v bool) predicate.Attachment {
|
||||||
|
return predicate.Attachment(sql.FieldEQ(FieldPrimary, v))
|
||||||
|
}
|
||||||
|
|
||||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||||
func CreatedAtEQ(v time.Time) predicate.Attachment {
|
func CreatedAtEQ(v time.Time) predicate.Attachment {
|
||||||
return predicate.Attachment(sql.FieldEQ(FieldCreatedAt, v))
|
return predicate.Attachment(sql.FieldEQ(FieldCreatedAt, v))
|
||||||
|
@ -166,6 +171,16 @@ func TypeNotIn(vs ...Type) predicate.Attachment {
|
||||||
return predicate.Attachment(sql.FieldNotIn(FieldType, vs...))
|
return predicate.Attachment(sql.FieldNotIn(FieldType, vs...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrimaryEQ applies the EQ predicate on the "primary" field.
|
||||||
|
func PrimaryEQ(v bool) predicate.Attachment {
|
||||||
|
return predicate.Attachment(sql.FieldEQ(FieldPrimary, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrimaryNEQ applies the NEQ predicate on the "primary" field.
|
||||||
|
func PrimaryNEQ(v bool) predicate.Attachment {
|
||||||
|
return predicate.Attachment(sql.FieldNEQ(FieldPrimary, v))
|
||||||
|
}
|
||||||
|
|
||||||
// HasItem applies the HasEdge predicate on the "item" edge.
|
// HasItem applies the HasEdge predicate on the "item" edge.
|
||||||
func HasItem() predicate.Attachment {
|
func HasItem() predicate.Attachment {
|
||||||
return predicate.Attachment(func(s *sql.Selector) {
|
return predicate.Attachment(func(s *sql.Selector) {
|
||||||
|
@ -180,11 +195,7 @@ func HasItem() predicate.Attachment {
|
||||||
// HasItemWith applies the HasEdge predicate on the "item" edge with a given conditions (other predicates).
|
// HasItemWith applies the HasEdge predicate on the "item" edge with a given conditions (other predicates).
|
||||||
func HasItemWith(preds ...predicate.Item) predicate.Attachment {
|
func HasItemWith(preds ...predicate.Item) predicate.Attachment {
|
||||||
return predicate.Attachment(func(s *sql.Selector) {
|
return predicate.Attachment(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newItemStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(ItemInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.M2O, true, ItemTable, ItemColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
@ -207,11 +218,7 @@ func HasDocument() predicate.Attachment {
|
||||||
// HasDocumentWith applies the HasEdge predicate on the "document" edge with a given conditions (other predicates).
|
// HasDocumentWith applies the HasEdge predicate on the "document" edge with a given conditions (other predicates).
|
||||||
func HasDocumentWith(preds ...predicate.Document) predicate.Attachment {
|
func HasDocumentWith(preds ...predicate.Document) predicate.Attachment {
|
||||||
return predicate.Attachment(func(s *sql.Selector) {
|
return predicate.Attachment(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newDocumentStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(DocumentInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.M2O, true, DocumentTable, DocumentColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
|
|
@ -65,6 +65,20 @@ func (ac *AttachmentCreate) SetNillableType(a *attachment.Type) *AttachmentCreat
|
||||||
return ac
|
return ac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPrimary sets the "primary" field.
|
||||||
|
func (ac *AttachmentCreate) SetPrimary(b bool) *AttachmentCreate {
|
||||||
|
ac.mutation.SetPrimary(b)
|
||||||
|
return ac
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillablePrimary sets the "primary" field if the given value is not nil.
|
||||||
|
func (ac *AttachmentCreate) SetNillablePrimary(b *bool) *AttachmentCreate {
|
||||||
|
if b != nil {
|
||||||
|
ac.SetPrimary(*b)
|
||||||
|
}
|
||||||
|
return ac
|
||||||
|
}
|
||||||
|
|
||||||
// SetID sets the "id" field.
|
// SetID sets the "id" field.
|
||||||
func (ac *AttachmentCreate) SetID(u uuid.UUID) *AttachmentCreate {
|
func (ac *AttachmentCreate) SetID(u uuid.UUID) *AttachmentCreate {
|
||||||
ac.mutation.SetID(u)
|
ac.mutation.SetID(u)
|
||||||
|
@ -109,7 +123,7 @@ func (ac *AttachmentCreate) Mutation() *AttachmentMutation {
|
||||||
// Save creates the Attachment in the database.
|
// Save creates the Attachment in the database.
|
||||||
func (ac *AttachmentCreate) Save(ctx context.Context) (*Attachment, error) {
|
func (ac *AttachmentCreate) Save(ctx context.Context) (*Attachment, error) {
|
||||||
ac.defaults()
|
ac.defaults()
|
||||||
return withHooks[*Attachment, AttachmentMutation](ctx, ac.sqlSave, ac.mutation, ac.hooks)
|
return withHooks(ctx, ac.sqlSave, ac.mutation, ac.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX calls Save and panics if Save returns an error.
|
// SaveX calls Save and panics if Save returns an error.
|
||||||
|
@ -148,6 +162,10 @@ func (ac *AttachmentCreate) defaults() {
|
||||||
v := attachment.DefaultType
|
v := attachment.DefaultType
|
||||||
ac.mutation.SetType(v)
|
ac.mutation.SetType(v)
|
||||||
}
|
}
|
||||||
|
if _, ok := ac.mutation.Primary(); !ok {
|
||||||
|
v := attachment.DefaultPrimary
|
||||||
|
ac.mutation.SetPrimary(v)
|
||||||
|
}
|
||||||
if _, ok := ac.mutation.ID(); !ok {
|
if _, ok := ac.mutation.ID(); !ok {
|
||||||
v := attachment.DefaultID()
|
v := attachment.DefaultID()
|
||||||
ac.mutation.SetID(v)
|
ac.mutation.SetID(v)
|
||||||
|
@ -170,6 +188,9 @@ func (ac *AttachmentCreate) check() error {
|
||||||
return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "Attachment.type": %w`, err)}
|
return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "Attachment.type": %w`, err)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if _, ok := ac.mutation.Primary(); !ok {
|
||||||
|
return &ValidationError{Name: "primary", err: errors.New(`ent: missing required field "Attachment.primary"`)}
|
||||||
|
}
|
||||||
if _, ok := ac.mutation.ItemID(); !ok {
|
if _, ok := ac.mutation.ItemID(); !ok {
|
||||||
return &ValidationError{Name: "item", err: errors.New(`ent: missing required edge "Attachment.item"`)}
|
return &ValidationError{Name: "item", err: errors.New(`ent: missing required edge "Attachment.item"`)}
|
||||||
}
|
}
|
||||||
|
@ -223,6 +244,10 @@ func (ac *AttachmentCreate) createSpec() (*Attachment, *sqlgraph.CreateSpec) {
|
||||||
_spec.SetField(attachment.FieldType, field.TypeEnum, value)
|
_spec.SetField(attachment.FieldType, field.TypeEnum, value)
|
||||||
_node.Type = value
|
_node.Type = value
|
||||||
}
|
}
|
||||||
|
if value, ok := ac.mutation.Primary(); ok {
|
||||||
|
_spec.SetField(attachment.FieldPrimary, field.TypeBool, value)
|
||||||
|
_node.Primary = value
|
||||||
|
}
|
||||||
if nodes := ac.mutation.ItemIDs(); len(nodes) > 0 {
|
if nodes := ac.mutation.ItemIDs(); len(nodes) > 0 {
|
||||||
edge := &sqlgraph.EdgeSpec{
|
edge := &sqlgraph.EdgeSpec{
|
||||||
Rel: sqlgraph.M2O,
|
Rel: sqlgraph.M2O,
|
||||||
|
@ -231,10 +256,7 @@ func (ac *AttachmentCreate) createSpec() (*Attachment, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{attachment.ItemColumn},
|
Columns: []string{attachment.ItemColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -251,10 +273,7 @@ func (ac *AttachmentCreate) createSpec() (*Attachment, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{attachment.DocumentColumn},
|
Columns: []string{attachment.DocumentColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -290,8 +309,8 @@ func (acb *AttachmentCreateBulk) Save(ctx context.Context) ([]*Attachment, error
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
builder.mutation = mutation
|
builder.mutation = mutation
|
||||||
nodes[i], specs[i] = builder.createSpec()
|
|
||||||
var err error
|
var err error
|
||||||
|
nodes[i], specs[i] = builder.createSpec()
|
||||||
if i < len(mutators)-1 {
|
if i < len(mutators)-1 {
|
||||||
_, err = mutators[i+1].Mutate(root, acb.builders[i+1].mutation)
|
_, err = mutators[i+1].Mutate(root, acb.builders[i+1].mutation)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -27,7 +27,7 @@ func (ad *AttachmentDelete) Where(ps ...predicate.Attachment) *AttachmentDelete
|
||||||
|
|
||||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||||
func (ad *AttachmentDelete) Exec(ctx context.Context) (int, error) {
|
func (ad *AttachmentDelete) Exec(ctx context.Context) (int, error) {
|
||||||
return withHooks[int, AttachmentMutation](ctx, ad.sqlExec, ad.mutation, ad.hooks)
|
return withHooks(ctx, ad.sqlExec, ad.mutation, ad.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecX is like Exec, but panics if an error occurs.
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
type AttachmentQuery struct {
|
type AttachmentQuery struct {
|
||||||
config
|
config
|
||||||
ctx *QueryContext
|
ctx *QueryContext
|
||||||
order []OrderFunc
|
order []attachment.OrderOption
|
||||||
inters []Interceptor
|
inters []Interceptor
|
||||||
predicates []predicate.Attachment
|
predicates []predicate.Attachment
|
||||||
withItem *ItemQuery
|
withItem *ItemQuery
|
||||||
|
@ -58,7 +58,7 @@ func (aq *AttachmentQuery) Unique(unique bool) *AttachmentQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order specifies how the records should be ordered.
|
// Order specifies how the records should be ordered.
|
||||||
func (aq *AttachmentQuery) Order(o ...OrderFunc) *AttachmentQuery {
|
func (aq *AttachmentQuery) Order(o ...attachment.OrderOption) *AttachmentQuery {
|
||||||
aq.order = append(aq.order, o...)
|
aq.order = append(aq.order, o...)
|
||||||
return aq
|
return aq
|
||||||
}
|
}
|
||||||
|
@ -296,7 +296,7 @@ func (aq *AttachmentQuery) Clone() *AttachmentQuery {
|
||||||
return &AttachmentQuery{
|
return &AttachmentQuery{
|
||||||
config: aq.config,
|
config: aq.config,
|
||||||
ctx: aq.ctx.Clone(),
|
ctx: aq.ctx.Clone(),
|
||||||
order: append([]OrderFunc{}, aq.order...),
|
order: append([]attachment.OrderOption{}, aq.order...),
|
||||||
inters: append([]Interceptor{}, aq.inters...),
|
inters: append([]Interceptor{}, aq.inters...),
|
||||||
predicates: append([]predicate.Attachment{}, aq.predicates...),
|
predicates: append([]predicate.Attachment{}, aq.predicates...),
|
||||||
withItem: aq.withItem.Clone(),
|
withItem: aq.withItem.Clone(),
|
||||||
|
|
|
@ -51,6 +51,20 @@ func (au *AttachmentUpdate) SetNillableType(a *attachment.Type) *AttachmentUpdat
|
||||||
return au
|
return au
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPrimary sets the "primary" field.
|
||||||
|
func (au *AttachmentUpdate) SetPrimary(b bool) *AttachmentUpdate {
|
||||||
|
au.mutation.SetPrimary(b)
|
||||||
|
return au
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillablePrimary sets the "primary" field if the given value is not nil.
|
||||||
|
func (au *AttachmentUpdate) SetNillablePrimary(b *bool) *AttachmentUpdate {
|
||||||
|
if b != nil {
|
||||||
|
au.SetPrimary(*b)
|
||||||
|
}
|
||||||
|
return au
|
||||||
|
}
|
||||||
|
|
||||||
// SetItemID sets the "item" edge to the Item entity by ID.
|
// SetItemID sets the "item" edge to the Item entity by ID.
|
||||||
func (au *AttachmentUpdate) SetItemID(id uuid.UUID) *AttachmentUpdate {
|
func (au *AttachmentUpdate) SetItemID(id uuid.UUID) *AttachmentUpdate {
|
||||||
au.mutation.SetItemID(id)
|
au.mutation.SetItemID(id)
|
||||||
|
@ -93,7 +107,7 @@ func (au *AttachmentUpdate) ClearDocument() *AttachmentUpdate {
|
||||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||||
func (au *AttachmentUpdate) Save(ctx context.Context) (int, error) {
|
func (au *AttachmentUpdate) Save(ctx context.Context) (int, error) {
|
||||||
au.defaults()
|
au.defaults()
|
||||||
return withHooks[int, AttachmentMutation](ctx, au.sqlSave, au.mutation, au.hooks)
|
return withHooks(ctx, au.sqlSave, au.mutation, au.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX is like Save, but panics if an error occurs.
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
@ -160,6 +174,9 @@ func (au *AttachmentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
if value, ok := au.mutation.GetType(); ok {
|
if value, ok := au.mutation.GetType(); ok {
|
||||||
_spec.SetField(attachment.FieldType, field.TypeEnum, value)
|
_spec.SetField(attachment.FieldType, field.TypeEnum, value)
|
||||||
}
|
}
|
||||||
|
if value, ok := au.mutation.Primary(); ok {
|
||||||
|
_spec.SetField(attachment.FieldPrimary, field.TypeBool, value)
|
||||||
|
}
|
||||||
if au.mutation.ItemCleared() {
|
if au.mutation.ItemCleared() {
|
||||||
edge := &sqlgraph.EdgeSpec{
|
edge := &sqlgraph.EdgeSpec{
|
||||||
Rel: sqlgraph.M2O,
|
Rel: sqlgraph.M2O,
|
||||||
|
@ -168,10 +185,7 @@ func (au *AttachmentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{attachment.ItemColumn},
|
Columns: []string{attachment.ItemColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -184,10 +198,7 @@ func (au *AttachmentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{attachment.ItemColumn},
|
Columns: []string{attachment.ItemColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -203,10 +214,7 @@ func (au *AttachmentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{attachment.DocumentColumn},
|
Columns: []string{attachment.DocumentColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -219,10 +227,7 @@ func (au *AttachmentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{attachment.DocumentColumn},
|
Columns: []string{attachment.DocumentColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -270,6 +275,20 @@ func (auo *AttachmentUpdateOne) SetNillableType(a *attachment.Type) *AttachmentU
|
||||||
return auo
|
return auo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPrimary sets the "primary" field.
|
||||||
|
func (auo *AttachmentUpdateOne) SetPrimary(b bool) *AttachmentUpdateOne {
|
||||||
|
auo.mutation.SetPrimary(b)
|
||||||
|
return auo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillablePrimary sets the "primary" field if the given value is not nil.
|
||||||
|
func (auo *AttachmentUpdateOne) SetNillablePrimary(b *bool) *AttachmentUpdateOne {
|
||||||
|
if b != nil {
|
||||||
|
auo.SetPrimary(*b)
|
||||||
|
}
|
||||||
|
return auo
|
||||||
|
}
|
||||||
|
|
||||||
// SetItemID sets the "item" edge to the Item entity by ID.
|
// SetItemID sets the "item" edge to the Item entity by ID.
|
||||||
func (auo *AttachmentUpdateOne) SetItemID(id uuid.UUID) *AttachmentUpdateOne {
|
func (auo *AttachmentUpdateOne) SetItemID(id uuid.UUID) *AttachmentUpdateOne {
|
||||||
auo.mutation.SetItemID(id)
|
auo.mutation.SetItemID(id)
|
||||||
|
@ -325,7 +344,7 @@ func (auo *AttachmentUpdateOne) Select(field string, fields ...string) *Attachme
|
||||||
// Save executes the query and returns the updated Attachment entity.
|
// Save executes the query and returns the updated Attachment entity.
|
||||||
func (auo *AttachmentUpdateOne) Save(ctx context.Context) (*Attachment, error) {
|
func (auo *AttachmentUpdateOne) Save(ctx context.Context) (*Attachment, error) {
|
||||||
auo.defaults()
|
auo.defaults()
|
||||||
return withHooks[*Attachment, AttachmentMutation](ctx, auo.sqlSave, auo.mutation, auo.hooks)
|
return withHooks(ctx, auo.sqlSave, auo.mutation, auo.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX is like Save, but panics if an error occurs.
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
@ -409,6 +428,9 @@ func (auo *AttachmentUpdateOne) sqlSave(ctx context.Context) (_node *Attachment,
|
||||||
if value, ok := auo.mutation.GetType(); ok {
|
if value, ok := auo.mutation.GetType(); ok {
|
||||||
_spec.SetField(attachment.FieldType, field.TypeEnum, value)
|
_spec.SetField(attachment.FieldType, field.TypeEnum, value)
|
||||||
}
|
}
|
||||||
|
if value, ok := auo.mutation.Primary(); ok {
|
||||||
|
_spec.SetField(attachment.FieldPrimary, field.TypeBool, value)
|
||||||
|
}
|
||||||
if auo.mutation.ItemCleared() {
|
if auo.mutation.ItemCleared() {
|
||||||
edge := &sqlgraph.EdgeSpec{
|
edge := &sqlgraph.EdgeSpec{
|
||||||
Rel: sqlgraph.M2O,
|
Rel: sqlgraph.M2O,
|
||||||
|
@ -417,10 +439,7 @@ func (auo *AttachmentUpdateOne) sqlSave(ctx context.Context) (_node *Attachment,
|
||||||
Columns: []string{attachment.ItemColumn},
|
Columns: []string{attachment.ItemColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -433,10 +452,7 @@ func (auo *AttachmentUpdateOne) sqlSave(ctx context.Context) (_node *Attachment,
|
||||||
Columns: []string{attachment.ItemColumn},
|
Columns: []string{attachment.ItemColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -452,10 +468,7 @@ func (auo *AttachmentUpdateOne) sqlSave(ctx context.Context) (_node *Attachment,
|
||||||
Columns: []string{attachment.DocumentColumn},
|
Columns: []string{attachment.DocumentColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -468,10 +481,7 @@ func (auo *AttachmentUpdateOne) sqlSave(ctx context.Context) (_node *Attachment,
|
||||||
Columns: []string{attachment.DocumentColumn},
|
Columns: []string{attachment.DocumentColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"entgo.io/ent"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||||
|
@ -23,6 +24,7 @@ type AuthRoles struct {
|
||||||
// The values are being populated by the AuthRolesQuery when eager-loading is set.
|
// The values are being populated by the AuthRolesQuery when eager-loading is set.
|
||||||
Edges AuthRolesEdges `json:"edges"`
|
Edges AuthRolesEdges `json:"edges"`
|
||||||
auth_tokens_roles *uuid.UUID
|
auth_tokens_roles *uuid.UUID
|
||||||
|
selectValues sql.SelectValues
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthRolesEdges holds the relations/edges for other nodes in the graph.
|
// AuthRolesEdges holds the relations/edges for other nodes in the graph.
|
||||||
|
@ -59,7 +61,7 @@ func (*AuthRoles) scanValues(columns []string) ([]any, error) {
|
||||||
case authroles.ForeignKeys[0]: // auth_tokens_roles
|
case authroles.ForeignKeys[0]: // auth_tokens_roles
|
||||||
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected column %q for type AuthRoles", columns[i])
|
values[i] = new(sql.UnknownType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values, nil
|
return values, nil
|
||||||
|
@ -92,11 +94,19 @@ func (ar *AuthRoles) assignValues(columns []string, values []any) error {
|
||||||
ar.auth_tokens_roles = new(uuid.UUID)
|
ar.auth_tokens_roles = new(uuid.UUID)
|
||||||
*ar.auth_tokens_roles = *value.S.(*uuid.UUID)
|
*ar.auth_tokens_roles = *value.S.(*uuid.UUID)
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
ar.selectValues.Set(columns[i], values[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Value returns the ent.Value that was dynamically selected and assigned to the AuthRoles.
|
||||||
|
// This includes values selected through modifiers, order, etc.
|
||||||
|
func (ar *AuthRoles) Value(name string) (ent.Value, error) {
|
||||||
|
return ar.selectValues.Get(name)
|
||||||
|
}
|
||||||
|
|
||||||
// QueryToken queries the "token" edge of the AuthRoles entity.
|
// QueryToken queries the "token" edge of the AuthRoles entity.
|
||||||
func (ar *AuthRoles) QueryToken() *AuthTokensQuery {
|
func (ar *AuthRoles) QueryToken() *AuthTokensQuery {
|
||||||
return NewAuthRolesClient(ar.config).QueryToken(ar)
|
return NewAuthRolesClient(ar.config).QueryToken(ar)
|
||||||
|
|
|
@ -4,6 +4,9 @@ package authroles
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -79,3 +82,30 @@ func RoleValidator(r Role) error {
|
||||||
return fmt.Errorf("authroles: invalid enum value for role field: %q", r)
|
return fmt.Errorf("authroles: invalid enum value for role field: %q", r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OrderOption defines the ordering options for the AuthRoles queries.
|
||||||
|
type OrderOption func(*sql.Selector)
|
||||||
|
|
||||||
|
// ByID orders the results by the id field.
|
||||||
|
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByRole orders the results by the role field.
|
||||||
|
func ByRole(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldRole, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByTokenField orders the results by token field.
|
||||||
|
func ByTokenField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newTokenStep(), sql.OrderByField(field, opts...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func newTokenStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(TokenInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2O, true, TokenTable, TokenColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -87,11 +87,7 @@ func HasToken() predicate.AuthRoles {
|
||||||
// HasTokenWith applies the HasEdge predicate on the "token" edge with a given conditions (other predicates).
|
// HasTokenWith applies the HasEdge predicate on the "token" edge with a given conditions (other predicates).
|
||||||
func HasTokenWith(preds ...predicate.AuthTokens) predicate.AuthRoles {
|
func HasTokenWith(preds ...predicate.AuthTokens) predicate.AuthRoles {
|
||||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newTokenStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(TokenInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.O2O, true, TokenTable, TokenColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
|
|
@ -62,7 +62,7 @@ func (arc *AuthRolesCreate) Mutation() *AuthRolesMutation {
|
||||||
// Save creates the AuthRoles in the database.
|
// Save creates the AuthRoles in the database.
|
||||||
func (arc *AuthRolesCreate) Save(ctx context.Context) (*AuthRoles, error) {
|
func (arc *AuthRolesCreate) Save(ctx context.Context) (*AuthRoles, error) {
|
||||||
arc.defaults()
|
arc.defaults()
|
||||||
return withHooks[*AuthRoles, AuthRolesMutation](ctx, arc.sqlSave, arc.mutation, arc.hooks)
|
return withHooks(ctx, arc.sqlSave, arc.mutation, arc.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX calls Save and panics if Save returns an error.
|
// SaveX calls Save and panics if Save returns an error.
|
||||||
|
@ -143,10 +143,7 @@ func (arc *AuthRolesCreate) createSpec() (*AuthRoles, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{authroles.TokenColumn},
|
Columns: []string{authroles.TokenColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(authtokens.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: authtokens.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -182,8 +179,8 @@ func (arcb *AuthRolesCreateBulk) Save(ctx context.Context) ([]*AuthRoles, error)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
builder.mutation = mutation
|
builder.mutation = mutation
|
||||||
nodes[i], specs[i] = builder.createSpec()
|
|
||||||
var err error
|
var err error
|
||||||
|
nodes[i], specs[i] = builder.createSpec()
|
||||||
if i < len(mutators)-1 {
|
if i < len(mutators)-1 {
|
||||||
_, err = mutators[i+1].Mutate(root, arcb.builders[i+1].mutation)
|
_, err = mutators[i+1].Mutate(root, arcb.builders[i+1].mutation)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -27,7 +27,7 @@ func (ard *AuthRolesDelete) Where(ps ...predicate.AuthRoles) *AuthRolesDelete {
|
||||||
|
|
||||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||||
func (ard *AuthRolesDelete) Exec(ctx context.Context) (int, error) {
|
func (ard *AuthRolesDelete) Exec(ctx context.Context) (int, error) {
|
||||||
return withHooks[int, AuthRolesMutation](ctx, ard.sqlExec, ard.mutation, ard.hooks)
|
return withHooks(ctx, ard.sqlExec, ard.mutation, ard.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecX is like Exec, but panics if an error occurs.
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
type AuthRolesQuery struct {
|
type AuthRolesQuery struct {
|
||||||
config
|
config
|
||||||
ctx *QueryContext
|
ctx *QueryContext
|
||||||
order []OrderFunc
|
order []authroles.OrderOption
|
||||||
inters []Interceptor
|
inters []Interceptor
|
||||||
predicates []predicate.AuthRoles
|
predicates []predicate.AuthRoles
|
||||||
withToken *AuthTokensQuery
|
withToken *AuthTokensQuery
|
||||||
|
@ -56,7 +56,7 @@ func (arq *AuthRolesQuery) Unique(unique bool) *AuthRolesQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order specifies how the records should be ordered.
|
// Order specifies how the records should be ordered.
|
||||||
func (arq *AuthRolesQuery) Order(o ...OrderFunc) *AuthRolesQuery {
|
func (arq *AuthRolesQuery) Order(o ...authroles.OrderOption) *AuthRolesQuery {
|
||||||
arq.order = append(arq.order, o...)
|
arq.order = append(arq.order, o...)
|
||||||
return arq
|
return arq
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,7 @@ func (arq *AuthRolesQuery) Clone() *AuthRolesQuery {
|
||||||
return &AuthRolesQuery{
|
return &AuthRolesQuery{
|
||||||
config: arq.config,
|
config: arq.config,
|
||||||
ctx: arq.ctx.Clone(),
|
ctx: arq.ctx.Clone(),
|
||||||
order: append([]OrderFunc{}, arq.order...),
|
order: append([]authroles.OrderOption{}, arq.order...),
|
||||||
inters: append([]Interceptor{}, arq.inters...),
|
inters: append([]Interceptor{}, arq.inters...),
|
||||||
predicates: append([]predicate.AuthRoles{}, arq.predicates...),
|
predicates: append([]predicate.AuthRoles{}, arq.predicates...),
|
||||||
withToken: arq.withToken.Clone(),
|
withToken: arq.withToken.Clone(),
|
||||||
|
|
|
@ -75,7 +75,7 @@ func (aru *AuthRolesUpdate) ClearToken() *AuthRolesUpdate {
|
||||||
|
|
||||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||||
func (aru *AuthRolesUpdate) Save(ctx context.Context) (int, error) {
|
func (aru *AuthRolesUpdate) Save(ctx context.Context) (int, error) {
|
||||||
return withHooks[int, AuthRolesMutation](ctx, aru.sqlSave, aru.mutation, aru.hooks)
|
return withHooks(ctx, aru.sqlSave, aru.mutation, aru.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX is like Save, but panics if an error occurs.
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
@ -133,10 +133,7 @@ func (aru *AuthRolesUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{authroles.TokenColumn},
|
Columns: []string{authroles.TokenColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(authtokens.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: authtokens.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -149,10 +146,7 @@ func (aru *AuthRolesUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{authroles.TokenColumn},
|
Columns: []string{authroles.TokenColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(authtokens.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: authtokens.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -239,7 +233,7 @@ func (aruo *AuthRolesUpdateOne) Select(field string, fields ...string) *AuthRole
|
||||||
|
|
||||||
// Save executes the query and returns the updated AuthRoles entity.
|
// Save executes the query and returns the updated AuthRoles entity.
|
||||||
func (aruo *AuthRolesUpdateOne) Save(ctx context.Context) (*AuthRoles, error) {
|
func (aruo *AuthRolesUpdateOne) Save(ctx context.Context) (*AuthRoles, error) {
|
||||||
return withHooks[*AuthRoles, AuthRolesMutation](ctx, aruo.sqlSave, aruo.mutation, aruo.hooks)
|
return withHooks(ctx, aruo.sqlSave, aruo.mutation, aruo.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX is like Save, but panics if an error occurs.
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
@ -314,10 +308,7 @@ func (aruo *AuthRolesUpdateOne) sqlSave(ctx context.Context) (_node *AuthRoles,
|
||||||
Columns: []string{authroles.TokenColumn},
|
Columns: []string{authroles.TokenColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(authtokens.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: authtokens.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -330,10 +321,7 @@ func (aruo *AuthRolesUpdateOne) sqlSave(ctx context.Context) (_node *AuthRoles,
|
||||||
Columns: []string{authroles.TokenColumn},
|
Columns: []string{authroles.TokenColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(authtokens.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: authtokens.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||||
|
@ -31,6 +32,7 @@ type AuthTokens struct {
|
||||||
// The values are being populated by the AuthTokensQuery when eager-loading is set.
|
// The values are being populated by the AuthTokensQuery when eager-loading is set.
|
||||||
Edges AuthTokensEdges `json:"edges"`
|
Edges AuthTokensEdges `json:"edges"`
|
||||||
user_auth_tokens *uuid.UUID
|
user_auth_tokens *uuid.UUID
|
||||||
|
selectValues sql.SelectValues
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthTokensEdges holds the relations/edges for other nodes in the graph.
|
// AuthTokensEdges holds the relations/edges for other nodes in the graph.
|
||||||
|
@ -84,7 +86,7 @@ func (*AuthTokens) scanValues(columns []string) ([]any, error) {
|
||||||
case authtokens.ForeignKeys[0]: // user_auth_tokens
|
case authtokens.ForeignKeys[0]: // user_auth_tokens
|
||||||
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected column %q for type AuthTokens", columns[i])
|
values[i] = new(sql.UnknownType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values, nil
|
return values, nil
|
||||||
|
@ -135,11 +137,19 @@ func (at *AuthTokens) assignValues(columns []string, values []any) error {
|
||||||
at.user_auth_tokens = new(uuid.UUID)
|
at.user_auth_tokens = new(uuid.UUID)
|
||||||
*at.user_auth_tokens = *value.S.(*uuid.UUID)
|
*at.user_auth_tokens = *value.S.(*uuid.UUID)
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
at.selectValues.Set(columns[i], values[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Value returns the ent.Value that was dynamically selected and assigned to the AuthTokens.
|
||||||
|
// This includes values selected through modifiers, order, etc.
|
||||||
|
func (at *AuthTokens) Value(name string) (ent.Value, error) {
|
||||||
|
return at.selectValues.Get(name)
|
||||||
|
}
|
||||||
|
|
||||||
// QueryUser queries the "user" edge of the AuthTokens entity.
|
// QueryUser queries the "user" edge of the AuthTokens entity.
|
||||||
func (at *AuthTokens) QueryUser() *UserQuery {
|
func (at *AuthTokens) QueryUser() *UserQuery {
|
||||||
return NewAuthTokensClient(at.config).QueryUser(at)
|
return NewAuthTokensClient(at.config).QueryUser(at)
|
||||||
|
|
|
@ -5,6 +5,8 @@ package authtokens
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -85,3 +87,54 @@ var (
|
||||||
// DefaultID holds the default value on creation for the "id" field.
|
// DefaultID holds the default value on creation for the "id" field.
|
||||||
DefaultID func() uuid.UUID
|
DefaultID func() uuid.UUID
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// OrderOption defines the ordering options for the AuthTokens queries.
|
||||||
|
type OrderOption func(*sql.Selector)
|
||||||
|
|
||||||
|
// ByID orders the results by the id field.
|
||||||
|
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByCreatedAt orders the results by the created_at field.
|
||||||
|
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUpdatedAt orders the results by the updated_at field.
|
||||||
|
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByExpiresAt orders the results by the expires_at field.
|
||||||
|
func ByExpiresAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldExpiresAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUserField orders the results by user field.
|
||||||
|
func ByUserField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newUserStep(), sql.OrderByField(field, opts...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByRolesField orders the results by roles field.
|
||||||
|
func ByRolesField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newRolesStep(), sql.OrderByField(field, opts...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func newUserStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(UserInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func newRolesStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(RolesInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2O, false, RolesTable, RolesColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -250,11 +250,7 @@ func HasUser() predicate.AuthTokens {
|
||||||
// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates).
|
// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates).
|
||||||
func HasUserWith(preds ...predicate.User) predicate.AuthTokens {
|
func HasUserWith(preds ...predicate.User) predicate.AuthTokens {
|
||||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newUserStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(UserInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
@ -277,11 +273,7 @@ func HasRoles() predicate.AuthTokens {
|
||||||
// HasRolesWith applies the HasEdge predicate on the "roles" edge with a given conditions (other predicates).
|
// HasRolesWith applies the HasEdge predicate on the "roles" edge with a given conditions (other predicates).
|
||||||
func HasRolesWith(preds ...predicate.AuthRoles) predicate.AuthTokens {
|
func HasRolesWith(preds ...predicate.AuthRoles) predicate.AuthTokens {
|
||||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newRolesStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(RolesInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.O2O, false, RolesTable, RolesColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
|
|
@ -131,7 +131,7 @@ func (atc *AuthTokensCreate) Mutation() *AuthTokensMutation {
|
||||||
// Save creates the AuthTokens in the database.
|
// Save creates the AuthTokens in the database.
|
||||||
func (atc *AuthTokensCreate) Save(ctx context.Context) (*AuthTokens, error) {
|
func (atc *AuthTokensCreate) Save(ctx context.Context) (*AuthTokens, error) {
|
||||||
atc.defaults()
|
atc.defaults()
|
||||||
return withHooks[*AuthTokens, AuthTokensMutation](ctx, atc.sqlSave, atc.mutation, atc.hooks)
|
return withHooks(ctx, atc.sqlSave, atc.mutation, atc.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX calls Save and panics if Save returns an error.
|
// SaveX calls Save and panics if Save returns an error.
|
||||||
|
@ -249,10 +249,7 @@ func (atc *AuthTokensCreate) createSpec() (*AuthTokens, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{authtokens.UserColumn},
|
Columns: []string{authtokens.UserColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -269,10 +266,7 @@ func (atc *AuthTokensCreate) createSpec() (*AuthTokens, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{authtokens.RolesColumn},
|
Columns: []string{authtokens.RolesColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(authroles.FieldID, field.TypeInt),
|
||||||
Type: field.TypeInt,
|
|
||||||
Column: authroles.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -307,8 +301,8 @@ func (atcb *AuthTokensCreateBulk) Save(ctx context.Context) ([]*AuthTokens, erro
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
builder.mutation = mutation
|
builder.mutation = mutation
|
||||||
nodes[i], specs[i] = builder.createSpec()
|
|
||||||
var err error
|
var err error
|
||||||
|
nodes[i], specs[i] = builder.createSpec()
|
||||||
if i < len(mutators)-1 {
|
if i < len(mutators)-1 {
|
||||||
_, err = mutators[i+1].Mutate(root, atcb.builders[i+1].mutation)
|
_, err = mutators[i+1].Mutate(root, atcb.builders[i+1].mutation)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -27,7 +27,7 @@ func (atd *AuthTokensDelete) Where(ps ...predicate.AuthTokens) *AuthTokensDelete
|
||||||
|
|
||||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||||
func (atd *AuthTokensDelete) Exec(ctx context.Context) (int, error) {
|
func (atd *AuthTokensDelete) Exec(ctx context.Context) (int, error) {
|
||||||
return withHooks[int, AuthTokensMutation](ctx, atd.sqlExec, atd.mutation, atd.hooks)
|
return withHooks(ctx, atd.sqlExec, atd.mutation, atd.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecX is like Exec, but panics if an error occurs.
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
|
|
@ -22,7 +22,7 @@ import (
|
||||||
type AuthTokensQuery struct {
|
type AuthTokensQuery struct {
|
||||||
config
|
config
|
||||||
ctx *QueryContext
|
ctx *QueryContext
|
||||||
order []OrderFunc
|
order []authtokens.OrderOption
|
||||||
inters []Interceptor
|
inters []Interceptor
|
||||||
predicates []predicate.AuthTokens
|
predicates []predicate.AuthTokens
|
||||||
withUser *UserQuery
|
withUser *UserQuery
|
||||||
|
@ -59,7 +59,7 @@ func (atq *AuthTokensQuery) Unique(unique bool) *AuthTokensQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order specifies how the records should be ordered.
|
// Order specifies how the records should be ordered.
|
||||||
func (atq *AuthTokensQuery) Order(o ...OrderFunc) *AuthTokensQuery {
|
func (atq *AuthTokensQuery) Order(o ...authtokens.OrderOption) *AuthTokensQuery {
|
||||||
atq.order = append(atq.order, o...)
|
atq.order = append(atq.order, o...)
|
||||||
return atq
|
return atq
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ func (atq *AuthTokensQuery) Clone() *AuthTokensQuery {
|
||||||
return &AuthTokensQuery{
|
return &AuthTokensQuery{
|
||||||
config: atq.config,
|
config: atq.config,
|
||||||
ctx: atq.ctx.Clone(),
|
ctx: atq.ctx.Clone(),
|
||||||
order: append([]OrderFunc{}, atq.order...),
|
order: append([]authtokens.OrderOption{}, atq.order...),
|
||||||
inters: append([]Interceptor{}, atq.inters...),
|
inters: append([]Interceptor{}, atq.inters...),
|
||||||
predicates: append([]predicate.AuthTokens{}, atq.predicates...),
|
predicates: append([]predicate.AuthTokens{}, atq.predicates...),
|
||||||
withUser: atq.withUser.Clone(),
|
withUser: atq.withUser.Clone(),
|
||||||
|
@ -494,7 +494,7 @@ func (atq *AuthTokensQuery) loadRoles(ctx context.Context, query *AuthRolesQuery
|
||||||
}
|
}
|
||||||
query.withFKs = true
|
query.withFKs = true
|
||||||
query.Where(predicate.AuthRoles(func(s *sql.Selector) {
|
query.Where(predicate.AuthRoles(func(s *sql.Selector) {
|
||||||
s.Where(sql.InValues(authtokens.RolesColumn, fks...))
|
s.Where(sql.InValues(s.C(authtokens.RolesColumn), fks...))
|
||||||
}))
|
}))
|
||||||
neighbors, err := query.All(ctx)
|
neighbors, err := query.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -507,7 +507,7 @@ func (atq *AuthTokensQuery) loadRoles(ctx context.Context, query *AuthRolesQuery
|
||||||
}
|
}
|
||||||
node, ok := nodeids[*fk]
|
node, ok := nodeids[*fk]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf(`unexpected foreign-key "auth_tokens_roles" returned %v for node %v`, *fk, n.ID)
|
return fmt.Errorf(`unexpected referenced foreign-key "auth_tokens_roles" returned %v for node %v`, *fk, n.ID)
|
||||||
}
|
}
|
||||||
assign(node, n)
|
assign(node, n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ func (atu *AuthTokensUpdate) ClearRoles() *AuthTokensUpdate {
|
||||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||||
func (atu *AuthTokensUpdate) Save(ctx context.Context) (int, error) {
|
func (atu *AuthTokensUpdate) Save(ctx context.Context) (int, error) {
|
||||||
atu.defaults()
|
atu.defaults()
|
||||||
return withHooks[int, AuthTokensMutation](ctx, atu.sqlSave, atu.mutation, atu.hooks)
|
return withHooks(ctx, atu.sqlSave, atu.mutation, atu.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX is like Save, but panics if an error occurs.
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
@ -174,10 +174,7 @@ func (atu *AuthTokensUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{authtokens.UserColumn},
|
Columns: []string{authtokens.UserColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -190,10 +187,7 @@ func (atu *AuthTokensUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{authtokens.UserColumn},
|
Columns: []string{authtokens.UserColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -209,10 +203,7 @@ func (atu *AuthTokensUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{authtokens.RolesColumn},
|
Columns: []string{authtokens.RolesColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(authroles.FieldID, field.TypeInt),
|
||||||
Type: field.TypeInt,
|
|
||||||
Column: authroles.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -225,10 +216,7 @@ func (atu *AuthTokensUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{authtokens.RolesColumn},
|
Columns: []string{authtokens.RolesColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(authroles.FieldID, field.TypeInt),
|
||||||
Type: field.TypeInt,
|
|
||||||
Column: authroles.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -353,7 +341,7 @@ func (atuo *AuthTokensUpdateOne) Select(field string, fields ...string) *AuthTok
|
||||||
// Save executes the query and returns the updated AuthTokens entity.
|
// Save executes the query and returns the updated AuthTokens entity.
|
||||||
func (atuo *AuthTokensUpdateOne) Save(ctx context.Context) (*AuthTokens, error) {
|
func (atuo *AuthTokensUpdateOne) Save(ctx context.Context) (*AuthTokens, error) {
|
||||||
atuo.defaults()
|
atuo.defaults()
|
||||||
return withHooks[*AuthTokens, AuthTokensMutation](ctx, atuo.sqlSave, atuo.mutation, atuo.hooks)
|
return withHooks(ctx, atuo.sqlSave, atuo.mutation, atuo.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX is like Save, but panics if an error occurs.
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
@ -429,10 +417,7 @@ func (atuo *AuthTokensUpdateOne) sqlSave(ctx context.Context) (_node *AuthTokens
|
||||||
Columns: []string{authtokens.UserColumn},
|
Columns: []string{authtokens.UserColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -445,10 +430,7 @@ func (atuo *AuthTokensUpdateOne) sqlSave(ctx context.Context) (_node *AuthTokens
|
||||||
Columns: []string{authtokens.UserColumn},
|
Columns: []string{authtokens.UserColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -464,10 +446,7 @@ func (atuo *AuthTokensUpdateOne) sqlSave(ctx context.Context) (_node *AuthTokens
|
||||||
Columns: []string{authtokens.RolesColumn},
|
Columns: []string{authtokens.RolesColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(authroles.FieldID, field.TypeInt),
|
||||||
Type: field.TypeInt,
|
|
||||||
Column: authroles.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -480,10 +459,7 @@ func (atuo *AuthTokensUpdateOne) sqlSave(ctx context.Context) (_node *AuthTokens
|
||||||
Columns: []string{authtokens.RolesColumn},
|
Columns: []string{authtokens.RolesColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(authroles.FieldID, field.TypeInt),
|
||||||
Type: field.TypeInt,
|
|
||||||
Column: authroles.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
|
|
@ -11,6 +11,10 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/migrate"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/migrate"
|
||||||
|
|
||||||
|
"entgo.io/ent"
|
||||||
|
"entgo.io/ent/dialect"
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||||
|
@ -22,11 +26,8 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||||
|
|
||||||
"entgo.io/ent/dialect"
|
|
||||||
"entgo.io/ent/dialect/sql"
|
|
||||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client is the client that holds all ent builders.
|
// Client is the client that holds all ent builders.
|
||||||
|
@ -56,6 +57,8 @@ type Client struct {
|
||||||
Location *LocationClient
|
Location *LocationClient
|
||||||
// MaintenanceEntry is the client for interacting with the MaintenanceEntry builders.
|
// MaintenanceEntry is the client for interacting with the MaintenanceEntry builders.
|
||||||
MaintenanceEntry *MaintenanceEntryClient
|
MaintenanceEntry *MaintenanceEntryClient
|
||||||
|
// Notifier is the client for interacting with the Notifier builders.
|
||||||
|
Notifier *NotifierClient
|
||||||
// User is the client for interacting with the User builders.
|
// User is the client for interacting with the User builders.
|
||||||
User *UserClient
|
User *UserClient
|
||||||
}
|
}
|
||||||
|
@ -82,9 +85,59 @@ func (c *Client) init() {
|
||||||
c.Label = NewLabelClient(c.config)
|
c.Label = NewLabelClient(c.config)
|
||||||
c.Location = NewLocationClient(c.config)
|
c.Location = NewLocationClient(c.config)
|
||||||
c.MaintenanceEntry = NewMaintenanceEntryClient(c.config)
|
c.MaintenanceEntry = NewMaintenanceEntryClient(c.config)
|
||||||
|
c.Notifier = NewNotifierClient(c.config)
|
||||||
c.User = NewUserClient(c.config)
|
c.User = NewUserClient(c.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
// config is the configuration for the client and its builder.
|
||||||
|
config struct {
|
||||||
|
// driver used for executing database requests.
|
||||||
|
driver dialect.Driver
|
||||||
|
// debug enable a debug logging.
|
||||||
|
debug bool
|
||||||
|
// log used for logging on debug mode.
|
||||||
|
log func(...any)
|
||||||
|
// hooks to execute on mutations.
|
||||||
|
hooks *hooks
|
||||||
|
// interceptors to execute on queries.
|
||||||
|
inters *inters
|
||||||
|
}
|
||||||
|
// Option function to configure the client.
|
||||||
|
Option func(*config)
|
||||||
|
)
|
||||||
|
|
||||||
|
// options applies the options on the config object.
|
||||||
|
func (c *config) options(opts ...Option) {
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(c)
|
||||||
|
}
|
||||||
|
if c.debug {
|
||||||
|
c.driver = dialect.Debug(c.driver, c.log)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug enables debug logging on the ent.Driver.
|
||||||
|
func Debug() Option {
|
||||||
|
return func(c *config) {
|
||||||
|
c.debug = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log sets the logging function for debug mode.
|
||||||
|
func Log(fn func(...any)) Option {
|
||||||
|
return func(c *config) {
|
||||||
|
c.log = fn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Driver configures the client driver.
|
||||||
|
func Driver(driver dialect.Driver) Option {
|
||||||
|
return func(c *config) {
|
||||||
|
c.driver = driver
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Open opens a database/sql.DB specified by the driver name and
|
// Open opens a database/sql.DB specified by the driver name and
|
||||||
// the data source name, and returns a new client attached to it.
|
// the data source name, and returns a new client attached to it.
|
||||||
// Optional parameters can be added for configuring the client.
|
// Optional parameters can be added for configuring the client.
|
||||||
|
@ -127,6 +180,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
|
||||||
Label: NewLabelClient(cfg),
|
Label: NewLabelClient(cfg),
|
||||||
Location: NewLocationClient(cfg),
|
Location: NewLocationClient(cfg),
|
||||||
MaintenanceEntry: NewMaintenanceEntryClient(cfg),
|
MaintenanceEntry: NewMaintenanceEntryClient(cfg),
|
||||||
|
Notifier: NewNotifierClient(cfg),
|
||||||
User: NewUserClient(cfg),
|
User: NewUserClient(cfg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -158,6 +212,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
|
||||||
Label: NewLabelClient(cfg),
|
Label: NewLabelClient(cfg),
|
||||||
Location: NewLocationClient(cfg),
|
Location: NewLocationClient(cfg),
|
||||||
MaintenanceEntry: NewMaintenanceEntryClient(cfg),
|
MaintenanceEntry: NewMaintenanceEntryClient(cfg),
|
||||||
|
Notifier: NewNotifierClient(cfg),
|
||||||
User: NewUserClient(cfg),
|
User: NewUserClient(cfg),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -187,35 +242,25 @@ func (c *Client) Close() error {
|
||||||
// Use adds the mutation hooks to all the entity clients.
|
// Use adds the mutation hooks to all the entity clients.
|
||||||
// In order to add hooks to a specific client, call: `client.Node.Use(...)`.
|
// In order to add hooks to a specific client, call: `client.Node.Use(...)`.
|
||||||
func (c *Client) Use(hooks ...Hook) {
|
func (c *Client) Use(hooks ...Hook) {
|
||||||
c.Attachment.Use(hooks...)
|
for _, n := range []interface{ Use(...Hook) }{
|
||||||
c.AuthRoles.Use(hooks...)
|
c.Attachment, c.AuthRoles, c.AuthTokens, c.Document, c.Group,
|
||||||
c.AuthTokens.Use(hooks...)
|
c.GroupInvitationToken, c.Item, c.ItemField, c.Label, c.Location,
|
||||||
c.Document.Use(hooks...)
|
c.MaintenanceEntry, c.Notifier, c.User,
|
||||||
c.Group.Use(hooks...)
|
} {
|
||||||
c.GroupInvitationToken.Use(hooks...)
|
n.Use(hooks...)
|
||||||
c.Item.Use(hooks...)
|
}
|
||||||
c.ItemField.Use(hooks...)
|
|
||||||
c.Label.Use(hooks...)
|
|
||||||
c.Location.Use(hooks...)
|
|
||||||
c.MaintenanceEntry.Use(hooks...)
|
|
||||||
c.User.Use(hooks...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intercept adds the query interceptors to all the entity clients.
|
// Intercept adds the query interceptors to all the entity clients.
|
||||||
// In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`.
|
// In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`.
|
||||||
func (c *Client) Intercept(interceptors ...Interceptor) {
|
func (c *Client) Intercept(interceptors ...Interceptor) {
|
||||||
c.Attachment.Intercept(interceptors...)
|
for _, n := range []interface{ Intercept(...Interceptor) }{
|
||||||
c.AuthRoles.Intercept(interceptors...)
|
c.Attachment, c.AuthRoles, c.AuthTokens, c.Document, c.Group,
|
||||||
c.AuthTokens.Intercept(interceptors...)
|
c.GroupInvitationToken, c.Item, c.ItemField, c.Label, c.Location,
|
||||||
c.Document.Intercept(interceptors...)
|
c.MaintenanceEntry, c.Notifier, c.User,
|
||||||
c.Group.Intercept(interceptors...)
|
} {
|
||||||
c.GroupInvitationToken.Intercept(interceptors...)
|
n.Intercept(interceptors...)
|
||||||
c.Item.Intercept(interceptors...)
|
}
|
||||||
c.ItemField.Intercept(interceptors...)
|
|
||||||
c.Label.Intercept(interceptors...)
|
|
||||||
c.Location.Intercept(interceptors...)
|
|
||||||
c.MaintenanceEntry.Intercept(interceptors...)
|
|
||||||
c.User.Intercept(interceptors...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mutate implements the ent.Mutator interface.
|
// Mutate implements the ent.Mutator interface.
|
||||||
|
@ -243,6 +288,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
|
||||||
return c.Location.mutate(ctx, m)
|
return c.Location.mutate(ctx, m)
|
||||||
case *MaintenanceEntryMutation:
|
case *MaintenanceEntryMutation:
|
||||||
return c.MaintenanceEntry.mutate(ctx, m)
|
return c.MaintenanceEntry.mutate(ctx, m)
|
||||||
|
case *NotifierMutation:
|
||||||
|
return c.Notifier.mutate(ctx, m)
|
||||||
case *UserMutation:
|
case *UserMutation:
|
||||||
return c.User.mutate(ctx, m)
|
return c.User.mutate(ctx, m)
|
||||||
default:
|
default:
|
||||||
|
@ -1023,6 +1070,22 @@ func (c *GroupClient) QueryInvitationTokens(gr *Group) *GroupInvitationTokenQuer
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryNotifiers queries the notifiers edge of a Group.
|
||||||
|
func (c *GroupClient) QueryNotifiers(gr *Group) *NotifierQuery {
|
||||||
|
query := (&NotifierClient{config: c.config}).Query()
|
||||||
|
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||||
|
id := gr.ID
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(group.Table, group.FieldID, id),
|
||||||
|
sqlgraph.To(notifier.Table, notifier.FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, group.NotifiersTable, group.NotifiersColumn),
|
||||||
|
)
|
||||||
|
fromV = sqlgraph.Neighbors(gr.driver.Dialect(), step)
|
||||||
|
return fromV, nil
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
// Hooks returns the client hooks.
|
// Hooks returns the client hooks.
|
||||||
func (c *GroupClient) Hooks() []Hook {
|
func (c *GroupClient) Hooks() []Hook {
|
||||||
return c.hooks.Group
|
return c.hooks.Group
|
||||||
|
@ -1275,6 +1338,22 @@ func (c *ItemClient) GetX(ctx context.Context, id uuid.UUID) *Item {
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryGroup queries the group edge of a Item.
|
||||||
|
func (c *ItemClient) QueryGroup(i *Item) *GroupQuery {
|
||||||
|
query := (&GroupClient{config: c.config}).Query()
|
||||||
|
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||||
|
id := i.ID
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(item.Table, item.FieldID, id),
|
||||||
|
sqlgraph.To(group.Table, group.FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, item.GroupTable, item.GroupColumn),
|
||||||
|
)
|
||||||
|
fromV = sqlgraph.Neighbors(i.driver.Dialect(), step)
|
||||||
|
return fromV, nil
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
// QueryParent queries the parent edge of a Item.
|
// QueryParent queries the parent edge of a Item.
|
||||||
func (c *ItemClient) QueryParent(i *Item) *ItemQuery {
|
func (c *ItemClient) QueryParent(i *Item) *ItemQuery {
|
||||||
query := (&ItemClient{config: c.config}).Query()
|
query := (&ItemClient{config: c.config}).Query()
|
||||||
|
@ -1307,22 +1386,6 @@ func (c *ItemClient) QueryChildren(i *Item) *ItemQuery {
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryGroup queries the group edge of a Item.
|
|
||||||
func (c *ItemClient) QueryGroup(i *Item) *GroupQuery {
|
|
||||||
query := (&GroupClient{config: c.config}).Query()
|
|
||||||
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
|
||||||
id := i.ID
|
|
||||||
step := sqlgraph.NewStep(
|
|
||||||
sqlgraph.From(item.Table, item.FieldID, id),
|
|
||||||
sqlgraph.To(group.Table, group.FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.M2O, true, item.GroupTable, item.GroupColumn),
|
|
||||||
)
|
|
||||||
fromV = sqlgraph.Neighbors(i.driver.Dialect(), step)
|
|
||||||
return fromV, nil
|
|
||||||
}
|
|
||||||
return query
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryLabel queries the label edge of a Item.
|
// QueryLabel queries the label edge of a Item.
|
||||||
func (c *ItemClient) QueryLabel(i *Item) *LabelQuery {
|
func (c *ItemClient) QueryLabel(i *Item) *LabelQuery {
|
||||||
query := (&LabelClient{config: c.config}).Query()
|
query := (&LabelClient{config: c.config}).Query()
|
||||||
|
@ -1805,6 +1868,22 @@ func (c *LocationClient) GetX(ctx context.Context, id uuid.UUID) *Location {
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryGroup queries the group edge of a Location.
|
||||||
|
func (c *LocationClient) QueryGroup(l *Location) *GroupQuery {
|
||||||
|
query := (&GroupClient{config: c.config}).Query()
|
||||||
|
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||||
|
id := l.ID
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(location.Table, location.FieldID, id),
|
||||||
|
sqlgraph.To(group.Table, group.FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, location.GroupTable, location.GroupColumn),
|
||||||
|
)
|
||||||
|
fromV = sqlgraph.Neighbors(l.driver.Dialect(), step)
|
||||||
|
return fromV, nil
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
// QueryParent queries the parent edge of a Location.
|
// QueryParent queries the parent edge of a Location.
|
||||||
func (c *LocationClient) QueryParent(l *Location) *LocationQuery {
|
func (c *LocationClient) QueryParent(l *Location) *LocationQuery {
|
||||||
query := (&LocationClient{config: c.config}).Query()
|
query := (&LocationClient{config: c.config}).Query()
|
||||||
|
@ -1837,22 +1916,6 @@ func (c *LocationClient) QueryChildren(l *Location) *LocationQuery {
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryGroup queries the group edge of a Location.
|
|
||||||
func (c *LocationClient) QueryGroup(l *Location) *GroupQuery {
|
|
||||||
query := (&GroupClient{config: c.config}).Query()
|
|
||||||
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
|
||||||
id := l.ID
|
|
||||||
step := sqlgraph.NewStep(
|
|
||||||
sqlgraph.From(location.Table, location.FieldID, id),
|
|
||||||
sqlgraph.To(group.Table, group.FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.M2O, true, location.GroupTable, location.GroupColumn),
|
|
||||||
)
|
|
||||||
fromV = sqlgraph.Neighbors(l.driver.Dialect(), step)
|
|
||||||
return fromV, nil
|
|
||||||
}
|
|
||||||
return query
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryItems queries the items edge of a Location.
|
// QueryItems queries the items edge of a Location.
|
||||||
func (c *LocationClient) QueryItems(l *Location) *ItemQuery {
|
func (c *LocationClient) QueryItems(l *Location) *ItemQuery {
|
||||||
query := (&ItemClient{config: c.config}).Query()
|
query := (&ItemClient{config: c.config}).Query()
|
||||||
|
@ -2028,6 +2091,156 @@ func (c *MaintenanceEntryClient) mutate(ctx context.Context, m *MaintenanceEntry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotifierClient is a client for the Notifier schema.
|
||||||
|
type NotifierClient struct {
|
||||||
|
config
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNotifierClient returns a client for the Notifier from the given config.
|
||||||
|
func NewNotifierClient(c config) *NotifierClient {
|
||||||
|
return &NotifierClient{config: c}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use adds a list of mutation hooks to the hooks stack.
|
||||||
|
// A call to `Use(f, g, h)` equals to `notifier.Hooks(f(g(h())))`.
|
||||||
|
func (c *NotifierClient) Use(hooks ...Hook) {
|
||||||
|
c.hooks.Notifier = append(c.hooks.Notifier, hooks...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intercept adds a list of query interceptors to the interceptors stack.
|
||||||
|
// A call to `Intercept(f, g, h)` equals to `notifier.Intercept(f(g(h())))`.
|
||||||
|
func (c *NotifierClient) Intercept(interceptors ...Interceptor) {
|
||||||
|
c.inters.Notifier = append(c.inters.Notifier, interceptors...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create returns a builder for creating a Notifier entity.
|
||||||
|
func (c *NotifierClient) Create() *NotifierCreate {
|
||||||
|
mutation := newNotifierMutation(c.config, OpCreate)
|
||||||
|
return &NotifierCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateBulk returns a builder for creating a bulk of Notifier entities.
|
||||||
|
func (c *NotifierClient) CreateBulk(builders ...*NotifierCreate) *NotifierCreateBulk {
|
||||||
|
return &NotifierCreateBulk{config: c.config, builders: builders}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update returns an update builder for Notifier.
|
||||||
|
func (c *NotifierClient) Update() *NotifierUpdate {
|
||||||
|
mutation := newNotifierMutation(c.config, OpUpdate)
|
||||||
|
return &NotifierUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOne returns an update builder for the given entity.
|
||||||
|
func (c *NotifierClient) UpdateOne(n *Notifier) *NotifierUpdateOne {
|
||||||
|
mutation := newNotifierMutation(c.config, OpUpdateOne, withNotifier(n))
|
||||||
|
return &NotifierUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOneID returns an update builder for the given id.
|
||||||
|
func (c *NotifierClient) UpdateOneID(id uuid.UUID) *NotifierUpdateOne {
|
||||||
|
mutation := newNotifierMutation(c.config, OpUpdateOne, withNotifierID(id))
|
||||||
|
return &NotifierUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete returns a delete builder for Notifier.
|
||||||
|
func (c *NotifierClient) Delete() *NotifierDelete {
|
||||||
|
mutation := newNotifierMutation(c.config, OpDelete)
|
||||||
|
return &NotifierDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOne returns a builder for deleting the given entity.
|
||||||
|
func (c *NotifierClient) DeleteOne(n *Notifier) *NotifierDeleteOne {
|
||||||
|
return c.DeleteOneID(n.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOneID returns a builder for deleting the given entity by its id.
|
||||||
|
func (c *NotifierClient) DeleteOneID(id uuid.UUID) *NotifierDeleteOne {
|
||||||
|
builder := c.Delete().Where(notifier.ID(id))
|
||||||
|
builder.mutation.id = &id
|
||||||
|
builder.mutation.op = OpDeleteOne
|
||||||
|
return &NotifierDeleteOne{builder}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query returns a query builder for Notifier.
|
||||||
|
func (c *NotifierClient) Query() *NotifierQuery {
|
||||||
|
return &NotifierQuery{
|
||||||
|
config: c.config,
|
||||||
|
ctx: &QueryContext{Type: TypeNotifier},
|
||||||
|
inters: c.Interceptors(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns a Notifier entity by its id.
|
||||||
|
func (c *NotifierClient) Get(ctx context.Context, id uuid.UUID) (*Notifier, error) {
|
||||||
|
return c.Query().Where(notifier.ID(id)).Only(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetX is like Get, but panics if an error occurs.
|
||||||
|
func (c *NotifierClient) GetX(ctx context.Context, id uuid.UUID) *Notifier {
|
||||||
|
obj, err := c.Get(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryGroup queries the group edge of a Notifier.
|
||||||
|
func (c *NotifierClient) QueryGroup(n *Notifier) *GroupQuery {
|
||||||
|
query := (&GroupClient{config: c.config}).Query()
|
||||||
|
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||||
|
id := n.ID
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(notifier.Table, notifier.FieldID, id),
|
||||||
|
sqlgraph.To(group.Table, group.FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, notifier.GroupTable, notifier.GroupColumn),
|
||||||
|
)
|
||||||
|
fromV = sqlgraph.Neighbors(n.driver.Dialect(), step)
|
||||||
|
return fromV, nil
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryUser queries the user edge of a Notifier.
|
||||||
|
func (c *NotifierClient) QueryUser(n *Notifier) *UserQuery {
|
||||||
|
query := (&UserClient{config: c.config}).Query()
|
||||||
|
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||||
|
id := n.ID
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(notifier.Table, notifier.FieldID, id),
|
||||||
|
sqlgraph.To(user.Table, user.FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, notifier.UserTable, notifier.UserColumn),
|
||||||
|
)
|
||||||
|
fromV = sqlgraph.Neighbors(n.driver.Dialect(), step)
|
||||||
|
return fromV, nil
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hooks returns the client hooks.
|
||||||
|
func (c *NotifierClient) Hooks() []Hook {
|
||||||
|
return c.hooks.Notifier
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interceptors returns the client interceptors.
|
||||||
|
func (c *NotifierClient) Interceptors() []Interceptor {
|
||||||
|
return c.inters.Notifier
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *NotifierClient) mutate(ctx context.Context, m *NotifierMutation) (Value, error) {
|
||||||
|
switch m.Op() {
|
||||||
|
case OpCreate:
|
||||||
|
return (&NotifierCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||||
|
case OpUpdate:
|
||||||
|
return (&NotifierUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||||
|
case OpUpdateOne:
|
||||||
|
return (&NotifierUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||||
|
case OpDelete, OpDeleteOne:
|
||||||
|
return (&NotifierDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("ent: unknown Notifier mutation op: %q", m.Op())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// UserClient is a client for the User schema.
|
// UserClient is a client for the User schema.
|
||||||
type UserClient struct {
|
type UserClient struct {
|
||||||
config
|
config
|
||||||
|
@ -2153,6 +2366,22 @@ func (c *UserClient) QueryAuthTokens(u *User) *AuthTokensQuery {
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryNotifiers queries the notifiers edge of a User.
|
||||||
|
func (c *UserClient) QueryNotifiers(u *User) *NotifierQuery {
|
||||||
|
query := (&NotifierClient{config: c.config}).Query()
|
||||||
|
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||||
|
id := u.ID
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(user.Table, user.FieldID, id),
|
||||||
|
sqlgraph.To(notifier.Table, notifier.FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, user.NotifiersTable, user.NotifiersColumn),
|
||||||
|
)
|
||||||
|
fromV = sqlgraph.Neighbors(u.driver.Dialect(), step)
|
||||||
|
return fromV, nil
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
// Hooks returns the client hooks.
|
// Hooks returns the client hooks.
|
||||||
func (c *UserClient) Hooks() []Hook {
|
func (c *UserClient) Hooks() []Hook {
|
||||||
return c.hooks.User
|
return c.hooks.User
|
||||||
|
@ -2177,3 +2406,15 @@ func (c *UserClient) mutate(ctx context.Context, m *UserMutation) (Value, error)
|
||||||
return nil, fmt.Errorf("ent: unknown User mutation op: %q", m.Op())
|
return nil, fmt.Errorf("ent: unknown User mutation op: %q", m.Op())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hooks and interceptors per client, for fast access.
|
||||||
|
type (
|
||||||
|
hooks struct {
|
||||||
|
Attachment, AuthRoles, AuthTokens, Document, Group, GroupInvitationToken, Item,
|
||||||
|
ItemField, Label, Location, MaintenanceEntry, Notifier, User []ent.Hook
|
||||||
|
}
|
||||||
|
inters struct {
|
||||||
|
Attachment, AuthRoles, AuthTokens, Document, Group, GroupInvitationToken, Item,
|
||||||
|
ItemField, Label, Location, MaintenanceEntry, Notifier, User []ent.Interceptor
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
// Code generated by ent, DO NOT EDIT.
|
|
||||||
|
|
||||||
package ent
|
|
||||||
|
|
||||||
import (
|
|
||||||
"entgo.io/ent"
|
|
||||||
"entgo.io/ent/dialect"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Option function to configure the client.
|
|
||||||
type Option func(*config)
|
|
||||||
|
|
||||||
// Config is the configuration for the client and its builder.
|
|
||||||
type config struct {
|
|
||||||
// driver used for executing database requests.
|
|
||||||
driver dialect.Driver
|
|
||||||
// debug enable a debug logging.
|
|
||||||
debug bool
|
|
||||||
// log used for logging on debug mode.
|
|
||||||
log func(...any)
|
|
||||||
// hooks to execute on mutations.
|
|
||||||
hooks *hooks
|
|
||||||
// interceptors to execute on queries.
|
|
||||||
inters *inters
|
|
||||||
}
|
|
||||||
|
|
||||||
// hooks and interceptors per client, for fast access.
|
|
||||||
type (
|
|
||||||
hooks struct {
|
|
||||||
Attachment []ent.Hook
|
|
||||||
AuthRoles []ent.Hook
|
|
||||||
AuthTokens []ent.Hook
|
|
||||||
Document []ent.Hook
|
|
||||||
Group []ent.Hook
|
|
||||||
GroupInvitationToken []ent.Hook
|
|
||||||
Item []ent.Hook
|
|
||||||
ItemField []ent.Hook
|
|
||||||
Label []ent.Hook
|
|
||||||
Location []ent.Hook
|
|
||||||
MaintenanceEntry []ent.Hook
|
|
||||||
User []ent.Hook
|
|
||||||
}
|
|
||||||
inters struct {
|
|
||||||
Attachment []ent.Interceptor
|
|
||||||
AuthRoles []ent.Interceptor
|
|
||||||
AuthTokens []ent.Interceptor
|
|
||||||
Document []ent.Interceptor
|
|
||||||
Group []ent.Interceptor
|
|
||||||
GroupInvitationToken []ent.Interceptor
|
|
||||||
Item []ent.Interceptor
|
|
||||||
ItemField []ent.Interceptor
|
|
||||||
Label []ent.Interceptor
|
|
||||||
Location []ent.Interceptor
|
|
||||||
MaintenanceEntry []ent.Interceptor
|
|
||||||
User []ent.Interceptor
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Options applies the options on the config object.
|
|
||||||
func (c *config) options(opts ...Option) {
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt(c)
|
|
||||||
}
|
|
||||||
if c.debug {
|
|
||||||
c.driver = dialect.Debug(c.driver, c.log)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug enables debug logging on the ent.Driver.
|
|
||||||
func Debug() Option {
|
|
||||||
return func(c *config) {
|
|
||||||
c.debug = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log sets the logging function for debug mode.
|
|
||||||
func Log(fn func(...any)) Option {
|
|
||||||
return func(c *config) {
|
|
||||||
c.log = fn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Driver configures the client driver.
|
|
||||||
func Driver(driver dialect.Driver) Option {
|
|
||||||
return func(c *config) {
|
|
||||||
c.driver = driver
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
// Code generated by ent, DO NOT EDIT.
|
|
||||||
|
|
||||||
package ent
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
)
|
|
||||||
|
|
||||||
type clientCtxKey struct{}
|
|
||||||
|
|
||||||
// FromContext returns a Client stored inside a context, or nil if there isn't one.
|
|
||||||
func FromContext(ctx context.Context) *Client {
|
|
||||||
c, _ := ctx.Value(clientCtxKey{}).(*Client)
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewContext returns a new context with the given Client attached.
|
|
||||||
func NewContext(parent context.Context, c *Client) context.Context {
|
|
||||||
return context.WithValue(parent, clientCtxKey{}, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
type txCtxKey struct{}
|
|
||||||
|
|
||||||
// TxFromContext returns a Tx stored inside a context, or nil if there isn't one.
|
|
||||||
func TxFromContext(ctx context.Context) *Tx {
|
|
||||||
tx, _ := ctx.Value(txCtxKey{}).(*Tx)
|
|
||||||
return tx
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTxContext returns a new context with the given Tx attached.
|
|
||||||
func NewTxContext(parent context.Context, tx *Tx) context.Context {
|
|
||||||
return context.WithValue(parent, txCtxKey{}, tx)
|
|
||||||
}
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||||
|
@ -30,6 +31,7 @@ type Document struct {
|
||||||
// The values are being populated by the DocumentQuery when eager-loading is set.
|
// The values are being populated by the DocumentQuery when eager-loading is set.
|
||||||
Edges DocumentEdges `json:"edges"`
|
Edges DocumentEdges `json:"edges"`
|
||||||
group_documents *uuid.UUID
|
group_documents *uuid.UUID
|
||||||
|
selectValues sql.SelectValues
|
||||||
}
|
}
|
||||||
|
|
||||||
// DocumentEdges holds the relations/edges for other nodes in the graph.
|
// DocumentEdges holds the relations/edges for other nodes in the graph.
|
||||||
|
@ -79,7 +81,7 @@ func (*Document) scanValues(columns []string) ([]any, error) {
|
||||||
case document.ForeignKeys[0]: // group_documents
|
case document.ForeignKeys[0]: // group_documents
|
||||||
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected column %q for type Document", columns[i])
|
values[i] = new(sql.UnknownType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values, nil
|
return values, nil
|
||||||
|
@ -130,11 +132,19 @@ func (d *Document) assignValues(columns []string, values []any) error {
|
||||||
d.group_documents = new(uuid.UUID)
|
d.group_documents = new(uuid.UUID)
|
||||||
*d.group_documents = *value.S.(*uuid.UUID)
|
*d.group_documents = *value.S.(*uuid.UUID)
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
d.selectValues.Set(columns[i], values[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Value returns the ent.Value that was dynamically selected and assigned to the Document.
|
||||||
|
// This includes values selected through modifiers, order, etc.
|
||||||
|
func (d *Document) Value(name string) (ent.Value, error) {
|
||||||
|
return d.selectValues.Get(name)
|
||||||
|
}
|
||||||
|
|
||||||
// QueryGroup queries the "group" edge of the Document entity.
|
// QueryGroup queries the "group" edge of the Document entity.
|
||||||
func (d *Document) QueryGroup() *GroupQuery {
|
func (d *Document) QueryGroup() *GroupQuery {
|
||||||
return NewDocumentClient(d.config).QueryGroup(d)
|
return NewDocumentClient(d.config).QueryGroup(d)
|
||||||
|
|
|
@ -5,6 +5,8 @@ package document
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -87,3 +89,66 @@ var (
|
||||||
// DefaultID holds the default value on creation for the "id" field.
|
// DefaultID holds the default value on creation for the "id" field.
|
||||||
DefaultID func() uuid.UUID
|
DefaultID func() uuid.UUID
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// OrderOption defines the ordering options for the Document queries.
|
||||||
|
type OrderOption func(*sql.Selector)
|
||||||
|
|
||||||
|
// ByID orders the results by the id field.
|
||||||
|
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByCreatedAt orders the results by the created_at field.
|
||||||
|
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUpdatedAt orders the results by the updated_at field.
|
||||||
|
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByTitle orders the results by the title field.
|
||||||
|
func ByTitle(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldTitle, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByPath orders the results by the path field.
|
||||||
|
func ByPath(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldPath, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByGroupField orders the results by group field.
|
||||||
|
func ByGroupField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newGroupStep(), sql.OrderByField(field, opts...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByAttachmentsCount orders the results by attachments count.
|
||||||
|
func ByAttachmentsCount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborsCount(s, newAttachmentsStep(), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByAttachments orders the results by attachments terms.
|
||||||
|
func ByAttachments(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newAttachmentsStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func newGroupStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(GroupInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, GroupTable, GroupColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func newAttachmentsStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(AttachmentsInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, AttachmentsTable, AttachmentsColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -300,11 +300,7 @@ func HasGroup() predicate.Document {
|
||||||
// HasGroupWith applies the HasEdge predicate on the "group" edge with a given conditions (other predicates).
|
// HasGroupWith applies the HasEdge predicate on the "group" edge with a given conditions (other predicates).
|
||||||
func HasGroupWith(preds ...predicate.Group) predicate.Document {
|
func HasGroupWith(preds ...predicate.Group) predicate.Document {
|
||||||
return predicate.Document(func(s *sql.Selector) {
|
return predicate.Document(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newGroupStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(GroupInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.M2O, true, GroupTable, GroupColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
@ -327,11 +323,7 @@ func HasAttachments() predicate.Document {
|
||||||
// HasAttachmentsWith applies the HasEdge predicate on the "attachments" edge with a given conditions (other predicates).
|
// HasAttachmentsWith applies the HasEdge predicate on the "attachments" edge with a given conditions (other predicates).
|
||||||
func HasAttachmentsWith(preds ...predicate.Attachment) predicate.Document {
|
func HasAttachmentsWith(preds ...predicate.Attachment) predicate.Document {
|
||||||
return predicate.Document(func(s *sql.Selector) {
|
return predicate.Document(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newAttachmentsStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(AttachmentsInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.O2M, false, AttachmentsTable, AttachmentsColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
|
|
@ -111,7 +111,7 @@ func (dc *DocumentCreate) Mutation() *DocumentMutation {
|
||||||
// Save creates the Document in the database.
|
// Save creates the Document in the database.
|
||||||
func (dc *DocumentCreate) Save(ctx context.Context) (*Document, error) {
|
func (dc *DocumentCreate) Save(ctx context.Context) (*Document, error) {
|
||||||
dc.defaults()
|
dc.defaults()
|
||||||
return withHooks[*Document, DocumentMutation](ctx, dc.sqlSave, dc.mutation, dc.hooks)
|
return withHooks(ctx, dc.sqlSave, dc.mutation, dc.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX calls Save and panics if Save returns an error.
|
// SaveX calls Save and panics if Save returns an error.
|
||||||
|
@ -238,10 +238,7 @@ func (dc *DocumentCreate) createSpec() (*Document, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{document.GroupColumn},
|
Columns: []string{document.GroupColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(group.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: group.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -258,10 +255,7 @@ func (dc *DocumentCreate) createSpec() (*Document, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{document.AttachmentsColumn},
|
Columns: []string{document.AttachmentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: attachment.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -296,8 +290,8 @@ func (dcb *DocumentCreateBulk) Save(ctx context.Context) ([]*Document, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
builder.mutation = mutation
|
builder.mutation = mutation
|
||||||
nodes[i], specs[i] = builder.createSpec()
|
|
||||||
var err error
|
var err error
|
||||||
|
nodes[i], specs[i] = builder.createSpec()
|
||||||
if i < len(mutators)-1 {
|
if i < len(mutators)-1 {
|
||||||
_, err = mutators[i+1].Mutate(root, dcb.builders[i+1].mutation)
|
_, err = mutators[i+1].Mutate(root, dcb.builders[i+1].mutation)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -27,7 +27,7 @@ func (dd *DocumentDelete) Where(ps ...predicate.Document) *DocumentDelete {
|
||||||
|
|
||||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||||
func (dd *DocumentDelete) Exec(ctx context.Context) (int, error) {
|
func (dd *DocumentDelete) Exec(ctx context.Context) (int, error) {
|
||||||
return withHooks[int, DocumentMutation](ctx, dd.sqlExec, dd.mutation, dd.hooks)
|
return withHooks(ctx, dd.sqlExec, dd.mutation, dd.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecX is like Exec, but panics if an error occurs.
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
|
|
@ -22,7 +22,7 @@ import (
|
||||||
type DocumentQuery struct {
|
type DocumentQuery struct {
|
||||||
config
|
config
|
||||||
ctx *QueryContext
|
ctx *QueryContext
|
||||||
order []OrderFunc
|
order []document.OrderOption
|
||||||
inters []Interceptor
|
inters []Interceptor
|
||||||
predicates []predicate.Document
|
predicates []predicate.Document
|
||||||
withGroup *GroupQuery
|
withGroup *GroupQuery
|
||||||
|
@ -59,7 +59,7 @@ func (dq *DocumentQuery) Unique(unique bool) *DocumentQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order specifies how the records should be ordered.
|
// Order specifies how the records should be ordered.
|
||||||
func (dq *DocumentQuery) Order(o ...OrderFunc) *DocumentQuery {
|
func (dq *DocumentQuery) Order(o ...document.OrderOption) *DocumentQuery {
|
||||||
dq.order = append(dq.order, o...)
|
dq.order = append(dq.order, o...)
|
||||||
return dq
|
return dq
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ func (dq *DocumentQuery) Clone() *DocumentQuery {
|
||||||
return &DocumentQuery{
|
return &DocumentQuery{
|
||||||
config: dq.config,
|
config: dq.config,
|
||||||
ctx: dq.ctx.Clone(),
|
ctx: dq.ctx.Clone(),
|
||||||
order: append([]OrderFunc{}, dq.order...),
|
order: append([]document.OrderOption{}, dq.order...),
|
||||||
inters: append([]Interceptor{}, dq.inters...),
|
inters: append([]Interceptor{}, dq.inters...),
|
||||||
predicates: append([]predicate.Document{}, dq.predicates...),
|
predicates: append([]predicate.Document{}, dq.predicates...),
|
||||||
withGroup: dq.withGroup.Clone(),
|
withGroup: dq.withGroup.Clone(),
|
||||||
|
@ -498,7 +498,7 @@ func (dq *DocumentQuery) loadAttachments(ctx context.Context, query *AttachmentQ
|
||||||
}
|
}
|
||||||
query.withFKs = true
|
query.withFKs = true
|
||||||
query.Where(predicate.Attachment(func(s *sql.Selector) {
|
query.Where(predicate.Attachment(func(s *sql.Selector) {
|
||||||
s.Where(sql.InValues(document.AttachmentsColumn, fks...))
|
s.Where(sql.InValues(s.C(document.AttachmentsColumn), fks...))
|
||||||
}))
|
}))
|
||||||
neighbors, err := query.All(ctx)
|
neighbors, err := query.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -511,7 +511,7 @@ func (dq *DocumentQuery) loadAttachments(ctx context.Context, query *AttachmentQ
|
||||||
}
|
}
|
||||||
node, ok := nodeids[*fk]
|
node, ok := nodeids[*fk]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf(`unexpected foreign-key "document_attachments" returned %v for node %v`, *fk, n.ID)
|
return fmt.Errorf(`unexpected referenced foreign-key "document_attachments" returned %v for node %v`, *fk, n.ID)
|
||||||
}
|
}
|
||||||
assign(node, n)
|
assign(node, n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ func (du *DocumentUpdate) RemoveAttachments(a ...*Attachment) *DocumentUpdate {
|
||||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||||
func (du *DocumentUpdate) Save(ctx context.Context) (int, error) {
|
func (du *DocumentUpdate) Save(ctx context.Context) (int, error) {
|
||||||
du.defaults()
|
du.defaults()
|
||||||
return withHooks[int, DocumentMutation](ctx, du.sqlSave, du.mutation, du.hooks)
|
return withHooks(ctx, du.sqlSave, du.mutation, du.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX is like Save, but panics if an error occurs.
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
@ -190,10 +190,7 @@ func (du *DocumentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{document.GroupColumn},
|
Columns: []string{document.GroupColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(group.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: group.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -206,10 +203,7 @@ func (du *DocumentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{document.GroupColumn},
|
Columns: []string{document.GroupColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(group.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: group.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -225,10 +219,7 @@ func (du *DocumentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{document.AttachmentsColumn},
|
Columns: []string{document.AttachmentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: attachment.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -241,10 +232,7 @@ func (du *DocumentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{document.AttachmentsColumn},
|
Columns: []string{document.AttachmentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: attachment.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -260,10 +248,7 @@ func (du *DocumentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{document.AttachmentsColumn},
|
Columns: []string{document.AttachmentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: attachment.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -383,7 +368,7 @@ func (duo *DocumentUpdateOne) Select(field string, fields ...string) *DocumentUp
|
||||||
// Save executes the query and returns the updated Document entity.
|
// Save executes the query and returns the updated Document entity.
|
||||||
func (duo *DocumentUpdateOne) Save(ctx context.Context) (*Document, error) {
|
func (duo *DocumentUpdateOne) Save(ctx context.Context) (*Document, error) {
|
||||||
duo.defaults()
|
duo.defaults()
|
||||||
return withHooks[*Document, DocumentMutation](ctx, duo.sqlSave, duo.mutation, duo.hooks)
|
return withHooks(ctx, duo.sqlSave, duo.mutation, duo.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX is like Save, but panics if an error occurs.
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
@ -480,10 +465,7 @@ func (duo *DocumentUpdateOne) sqlSave(ctx context.Context) (_node *Document, err
|
||||||
Columns: []string{document.GroupColumn},
|
Columns: []string{document.GroupColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(group.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: group.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -496,10 +478,7 @@ func (duo *DocumentUpdateOne) sqlSave(ctx context.Context) (_node *Document, err
|
||||||
Columns: []string{document.GroupColumn},
|
Columns: []string{document.GroupColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(group.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: group.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -515,10 +494,7 @@ func (duo *DocumentUpdateOne) sqlSave(ctx context.Context) (_node *Document, err
|
||||||
Columns: []string{document.AttachmentsColumn},
|
Columns: []string{document.AttachmentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: attachment.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -531,10 +507,7 @@ func (duo *DocumentUpdateOne) sqlSave(ctx context.Context) (_node *Document, err
|
||||||
Columns: []string{document.AttachmentsColumn},
|
Columns: []string{document.AttachmentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: attachment.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -550,10 +523,7 @@ func (duo *DocumentUpdateOne) sqlSave(ctx context.Context) (_node *Document, err
|
||||||
Columns: []string{document.AttachmentsColumn},
|
Columns: []string{document.AttachmentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: attachment.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"entgo.io/ent"
|
"entgo.io/ent"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
|
@ -22,6 +23,7 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,45 +46,68 @@ type (
|
||||||
MutateFunc = ent.MutateFunc
|
MutateFunc = ent.MutateFunc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type clientCtxKey struct{}
|
||||||
|
|
||||||
|
// FromContext returns a Client stored inside a context, or nil if there isn't one.
|
||||||
|
func FromContext(ctx context.Context) *Client {
|
||||||
|
c, _ := ctx.Value(clientCtxKey{}).(*Client)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContext returns a new context with the given Client attached.
|
||||||
|
func NewContext(parent context.Context, c *Client) context.Context {
|
||||||
|
return context.WithValue(parent, clientCtxKey{}, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
type txCtxKey struct{}
|
||||||
|
|
||||||
|
// TxFromContext returns a Tx stored inside a context, or nil if there isn't one.
|
||||||
|
func TxFromContext(ctx context.Context) *Tx {
|
||||||
|
tx, _ := ctx.Value(txCtxKey{}).(*Tx)
|
||||||
|
return tx
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTxContext returns a new context with the given Tx attached.
|
||||||
|
func NewTxContext(parent context.Context, tx *Tx) context.Context {
|
||||||
|
return context.WithValue(parent, txCtxKey{}, tx)
|
||||||
|
}
|
||||||
|
|
||||||
// OrderFunc applies an ordering on the sql selector.
|
// OrderFunc applies an ordering on the sql selector.
|
||||||
|
// Deprecated: Use Asc/Desc functions or the package builders instead.
|
||||||
type OrderFunc func(*sql.Selector)
|
type OrderFunc func(*sql.Selector)
|
||||||
|
|
||||||
// columnChecker returns a function indicates if the column exists in the given column.
|
var (
|
||||||
func columnChecker(table string) func(string) error {
|
initCheck sync.Once
|
||||||
checks := map[string]func(string) bool{
|
columnCheck sql.ColumnCheck
|
||||||
attachment.Table: attachment.ValidColumn,
|
)
|
||||||
authroles.Table: authroles.ValidColumn,
|
|
||||||
authtokens.Table: authtokens.ValidColumn,
|
// columnChecker checks if the column exists in the given table.
|
||||||
document.Table: document.ValidColumn,
|
func checkColumn(table, column string) error {
|
||||||
group.Table: group.ValidColumn,
|
initCheck.Do(func() {
|
||||||
groupinvitationtoken.Table: groupinvitationtoken.ValidColumn,
|
columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
|
||||||
item.Table: item.ValidColumn,
|
attachment.Table: attachment.ValidColumn,
|
||||||
itemfield.Table: itemfield.ValidColumn,
|
authroles.Table: authroles.ValidColumn,
|
||||||
label.Table: label.ValidColumn,
|
authtokens.Table: authtokens.ValidColumn,
|
||||||
location.Table: location.ValidColumn,
|
document.Table: document.ValidColumn,
|
||||||
maintenanceentry.Table: maintenanceentry.ValidColumn,
|
group.Table: group.ValidColumn,
|
||||||
user.Table: user.ValidColumn,
|
groupinvitationtoken.Table: groupinvitationtoken.ValidColumn,
|
||||||
}
|
item.Table: item.ValidColumn,
|
||||||
check, ok := checks[table]
|
itemfield.Table: itemfield.ValidColumn,
|
||||||
if !ok {
|
label.Table: label.ValidColumn,
|
||||||
return func(string) error {
|
location.Table: location.ValidColumn,
|
||||||
return fmt.Errorf("unknown table %q", table)
|
maintenanceentry.Table: maintenanceentry.ValidColumn,
|
||||||
}
|
notifier.Table: notifier.ValidColumn,
|
||||||
}
|
user.Table: user.ValidColumn,
|
||||||
return func(column string) error {
|
})
|
||||||
if !check(column) {
|
})
|
||||||
return fmt.Errorf("unknown column %q for table %q", column, table)
|
return columnCheck(table, column)
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asc applies the given fields in ASC order.
|
// Asc applies the given fields in ASC order.
|
||||||
func Asc(fields ...string) OrderFunc {
|
func Asc(fields ...string) func(*sql.Selector) {
|
||||||
return func(s *sql.Selector) {
|
return func(s *sql.Selector) {
|
||||||
check := columnChecker(s.TableName())
|
|
||||||
for _, f := range fields {
|
for _, f := range fields {
|
||||||
if err := check(f); err != nil {
|
if err := checkColumn(s.TableName(), f); err != nil {
|
||||||
s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)})
|
s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)})
|
||||||
}
|
}
|
||||||
s.OrderBy(sql.Asc(s.C(f)))
|
s.OrderBy(sql.Asc(s.C(f)))
|
||||||
|
@ -91,11 +116,10 @@ func Asc(fields ...string) OrderFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Desc applies the given fields in DESC order.
|
// Desc applies the given fields in DESC order.
|
||||||
func Desc(fields ...string) OrderFunc {
|
func Desc(fields ...string) func(*sql.Selector) {
|
||||||
return func(s *sql.Selector) {
|
return func(s *sql.Selector) {
|
||||||
check := columnChecker(s.TableName())
|
|
||||||
for _, f := range fields {
|
for _, f := range fields {
|
||||||
if err := check(f); err != nil {
|
if err := checkColumn(s.TableName(), f); err != nil {
|
||||||
s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)})
|
s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)})
|
||||||
}
|
}
|
||||||
s.OrderBy(sql.Desc(s.C(f)))
|
s.OrderBy(sql.Desc(s.C(f)))
|
||||||
|
@ -127,8 +151,7 @@ func Count() AggregateFunc {
|
||||||
// Max applies the "max" aggregation function on the given field of each group.
|
// Max applies the "max" aggregation function on the given field of each group.
|
||||||
func Max(field string) AggregateFunc {
|
func Max(field string) AggregateFunc {
|
||||||
return func(s *sql.Selector) string {
|
return func(s *sql.Selector) string {
|
||||||
check := columnChecker(s.TableName())
|
if err := checkColumn(s.TableName(), field); err != nil {
|
||||||
if err := check(field); err != nil {
|
|
||||||
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -139,8 +162,7 @@ func Max(field string) AggregateFunc {
|
||||||
// Mean applies the "mean" aggregation function on the given field of each group.
|
// Mean applies the "mean" aggregation function on the given field of each group.
|
||||||
func Mean(field string) AggregateFunc {
|
func Mean(field string) AggregateFunc {
|
||||||
return func(s *sql.Selector) string {
|
return func(s *sql.Selector) string {
|
||||||
check := columnChecker(s.TableName())
|
if err := checkColumn(s.TableName(), field); err != nil {
|
||||||
if err := check(field); err != nil {
|
|
||||||
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -151,8 +173,7 @@ func Mean(field string) AggregateFunc {
|
||||||
// Min applies the "min" aggregation function on the given field of each group.
|
// Min applies the "min" aggregation function on the given field of each group.
|
||||||
func Min(field string) AggregateFunc {
|
func Min(field string) AggregateFunc {
|
||||||
return func(s *sql.Selector) string {
|
return func(s *sql.Selector) string {
|
||||||
check := columnChecker(s.TableName())
|
if err := checkColumn(s.TableName(), field); err != nil {
|
||||||
if err := check(field); err != nil {
|
|
||||||
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -163,8 +184,7 @@ func Min(field string) AggregateFunc {
|
||||||
// Sum applies the "sum" aggregation function on the given field of each group.
|
// Sum applies the "sum" aggregation function on the given field of each group.
|
||||||
func Sum(field string) AggregateFunc {
|
func Sum(field string) AggregateFunc {
|
||||||
return func(s *sql.Selector) string {
|
return func(s *sql.Selector) string {
|
||||||
check := columnChecker(s.TableName())
|
if err := checkColumn(s.TableName(), field); err != nil {
|
||||||
if err := check(field); err != nil {
|
|
||||||
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -501,7 +521,7 @@ func withHooks[V Value, M any, PM interface {
|
||||||
return exec(ctx)
|
return exec(ctx)
|
||||||
}
|
}
|
||||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||||
mutationT, ok := m.(PM)
|
mutationT, ok := any(m).(PM)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
||||||
|
@ -27,7 +28,8 @@ type Group struct {
|
||||||
Currency group.Currency `json:"currency,omitempty"`
|
Currency group.Currency `json:"currency,omitempty"`
|
||||||
// Edges holds the relations/edges for other nodes in the graph.
|
// Edges holds the relations/edges for other nodes in the graph.
|
||||||
// The values are being populated by the GroupQuery when eager-loading is set.
|
// The values are being populated by the GroupQuery when eager-loading is set.
|
||||||
Edges GroupEdges `json:"edges"`
|
Edges GroupEdges `json:"edges"`
|
||||||
|
selectValues sql.SelectValues
|
||||||
}
|
}
|
||||||
|
|
||||||
// GroupEdges holds the relations/edges for other nodes in the graph.
|
// GroupEdges holds the relations/edges for other nodes in the graph.
|
||||||
|
@ -44,9 +46,11 @@ type GroupEdges struct {
|
||||||
Documents []*Document `json:"documents,omitempty"`
|
Documents []*Document `json:"documents,omitempty"`
|
||||||
// InvitationTokens holds the value of the invitation_tokens edge.
|
// InvitationTokens holds the value of the invitation_tokens edge.
|
||||||
InvitationTokens []*GroupInvitationToken `json:"invitation_tokens,omitempty"`
|
InvitationTokens []*GroupInvitationToken `json:"invitation_tokens,omitempty"`
|
||||||
|
// Notifiers holds the value of the notifiers edge.
|
||||||
|
Notifiers []*Notifier `json:"notifiers,omitempty"`
|
||||||
// loadedTypes holds the information for reporting if a
|
// loadedTypes holds the information for reporting if a
|
||||||
// type was loaded (or requested) in eager-loading or not.
|
// type was loaded (or requested) in eager-loading or not.
|
||||||
loadedTypes [6]bool
|
loadedTypes [7]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// UsersOrErr returns the Users value or an error if the edge
|
// UsersOrErr returns the Users value or an error if the edge
|
||||||
|
@ -103,6 +107,15 @@ func (e GroupEdges) InvitationTokensOrErr() ([]*GroupInvitationToken, error) {
|
||||||
return nil, &NotLoadedError{edge: "invitation_tokens"}
|
return nil, &NotLoadedError{edge: "invitation_tokens"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotifiersOrErr returns the Notifiers value or an error if the edge
|
||||||
|
// was not loaded in eager-loading.
|
||||||
|
func (e GroupEdges) NotifiersOrErr() ([]*Notifier, error) {
|
||||||
|
if e.loadedTypes[6] {
|
||||||
|
return e.Notifiers, nil
|
||||||
|
}
|
||||||
|
return nil, &NotLoadedError{edge: "notifiers"}
|
||||||
|
}
|
||||||
|
|
||||||
// scanValues returns the types for scanning values from sql.Rows.
|
// scanValues returns the types for scanning values from sql.Rows.
|
||||||
func (*Group) scanValues(columns []string) ([]any, error) {
|
func (*Group) scanValues(columns []string) ([]any, error) {
|
||||||
values := make([]any, len(columns))
|
values := make([]any, len(columns))
|
||||||
|
@ -115,7 +128,7 @@ func (*Group) scanValues(columns []string) ([]any, error) {
|
||||||
case group.FieldID:
|
case group.FieldID:
|
||||||
values[i] = new(uuid.UUID)
|
values[i] = new(uuid.UUID)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected column %q for type Group", columns[i])
|
values[i] = new(sql.UnknownType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values, nil
|
return values, nil
|
||||||
|
@ -159,11 +172,19 @@ func (gr *Group) assignValues(columns []string, values []any) error {
|
||||||
} else if value.Valid {
|
} else if value.Valid {
|
||||||
gr.Currency = group.Currency(value.String)
|
gr.Currency = group.Currency(value.String)
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
gr.selectValues.Set(columns[i], values[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Value returns the ent.Value that was dynamically selected and assigned to the Group.
|
||||||
|
// This includes values selected through modifiers, order, etc.
|
||||||
|
func (gr *Group) Value(name string) (ent.Value, error) {
|
||||||
|
return gr.selectValues.Get(name)
|
||||||
|
}
|
||||||
|
|
||||||
// QueryUsers queries the "users" edge of the Group entity.
|
// QueryUsers queries the "users" edge of the Group entity.
|
||||||
func (gr *Group) QueryUsers() *UserQuery {
|
func (gr *Group) QueryUsers() *UserQuery {
|
||||||
return NewGroupClient(gr.config).QueryUsers(gr)
|
return NewGroupClient(gr.config).QueryUsers(gr)
|
||||||
|
@ -194,6 +215,11 @@ func (gr *Group) QueryInvitationTokens() *GroupInvitationTokenQuery {
|
||||||
return NewGroupClient(gr.config).QueryInvitationTokens(gr)
|
return NewGroupClient(gr.config).QueryInvitationTokens(gr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryNotifiers queries the "notifiers" edge of the Group entity.
|
||||||
|
func (gr *Group) QueryNotifiers() *NotifierQuery {
|
||||||
|
return NewGroupClient(gr.config).QueryNotifiers(gr)
|
||||||
|
}
|
||||||
|
|
||||||
// Update returns a builder for updating this Group.
|
// Update returns a builder for updating this Group.
|
||||||
// Note that you need to call Group.Unwrap() before calling this method if this Group
|
// Note that you need to call Group.Unwrap() before calling this method if this Group
|
||||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -34,6 +36,8 @@ const (
|
||||||
EdgeDocuments = "documents"
|
EdgeDocuments = "documents"
|
||||||
// EdgeInvitationTokens holds the string denoting the invitation_tokens edge name in mutations.
|
// EdgeInvitationTokens holds the string denoting the invitation_tokens edge name in mutations.
|
||||||
EdgeInvitationTokens = "invitation_tokens"
|
EdgeInvitationTokens = "invitation_tokens"
|
||||||
|
// EdgeNotifiers holds the string denoting the notifiers edge name in mutations.
|
||||||
|
EdgeNotifiers = "notifiers"
|
||||||
// Table holds the table name of the group in the database.
|
// Table holds the table name of the group in the database.
|
||||||
Table = "groups"
|
Table = "groups"
|
||||||
// UsersTable is the table that holds the users relation/edge.
|
// UsersTable is the table that holds the users relation/edge.
|
||||||
|
@ -78,6 +82,13 @@ const (
|
||||||
InvitationTokensInverseTable = "group_invitation_tokens"
|
InvitationTokensInverseTable = "group_invitation_tokens"
|
||||||
// InvitationTokensColumn is the table column denoting the invitation_tokens relation/edge.
|
// InvitationTokensColumn is the table column denoting the invitation_tokens relation/edge.
|
||||||
InvitationTokensColumn = "group_invitation_tokens"
|
InvitationTokensColumn = "group_invitation_tokens"
|
||||||
|
// NotifiersTable is the table that holds the notifiers relation/edge.
|
||||||
|
NotifiersTable = "notifiers"
|
||||||
|
// NotifiersInverseTable is the table name for the Notifier entity.
|
||||||
|
// It exists in this package in order to avoid circular dependency with the "notifier" package.
|
||||||
|
NotifiersInverseTable = "notifiers"
|
||||||
|
// NotifiersColumn is the table column denoting the notifiers relation/edge.
|
||||||
|
NotifiersColumn = "group_id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Columns holds all SQL columns for group fields.
|
// Columns holds all SQL columns for group fields.
|
||||||
|
@ -120,22 +131,37 @@ const DefaultCurrency = CurrencyUsd
|
||||||
|
|
||||||
// Currency values.
|
// Currency values.
|
||||||
const (
|
const (
|
||||||
CurrencyUsd Currency = "usd"
|
CurrencyAed Currency = "aed"
|
||||||
|
CurrencyAud Currency = "aud"
|
||||||
|
CurrencyBgn Currency = "bgn"
|
||||||
|
CurrencyBrl Currency = "brl"
|
||||||
|
CurrencyCad Currency = "cad"
|
||||||
|
CurrencyChf Currency = "chf"
|
||||||
|
CurrencyCzk Currency = "czk"
|
||||||
|
CurrencyDkk Currency = "dkk"
|
||||||
CurrencyEur Currency = "eur"
|
CurrencyEur Currency = "eur"
|
||||||
CurrencyGbp Currency = "gbp"
|
CurrencyGbp Currency = "gbp"
|
||||||
CurrencyJpy Currency = "jpy"
|
CurrencyHkd Currency = "hkd"
|
||||||
CurrencyZar Currency = "zar"
|
CurrencyIdr Currency = "idr"
|
||||||
CurrencyAud Currency = "aud"
|
|
||||||
CurrencyNok Currency = "nok"
|
|
||||||
CurrencySek Currency = "sek"
|
|
||||||
CurrencyDkk Currency = "dkk"
|
|
||||||
CurrencyInr Currency = "inr"
|
CurrencyInr Currency = "inr"
|
||||||
CurrencyRmb Currency = "rmb"
|
CurrencyJpy Currency = "jpy"
|
||||||
CurrencyBgn Currency = "bgn"
|
CurrencyKrw Currency = "krw"
|
||||||
CurrencyChf Currency = "chf"
|
CurrencyMxn Currency = "mxn"
|
||||||
|
CurrencyNok Currency = "nok"
|
||||||
|
CurrencyNzd Currency = "nzd"
|
||||||
CurrencyPln Currency = "pln"
|
CurrencyPln Currency = "pln"
|
||||||
CurrencyTry Currency = "try"
|
CurrencyRmb Currency = "rmb"
|
||||||
CurrencyRon Currency = "ron"
|
CurrencyRon Currency = "ron"
|
||||||
|
CurrencyRub Currency = "rub"
|
||||||
|
CurrencySar Currency = "sar"
|
||||||
|
CurrencySek Currency = "sek"
|
||||||
|
CurrencySgd Currency = "sgd"
|
||||||
|
CurrencyThb Currency = "thb"
|
||||||
|
CurrencyTry Currency = "try"
|
||||||
|
CurrencyUsd Currency = "usd"
|
||||||
|
CurrencyXag Currency = "xag"
|
||||||
|
CurrencyXau Currency = "xau"
|
||||||
|
CurrencyZar Currency = "zar"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c Currency) String() string {
|
func (c Currency) String() string {
|
||||||
|
@ -145,9 +171,184 @@ func (c Currency) String() string {
|
||||||
// CurrencyValidator is a validator for the "currency" field enum values. It is called by the builders before save.
|
// CurrencyValidator is a validator for the "currency" field enum values. It is called by the builders before save.
|
||||||
func CurrencyValidator(c Currency) error {
|
func CurrencyValidator(c Currency) error {
|
||||||
switch c {
|
switch c {
|
||||||
case CurrencyUsd, CurrencyEur, CurrencyGbp, CurrencyJpy, CurrencyZar, CurrencyAud, CurrencyNok, CurrencySek, CurrencyDkk, CurrencyInr, CurrencyRmb, CurrencyBgn, CurrencyChf, CurrencyPln, CurrencyTry, CurrencyRon:
|
case CurrencyAed, CurrencyAud, CurrencyBgn, CurrencyBrl, CurrencyCad, CurrencyChf, CurrencyCzk, CurrencyDkk, CurrencyEur, CurrencyGbp, CurrencyHkd, CurrencyIdr, CurrencyInr, CurrencyJpy, CurrencyKrw, CurrencyMxn, CurrencyNok, CurrencyNzd, CurrencyPln, CurrencyRmb, CurrencyRon, CurrencyRub, CurrencySar, CurrencySek, CurrencySgd, CurrencyThb, CurrencyTry, CurrencyUsd, CurrencyXag, CurrencyXau, CurrencyZar:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("group: invalid enum value for currency field: %q", c)
|
return fmt.Errorf("group: invalid enum value for currency field: %q", c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OrderOption defines the ordering options for the Group queries.
|
||||||
|
type OrderOption func(*sql.Selector)
|
||||||
|
|
||||||
|
// ByID orders the results by the id field.
|
||||||
|
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByCreatedAt orders the results by the created_at field.
|
||||||
|
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUpdatedAt orders the results by the updated_at field.
|
||||||
|
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByName orders the results by the name field.
|
||||||
|
func ByName(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldName, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByCurrency orders the results by the currency field.
|
||||||
|
func ByCurrency(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldCurrency, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUsersCount orders the results by users count.
|
||||||
|
func ByUsersCount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborsCount(s, newUsersStep(), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUsers orders the results by users terms.
|
||||||
|
func ByUsers(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newUsersStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByLocationsCount orders the results by locations count.
|
||||||
|
func ByLocationsCount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborsCount(s, newLocationsStep(), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByLocations orders the results by locations terms.
|
||||||
|
func ByLocations(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newLocationsStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByItemsCount orders the results by items count.
|
||||||
|
func ByItemsCount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborsCount(s, newItemsStep(), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByItems orders the results by items terms.
|
||||||
|
func ByItems(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newItemsStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByLabelsCount orders the results by labels count.
|
||||||
|
func ByLabelsCount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborsCount(s, newLabelsStep(), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByLabels orders the results by labels terms.
|
||||||
|
func ByLabels(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newLabelsStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByDocumentsCount orders the results by documents count.
|
||||||
|
func ByDocumentsCount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborsCount(s, newDocumentsStep(), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByDocuments orders the results by documents terms.
|
||||||
|
func ByDocuments(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newDocumentsStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByInvitationTokensCount orders the results by invitation_tokens count.
|
||||||
|
func ByInvitationTokensCount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborsCount(s, newInvitationTokensStep(), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByInvitationTokens orders the results by invitation_tokens terms.
|
||||||
|
func ByInvitationTokens(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newInvitationTokensStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByNotifiersCount orders the results by notifiers count.
|
||||||
|
func ByNotifiersCount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborsCount(s, newNotifiersStep(), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByNotifiers orders the results by notifiers terms.
|
||||||
|
func ByNotifiers(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newNotifiersStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func newUsersStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(UsersInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, UsersTable, UsersColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func newLocationsStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(LocationsInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, LocationsTable, LocationsColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func newItemsStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(ItemsInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, ItemsTable, ItemsColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func newLabelsStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(LabelsInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, LabelsTable, LabelsColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func newDocumentsStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(DocumentsInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, DocumentsTable, DocumentsColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func newInvitationTokensStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(InvitationTokensInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, InvitationTokensTable, InvitationTokensColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func newNotifiersStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(NotifiersInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, NotifiersTable, NotifiersColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -250,11 +250,7 @@ func HasUsers() predicate.Group {
|
||||||
// HasUsersWith applies the HasEdge predicate on the "users" edge with a given conditions (other predicates).
|
// HasUsersWith applies the HasEdge predicate on the "users" edge with a given conditions (other predicates).
|
||||||
func HasUsersWith(preds ...predicate.User) predicate.Group {
|
func HasUsersWith(preds ...predicate.User) predicate.Group {
|
||||||
return predicate.Group(func(s *sql.Selector) {
|
return predicate.Group(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newUsersStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(UsersInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.O2M, false, UsersTable, UsersColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
@ -277,11 +273,7 @@ func HasLocations() predicate.Group {
|
||||||
// HasLocationsWith applies the HasEdge predicate on the "locations" edge with a given conditions (other predicates).
|
// HasLocationsWith applies the HasEdge predicate on the "locations" edge with a given conditions (other predicates).
|
||||||
func HasLocationsWith(preds ...predicate.Location) predicate.Group {
|
func HasLocationsWith(preds ...predicate.Location) predicate.Group {
|
||||||
return predicate.Group(func(s *sql.Selector) {
|
return predicate.Group(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newLocationsStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(LocationsInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.O2M, false, LocationsTable, LocationsColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
@ -304,11 +296,7 @@ func HasItems() predicate.Group {
|
||||||
// HasItemsWith applies the HasEdge predicate on the "items" edge with a given conditions (other predicates).
|
// HasItemsWith applies the HasEdge predicate on the "items" edge with a given conditions (other predicates).
|
||||||
func HasItemsWith(preds ...predicate.Item) predicate.Group {
|
func HasItemsWith(preds ...predicate.Item) predicate.Group {
|
||||||
return predicate.Group(func(s *sql.Selector) {
|
return predicate.Group(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newItemsStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(ItemsInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.O2M, false, ItemsTable, ItemsColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
@ -331,11 +319,7 @@ func HasLabels() predicate.Group {
|
||||||
// HasLabelsWith applies the HasEdge predicate on the "labels" edge with a given conditions (other predicates).
|
// HasLabelsWith applies the HasEdge predicate on the "labels" edge with a given conditions (other predicates).
|
||||||
func HasLabelsWith(preds ...predicate.Label) predicate.Group {
|
func HasLabelsWith(preds ...predicate.Label) predicate.Group {
|
||||||
return predicate.Group(func(s *sql.Selector) {
|
return predicate.Group(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newLabelsStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(LabelsInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.O2M, false, LabelsTable, LabelsColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
@ -358,11 +342,7 @@ func HasDocuments() predicate.Group {
|
||||||
// HasDocumentsWith applies the HasEdge predicate on the "documents" edge with a given conditions (other predicates).
|
// HasDocumentsWith applies the HasEdge predicate on the "documents" edge with a given conditions (other predicates).
|
||||||
func HasDocumentsWith(preds ...predicate.Document) predicate.Group {
|
func HasDocumentsWith(preds ...predicate.Document) predicate.Group {
|
||||||
return predicate.Group(func(s *sql.Selector) {
|
return predicate.Group(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newDocumentsStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(DocumentsInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.O2M, false, DocumentsTable, DocumentsColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
@ -384,12 +364,31 @@ func HasInvitationTokens() predicate.Group {
|
||||||
|
|
||||||
// HasInvitationTokensWith applies the HasEdge predicate on the "invitation_tokens" edge with a given conditions (other predicates).
|
// HasInvitationTokensWith applies the HasEdge predicate on the "invitation_tokens" edge with a given conditions (other predicates).
|
||||||
func HasInvitationTokensWith(preds ...predicate.GroupInvitationToken) predicate.Group {
|
func HasInvitationTokensWith(preds ...predicate.GroupInvitationToken) predicate.Group {
|
||||||
|
return predicate.Group(func(s *sql.Selector) {
|
||||||
|
step := newInvitationTokensStep()
|
||||||
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
|
for _, p := range preds {
|
||||||
|
p(s)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasNotifiers applies the HasEdge predicate on the "notifiers" edge.
|
||||||
|
func HasNotifiers() predicate.Group {
|
||||||
return predicate.Group(func(s *sql.Selector) {
|
return predicate.Group(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := sqlgraph.NewStep(
|
||||||
sqlgraph.From(Table, FieldID),
|
sqlgraph.From(Table, FieldID),
|
||||||
sqlgraph.To(InvitationTokensInverseTable, FieldID),
|
sqlgraph.Edge(sqlgraph.O2M, false, NotifiersTable, NotifiersColumn),
|
||||||
sqlgraph.Edge(sqlgraph.O2M, false, InvitationTokensTable, InvitationTokensColumn),
|
|
||||||
)
|
)
|
||||||
|
sqlgraph.HasNeighbors(s, step)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasNotifiersWith applies the HasEdge predicate on the "notifiers" edge with a given conditions (other predicates).
|
||||||
|
func HasNotifiersWith(preds ...predicate.Notifier) predicate.Group {
|
||||||
|
return predicate.Group(func(s *sql.Selector) {
|
||||||
|
step := newNotifiersStep()
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/item"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/item"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -179,6 +180,21 @@ func (gc *GroupCreate) AddInvitationTokens(g ...*GroupInvitationToken) *GroupCre
|
||||||
return gc.AddInvitationTokenIDs(ids...)
|
return gc.AddInvitationTokenIDs(ids...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddNotifierIDs adds the "notifiers" edge to the Notifier entity by IDs.
|
||||||
|
func (gc *GroupCreate) AddNotifierIDs(ids ...uuid.UUID) *GroupCreate {
|
||||||
|
gc.mutation.AddNotifierIDs(ids...)
|
||||||
|
return gc
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNotifiers adds the "notifiers" edges to the Notifier entity.
|
||||||
|
func (gc *GroupCreate) AddNotifiers(n ...*Notifier) *GroupCreate {
|
||||||
|
ids := make([]uuid.UUID, len(n))
|
||||||
|
for i := range n {
|
||||||
|
ids[i] = n[i].ID
|
||||||
|
}
|
||||||
|
return gc.AddNotifierIDs(ids...)
|
||||||
|
}
|
||||||
|
|
||||||
// Mutation returns the GroupMutation object of the builder.
|
// Mutation returns the GroupMutation object of the builder.
|
||||||
func (gc *GroupCreate) Mutation() *GroupMutation {
|
func (gc *GroupCreate) Mutation() *GroupMutation {
|
||||||
return gc.mutation
|
return gc.mutation
|
||||||
|
@ -187,7 +203,7 @@ func (gc *GroupCreate) Mutation() *GroupMutation {
|
||||||
// Save creates the Group in the database.
|
// Save creates the Group in the database.
|
||||||
func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) {
|
func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) {
|
||||||
gc.defaults()
|
gc.defaults()
|
||||||
return withHooks[*Group, GroupMutation](ctx, gc.sqlSave, gc.mutation, gc.hooks)
|
return withHooks(ctx, gc.sqlSave, gc.mutation, gc.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX calls Save and panics if Save returns an error.
|
// SaveX calls Save and panics if Save returns an error.
|
||||||
|
@ -315,10 +331,7 @@ func (gc *GroupCreate) createSpec() (*Group, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{group.UsersColumn},
|
Columns: []string{group.UsersColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -334,10 +347,7 @@ func (gc *GroupCreate) createSpec() (*Group, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{group.LocationsColumn},
|
Columns: []string{group.LocationsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(location.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: location.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -353,10 +363,7 @@ func (gc *GroupCreate) createSpec() (*Group, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{group.ItemsColumn},
|
Columns: []string{group.ItemsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -372,10 +379,7 @@ func (gc *GroupCreate) createSpec() (*Group, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{group.LabelsColumn},
|
Columns: []string{group.LabelsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(label.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: label.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -391,10 +395,7 @@ func (gc *GroupCreate) createSpec() (*Group, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{group.DocumentsColumn},
|
Columns: []string{group.DocumentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -410,10 +411,23 @@ func (gc *GroupCreate) createSpec() (*Group, *sqlgraph.CreateSpec) {
|
||||||
Columns: []string{group.InvitationTokensColumn},
|
Columns: []string{group.InvitationTokensColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(groupinvitationtoken.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
},
|
||||||
Column: groupinvitationtoken.FieldID,
|
}
|
||||||
},
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges = append(_spec.Edges, edge)
|
||||||
|
}
|
||||||
|
if nodes := gc.mutation.NotifiersIDs(); len(nodes) > 0 {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: group.NotifiersTable,
|
||||||
|
Columns: []string{group.NotifiersColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(notifier.FieldID, field.TypeUUID),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -448,8 +462,8 @@ func (gcb *GroupCreateBulk) Save(ctx context.Context) ([]*Group, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
builder.mutation = mutation
|
builder.mutation = mutation
|
||||||
nodes[i], specs[i] = builder.createSpec()
|
|
||||||
var err error
|
var err error
|
||||||
|
nodes[i], specs[i] = builder.createSpec()
|
||||||
if i < len(mutators)-1 {
|
if i < len(mutators)-1 {
|
||||||
_, err = mutators[i+1].Mutate(root, gcb.builders[i+1].mutation)
|
_, err = mutators[i+1].Mutate(root, gcb.builders[i+1].mutation)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -27,7 +27,7 @@ func (gd *GroupDelete) Where(ps ...predicate.Group) *GroupDelete {
|
||||||
|
|
||||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||||
func (gd *GroupDelete) Exec(ctx context.Context) (int, error) {
|
func (gd *GroupDelete) Exec(ctx context.Context) (int, error) {
|
||||||
return withHooks[int, GroupMutation](ctx, gd.sqlExec, gd.mutation, gd.hooks)
|
return withHooks(ctx, gd.sqlExec, gd.mutation, gd.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecX is like Exec, but panics if an error occurs.
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/item"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/item"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||||
)
|
)
|
||||||
|
@ -26,7 +27,7 @@ import (
|
||||||
type GroupQuery struct {
|
type GroupQuery struct {
|
||||||
config
|
config
|
||||||
ctx *QueryContext
|
ctx *QueryContext
|
||||||
order []OrderFunc
|
order []group.OrderOption
|
||||||
inters []Interceptor
|
inters []Interceptor
|
||||||
predicates []predicate.Group
|
predicates []predicate.Group
|
||||||
withUsers *UserQuery
|
withUsers *UserQuery
|
||||||
|
@ -35,6 +36,7 @@ type GroupQuery struct {
|
||||||
withLabels *LabelQuery
|
withLabels *LabelQuery
|
||||||
withDocuments *DocumentQuery
|
withDocuments *DocumentQuery
|
||||||
withInvitationTokens *GroupInvitationTokenQuery
|
withInvitationTokens *GroupInvitationTokenQuery
|
||||||
|
withNotifiers *NotifierQuery
|
||||||
// intermediate query (i.e. traversal path).
|
// intermediate query (i.e. traversal path).
|
||||||
sql *sql.Selector
|
sql *sql.Selector
|
||||||
path func(context.Context) (*sql.Selector, error)
|
path func(context.Context) (*sql.Selector, error)
|
||||||
|
@ -66,7 +68,7 @@ func (gq *GroupQuery) Unique(unique bool) *GroupQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order specifies how the records should be ordered.
|
// Order specifies how the records should be ordered.
|
||||||
func (gq *GroupQuery) Order(o ...OrderFunc) *GroupQuery {
|
func (gq *GroupQuery) Order(o ...group.OrderOption) *GroupQuery {
|
||||||
gq.order = append(gq.order, o...)
|
gq.order = append(gq.order, o...)
|
||||||
return gq
|
return gq
|
||||||
}
|
}
|
||||||
|
@ -203,6 +205,28 @@ func (gq *GroupQuery) QueryInvitationTokens() *GroupInvitationTokenQuery {
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryNotifiers chains the current query on the "notifiers" edge.
|
||||||
|
func (gq *GroupQuery) QueryNotifiers() *NotifierQuery {
|
||||||
|
query := (&NotifierClient{config: gq.config}).Query()
|
||||||
|
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||||
|
if err := gq.prepareQuery(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
selector := gq.sqlQuery(ctx)
|
||||||
|
if err := selector.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(group.Table, group.FieldID, selector),
|
||||||
|
sqlgraph.To(notifier.Table, notifier.FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, group.NotifiersTable, group.NotifiersColumn),
|
||||||
|
)
|
||||||
|
fromU = sqlgraph.SetNeighbors(gq.driver.Dialect(), step)
|
||||||
|
return fromU, nil
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
// First returns the first Group entity from the query.
|
// First returns the first Group entity from the query.
|
||||||
// Returns a *NotFoundError when no Group was found.
|
// Returns a *NotFoundError when no Group was found.
|
||||||
func (gq *GroupQuery) First(ctx context.Context) (*Group, error) {
|
func (gq *GroupQuery) First(ctx context.Context) (*Group, error) {
|
||||||
|
@ -392,7 +416,7 @@ func (gq *GroupQuery) Clone() *GroupQuery {
|
||||||
return &GroupQuery{
|
return &GroupQuery{
|
||||||
config: gq.config,
|
config: gq.config,
|
||||||
ctx: gq.ctx.Clone(),
|
ctx: gq.ctx.Clone(),
|
||||||
order: append([]OrderFunc{}, gq.order...),
|
order: append([]group.OrderOption{}, gq.order...),
|
||||||
inters: append([]Interceptor{}, gq.inters...),
|
inters: append([]Interceptor{}, gq.inters...),
|
||||||
predicates: append([]predicate.Group{}, gq.predicates...),
|
predicates: append([]predicate.Group{}, gq.predicates...),
|
||||||
withUsers: gq.withUsers.Clone(),
|
withUsers: gq.withUsers.Clone(),
|
||||||
|
@ -401,6 +425,7 @@ func (gq *GroupQuery) Clone() *GroupQuery {
|
||||||
withLabels: gq.withLabels.Clone(),
|
withLabels: gq.withLabels.Clone(),
|
||||||
withDocuments: gq.withDocuments.Clone(),
|
withDocuments: gq.withDocuments.Clone(),
|
||||||
withInvitationTokens: gq.withInvitationTokens.Clone(),
|
withInvitationTokens: gq.withInvitationTokens.Clone(),
|
||||||
|
withNotifiers: gq.withNotifiers.Clone(),
|
||||||
// clone intermediate query.
|
// clone intermediate query.
|
||||||
sql: gq.sql.Clone(),
|
sql: gq.sql.Clone(),
|
||||||
path: gq.path,
|
path: gq.path,
|
||||||
|
@ -473,6 +498,17 @@ func (gq *GroupQuery) WithInvitationTokens(opts ...func(*GroupInvitationTokenQue
|
||||||
return gq
|
return gq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithNotifiers tells the query-builder to eager-load the nodes that are connected to
|
||||||
|
// the "notifiers" edge. The optional arguments are used to configure the query builder of the edge.
|
||||||
|
func (gq *GroupQuery) WithNotifiers(opts ...func(*NotifierQuery)) *GroupQuery {
|
||||||
|
query := (&NotifierClient{config: gq.config}).Query()
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(query)
|
||||||
|
}
|
||||||
|
gq.withNotifiers = query
|
||||||
|
return gq
|
||||||
|
}
|
||||||
|
|
||||||
// GroupBy is used to group vertices by one or more fields/columns.
|
// GroupBy is used to group vertices by one or more fields/columns.
|
||||||
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||||
//
|
//
|
||||||
|
@ -551,13 +587,14 @@ func (gq *GroupQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Group,
|
||||||
var (
|
var (
|
||||||
nodes = []*Group{}
|
nodes = []*Group{}
|
||||||
_spec = gq.querySpec()
|
_spec = gq.querySpec()
|
||||||
loadedTypes = [6]bool{
|
loadedTypes = [7]bool{
|
||||||
gq.withUsers != nil,
|
gq.withUsers != nil,
|
||||||
gq.withLocations != nil,
|
gq.withLocations != nil,
|
||||||
gq.withItems != nil,
|
gq.withItems != nil,
|
||||||
gq.withLabels != nil,
|
gq.withLabels != nil,
|
||||||
gq.withDocuments != nil,
|
gq.withDocuments != nil,
|
||||||
gq.withInvitationTokens != nil,
|
gq.withInvitationTokens != nil,
|
||||||
|
gq.withNotifiers != nil,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||||
|
@ -622,6 +659,13 @@ func (gq *GroupQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Group,
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if query := gq.withNotifiers; query != nil {
|
||||||
|
if err := gq.loadNotifiers(ctx, query, nodes,
|
||||||
|
func(n *Group) { n.Edges.Notifiers = []*Notifier{} },
|
||||||
|
func(n *Group, e *Notifier) { n.Edges.Notifiers = append(n.Edges.Notifiers, e) }); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
return nodes, nil
|
return nodes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,7 +681,7 @@ func (gq *GroupQuery) loadUsers(ctx context.Context, query *UserQuery, nodes []*
|
||||||
}
|
}
|
||||||
query.withFKs = true
|
query.withFKs = true
|
||||||
query.Where(predicate.User(func(s *sql.Selector) {
|
query.Where(predicate.User(func(s *sql.Selector) {
|
||||||
s.Where(sql.InValues(group.UsersColumn, fks...))
|
s.Where(sql.InValues(s.C(group.UsersColumn), fks...))
|
||||||
}))
|
}))
|
||||||
neighbors, err := query.All(ctx)
|
neighbors, err := query.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -650,7 +694,7 @@ func (gq *GroupQuery) loadUsers(ctx context.Context, query *UserQuery, nodes []*
|
||||||
}
|
}
|
||||||
node, ok := nodeids[*fk]
|
node, ok := nodeids[*fk]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf(`unexpected foreign-key "group_users" returned %v for node %v`, *fk, n.ID)
|
return fmt.Errorf(`unexpected referenced foreign-key "group_users" returned %v for node %v`, *fk, n.ID)
|
||||||
}
|
}
|
||||||
assign(node, n)
|
assign(node, n)
|
||||||
}
|
}
|
||||||
|
@ -668,7 +712,7 @@ func (gq *GroupQuery) loadLocations(ctx context.Context, query *LocationQuery, n
|
||||||
}
|
}
|
||||||
query.withFKs = true
|
query.withFKs = true
|
||||||
query.Where(predicate.Location(func(s *sql.Selector) {
|
query.Where(predicate.Location(func(s *sql.Selector) {
|
||||||
s.Where(sql.InValues(group.LocationsColumn, fks...))
|
s.Where(sql.InValues(s.C(group.LocationsColumn), fks...))
|
||||||
}))
|
}))
|
||||||
neighbors, err := query.All(ctx)
|
neighbors, err := query.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -681,7 +725,7 @@ func (gq *GroupQuery) loadLocations(ctx context.Context, query *LocationQuery, n
|
||||||
}
|
}
|
||||||
node, ok := nodeids[*fk]
|
node, ok := nodeids[*fk]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf(`unexpected foreign-key "group_locations" returned %v for node %v`, *fk, n.ID)
|
return fmt.Errorf(`unexpected referenced foreign-key "group_locations" returned %v for node %v`, *fk, n.ID)
|
||||||
}
|
}
|
||||||
assign(node, n)
|
assign(node, n)
|
||||||
}
|
}
|
||||||
|
@ -699,7 +743,7 @@ func (gq *GroupQuery) loadItems(ctx context.Context, query *ItemQuery, nodes []*
|
||||||
}
|
}
|
||||||
query.withFKs = true
|
query.withFKs = true
|
||||||
query.Where(predicate.Item(func(s *sql.Selector) {
|
query.Where(predicate.Item(func(s *sql.Selector) {
|
||||||
s.Where(sql.InValues(group.ItemsColumn, fks...))
|
s.Where(sql.InValues(s.C(group.ItemsColumn), fks...))
|
||||||
}))
|
}))
|
||||||
neighbors, err := query.All(ctx)
|
neighbors, err := query.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -712,7 +756,7 @@ func (gq *GroupQuery) loadItems(ctx context.Context, query *ItemQuery, nodes []*
|
||||||
}
|
}
|
||||||
node, ok := nodeids[*fk]
|
node, ok := nodeids[*fk]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf(`unexpected foreign-key "group_items" returned %v for node %v`, *fk, n.ID)
|
return fmt.Errorf(`unexpected referenced foreign-key "group_items" returned %v for node %v`, *fk, n.ID)
|
||||||
}
|
}
|
||||||
assign(node, n)
|
assign(node, n)
|
||||||
}
|
}
|
||||||
|
@ -730,7 +774,7 @@ func (gq *GroupQuery) loadLabels(ctx context.Context, query *LabelQuery, nodes [
|
||||||
}
|
}
|
||||||
query.withFKs = true
|
query.withFKs = true
|
||||||
query.Where(predicate.Label(func(s *sql.Selector) {
|
query.Where(predicate.Label(func(s *sql.Selector) {
|
||||||
s.Where(sql.InValues(group.LabelsColumn, fks...))
|
s.Where(sql.InValues(s.C(group.LabelsColumn), fks...))
|
||||||
}))
|
}))
|
||||||
neighbors, err := query.All(ctx)
|
neighbors, err := query.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -743,7 +787,7 @@ func (gq *GroupQuery) loadLabels(ctx context.Context, query *LabelQuery, nodes [
|
||||||
}
|
}
|
||||||
node, ok := nodeids[*fk]
|
node, ok := nodeids[*fk]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf(`unexpected foreign-key "group_labels" returned %v for node %v`, *fk, n.ID)
|
return fmt.Errorf(`unexpected referenced foreign-key "group_labels" returned %v for node %v`, *fk, n.ID)
|
||||||
}
|
}
|
||||||
assign(node, n)
|
assign(node, n)
|
||||||
}
|
}
|
||||||
|
@ -761,7 +805,7 @@ func (gq *GroupQuery) loadDocuments(ctx context.Context, query *DocumentQuery, n
|
||||||
}
|
}
|
||||||
query.withFKs = true
|
query.withFKs = true
|
||||||
query.Where(predicate.Document(func(s *sql.Selector) {
|
query.Where(predicate.Document(func(s *sql.Selector) {
|
||||||
s.Where(sql.InValues(group.DocumentsColumn, fks...))
|
s.Where(sql.InValues(s.C(group.DocumentsColumn), fks...))
|
||||||
}))
|
}))
|
||||||
neighbors, err := query.All(ctx)
|
neighbors, err := query.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -774,7 +818,7 @@ func (gq *GroupQuery) loadDocuments(ctx context.Context, query *DocumentQuery, n
|
||||||
}
|
}
|
||||||
node, ok := nodeids[*fk]
|
node, ok := nodeids[*fk]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf(`unexpected foreign-key "group_documents" returned %v for node %v`, *fk, n.ID)
|
return fmt.Errorf(`unexpected referenced foreign-key "group_documents" returned %v for node %v`, *fk, n.ID)
|
||||||
}
|
}
|
||||||
assign(node, n)
|
assign(node, n)
|
||||||
}
|
}
|
||||||
|
@ -792,7 +836,7 @@ func (gq *GroupQuery) loadInvitationTokens(ctx context.Context, query *GroupInvi
|
||||||
}
|
}
|
||||||
query.withFKs = true
|
query.withFKs = true
|
||||||
query.Where(predicate.GroupInvitationToken(func(s *sql.Selector) {
|
query.Where(predicate.GroupInvitationToken(func(s *sql.Selector) {
|
||||||
s.Where(sql.InValues(group.InvitationTokensColumn, fks...))
|
s.Where(sql.InValues(s.C(group.InvitationTokensColumn), fks...))
|
||||||
}))
|
}))
|
||||||
neighbors, err := query.All(ctx)
|
neighbors, err := query.All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -805,7 +849,37 @@ func (gq *GroupQuery) loadInvitationTokens(ctx context.Context, query *GroupInvi
|
||||||
}
|
}
|
||||||
node, ok := nodeids[*fk]
|
node, ok := nodeids[*fk]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf(`unexpected foreign-key "group_invitation_tokens" returned %v for node %v`, *fk, n.ID)
|
return fmt.Errorf(`unexpected referenced foreign-key "group_invitation_tokens" returned %v for node %v`, *fk, n.ID)
|
||||||
|
}
|
||||||
|
assign(node, n)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (gq *GroupQuery) loadNotifiers(ctx context.Context, query *NotifierQuery, nodes []*Group, init func(*Group), assign func(*Group, *Notifier)) error {
|
||||||
|
fks := make([]driver.Value, 0, len(nodes))
|
||||||
|
nodeids := make(map[uuid.UUID]*Group)
|
||||||
|
for i := range nodes {
|
||||||
|
fks = append(fks, nodes[i].ID)
|
||||||
|
nodeids[nodes[i].ID] = nodes[i]
|
||||||
|
if init != nil {
|
||||||
|
init(nodes[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(query.ctx.Fields) > 0 {
|
||||||
|
query.ctx.AppendFieldOnce(notifier.FieldGroupID)
|
||||||
|
}
|
||||||
|
query.Where(predicate.Notifier(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.InValues(s.C(group.NotifiersColumn), fks...))
|
||||||
|
}))
|
||||||
|
neighbors, err := query.All(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, n := range neighbors {
|
||||||
|
fk := n.GroupID
|
||||||
|
node, ok := nodeids[fk]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf(`unexpected referenced foreign-key "group_id" returned %v for node %v`, fk, n.ID)
|
||||||
}
|
}
|
||||||
assign(node, n)
|
assign(node, n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/item"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/item"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||||
)
|
)
|
||||||
|
@ -151,6 +152,21 @@ func (gu *GroupUpdate) AddInvitationTokens(g ...*GroupInvitationToken) *GroupUpd
|
||||||
return gu.AddInvitationTokenIDs(ids...)
|
return gu.AddInvitationTokenIDs(ids...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddNotifierIDs adds the "notifiers" edge to the Notifier entity by IDs.
|
||||||
|
func (gu *GroupUpdate) AddNotifierIDs(ids ...uuid.UUID) *GroupUpdate {
|
||||||
|
gu.mutation.AddNotifierIDs(ids...)
|
||||||
|
return gu
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNotifiers adds the "notifiers" edges to the Notifier entity.
|
||||||
|
func (gu *GroupUpdate) AddNotifiers(n ...*Notifier) *GroupUpdate {
|
||||||
|
ids := make([]uuid.UUID, len(n))
|
||||||
|
for i := range n {
|
||||||
|
ids[i] = n[i].ID
|
||||||
|
}
|
||||||
|
return gu.AddNotifierIDs(ids...)
|
||||||
|
}
|
||||||
|
|
||||||
// Mutation returns the GroupMutation object of the builder.
|
// Mutation returns the GroupMutation object of the builder.
|
||||||
func (gu *GroupUpdate) Mutation() *GroupMutation {
|
func (gu *GroupUpdate) Mutation() *GroupMutation {
|
||||||
return gu.mutation
|
return gu.mutation
|
||||||
|
@ -282,10 +298,31 @@ func (gu *GroupUpdate) RemoveInvitationTokens(g ...*GroupInvitationToken) *Group
|
||||||
return gu.RemoveInvitationTokenIDs(ids...)
|
return gu.RemoveInvitationTokenIDs(ids...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearNotifiers clears all "notifiers" edges to the Notifier entity.
|
||||||
|
func (gu *GroupUpdate) ClearNotifiers() *GroupUpdate {
|
||||||
|
gu.mutation.ClearNotifiers()
|
||||||
|
return gu
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveNotifierIDs removes the "notifiers" edge to Notifier entities by IDs.
|
||||||
|
func (gu *GroupUpdate) RemoveNotifierIDs(ids ...uuid.UUID) *GroupUpdate {
|
||||||
|
gu.mutation.RemoveNotifierIDs(ids...)
|
||||||
|
return gu
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveNotifiers removes "notifiers" edges to Notifier entities.
|
||||||
|
func (gu *GroupUpdate) RemoveNotifiers(n ...*Notifier) *GroupUpdate {
|
||||||
|
ids := make([]uuid.UUID, len(n))
|
||||||
|
for i := range n {
|
||||||
|
ids[i] = n[i].ID
|
||||||
|
}
|
||||||
|
return gu.RemoveNotifierIDs(ids...)
|
||||||
|
}
|
||||||
|
|
||||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||||
func (gu *GroupUpdate) Save(ctx context.Context) (int, error) {
|
func (gu *GroupUpdate) Save(ctx context.Context) (int, error) {
|
||||||
gu.defaults()
|
gu.defaults()
|
||||||
return withHooks[int, GroupMutation](ctx, gu.sqlSave, gu.mutation, gu.hooks)
|
return withHooks(ctx, gu.sqlSave, gu.mutation, gu.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX is like Save, but panics if an error occurs.
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
@ -362,10 +399,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.UsersColumn},
|
Columns: []string{group.UsersColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -378,10 +412,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.UsersColumn},
|
Columns: []string{group.UsersColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -397,10 +428,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.UsersColumn},
|
Columns: []string{group.UsersColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -416,10 +444,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.LocationsColumn},
|
Columns: []string{group.LocationsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(location.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: location.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -432,10 +457,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.LocationsColumn},
|
Columns: []string{group.LocationsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(location.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: location.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -451,10 +473,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.LocationsColumn},
|
Columns: []string{group.LocationsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(location.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: location.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -470,10 +489,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.ItemsColumn},
|
Columns: []string{group.ItemsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -486,10 +502,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.ItemsColumn},
|
Columns: []string{group.ItemsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -505,10 +518,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.ItemsColumn},
|
Columns: []string{group.ItemsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -524,10 +534,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.LabelsColumn},
|
Columns: []string{group.LabelsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(label.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: label.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -540,10 +547,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.LabelsColumn},
|
Columns: []string{group.LabelsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(label.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: label.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -559,10 +563,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.LabelsColumn},
|
Columns: []string{group.LabelsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(label.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: label.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -578,10 +579,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.DocumentsColumn},
|
Columns: []string{group.DocumentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -594,10 +592,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.DocumentsColumn},
|
Columns: []string{group.DocumentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -613,10 +608,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.DocumentsColumn},
|
Columns: []string{group.DocumentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -632,10 +624,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.InvitationTokensColumn},
|
Columns: []string{group.InvitationTokensColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(groupinvitationtoken.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: groupinvitationtoken.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -648,10 +637,7 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.InvitationTokensColumn},
|
Columns: []string{group.InvitationTokensColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(groupinvitationtoken.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: groupinvitationtoken.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -667,10 +653,52 @@ func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Columns: []string{group.InvitationTokensColumn},
|
Columns: []string{group.InvitationTokensColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(groupinvitationtoken.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
},
|
||||||
Column: groupinvitationtoken.FieldID,
|
}
|
||||||
},
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||||
|
}
|
||||||
|
if gu.mutation.NotifiersCleared() {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: group.NotifiersTable,
|
||||||
|
Columns: []string{group.NotifiersColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(notifier.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
}
|
||||||
|
if nodes := gu.mutation.RemovedNotifiersIDs(); len(nodes) > 0 && !gu.mutation.NotifiersCleared() {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: group.NotifiersTable,
|
||||||
|
Columns: []string{group.NotifiersColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(notifier.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
}
|
||||||
|
if nodes := gu.mutation.NotifiersIDs(); len(nodes) > 0 {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: group.NotifiersTable,
|
||||||
|
Columns: []string{group.NotifiersColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(notifier.FieldID, field.TypeUUID),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -814,6 +842,21 @@ func (guo *GroupUpdateOne) AddInvitationTokens(g ...*GroupInvitationToken) *Grou
|
||||||
return guo.AddInvitationTokenIDs(ids...)
|
return guo.AddInvitationTokenIDs(ids...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddNotifierIDs adds the "notifiers" edge to the Notifier entity by IDs.
|
||||||
|
func (guo *GroupUpdateOne) AddNotifierIDs(ids ...uuid.UUID) *GroupUpdateOne {
|
||||||
|
guo.mutation.AddNotifierIDs(ids...)
|
||||||
|
return guo
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNotifiers adds the "notifiers" edges to the Notifier entity.
|
||||||
|
func (guo *GroupUpdateOne) AddNotifiers(n ...*Notifier) *GroupUpdateOne {
|
||||||
|
ids := make([]uuid.UUID, len(n))
|
||||||
|
for i := range n {
|
||||||
|
ids[i] = n[i].ID
|
||||||
|
}
|
||||||
|
return guo.AddNotifierIDs(ids...)
|
||||||
|
}
|
||||||
|
|
||||||
// Mutation returns the GroupMutation object of the builder.
|
// Mutation returns the GroupMutation object of the builder.
|
||||||
func (guo *GroupUpdateOne) Mutation() *GroupMutation {
|
func (guo *GroupUpdateOne) Mutation() *GroupMutation {
|
||||||
return guo.mutation
|
return guo.mutation
|
||||||
|
@ -945,6 +988,27 @@ func (guo *GroupUpdateOne) RemoveInvitationTokens(g ...*GroupInvitationToken) *G
|
||||||
return guo.RemoveInvitationTokenIDs(ids...)
|
return guo.RemoveInvitationTokenIDs(ids...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearNotifiers clears all "notifiers" edges to the Notifier entity.
|
||||||
|
func (guo *GroupUpdateOne) ClearNotifiers() *GroupUpdateOne {
|
||||||
|
guo.mutation.ClearNotifiers()
|
||||||
|
return guo
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveNotifierIDs removes the "notifiers" edge to Notifier entities by IDs.
|
||||||
|
func (guo *GroupUpdateOne) RemoveNotifierIDs(ids ...uuid.UUID) *GroupUpdateOne {
|
||||||
|
guo.mutation.RemoveNotifierIDs(ids...)
|
||||||
|
return guo
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveNotifiers removes "notifiers" edges to Notifier entities.
|
||||||
|
func (guo *GroupUpdateOne) RemoveNotifiers(n ...*Notifier) *GroupUpdateOne {
|
||||||
|
ids := make([]uuid.UUID, len(n))
|
||||||
|
for i := range n {
|
||||||
|
ids[i] = n[i].ID
|
||||||
|
}
|
||||||
|
return guo.RemoveNotifierIDs(ids...)
|
||||||
|
}
|
||||||
|
|
||||||
// Where appends a list predicates to the GroupUpdate builder.
|
// Where appends a list predicates to the GroupUpdate builder.
|
||||||
func (guo *GroupUpdateOne) Where(ps ...predicate.Group) *GroupUpdateOne {
|
func (guo *GroupUpdateOne) Where(ps ...predicate.Group) *GroupUpdateOne {
|
||||||
guo.mutation.Where(ps...)
|
guo.mutation.Where(ps...)
|
||||||
|
@ -961,7 +1025,7 @@ func (guo *GroupUpdateOne) Select(field string, fields ...string) *GroupUpdateOn
|
||||||
// Save executes the query and returns the updated Group entity.
|
// Save executes the query and returns the updated Group entity.
|
||||||
func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) {
|
func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) {
|
||||||
guo.defaults()
|
guo.defaults()
|
||||||
return withHooks[*Group, GroupMutation](ctx, guo.sqlSave, guo.mutation, guo.hooks)
|
return withHooks(ctx, guo.sqlSave, guo.mutation, guo.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveX is like Save, but panics if an error occurs.
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
@ -1055,10 +1119,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.UsersColumn},
|
Columns: []string{group.UsersColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -1071,10 +1132,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.UsersColumn},
|
Columns: []string{group.UsersColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -1090,10 +1148,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.UsersColumn},
|
Columns: []string{group.UsersColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: user.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -1109,10 +1164,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.LocationsColumn},
|
Columns: []string{group.LocationsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(location.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: location.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -1125,10 +1177,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.LocationsColumn},
|
Columns: []string{group.LocationsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(location.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: location.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -1144,10 +1193,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.LocationsColumn},
|
Columns: []string{group.LocationsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(location.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: location.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -1163,10 +1209,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.ItemsColumn},
|
Columns: []string{group.ItemsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -1179,10 +1222,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.ItemsColumn},
|
Columns: []string{group.ItemsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -1198,10 +1238,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.ItemsColumn},
|
Columns: []string{group.ItemsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(item.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: item.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -1217,10 +1254,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.LabelsColumn},
|
Columns: []string{group.LabelsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(label.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: label.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -1233,10 +1267,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.LabelsColumn},
|
Columns: []string{group.LabelsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(label.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: label.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -1252,10 +1283,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.LabelsColumn},
|
Columns: []string{group.LabelsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(label.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: label.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -1271,10 +1299,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.DocumentsColumn},
|
Columns: []string{group.DocumentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -1287,10 +1312,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.DocumentsColumn},
|
Columns: []string{group.DocumentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -1306,10 +1328,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.DocumentsColumn},
|
Columns: []string{group.DocumentsColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: document.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -1325,10 +1344,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.InvitationTokensColumn},
|
Columns: []string{group.InvitationTokensColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(groupinvitationtoken.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: groupinvitationtoken.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
@ -1341,10 +1357,7 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.InvitationTokensColumn},
|
Columns: []string{group.InvitationTokensColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(groupinvitationtoken.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
|
||||||
Column: groupinvitationtoken.FieldID,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
@ -1360,10 +1373,52 @@ func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error
|
||||||
Columns: []string{group.InvitationTokensColumn},
|
Columns: []string{group.InvitationTokensColumn},
|
||||||
Bidi: false,
|
Bidi: false,
|
||||||
Target: &sqlgraph.EdgeTarget{
|
Target: &sqlgraph.EdgeTarget{
|
||||||
IDSpec: &sqlgraph.FieldSpec{
|
IDSpec: sqlgraph.NewFieldSpec(groupinvitationtoken.FieldID, field.TypeUUID),
|
||||||
Type: field.TypeUUID,
|
},
|
||||||
Column: groupinvitationtoken.FieldID,
|
}
|
||||||
},
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||||
|
}
|
||||||
|
if guo.mutation.NotifiersCleared() {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: group.NotifiersTable,
|
||||||
|
Columns: []string{group.NotifiersColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(notifier.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
}
|
||||||
|
if nodes := guo.mutation.RemovedNotifiersIDs(); len(nodes) > 0 && !guo.mutation.NotifiersCleared() {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: group.NotifiersTable,
|
||||||
|
Columns: []string{group.NotifiersColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(notifier.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
}
|
||||||
|
if nodes := guo.mutation.NotifiersIDs(); len(nodes) > 0 {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: group.NotifiersTable,
|
||||||
|
Columns: []string{group.NotifiersColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(notifier.FieldID, field.TypeUUID),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
||||||
|
@ -32,6 +33,7 @@ type GroupInvitationToken struct {
|
||||||
// The values are being populated by the GroupInvitationTokenQuery when eager-loading is set.
|
// The values are being populated by the GroupInvitationTokenQuery when eager-loading is set.
|
||||||
Edges GroupInvitationTokenEdges `json:"edges"`
|
Edges GroupInvitationTokenEdges `json:"edges"`
|
||||||
group_invitation_tokens *uuid.UUID
|
group_invitation_tokens *uuid.UUID
|
||||||
|
selectValues sql.SelectValues
|
||||||
}
|
}
|
||||||
|
|
||||||
// GroupInvitationTokenEdges holds the relations/edges for other nodes in the graph.
|
// GroupInvitationTokenEdges holds the relations/edges for other nodes in the graph.
|
||||||
|
@ -72,7 +74,7 @@ func (*GroupInvitationToken) scanValues(columns []string) ([]any, error) {
|
||||||
case groupinvitationtoken.ForeignKeys[0]: // group_invitation_tokens
|
case groupinvitationtoken.ForeignKeys[0]: // group_invitation_tokens
|
||||||
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected column %q for type GroupInvitationToken", columns[i])
|
values[i] = new(sql.UnknownType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values, nil
|
return values, nil
|
||||||
|
@ -129,11 +131,19 @@ func (git *GroupInvitationToken) assignValues(columns []string, values []any) er
|
||||||
git.group_invitation_tokens = new(uuid.UUID)
|
git.group_invitation_tokens = new(uuid.UUID)
|
||||||
*git.group_invitation_tokens = *value.S.(*uuid.UUID)
|
*git.group_invitation_tokens = *value.S.(*uuid.UUID)
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
git.selectValues.Set(columns[i], values[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Value returns the ent.Value that was dynamically selected and assigned to the GroupInvitationToken.
|
||||||
|
// This includes values selected through modifiers, order, etc.
|
||||||
|
func (git *GroupInvitationToken) Value(name string) (ent.Value, error) {
|
||||||
|
return git.selectValues.Get(name)
|
||||||
|
}
|
||||||
|
|
||||||
// QueryGroup queries the "group" edge of the GroupInvitationToken entity.
|
// QueryGroup queries the "group" edge of the GroupInvitationToken entity.
|
||||||
func (git *GroupInvitationToken) QueryGroup() *GroupQuery {
|
func (git *GroupInvitationToken) QueryGroup() *GroupQuery {
|
||||||
return NewGroupInvitationTokenClient(git.config).QueryGroup(git)
|
return NewGroupInvitationTokenClient(git.config).QueryGroup(git)
|
||||||
|
|
|
@ -5,6 +5,8 @@ package groupinvitationtoken
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -81,3 +83,45 @@ var (
|
||||||
// DefaultID holds the default value on creation for the "id" field.
|
// DefaultID holds the default value on creation for the "id" field.
|
||||||
DefaultID func() uuid.UUID
|
DefaultID func() uuid.UUID
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// OrderOption defines the ordering options for the GroupInvitationToken queries.
|
||||||
|
type OrderOption func(*sql.Selector)
|
||||||
|
|
||||||
|
// ByID orders the results by the id field.
|
||||||
|
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByCreatedAt orders the results by the created_at field.
|
||||||
|
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUpdatedAt orders the results by the updated_at field.
|
||||||
|
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByExpiresAt orders the results by the expires_at field.
|
||||||
|
func ByExpiresAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldExpiresAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUses orders the results by the uses field.
|
||||||
|
func ByUses(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldUses, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByGroupField orders the results by group field.
|
||||||
|
func ByGroupField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newGroupStep(), sql.OrderByField(field, opts...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func newGroupStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(GroupInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, GroupTable, GroupColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -295,11 +295,7 @@ func HasGroup() predicate.GroupInvitationToken {
|
||||||
// HasGroupWith applies the HasEdge predicate on the "group" edge with a given conditions (other predicates).
|
// HasGroupWith applies the HasEdge predicate on the "group" edge with a given conditions (other predicates).
|
||||||
func HasGroupWith(preds ...predicate.Group) predicate.GroupInvitationToken {
|
func HasGroupWith(preds ...predicate.Group) predicate.GroupInvitationToken {
|
||||||
return predicate.GroupInvitationToken(func(s *sql.Selector) {
|
return predicate.GroupInvitationToken(func(s *sql.Selector) {
|
||||||
step := sqlgraph.NewStep(
|
step := newGroupStep()
|
||||||
sqlgraph.From(Table, FieldID),
|
|
||||||
sqlgraph.To(GroupInverseTable, FieldID),
|
|
||||||
sqlgraph.Edge(sqlgraph.M2O, true, GroupTable, GroupColumn),
|
|
||||||
)
|
|
||||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
for _, p := range preds {
|
for _, p := range preds {
|
||||||
p(s)
|
p(s)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue