mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-24 22:39:14 +01:00
Compare commits
343 Commits
katos/purc
...
v0.16.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e81e60106 | ||
|
|
19ccfee083 | ||
|
|
363c9dac6e | ||
|
|
9f3d50b9f7 | ||
|
|
2f8a7e2a90 | ||
|
|
5d51c74af2 | ||
|
|
121d577e45 | ||
|
|
64237a2722 | ||
|
|
3d972dcac3 | ||
|
|
6662bbd5b9 | ||
|
|
05fbb207d1 | ||
|
|
b5c7566d37 | ||
|
|
7228c64b26 | ||
|
|
744d8d6733 | ||
|
|
d5e66f29b0 | ||
|
|
030323224d | ||
|
|
76b6c34533 | ||
|
|
8d65b70922 | ||
|
|
40b1793cce | ||
|
|
e2740a9b79 | ||
|
|
4510712359 | ||
|
|
1268fd90ba | ||
|
|
ec5b6bb8ff | ||
|
|
c0860fc9ca | ||
|
|
8d93ab3d7f | ||
|
|
d39d109031 | ||
|
|
1d5b62fdf3 | ||
|
|
a9616911f5 | ||
|
|
3eb5ece34d | ||
|
|
77246ca57b | ||
|
|
087a328e83 | ||
|
|
8a6df8a69b | ||
|
|
c2546f06d4 | ||
|
|
3a4c78ed86 | ||
|
|
ed7670ac67 | ||
|
|
2cd50435b5 | ||
|
|
9b72419e6b | ||
|
|
a1e66854cd | ||
|
|
ab756aaa56 | ||
|
|
d45c8b2b2d | ||
|
|
f26b5e1190 | ||
|
|
8bfa930cf0 | ||
|
|
52f9306e98 | ||
|
|
483934bd5e | ||
|
|
de7ef70d40 | ||
|
|
1e020f7fae | ||
|
|
0d6ec9c427 | ||
|
|
e32683fb28 | ||
|
|
67c77a7d91 | ||
|
|
55acfa54f5 | ||
|
|
7f742738fa | ||
|
|
888973e2cb | ||
|
|
65b247573e | ||
|
|
8f255ccfd4 | ||
|
|
c9ed50afad | ||
|
|
3fd14aac47 | ||
|
|
ed780e292b | ||
|
|
c6158e7c9e | ||
|
|
5d3698d0d8 | ||
|
|
a70bb227a9 | ||
|
|
908bfb530e | ||
|
|
738fe6db03 | ||
|
|
733ccb51c3 | ||
|
|
ed3d106289 | ||
|
|
333bca85f8 | ||
|
|
1ebc3d9c27 | ||
|
|
c298b651b6 | ||
|
|
d8260b9988 | ||
|
|
d0a69c8446 | ||
|
|
f3388b8449 | ||
|
|
c94eb4e183 | ||
|
|
f386d1213f | ||
|
|
9b7b00e8f2 | ||
|
|
055f0219a8 | ||
|
|
9d3f3cf1da | ||
|
|
da8cc19838 | ||
|
|
a3d5485c1d | ||
|
|
865661097c | ||
|
|
ab48f55335 | ||
|
|
49f52cada4 | ||
|
|
059bc5f16c | ||
|
|
a8eab724f9 | ||
|
|
eed967e9b4 | ||
|
|
2eb421455b | ||
|
|
e0d86ce745 | ||
|
|
ba8f32cec8 | ||
|
|
4af6bf210e | ||
|
|
1de3ecda19 | ||
|
|
4a0039c838 | ||
|
|
02a34ed1a0 | ||
|
|
dc23a1ae23 | ||
|
|
4fea927880 | ||
|
|
ff874ac472 | ||
|
|
ba48a615cd | ||
|
|
5aa389b13c | ||
|
|
b500f6b51f | ||
|
|
2ea9ed0476 | ||
|
|
68ee701e46 | ||
|
|
dc88406bcc | ||
|
|
ca85d4b483 | ||
|
|
17ecfa2c66 | ||
|
|
cabaa07384 | ||
|
|
d9b05e872c | ||
|
|
bd60c36240 | ||
|
|
1fc9843450 | ||
|
|
4e260c5a8b | ||
|
|
55a9355046 | ||
|
|
5bee3dd429 | ||
|
|
a85c42b539 | ||
|
|
897f3842e0 | ||
|
|
791d390187 | ||
|
|
e85b1a44b1 | ||
|
|
ffd59d535c | ||
|
|
e32a1041b1 | ||
|
|
c16269bcb4 | ||
|
|
81d57d4c47 | ||
|
|
bdb3b5dc24 | ||
|
|
666903e663 | ||
|
|
24deb462a8 | ||
|
|
85b54c4ccf | ||
|
|
ca33d499ab | ||
|
|
52ebff7ca4 | ||
|
|
4cf0b0a9df | ||
|
|
0d92d2718d | ||
|
|
22937dd314 | ||
|
|
26a99b6bad | ||
|
|
4bf7f3e00c | ||
|
|
269c5ea7e3 | ||
|
|
bac6212188 | ||
|
|
7a7d00220a | ||
|
|
a20f94b68a | ||
|
|
7c4c373851 | ||
|
|
8b0684a0ca | ||
|
|
c903a9df13 | ||
|
|
a5d4e4f491 | ||
|
|
f3116e4729 | ||
|
|
c0b88142d8 | ||
|
|
19adc6a441 | ||
|
|
d9fa7a846c | ||
|
|
aa30fba7af | ||
|
|
edbb4b9fa0 | ||
|
|
7d8534ffc1 | ||
|
|
28b79beb76 | ||
|
|
8a7af9a98d | ||
|
|
47600ade0e | ||
|
|
2af0cfeb49 | ||
|
|
f6690dc80f | ||
|
|
9de5cf8c58 | ||
|
|
9e66bf0bc1 | ||
|
|
5f27f5d9cc | ||
|
|
0a1667ed24 | ||
|
|
6348aeac6e | ||
|
|
7e9bd7f44b | ||
|
|
cf780393c2 | ||
|
|
e94f436ba6 | ||
|
|
0c6be05b05 | ||
|
|
9297ac59ae | ||
|
|
983dedfdad | ||
|
|
d159908b91 | ||
|
|
1b53a5235c | ||
|
|
f3f709748e | ||
|
|
64ceffefe9 | ||
|
|
4b24653b86 | ||
|
|
6a0ebb76ea | ||
|
|
8e273730be | ||
|
|
5c09953e4c | ||
|
|
6866dc76c0 | ||
|
|
de16f09108 | ||
|
|
3f3ca345fd | ||
|
|
9275d2db9c | ||
|
|
d88b04b66f | ||
|
|
62e6b08baf | ||
|
|
6fa37cb474 | ||
|
|
d63d6e94dd | ||
|
|
0c8ce366eb | ||
|
|
3da3025935 | ||
|
|
d1a57e3ec5 | ||
|
|
969ef1941b | ||
|
|
214b16a26e | ||
|
|
405d0c7487 | ||
|
|
6800c2112e | ||
|
|
5fc7b3e25b | ||
|
|
88dc943b6b | ||
|
|
f8482b1c64 | ||
|
|
a6e49295e0 | ||
|
|
8ef1b8b6ce | ||
|
|
404791a344 | ||
|
|
073aade67f | ||
|
|
784cc409d4 | ||
|
|
9e3f82fbac | ||
|
|
19c6d4dec5 | ||
|
|
b18f0c790b | ||
|
|
fb62f51958 | ||
|
|
dafc6aa13f | ||
|
|
93f13b1e80 | ||
|
|
5de649d85f | ||
|
|
b37cf24f09 | ||
|
|
cf2edc8d34 | ||
|
|
f113de180b | ||
|
|
adb4b52752 | ||
|
|
baf8912dda | ||
|
|
489deda6a8 | ||
|
|
2fee607327 | ||
|
|
c428a22b5b | ||
|
|
42c01adb98 | ||
|
|
209bb2932c | ||
|
|
ec9cdb391a | ||
|
|
a6aafeb374 | ||
|
|
ffb538ef21 | ||
|
|
15925de2f0 | ||
|
|
25d72044e9 | ||
|
|
6b598383d3 | ||
|
|
25c76522d6 | ||
|
|
c0e2aa5c62 | ||
|
|
d0b9f742ae | ||
|
|
80d56829c5 | ||
|
|
0946310f60 | ||
|
|
7c855cf55d | ||
|
|
0ab95fb670 | ||
|
|
1e81b4bab4 | ||
|
|
67c50068d9 | ||
|
|
c3628e36f7 | ||
|
|
526799c6da | ||
|
|
4ef7529533 | ||
|
|
b06d670dff | ||
|
|
02c0453ff3 | ||
|
|
09358aa5b2 | ||
|
|
229d4db996 | ||
|
|
184be32f3a | ||
|
|
dbe77ea19d | ||
|
|
85e5c7e8e7 | ||
|
|
3c273b370d | ||
|
|
343e56b440 | ||
|
|
3a949aee5a | ||
|
|
1601e52c9c | ||
|
|
760cc8e35c | ||
|
|
6051e1fb8b | ||
|
|
7b146947df | ||
|
|
5497a10f9f | ||
|
|
3e6f4b3657 | ||
|
|
7baf58ad61 | ||
|
|
d72437d18c | ||
|
|
ea57981953 | ||
|
|
c2d0cce02d | ||
|
|
9f7a119e95 | ||
|
|
0dacc97e99 | ||
|
|
52a44da56b | ||
|
|
7114f262c2 | ||
|
|
7647ea96d1 | ||
|
|
593da25cdb | ||
|
|
f22bce7ccb | ||
|
|
1688773bba | ||
|
|
b56b5d2400 | ||
|
|
33ee208071 | ||
|
|
fe880cc2c7 | ||
|
|
cffe57b74e | ||
|
|
66882d6fd9 | ||
|
|
050f22f051 | ||
|
|
7891af3a9a | ||
|
|
40cbccf50a | ||
|
|
0348da362c | ||
|
|
f0a3780f3a | ||
|
|
8058743c2f | ||
|
|
39163f3cfc | ||
|
|
43676ab407 | ||
|
|
a6bdadedb1 | ||
|
|
639f795b9a | ||
|
|
fc95d2cab8 | ||
|
|
695b6d68e6 | ||
|
|
b6c265098d | ||
|
|
2a80d348bd | ||
|
|
d08dafd965 | ||
|
|
c6542de93d | ||
|
|
5928678564 | ||
|
|
fac52ca122 | ||
|
|
e9d270269f | ||
|
|
0a4c5fbb28 | ||
|
|
2bfb0283d9 | ||
|
|
94e8aee36f | ||
|
|
8051956a2e | ||
|
|
c7020503be | ||
|
|
28edce96d9 | ||
|
|
b4481fcc84 | ||
|
|
2be2bebb4e | ||
|
|
d4bb8def62 | ||
|
|
7442cb01b7 | ||
|
|
95ba8275e8 | ||
|
|
2f4a0dd212 | ||
|
|
52a621e9ba | ||
|
|
1f77fad829 | ||
|
|
8d93a3f56e | ||
|
|
9c572e7ab2 | ||
|
|
1f15e74730 | ||
|
|
7570a04c02 | ||
|
|
fc2e89c448 | ||
|
|
be216ff7fe | ||
|
|
388208571b | ||
|
|
1891903007 | ||
|
|
41a7e73ff4 | ||
|
|
81d9fb0700 | ||
|
|
76312d6eb6 | ||
|
|
f31528c841 | ||
|
|
6d869fdece | ||
|
|
d0784a7773 | ||
|
|
791f843bc8 | ||
|
|
a0cdb231fd | ||
|
|
e0004842e6 | ||
|
|
fdbfa0e76f | ||
|
|
005516013f | ||
|
|
9ec3dd4b16 | ||
|
|
4dacf981a9 | ||
|
|
9f7b76b37d | ||
|
|
0d51558e74 | ||
|
|
236c257892 | ||
|
|
3540ce4297 | ||
|
|
fef026ed47 | ||
|
|
0bcb155756 | ||
|
|
12219522ab | ||
|
|
6001bf90c5 | ||
|
|
13864997ab | ||
|
|
2ab2766534 | ||
|
|
e051352070 | ||
|
|
3bf1e50620 | ||
|
|
42f3c88396 | ||
|
|
c9f31ef934 | ||
|
|
01f54aeb52 | ||
|
|
f51de34355 | ||
|
|
4e9647651c | ||
|
|
2d1016d362 | ||
|
|
b48c961ac1 | ||
|
|
4d47567995 | ||
|
|
6b2e3accf7 | ||
|
|
c1f8520c4f | ||
|
|
41eb99ec40 | ||
|
|
97a74127fb | ||
|
|
a9396167bf | ||
|
|
3385e5684e | ||
|
|
bb9672214c | ||
|
|
1b93672417 | ||
|
|
8b1cedd4a8 | ||
|
|
2c34047b6d | ||
|
|
f0942f0714 | ||
|
|
967e574ea8 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1 +1 @@
|
||||
github: [tankerkiller125,katosdev]
|
||||
github: [tankerkiller125,katosdev,tonyaellie]
|
||||
|
||||
17
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
17
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,8 +1,9 @@
|
||||
---
|
||||
name: "Bug Report"
|
||||
description: "Submit a bug report for the current release"
|
||||
labels: ["bug"]
|
||||
labels: ["🕷️ bug"]
|
||||
projects: ["sysadminsmedia/2"]
|
||||
type: "Bug"
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
@@ -20,6 +21,8 @@ body:
|
||||
required: true
|
||||
- label: I already read the docs and didn't find an answer.
|
||||
required: true
|
||||
- label: I can replicate the issue inside the Demo install.
|
||||
required: true
|
||||
- type: input
|
||||
id: homebox-version
|
||||
attributes:
|
||||
@@ -55,6 +58,18 @@ body:
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: arch
|
||||
attributes:
|
||||
label: OS Architechture
|
||||
description: What type of processor are you running on.
|
||||
multiple: true
|
||||
options:
|
||||
- x86_64 (AMD, Intel)
|
||||
- ARM64
|
||||
- ARM/v7
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: os-details
|
||||
attributes:
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
3
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -1,8 +1,9 @@
|
||||
---
|
||||
name: "Feature Request"
|
||||
description: "Submit a feature request for the current release"
|
||||
labels: ["enhancement"]
|
||||
labels: ["⬆️ enhancement"]
|
||||
projects: ["sysadminsmedia/2"]
|
||||
type: "Enhancement"
|
||||
body:
|
||||
- type: textarea
|
||||
id: problem-statement
|
||||
|
||||
65
.github/scripts/update_currencies.py
vendored
Normal file
65
.github/scripts/update_currencies.py
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
import requests
|
||||
import json
|
||||
import os
|
||||
|
||||
def fetch_currencies():
|
||||
try:
|
||||
response = requests.get('https://restcountries.com/v3.1/all')
|
||||
response.raise_for_status()
|
||||
except requests.exceptions.Timeout:
|
||||
print("Request to the API timed out.")
|
||||
return []
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"An error occurred while making the request: {e}")
|
||||
return []
|
||||
|
||||
try:
|
||||
countries = response.json()
|
||||
except json.JSONDecodeError:
|
||||
print("Failed to decode JSON from the response.")
|
||||
return []
|
||||
|
||||
currencies_list = []
|
||||
for country in countries:
|
||||
country_name = country.get('name', {}).get('common')
|
||||
country_currencies = country.get('currencies', {})
|
||||
for currency_code, currency_info in country_currencies.items():
|
||||
symbol = currency_info.get('symbol', '')
|
||||
currencies_list.append({
|
||||
'code': currency_code,
|
||||
'local': country_name,
|
||||
'symbol': symbol,
|
||||
'name': currency_info.get('name')
|
||||
})
|
||||
|
||||
return currencies_list
|
||||
|
||||
def save_currencies(currencies, file_path):
|
||||
try:
|
||||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
||||
with open(file_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(currencies, f, ensure_ascii=False, indent=4)
|
||||
except IOError as e:
|
||||
print(f"An error occurred while writing to the file: {e}")
|
||||
|
||||
def load_existing_currencies(file_path):
|
||||
try:
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
except (IOError, json.JSONDecodeError):
|
||||
return [] # Return an empty list if file doesn't exist or is invalid
|
||||
|
||||
def main():
|
||||
save_path = 'backend/internal/core/currencies/currencies.json'
|
||||
|
||||
existing_currencies = load_existing_currencies(save_path)
|
||||
new_currencies = fetch_currencies()
|
||||
|
||||
if new_currencies == existing_currencies:
|
||||
print("Currencies up-to-date with API, skipping commit.")
|
||||
else:
|
||||
save_currencies(new_currencies, save_path)
|
||||
print("Currencies updated and saved.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
105
.github/workflows/docker-publish-arm.yaml
vendored
Normal file
105
.github/workflows/docker-publish-arm.yaml
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
name: Docker publish ARM
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '00 0 * * *'
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- 'backend/**'
|
||||
- 'frontend/**'
|
||||
- 'Dockerfile'
|
||||
- 'Dockerfile.rootless'
|
||||
- '.dockerignore'
|
||||
- '.github/workflows'
|
||||
# Publish semver tags as releases.
|
||||
tags: [ 'v*.*.*' ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- 'backend/**'
|
||||
- 'frontend/**'
|
||||
- 'Dockerfile'
|
||||
- 'Dockerfile.rootless'
|
||||
- '.dockerignore'
|
||||
- '.github/workflows'
|
||||
|
||||
env:
|
||||
# Use docker.io for Docker Hub if empty
|
||||
REGISTRY: ghcr.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
attestations: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
# Step 1: Checkout repository
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Step 2: Set up Buildx without specifying driver
|
||||
# Let it use default settings to avoid the 'no remote endpoint' issue
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3.0.0
|
||||
with:
|
||||
install: true # Ensure Buildx is installed and set up properly
|
||||
use: true # Use Buildx instance directly for this job
|
||||
|
||||
# Step 3: Login against Docker registry except on PR
|
||||
- name: Log into registry ${{ env.REGISTRY }}
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Step 4: Extract metadata for Docker images
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5.0.0
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=schedule,pattern=nightly
|
||||
flavor: |
|
||||
suffix=-arm,onlatest=true
|
||||
|
||||
# Step 5: Build and push the Docker image
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@v5.0.0
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
platforms: linux/arm64,linux/arm/v7
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
VERSION=${{ github.ref_name }}
|
||||
COMMIT=${{ github.sha }}
|
||||
|
||||
# Step 6: Attest built image to prove build provenance
|
||||
- name: Attest
|
||||
uses: actions/attest-build-provenance@v1
|
||||
id: attest
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
with:
|
||||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
subject-digest: ${{ steps.build-and-push.outputs.digest }}
|
||||
push-to-registry: true
|
||||
104
.github/workflows/docker-publish-rootless-arm.yaml
vendored
Normal file
104
.github/workflows/docker-publish-rootless-arm.yaml
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
name: Docker publish rootless ARM
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '00 0 * * *'
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- 'backend/**'
|
||||
- 'frontend/**'
|
||||
- 'Dockerfile'
|
||||
- 'Dockerfile.rootless'
|
||||
- '.dockerignore'
|
||||
- '.github/workflows'
|
||||
# Publish semver tags as releases.
|
||||
tags: [ 'v*.*.*' ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- 'backend/**'
|
||||
- 'frontend/**'
|
||||
- 'Dockerfile'
|
||||
- 'Dockerfile.rootless'
|
||||
- '.dockerignore'
|
||||
- '.github/workflows'
|
||||
|
||||
env:
|
||||
# Use docker.io for Docker Hub if empty
|
||||
REGISTRY: ghcr.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build-rootless:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
attestations: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
# Step 1: Checkout repository
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Step 2: Set up Buildx without specifying driver
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3.0.0
|
||||
with:
|
||||
install: true # Ensure Buildx is installed and set up properly
|
||||
use: true # Use Buildx instance directly for this job
|
||||
|
||||
# Step 3: Login to Docker registry except on PR
|
||||
- name: Log into registry ${{ env.REGISTRY }}
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Step 4: Extract metadata for Docker images
|
||||
- name: Extract Docker metadata
|
||||
id: metadata
|
||||
uses: docker/metadata-action@v5.0.0
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=schedule,pattern=nightly
|
||||
flavor: |
|
||||
suffix=-rootless-arm,onlatest=true
|
||||
|
||||
# Step 5: Build and push the Docker image
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@v5.0.0
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.metadata.outputs.tags }}
|
||||
labels: ${{ steps.metadata.outputs.labels }}
|
||||
platforms: linux/arm64,linux/arm/v7
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
VERSION=${{ github.ref_name }}
|
||||
COMMIT=${{ github.sha }}
|
||||
|
||||
# Step 6: Attest built image to prove build provenance
|
||||
- name: Attest
|
||||
uses: actions/attest-build-provenance@v1
|
||||
id: attest
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
with:
|
||||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
subject-digest: ${{ steps.build-and-push.outputs.digest }}
|
||||
push-to-registry: true
|
||||
@@ -2,7 +2,7 @@ name: Docker publish rootless
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '00 6 * * *'
|
||||
- cron: '00 0 * * *'
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
@@ -91,9 +91,9 @@ jobs:
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.metadata.outputs.tags }}
|
||||
labels: ${{ steps.metadata.outputs.labels }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
# cache-from: type=gha
|
||||
# cache-to: type=gha,mode=max
|
||||
platforms: linux/amd64
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
VERSION=${{ github.ref_name }}
|
||||
COMMIT=${{ github.sha }}
|
||||
|
||||
8
.github/workflows/docker-publish.yaml
vendored
8
.github/workflows/docker-publish.yaml
vendored
@@ -2,7 +2,7 @@ name: Docker publish
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '00 6 * * *'
|
||||
- cron: '00 0 * * *'
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
@@ -88,9 +88,9 @@ jobs:
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
# cache-from: type=gha
|
||||
# cache-to: type=gha,mode=max
|
||||
platforms: linux/amd64
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
VERSION=${{ github.ref_name }}
|
||||
COMMIT=${{ github.sha }}
|
||||
|
||||
4
.github/workflows/partial-frontend.yaml
vendored
4
.github/workflows/partial-frontend.yaml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
|
||||
- uses: pnpm/action-setup@v3.0.0
|
||||
with:
|
||||
version: 6.0.2
|
||||
version: 9.12.2
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --shamefully-hoist
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
|
||||
- uses: pnpm/action-setup@v3.0.0
|
||||
with:
|
||||
version: 6.0.2
|
||||
version: 9.12.2
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
100
.github/workflows/update-currencies.yml
vendored
Normal file
100
.github/workflows/update-currencies.yml
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
name: Update Currencies
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
update-currencies:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.8'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install requests
|
||||
|
||||
- name: Run currency fetch script
|
||||
run: python .github/scripts/update_currencies.py
|
||||
|
||||
- name: Check for changes
|
||||
id: check_changes
|
||||
run: |
|
||||
if [[ $(git status --porcelain) ]]; then
|
||||
echo "Changes detected."
|
||||
echo "changes=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "No changes detected."
|
||||
echo "changes=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Delete existing update-currencies branch
|
||||
run: |
|
||||
if git show-ref --verify --quiet refs/heads/update-currencies; then
|
||||
git branch -D update-currencies
|
||||
echo "Deleted existing update-currencies branch."
|
||||
else
|
||||
echo "No existing update-currencies branch to delete."
|
||||
fi
|
||||
|
||||
- name: Create new update-currencies branch
|
||||
if: env.changes == 'true'
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
# Create a new branch
|
||||
git checkout -b update-currencies
|
||||
git add backend/internal/core/currencies/currencies.json
|
||||
git commit -m "Update currencies.json"
|
||||
|
||||
# Fetch the latest changes from the remote
|
||||
git fetch origin
|
||||
|
||||
# Attempt to rebase with the latest changes
|
||||
if git show-ref --verify --quiet refs/remotes/origin/update-currencies; then
|
||||
if ! git rebase origin/update-currencies; then
|
||||
echo "Rebase conflicts occurred. Please resolve them manually."
|
||||
echo "To resolve conflicts, check out the 'update-currencies' branch locally."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "No existing remote branch 'update-currencies'. Skipping rebase."
|
||||
fi
|
||||
|
||||
# Push the new branch to the remote
|
||||
if ! git push --set-upstream origin update-currencies; then
|
||||
echo "Push failed, trying to fetch and rebase again."
|
||||
git fetch origin
|
||||
if git show-ref --verify --quiet refs/remotes/origin/update-currencies; then
|
||||
if ! git rebase origin/update-currencies; then
|
||||
echo "Second rebase failed. Please resolve manually."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "No existing remote branch 'update-currencies'. Skipping rebase."
|
||||
fi
|
||||
if ! git push --set-upstream origin update-currencies; then
|
||||
echo "Second push failed. Please resolve manually."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create a pull request
|
||||
curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
|
||||
-X POST \
|
||||
-d '{"title": "Update currencies", "head": "update-currencies", "base": "main"}' \
|
||||
https://api.github.com/repos/${{ github.repository }}/pulls
|
||||
|
||||
- name: Notify no changes
|
||||
if: env.changes == 'false'
|
||||
run: echo "Currencies up-to-date with API, skipping commit."
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -56,4 +56,5 @@ backend/app/api/static/public/*
|
||||
!backend/app/api/static/public/.gitkeep
|
||||
backend/api
|
||||
|
||||
docs/.vitepress/cache/
|
||||
docs/.vitepress/cache/
|
||||
/.data/
|
||||
|
||||
@@ -44,7 +44,7 @@ start command `task go:run`
|
||||
|
||||
### Frontend Development Notes
|
||||
|
||||
start command `task: ui:dev`
|
||||
start command `task ui:dev`
|
||||
|
||||
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`.
|
||||
@@ -54,4 +54,4 @@ start command `task: ui:dev`
|
||||
|
||||
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
|
||||
Test -> Goreleaser -> Publish Release -> Trigger Docker Builds -> Deploy Docs + Fly.io Demo
|
||||
|
||||
79
Dockerfile
79
Dockerfile
@@ -1,58 +1,91 @@
|
||||
# Node dependencies stage
|
||||
FROM --platform=$TARGETPLATFORM node:18-alpine AS frontend-dependencies
|
||||
WORKDIR /app
|
||||
|
||||
# Build Nuxt
|
||||
FROM node:18-alpine AS frontend-builder
|
||||
WORKDIR /app
|
||||
# Install pnpm globally (caching layer)
|
||||
RUN npm install -g pnpm
|
||||
|
||||
# Copy package.json and lockfile to leverage caching
|
||||
COPY frontend/package.json frontend/pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile --shamefully-hoist
|
||||
COPY frontend .
|
||||
|
||||
# Build Nuxt (frontend) stage
|
||||
FROM --platform=$TARGETPLATFORM node:18-alpine AS frontend-builder
|
||||
WORKDIR /app
|
||||
|
||||
# Install pnpm globally again (it can reuse the cache if not changed)
|
||||
RUN npm install -g pnpm
|
||||
|
||||
# Copy over source files and node_modules from dependencies stage
|
||||
COPY frontend .
|
||||
COPY --from=frontend-dependencies /app/node_modules ./node_modules
|
||||
RUN pnpm build
|
||||
|
||||
# Build API
|
||||
FROM golang:alpine AS builder
|
||||
# Go dependencies stage
|
||||
FROM --platform=$TARGETPLATFORM golang:alpine AS builder-dependencies
|
||||
WORKDIR /go/src/app
|
||||
|
||||
# Copy go.mod and go.sum for better caching
|
||||
COPY ./backend/go.mod ./backend/go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
# Build API stage
|
||||
FROM --platform=$TARGETPLATFORM golang:alpine AS builder
|
||||
ARG BUILD_TIME
|
||||
ARG COMMIT
|
||||
ARG VERSION
|
||||
|
||||
# Install necessary build tools
|
||||
RUN apk update && \
|
||||
apk upgrade && \
|
||||
apk add --update git build-base gcc g++
|
||||
apk add --no-cache git build-base gcc g++
|
||||
|
||||
WORKDIR /go/src/app
|
||||
|
||||
# Copy Go modules (from dependencies stage) and source code
|
||||
COPY --from=builder-dependencies /go/pkg/mod /go/pkg/mod
|
||||
COPY ./backend .
|
||||
RUN go get -d -v ./...
|
||||
|
||||
# Clear old public files and copy new ones from frontend build
|
||||
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" \
|
||||
|
||||
# Use cache for Go build artifacts
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
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
|
||||
|
||||
FROM gcr.io/distroless/java:latest
|
||||
|
||||
# Production Stage
|
||||
FROM alpine:latest
|
||||
|
||||
# Production stage
|
||||
FROM --platform=$TARGETPLATFORM alpine:latest
|
||||
ENV HBOX_MODE=production
|
||||
ENV HBOX_STORAGE_DATA=/data/
|
||||
ENV HBOX_STORAGE_SQLITE_URL=/data/homebox.db?_pragma=busy_timeout=2000&_pragma=journal_mode=WAL&_fk=1
|
||||
|
||||
RUN apk --no-cache add ca-certificates
|
||||
# Install necessary runtime dependencies
|
||||
RUN apk --no-cache add ca-certificates wget
|
||||
|
||||
# Create application directory and copy over built Go binary
|
||||
RUN mkdir /app
|
||||
COPY --from=builder /go/bin/api /app
|
||||
|
||||
RUN chmod +x /app/api
|
||||
RUN apk add --no-cache wget
|
||||
|
||||
# Labels and configuration for the final image
|
||||
LABEL Name=homebox Version=0.0.1
|
||||
LABEL org.opencontainers.image.source="https://github.com/sysadminsmedia/homebox"
|
||||
|
||||
# Expose necessary ports
|
||||
EXPOSE 7745
|
||||
WORKDIR /app
|
||||
HEALTHCHECK --interval=30s \
|
||||
--timeout=5s \
|
||||
--start-period=5s \
|
||||
--retries=3 \
|
||||
CMD [ "/usr/bin/wget", "--no-verbose", "--tries=1", "-O -", "http://localhost:7745/api/v1/status" ]
|
||||
|
||||
# Healthcheck configuration
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
|
||||
CMD [ "wget", "--no-verbose", "--tries=1", "-O", "-", "http://localhost:7745/api/v1/status" ]
|
||||
|
||||
# Persist volume
|
||||
VOLUME [ "/data" ]
|
||||
|
||||
# Entrypoint and CMD
|
||||
ENTRYPOINT [ "/app/api" ]
|
||||
CMD [ "/data/config.yml" ]
|
||||
|
||||
@@ -1,63 +1,73 @@
|
||||
|
||||
# Build Nuxt
|
||||
FROM node:18-alpine AS frontend-builder
|
||||
WORKDIR /app
|
||||
# Node dependencies
|
||||
FROM node:18-alpine AS frontend-dependencies
|
||||
WORKDIR /app
|
||||
RUN npm install -g pnpm
|
||||
COPY frontend/package.json frontend/pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile --shamefully-hoist
|
||||
COPY frontend .
|
||||
|
||||
# Build Nuxt
|
||||
FROM node:18-alpine AS frontend-builder
|
||||
WORKDIR /app
|
||||
COPY frontend ./
|
||||
COPY --from=frontend-dependencies /app/node_modules ./node_modules
|
||||
RUN pnpm build
|
||||
|
||||
# Build Go dependencies
|
||||
FROM golang:alpine AS builder-dependencies
|
||||
WORKDIR /go/src/app
|
||||
COPY ./backend/go.mod ./backend/go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
# Build API
|
||||
FROM golang:alpine AS builder
|
||||
ARG BUILD_TIME
|
||||
ARG COMMIT
|
||||
ARG VERSION
|
||||
ARG BUSYBOX_VERSION=1.36.1-r31
|
||||
RUN apk update && \
|
||||
apk upgrade && \
|
||||
apk add --update git build-base gcc g++
|
||||
|
||||
RUN apk update && apk upgrade && apk add --no-cache 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
|
||||
COPY --from=builder-dependencies /go/pkg/mod /go/pkg/mod
|
||||
|
||||
FROM gcr.io/distroless/java:latest
|
||||
# Use cache for Go build
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
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 ./app/api/*.go
|
||||
|
||||
# Production Stage
|
||||
# Production stage with distroless
|
||||
FROM gcr.io/distroless/static:latest
|
||||
|
||||
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 the binary and data directory, change ownership
|
||||
COPY --from=builder --chown=nonroot /go/bin/api /app
|
||||
COPY --from=builder --chown=nonroot /data /data
|
||||
|
||||
RUN apk add --no-cache wget
|
||||
# Add wget to the image
|
||||
# Note: If using distroless, this may not be applicable
|
||||
# as distroless images do not include package managers.
|
||||
# This line may be omitted if you're relying on another way to handle healthchecks.
|
||||
COPY --from=alpine:latest /bin/wget /usr/bin/wget
|
||||
|
||||
LABEL Name=homebox Version=0.0.1
|
||||
LABEL org.opencontainers.image.source="https://github.com/sysadminsmedia/homebox"
|
||||
EXPOSE 7745
|
||||
|
||||
HEALTHCHECK --interval=30s \
|
||||
--timeout=5s \
|
||||
--start-period=5s \
|
||||
--retries=3 \
|
||||
CMD [ "/usr/bin/wget", "--no-verbose", "--tries=1", "-O -", "http://localhost:7745/api/v1/status" ]
|
||||
VOLUME [ "/data" ]
|
||||
CMD ["/usr/bin/wget", "--no-verbose", "--tries=1", "-O", "-", "http://localhost:7745/api/v1/status"]
|
||||
|
||||
# Drop root and run as low-privileged user
|
||||
VOLUME ["/data"]
|
||||
|
||||
# Drop root and run as a low-privileged user
|
||||
USER nonroot
|
||||
ENTRYPOINT [ "/app" ]
|
||||
CMD [ "/data/config.yml" ]
|
||||
ENTRYPOINT ["/app"]
|
||||
CMD ["/data/config.yml"]
|
||||
|
||||
11
README.md
11
README.md
@@ -4,9 +4,9 @@
|
||||
|
||||
<h1 align="center" style="margin-top: -10px"> HomeBox </h1>
|
||||
<p align="center" style="width: 100;">
|
||||
<a href="https://homebox.sysadminsmedia.com">Docs</a>
|
||||
<a href="https://homebox.software/en/">Docs</a>
|
||||
|
|
||||
<a href="https://homebox.fly.dev">Demo</a>
|
||||
<a href="https://demo.homebox.software">Demo</a>
|
||||
|
|
||||
<a href="https://discord.gg/aY4DCkpNA9">Discord</a>
|
||||
</p>
|
||||
@@ -24,7 +24,7 @@ Check out screenshots of the project [here](https://imgur.com/a/5gLWt2j).
|
||||
|
||||
## Quick Start
|
||||
|
||||
[Configuration & Docker Compose](https://homebox.sysadminsmedia.com/en/quick-start.html)
|
||||
[Configuration & Docker Compose](https://homebox.software/en/quick-start.html)
|
||||
|
||||
```bash
|
||||
# If using the rootless image, ensure data
|
||||
@@ -49,6 +49,11 @@ Contributions are what make the open source community such an amazing place to l
|
||||
|
||||
If you are not a coder, you can still contribute financially. Financial contributions help me prioritize working on this project over others and helps me know that there is a real demand for project development.
|
||||
|
||||
## Help us Translate
|
||||
We want to make sure that Homebox is available in as many languages as possible. If you are interested in helping us translate Homebox, please help us via our [Weblate instance](https://translate.sysadminsmedia.com/projects/homebox/).
|
||||
|
||||
[](http://translate.sysadminsmedia.com/engage/homebox/)
|
||||
|
||||
## Credits
|
||||
|
||||
- Original project by [@hay-kot](https://github.com/hay-kot)
|
||||
|
||||
@@ -52,6 +52,8 @@ tasks:
|
||||
- cp ./backend/app/api/static/docs/swagger.json docs/docs/api/openapi-2.0.json
|
||||
|
||||
go:run:
|
||||
env:
|
||||
HBOX_DEMO: true
|
||||
desc: Starts the backend api server (depends on generate task)
|
||||
dir: backend
|
||||
deps:
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
run:
|
||||
timeout: 10m
|
||||
skip-dirs:
|
||||
- internal/data/ent.*
|
||||
linters-settings:
|
||||
goconst:
|
||||
min-len: 5
|
||||
@@ -45,7 +43,7 @@ linters:
|
||||
- errcheck
|
||||
- errorlint
|
||||
- exhaustive
|
||||
- exportloopref
|
||||
- copyloopvar
|
||||
- gochecknoinits
|
||||
- goconst
|
||||
- gocritic
|
||||
@@ -71,4 +69,6 @@ linters:
|
||||
- sqlclosecheck
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
exclude-dirs:
|
||||
- internal/data/ent.*
|
||||
fix: true
|
||||
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -9,7 +10,7 @@ import (
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/core/services"
|
||||
)
|
||||
|
||||
func (a *app) SetupDemo() {
|
||||
func (a *app) SetupDemo() error {
|
||||
csvText := `HB.import_ref,HB.location,HB.labels,HB.quantity,HB.name,HB.description,HB.insured,HB.serial_number,HB.model_number,HB.manufacturer,HB.notes,HB.purchase_from,HB.purchase_price,HB.purchase_time,HB.lifetime_warranty,HB.warranty_expires,HB.warranty_details,HB.sold_to,HB.sold_price,HB.sold_time,HB.sold_notes
|
||||
,Garage,IOT;Home Assistant; Z-Wave,1,Zooz Universal Relay ZEN17,"Zooz 700 Series Z-Wave Universal Relay ZEN17 for Awnings, Garage Doors, Sprinklers, and More | 2 NO-C-NC Relays (20A, 10A) | Signal Repeater | Hub Required (Compatible with SmartThings and Hubitat)",,,ZEN17,Zooz,,Amazon,39.95,10/13/2021,,,,,,,
|
||||
,Living Room,IOT;Home Assistant; Z-Wave,1,Zooz Motion Sensor,"Zooz Z-Wave Plus S2 Motion Sensor ZSE18 with Magnetic Mount, Works with Vera and SmartThings",,,ZSE18,Zooz,,Amazon,29.95,10/15/2021,,,,,,,
|
||||
@@ -33,34 +34,34 @@ func (a *app) SetupDemo() {
|
||||
_, err := a.services.User.Login(ctx, registration.Email, registration.Password, false)
|
||||
if err == nil {
|
||||
log.Info().Msg("Demo user already exists, skipping setup")
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Debug().Msg("Demo user does not exist, setting up demo")
|
||||
_, err = a.services.User.RegisterUser(ctx, registration)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to register demo user")
|
||||
log.Fatal().Msg("Failed to setup demo")
|
||||
return errors.New("failed to setup demo")
|
||||
}
|
||||
|
||||
token, err := a.services.User.Login(ctx, registration.Email, registration.Password, false)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to login demo user")
|
||||
log.Fatal().Msg("Failed to setup demo")
|
||||
return
|
||||
return errors.New("failed to setup demo")
|
||||
}
|
||||
self, err := a.services.User.GetSelf(ctx, token.Raw)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to get self")
|
||||
log.Fatal().Msg("Failed to setup demo")
|
||||
return
|
||||
return errors.New("failed to setup demo")
|
||||
}
|
||||
|
||||
_, err = a.services.Items.CsvImport(ctx, self.GroupID, strings.NewReader(csvText))
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to import CSV")
|
||||
log.Fatal().Msg("Failed to setup demo")
|
||||
return errors.New("failed to setup demo")
|
||||
}
|
||||
|
||||
log.Info().Msg("Demo setup complete")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -57,6 +57,12 @@ func WithSecureCookies(secure bool) func(*V1Controller) {
|
||||
}
|
||||
}
|
||||
|
||||
func WithURL(url string) func(*V1Controller) {
|
||||
return func(ctrl *V1Controller) {
|
||||
ctrl.url = url
|
||||
}
|
||||
}
|
||||
|
||||
type V1Controller struct {
|
||||
cookieSecure bool
|
||||
repo *repo.AllRepos
|
||||
@@ -65,6 +71,7 @@ type V1Controller struct {
|
||||
isDemo bool
|
||||
allowRegistration bool
|
||||
bus *eventbus.EventBus
|
||||
url string
|
||||
}
|
||||
|
||||
type (
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -333,7 +334,7 @@ func (ctrl *V1Controller) HandleItemsExport() errchain.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
csvData, err := ctrl.svc.Items.ExportCSV(r.Context(), ctx.GID)
|
||||
csvData, err := ctrl.svc.Items.ExportCSV(r.Context(), ctx.GID, getHBURL(r.Header.Get("Referer"), ctrl.url))
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to export items")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
@@ -347,3 +348,26 @@ func (ctrl *V1Controller) HandleItemsExport() errchain.HandlerFunc {
|
||||
return writer.WriteAll(csvData)
|
||||
}
|
||||
}
|
||||
|
||||
func getHBURL(refererHeader, fallback string) (hbURL string) {
|
||||
hbURL = refererHeader
|
||||
if hbURL == "" {
|
||||
hbURL = fallback
|
||||
}
|
||||
|
||||
return stripPathFromURL(hbURL)
|
||||
}
|
||||
|
||||
// stripPathFromURL removes the path from a URL.
|
||||
// ex. https://example.com/tools -> https://example.com
|
||||
func stripPathFromURL(rawURL string) string {
|
||||
parsedURL, err := url.Parse(rawURL)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to parse URL")
|
||||
return ""
|
||||
}
|
||||
|
||||
strippedURL := url.URL{Scheme: parsedURL.Scheme, Host: parsedURL.Host}
|
||||
|
||||
return strippedURL.String()
|
||||
}
|
||||
|
||||
@@ -85,15 +85,15 @@ func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc {
|
||||
return adapters.CommandID("id", fn, http.StatusNoContent)
|
||||
}
|
||||
|
||||
func (ctrl *V1Controller) GetLocationWithPrice(auth context.Context, GID uuid.UUID, ID uuid.UUID) (repo.LocationOut, error) {
|
||||
var location, err = ctrl.repo.Locations.GetOneByGroup(auth, GID, ID)
|
||||
func (ctrl *V1Controller) GetLocationWithPrice(auth context.Context, gid uuid.UUID, id uuid.UUID) (repo.LocationOut, error) {
|
||||
var location, err = ctrl.repo.Locations.GetOneByGroup(auth, gid, id)
|
||||
if err != nil {
|
||||
return repo.LocationOut{}, err
|
||||
}
|
||||
|
||||
// Add direct child items price
|
||||
totalPrice := new(big.Int)
|
||||
items, err := ctrl.repo.Items.QueryByGroup(auth, GID, repo.ItemQuery{LocationIDs: []uuid.UUID{ID}})
|
||||
items, err := ctrl.repo.Items.QueryByGroup(auth, gid, repo.ItemQuery{LocationIDs: []uuid.UUID{id}})
|
||||
if err != nil {
|
||||
return repo.LocationOut{}, err
|
||||
}
|
||||
@@ -112,7 +112,7 @@ func (ctrl *V1Controller) GetLocationWithPrice(auth context.Context, GID uuid.UU
|
||||
// Add price from child locations
|
||||
for _, childLocation := range location.Children {
|
||||
var childLocationWithPrice repo.LocationOut
|
||||
childLocationWithPrice, err = ctrl.GetLocationWithPrice(auth, GID, childLocation.ID)
|
||||
childLocationWithPrice, err = ctrl.GetLocationWithPrice(auth, gid, childLocation.ID)
|
||||
if err != nil {
|
||||
return repo.LocationOut{}, err
|
||||
}
|
||||
|
||||
@@ -13,15 +13,16 @@ import (
|
||||
// HandleMaintenanceLogGet godoc
|
||||
//
|
||||
// @Summary Get Maintenance Log
|
||||
// @Tags Maintenance
|
||||
// @Tags Item Maintenance
|
||||
// @Produce json
|
||||
// @Success 200 {object} repo.MaintenanceLog
|
||||
// @Param filters query repo.MaintenanceFilters false "which maintenance to retrieve"
|
||||
// @Success 200 {array} repo.MaintenanceEntryWithDetails[]
|
||||
// @Router /v1/items/{id}/maintenance [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleMaintenanceLogGet() errchain.HandlerFunc {
|
||||
fn := func(r *http.Request, ID uuid.UUID, q repo.MaintenanceLogQuery) (repo.MaintenanceLog, error) {
|
||||
fn := func(r *http.Request, ID uuid.UUID, filters repo.MaintenanceFilters) ([]repo.MaintenanceEntryWithDetails, error) {
|
||||
auth := services.NewContext(r.Context())
|
||||
return ctrl.repo.MaintEntry.GetLog(auth, auth.GID, ID, q)
|
||||
return ctrl.repo.MaintEntry.GetMaintenanceByItemID(auth, auth.GID, ID, filters)
|
||||
}
|
||||
|
||||
return adapters.QueryID("id", fn, http.StatusOK)
|
||||
@@ -30,7 +31,7 @@ func (ctrl *V1Controller) HandleMaintenanceLogGet() errchain.HandlerFunc {
|
||||
// HandleMaintenanceEntryCreate godoc
|
||||
//
|
||||
// @Summary Create Maintenance Entry
|
||||
// @Tags Maintenance
|
||||
// @Tags Item Maintenance
|
||||
// @Produce json
|
||||
// @Param payload body repo.MaintenanceEntryCreate true "Entry Data"
|
||||
// @Success 201 {object} repo.MaintenanceEntry
|
||||
@@ -44,39 +45,3 @@ func (ctrl *V1Controller) HandleMaintenanceEntryCreate() errchain.HandlerFunc {
|
||||
|
||||
return adapters.ActionID("id", fn, http.StatusCreated)
|
||||
}
|
||||
|
||||
// HandleMaintenanceEntryDelete godoc
|
||||
//
|
||||
// @Summary Delete Maintenance Entry
|
||||
// @Tags Maintenance
|
||||
// @Produce json
|
||||
// @Success 204
|
||||
// @Router /v1/items/{id}/maintenance/{entry_id} [DELETE]
|
||||
// @Security Bearer
|
||||
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
|
||||
//
|
||||
// @Summary Update Maintenance Entry
|
||||
// @Tags Maintenance
|
||||
// @Produce json
|
||||
// @Param payload body repo.MaintenanceEntryUpdate true "Entry Data"
|
||||
// @Success 200 {object} repo.MaintenanceEntry
|
||||
// @Router /v1/items/{id}/maintenance/{entry_id} [PUT]
|
||||
// @Security Bearer
|
||||
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())
|
||||
return ctrl.repo.MaintEntry.Update(auth, entryID, body)
|
||||
}
|
||||
|
||||
return adapters.ActionID("entry_id", fn, http.StatusOK)
|
||||
}
|
||||
|
||||
65
backend/app/api/handlers/v1/v1_ctrl_maintenance.go
Normal file
65
backend/app/api/handlers/v1/v1_ctrl_maintenance.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/httpkit/errchain"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/core/services"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/data/repo"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/web/adapters"
|
||||
)
|
||||
|
||||
// HandleMaintenanceGetAll godoc
|
||||
//
|
||||
// @Summary Query All Maintenance
|
||||
// @Tags Maintenance
|
||||
// @Produce json
|
||||
// @Param filters query repo.MaintenanceFilters false "which maintenance to retrieve"
|
||||
// @Success 200 {array} repo.MaintenanceEntryWithDetails[]
|
||||
// @Router /v1/maintenance [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleMaintenanceGetAll() errchain.HandlerFunc {
|
||||
fn := func(r *http.Request, filters repo.MaintenanceFilters) ([]repo.MaintenanceEntryWithDetails, error) {
|
||||
auth := services.NewContext(r.Context())
|
||||
return ctrl.repo.MaintEntry.GetAllMaintenance(auth, auth.GID, filters)
|
||||
}
|
||||
|
||||
return adapters.Query(fn, http.StatusOK)
|
||||
}
|
||||
|
||||
// HandleMaintenanceEntryUpdate godoc
|
||||
//
|
||||
// @Summary Update Maintenance Entry
|
||||
// @Tags Maintenance
|
||||
// @Produce json
|
||||
// @Param payload body repo.MaintenanceEntryUpdate true "Entry Data"
|
||||
// @Success 200 {object} repo.MaintenanceEntry
|
||||
// @Router /v1/maintenance/{id} [PUT]
|
||||
// @Security Bearer
|
||||
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())
|
||||
return ctrl.repo.MaintEntry.Update(auth, entryID, body)
|
||||
}
|
||||
|
||||
return adapters.ActionID("id", fn, http.StatusOK)
|
||||
}
|
||||
|
||||
// HandleMaintenanceEntryDelete godoc
|
||||
//
|
||||
// @Summary Delete Maintenance Entry
|
||||
// @Tags Maintenance
|
||||
// @Produce json
|
||||
// @Success 204
|
||||
// @Router /v1/maintenance/{id} [DELETE]
|
||||
// @Security Bearer
|
||||
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("id", fn, http.StatusNoContent)
|
||||
}
|
||||
@@ -115,16 +115,17 @@ func run(cfg *config.Config) error {
|
||||
|
||||
err = c.Schema.Create(context.Background(), options...)
|
||||
if err != nil {
|
||||
log.Fatal().
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("driver", "sqlite").
|
||||
Str("url", cfg.Storage.SqliteURL).
|
||||
Msg("failed creating schema resources")
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.RemoveAll(temp)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("failed to remove temporary directory for database migrations")
|
||||
log.Error().Err(err).Msg("failed to remove temporary directory for database migrations")
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -139,10 +140,11 @@ func run(cfg *config.Config) error {
|
||||
|
||||
content, err := os.ReadFile(cfg.Options.CurrencyConfig)
|
||||
if err != nil {
|
||||
log.Fatal().
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("path", cfg.Options.CurrencyConfig).
|
||||
Msg("failed to read currency config file")
|
||||
return err
|
||||
}
|
||||
|
||||
collectFuncs = append(collectFuncs, currencies.CollectJSON(bytes.NewReader(content)))
|
||||
@@ -150,9 +152,10 @@ func run(cfg *config.Config) error {
|
||||
|
||||
currencies, err := currencies.CollectionCurrencies(collectFuncs...)
|
||||
if err != nil {
|
||||
log.Fatal().
|
||||
log.Error().
|
||||
Err(err).
|
||||
Msg("failed to collect currencies")
|
||||
return err
|
||||
}
|
||||
|
||||
app.bus = eventbus.New()
|
||||
@@ -211,7 +214,10 @@ func run(cfg *config.Config) error {
|
||||
// TODO: Remove through external API that does setup
|
||||
if cfg.Demo {
|
||||
log.Info().Msg("Running in demo mode, creating demo data")
|
||||
app.SetupDemo()
|
||||
err := app.SetupDemo()
|
||||
if err != nil {
|
||||
log.Fatal().Msg(err.Error())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"net/http"
|
||||
@@ -54,6 +55,7 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR
|
||||
v1.WithMaxUploadSize(a.conf.Web.MaxUploadSize),
|
||||
v1.WithRegistration(a.conf.Options.AllowRegistration),
|
||||
v1.WithDemoStatus(a.conf.Demo), // Disable Password Change in Demo Mode
|
||||
v1.WithURL(fmt.Sprintf("%s:%s", a.conf.Web.Host, a.conf.Web.Port)),
|
||||
)
|
||||
|
||||
r.Route(prefix+"/v1", func(r chi.Router) {
|
||||
@@ -132,11 +134,14 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR
|
||||
|
||||
r.Get("/items/{id}/maintenance", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceLogGet(), userMW...))
|
||||
r.Post("/items/{id}/maintenance", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryCreate(), userMW...))
|
||||
r.Put("/items/{id}/maintenance/{entry_id}", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryUpdate(), userMW...))
|
||||
r.Delete("/items/{id}/maintenance/{entry_id}", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryDelete(), userMW...))
|
||||
|
||||
r.Get("/assets/{id}", chain.ToHandlerFunc(v1Ctrl.HandleAssetGet(), userMW...))
|
||||
|
||||
// Maintenance
|
||||
r.Get("/maintenance", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceGetAll(), userMW...))
|
||||
r.Put("/maintenance/{id}", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryUpdate(), userMW...))
|
||||
r.Delete("/maintenance/{id}", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryDelete(), userMW...))
|
||||
|
||||
// Notifiers
|
||||
r.Get("/notifiers", chain.ToHandlerFunc(v1Ctrl.HandleGetUserNotifiers(), userMW...))
|
||||
r.Post("/notifiers", chain.ToHandlerFunc(v1Ctrl.HandleCreateNotifier(), userMW...))
|
||||
|
||||
@@ -917,14 +917,34 @@ const docTemplate = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
"Item Maintenance"
|
||||
],
|
||||
"summary": "Get Maintenance Log",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"scheduled",
|
||||
"completed",
|
||||
"both"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
"MaintenanceFilterStatusScheduled",
|
||||
"MaintenanceFilterStatusCompleted",
|
||||
"MaintenanceFilterStatusBoth"
|
||||
],
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceLog"
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryWithDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -939,7 +959,7 @@ const docTemplate = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
"Item Maintenance"
|
||||
],
|
||||
"summary": "Create Maintenance Entry",
|
||||
"parameters": [
|
||||
@@ -963,60 +983,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/{id}/maintenance/{entry_id}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Update Maintenance Entry",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Entry Data",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Delete Maintenance Entry",
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/{id}/path": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -1409,6 +1375,104 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/maintenance": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Query All Maintenance",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"scheduled",
|
||||
"completed",
|
||||
"both"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
"MaintenanceFilterStatusScheduled",
|
||||
"MaintenanceFilterStatusCompleted",
|
||||
"MaintenanceFilterStatusBoth"
|
||||
],
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryWithDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/maintenance/{id}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Update Maintenance Entry",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Entry Data",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Delete Maintenance Entry",
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/notifiers": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -2153,8 +2217,7 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2170,8 +2233,7 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
@@ -2224,6 +2286,10 @@ const docTemplate = `{
|
||||
"archived": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"assetId": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -2259,8 +2325,7 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "integer"
|
||||
@@ -2283,6 +2348,9 @@ const docTemplate = `{
|
||||
},
|
||||
"repo.ItemUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"archived": {
|
||||
"type": "boolean"
|
||||
@@ -2291,7 +2359,8 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 1000
|
||||
},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
@@ -2326,7 +2395,9 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255,
|
||||
"minLength": 1
|
||||
},
|
||||
"notes": {
|
||||
"description": "Extras",
|
||||
@@ -2338,11 +2409,13 @@ const docTemplate = `{
|
||||
"x-omitempty": true
|
||||
},
|
||||
"purchaseFrom": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2359,15 +2432,17 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
"type": "string"
|
||||
},
|
||||
"soldTo": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"warrantyDetails": {
|
||||
"type": "string"
|
||||
@@ -2476,6 +2551,9 @@ const docTemplate = `{
|
||||
"parent": {
|
||||
"$ref": "#/definitions/repo.LocationSummary"
|
||||
},
|
||||
"totalPrice": {
|
||||
"type": "number"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string"
|
||||
}
|
||||
@@ -2611,26 +2689,49 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"repo.MaintenanceLog": {
|
||||
"repo.MaintenanceEntryWithDetails": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"costAverage": {
|
||||
"type": "number"
|
||||
"completedDate": {
|
||||
"type": "string"
|
||||
},
|
||||
"costTotal": {
|
||||
"type": "number"
|
||||
"cost": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"entries": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntry"
|
||||
}
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemId": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemID": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemName": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"scheduledDate": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repo.MaintenanceFilterStatus": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"scheduled",
|
||||
"completed",
|
||||
"both"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"MaintenanceFilterStatusScheduled",
|
||||
"MaintenanceFilterStatusCompleted",
|
||||
"MaintenanceFilterStatusBoth"
|
||||
]
|
||||
},
|
||||
"repo.NotifierCreate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -2672,6 +2773,9 @@ const docTemplate = `{
|
||||
"updatedAt": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"userId": {
|
||||
"type": "string"
|
||||
}
|
||||
|
||||
@@ -910,14 +910,34 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
"Item Maintenance"
|
||||
],
|
||||
"summary": "Get Maintenance Log",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"scheduled",
|
||||
"completed",
|
||||
"both"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
"MaintenanceFilterStatusScheduled",
|
||||
"MaintenanceFilterStatusCompleted",
|
||||
"MaintenanceFilterStatusBoth"
|
||||
],
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceLog"
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryWithDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -932,7 +952,7 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
"Item Maintenance"
|
||||
],
|
||||
"summary": "Create Maintenance Entry",
|
||||
"parameters": [
|
||||
@@ -956,60 +976,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/{id}/maintenance/{entry_id}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Update Maintenance Entry",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Entry Data",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Delete Maintenance Entry",
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/{id}/path": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -1402,6 +1368,104 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/maintenance": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Query All Maintenance",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"scheduled",
|
||||
"completed",
|
||||
"both"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
"MaintenanceFilterStatusScheduled",
|
||||
"MaintenanceFilterStatusCompleted",
|
||||
"MaintenanceFilterStatusBoth"
|
||||
],
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryWithDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/maintenance/{id}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Update Maintenance Entry",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Entry Data",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Delete Maintenance Entry",
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/notifiers": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -2145,12 +2209,8 @@
|
||||
"purchaseFrom": {
|
||||
"type": "string"
|
||||
},
|
||||
"purchaseFrom": {
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2166,8 +2226,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
@@ -2220,6 +2279,10 @@
|
||||
"archived": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"assetId": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -2255,8 +2318,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "integer"
|
||||
@@ -2279,6 +2341,9 @@
|
||||
},
|
||||
"repo.ItemUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"archived": {
|
||||
"type": "boolean"
|
||||
@@ -2287,7 +2352,8 @@
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 1000
|
||||
},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
@@ -2322,7 +2388,9 @@
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255,
|
||||
"minLength": 1
|
||||
},
|
||||
"notes": {
|
||||
"description": "Extras",
|
||||
@@ -2334,11 +2402,13 @@
|
||||
"x-omitempty": true
|
||||
},
|
||||
"purchaseFrom": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2355,15 +2425,17 @@
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
"type": "string"
|
||||
},
|
||||
"soldTo": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"warrantyDetails": {
|
||||
"type": "string"
|
||||
@@ -2610,26 +2682,49 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"repo.MaintenanceLog": {
|
||||
"repo.MaintenanceEntryWithDetails": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"costAverage": {
|
||||
"type": "number"
|
||||
"completedDate": {
|
||||
"type": "string"
|
||||
},
|
||||
"costTotal": {
|
||||
"type": "number"
|
||||
"cost": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"entries": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntry"
|
||||
}
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemId": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemID": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemName": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"scheduledDate": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repo.MaintenanceFilterStatus": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"scheduled",
|
||||
"completed",
|
||||
"both"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"MaintenanceFilterStatusScheduled",
|
||||
"MaintenanceFilterStatusCompleted",
|
||||
"MaintenanceFilterStatusBoth"
|
||||
]
|
||||
},
|
||||
"repo.NotifierCreate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -2671,6 +2766,9 @@
|
||||
"updatedAt": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"userId": {
|
||||
"type": "string"
|
||||
}
|
||||
@@ -2713,9 +2811,6 @@
|
||||
},
|
||||
"total": {
|
||||
"type": "integer"
|
||||
},
|
||||
"totalPrice": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2998,4 +3093,4 @@
|
||||
"in": "header"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,11 +170,8 @@ definitions:
|
||||
x-omitempty: true
|
||||
purchaseFrom:
|
||||
type: string
|
||||
purchaseMethod:
|
||||
type: string
|
||||
purchasePrice:
|
||||
example: "0"
|
||||
type: string
|
||||
type: number
|
||||
purchaseTime:
|
||||
description: Purchase
|
||||
type: string
|
||||
@@ -185,8 +182,7 @@ definitions:
|
||||
soldNotes:
|
||||
type: string
|
||||
soldPrice:
|
||||
example: "0"
|
||||
type: string
|
||||
type: number
|
||||
soldTime:
|
||||
description: Sold
|
||||
type: string
|
||||
@@ -221,6 +217,9 @@ definitions:
|
||||
properties:
|
||||
archived:
|
||||
type: boolean
|
||||
assetId:
|
||||
example: "0"
|
||||
type: string
|
||||
createdAt:
|
||||
type: string
|
||||
description:
|
||||
@@ -244,8 +243,7 @@ definitions:
|
||||
name:
|
||||
type: string
|
||||
purchasePrice:
|
||||
example: "0"
|
||||
type: string
|
||||
type: number
|
||||
quantity:
|
||||
type: integer
|
||||
updatedAt:
|
||||
@@ -266,6 +264,7 @@ definitions:
|
||||
assetId:
|
||||
type: string
|
||||
description:
|
||||
maxLength: 1000
|
||||
type: string
|
||||
fields:
|
||||
items:
|
||||
@@ -290,6 +289,8 @@ definitions:
|
||||
modelNumber:
|
||||
type: string
|
||||
name:
|
||||
maxLength: 255
|
||||
minLength: 1
|
||||
type: string
|
||||
notes:
|
||||
description: Extras
|
||||
@@ -299,10 +300,12 @@ definitions:
|
||||
x-nullable: true
|
||||
x-omitempty: true
|
||||
purchaseFrom:
|
||||
maxLength: 255
|
||||
type: string
|
||||
purchasePrice:
|
||||
example: "0"
|
||||
type: string
|
||||
type: number
|
||||
x-nullable: true
|
||||
x-omitempty: true
|
||||
purchaseTime:
|
||||
description: Purchase
|
||||
type: string
|
||||
@@ -314,17 +317,21 @@ definitions:
|
||||
soldNotes:
|
||||
type: string
|
||||
soldPrice:
|
||||
example: "0"
|
||||
type: string
|
||||
type: number
|
||||
x-nullable: true
|
||||
x-omitempty: true
|
||||
soldTime:
|
||||
description: Sold
|
||||
type: string
|
||||
soldTo:
|
||||
maxLength: 255
|
||||
type: string
|
||||
warrantyDetails:
|
||||
type: string
|
||||
warrantyExpires:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
repo.LabelCreate:
|
||||
properties:
|
||||
@@ -392,6 +399,8 @@ definitions:
|
||||
type: string
|
||||
parent:
|
||||
$ref: '#/definitions/repo.LocationSummary'
|
||||
totalPrice:
|
||||
type: number
|
||||
updatedAt:
|
||||
type: string
|
||||
type: object
|
||||
@@ -481,19 +490,36 @@ definitions:
|
||||
scheduledDate:
|
||||
type: string
|
||||
type: object
|
||||
repo.MaintenanceLog:
|
||||
repo.MaintenanceEntryWithDetails:
|
||||
properties:
|
||||
costAverage:
|
||||
type: number
|
||||
costTotal:
|
||||
type: number
|
||||
entries:
|
||||
items:
|
||||
$ref: '#/definitions/repo.MaintenanceEntry'
|
||||
type: array
|
||||
itemId:
|
||||
completedDate:
|
||||
type: string
|
||||
cost:
|
||||
example: "0"
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
itemID:
|
||||
type: string
|
||||
itemName:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
scheduledDate:
|
||||
type: string
|
||||
type: object
|
||||
repo.MaintenanceFilterStatus:
|
||||
enum:
|
||||
- scheduled
|
||||
- completed
|
||||
- both
|
||||
type: string
|
||||
x-enum-varnames:
|
||||
- MaintenanceFilterStatusScheduled
|
||||
- MaintenanceFilterStatusCompleted
|
||||
- MaintenanceFilterStatusBoth
|
||||
repo.NotifierCreate:
|
||||
properties:
|
||||
isActive:
|
||||
@@ -522,6 +548,8 @@ definitions:
|
||||
type: string
|
||||
updatedAt:
|
||||
type: string
|
||||
url:
|
||||
type: string
|
||||
userId:
|
||||
type: string
|
||||
type: object
|
||||
@@ -1219,18 +1247,32 @@ paths:
|
||||
- Items Attachments
|
||||
/v1/items/{id}/maintenance:
|
||||
get:
|
||||
parameters:
|
||||
- enum:
|
||||
- scheduled
|
||||
- completed
|
||||
- both
|
||||
in: query
|
||||
name: status
|
||||
type: string
|
||||
x-enum-varnames:
|
||||
- MaintenanceFilterStatusScheduled
|
||||
- MaintenanceFilterStatusCompleted
|
||||
- MaintenanceFilterStatusBoth
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/repo.MaintenanceLog'
|
||||
items:
|
||||
$ref: '#/definitions/repo.MaintenanceEntryWithDetails'
|
||||
type: array
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get Maintenance Log
|
||||
tags:
|
||||
- Maintenance
|
||||
- Item Maintenance
|
||||
post:
|
||||
parameters:
|
||||
- description: Entry Data
|
||||
@@ -1250,39 +1292,7 @@ paths:
|
||||
- Bearer: []
|
||||
summary: Create Maintenance Entry
|
||||
tags:
|
||||
- Maintenance
|
||||
/v1/items/{id}/maintenance/{entry_id}:
|
||||
delete:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Delete Maintenance Entry
|
||||
tags:
|
||||
- Maintenance
|
||||
put:
|
||||
parameters:
|
||||
- description: Entry Data
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/repo.MaintenanceEntryUpdate'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/repo.MaintenanceEntry'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Update Maintenance Entry
|
||||
tags:
|
||||
- Maintenance
|
||||
- Item Maintenance
|
||||
/v1/items/{id}/path:
|
||||
get:
|
||||
parameters:
|
||||
@@ -1583,6 +1593,66 @@ paths:
|
||||
summary: Get Locations Tree
|
||||
tags:
|
||||
- Locations
|
||||
/v1/maintenance:
|
||||
get:
|
||||
parameters:
|
||||
- enum:
|
||||
- scheduled
|
||||
- completed
|
||||
- both
|
||||
in: query
|
||||
name: status
|
||||
type: string
|
||||
x-enum-varnames:
|
||||
- MaintenanceFilterStatusScheduled
|
||||
- MaintenanceFilterStatusCompleted
|
||||
- MaintenanceFilterStatusBoth
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/repo.MaintenanceEntryWithDetails'
|
||||
type: array
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Query All Maintenance
|
||||
tags:
|
||||
- Maintenance
|
||||
/v1/maintenance/{id}:
|
||||
delete:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Delete Maintenance Entry
|
||||
tags:
|
||||
- Maintenance
|
||||
put:
|
||||
parameters:
|
||||
- description: Entry Data
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/repo.MaintenanceEntryUpdate'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/repo.MaintenanceEntry'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Update Maintenance Entry
|
||||
tags:
|
||||
- Maintenance
|
||||
/v1/notifiers:
|
||||
get:
|
||||
produces:
|
||||
|
||||
@@ -1,31 +1,29 @@
|
||||
module github.com/sysadminsmedia/homebox/backend
|
||||
|
||||
go 1.22
|
||||
|
||||
toolchain go1.22.0
|
||||
go 1.23.0
|
||||
|
||||
require (
|
||||
ariga.io/atlas v0.19.1
|
||||
entgo.io/ent v0.12.5
|
||||
github.com/ardanlabs/conf/v3 v3.1.7
|
||||
entgo.io/ent v0.14.1
|
||||
github.com/ardanlabs/conf/v3 v3.1.8
|
||||
github.com/containrrr/shoutrrr v0.8.0
|
||||
github.com/go-chi/chi/v5 v5.0.12
|
||||
github.com/go-playground/validator/v10 v10.18.0
|
||||
github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a
|
||||
github.com/go-chi/chi/v5 v5.1.0
|
||||
github.com/go-playground/validator/v10 v10.22.1
|
||||
github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/schema v1.4.1
|
||||
github.com/hay-kot/httpkit v0.0.9
|
||||
github.com/mattn/go-sqlite3 v1.14.22
|
||||
github.com/olahol/melody v1.1.4
|
||||
github.com/hay-kot/httpkit v0.0.11
|
||||
github.com/mattn/go-sqlite3 v1.14.24
|
||||
github.com/olahol/melody v1.2.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/rs/zerolog v1.32.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/rs/zerolog v1.33.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/swaggo/http-swagger/v2 v2.0.2
|
||||
github.com/swaggo/swag v1.16.3
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.2
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.2.2
|
||||
golang.org/x/crypto v0.23.0
|
||||
modernc.org/sqlite v1.29.2
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.4
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.2.4
|
||||
golang.org/x/crypto v0.28.0
|
||||
modernc.org/sqlite v1.33.1
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -63,16 +61,16 @@ require (
|
||||
github.com/yeqown/reedsolomon v1.0.0 // indirect
|
||||
github.com/zclconf/go-cty v1.14.1 // indirect
|
||||
golang.org/x/image v0.18.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
golang.org/x/mod v0.20.0 // indirect
|
||||
golang.org/x/net v0.28.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
golang.org/x/tools v0.24.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
||||
modernc.org/libc v1.41.0 // indirect
|
||||
modernc.org/libc v1.55.3 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.7.2 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
)
|
||||
|
||||
111
backend/go.sum
111
backend/go.sum
@@ -1,7 +1,11 @@
|
||||
ariga.io/atlas v0.19.1 h1:QzBHkakwzEhmPWOzNhw8Yr/Bbicj6Iq5hwEoNI/Jr9A=
|
||||
ariga.io/atlas v0.19.1/go.mod h1:VPlcXdd4w2KqKnH54yEZcry79UAhpaWaxEsmn5JRNoE=
|
||||
ariga.io/atlas v0.28.0 h1:qmn9tUyJypJkIw+X3ECUwDtkMTiFupgstHbjRN4xGH0=
|
||||
ariga.io/atlas v0.28.0/go.mod h1:LOOp18LCL9r+VifvVlJqgYJwYl271rrXD9/wIyzJ8sw=
|
||||
entgo.io/ent v0.12.5 h1:KREM5E4CSoej4zeGa88Ou/gfturAnpUv0mzAjch1sj4=
|
||||
entgo.io/ent v0.12.5/go.mod h1:Y3JVAjtlIk8xVZYSn3t3mf8xlZIn5SAOXZQxD6kKI+Q=
|
||||
entgo.io/ent v0.14.1 h1:fUERL506Pqr92EPHJqr8EYxbPioflJo6PudkrEA8a/s=
|
||||
entgo.io/ent v0.14.1/go.mod h1:MH6XLG0KXpkcDQhKiHfANZSzR55TJyPL5IGNpI8wpco=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
@@ -10,8 +14,8 @@ github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7l
|
||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/ardanlabs/conf/v3 v3.1.7 h1:p232cF68TafoA5U9ZlbxUIhGJtGNdKHBXF80Fdqb5t0=
|
||||
github.com/ardanlabs/conf/v3 v3.1.7/go.mod h1:zclexWKe0NVj6LHQ8NgDDZ7bQ1spE0KeKPFficdtAjU=
|
||||
github.com/ardanlabs/conf/v3 v3.1.8 h1:r0KUV9/Hni5XdeWR2+A1BiedIDnry5CjezoqgJ0rnFQ=
|
||||
github.com/ardanlabs/conf/v3 v3.1.8/go.mod h1:OIi6NK95fj8jKFPdZ/UmcPlY37JBg99hdP9o5XmNK9c=
|
||||
github.com/containrrr/shoutrrr v0.8.0 h1:mfG2ATzIS7NR2Ec6XL+xyoHzN97H8WPjir8aYzJUSec=
|
||||
github.com/containrrr/shoutrrr v0.8.0/go.mod h1:ioyQAyu1LJY6sILuNyKaQaw+9Ttik5QePU8atnAdO2o=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
@@ -27,8 +31,8 @@ github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
||||
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
|
||||
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
|
||||
@@ -54,24 +58,25 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.18.0 h1:BvolUXjp4zuvkZ5YN5t7ebzbhlUtPsPm2S9NAZ5nl9U=
|
||||
github.com/go-playground/validator/v10 v10.18.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
|
||||
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
|
||||
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a h1:RYfmiM0zluBJOiPDJseKLEN4BapJ42uSi9SZBQ2YyiA=
|
||||
github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
|
||||
github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 h1:FWNFq4fM1wPfcK40yHE5UO3RUdSNPaBC+j3PokzA6OQ=
|
||||
github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo=
|
||||
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E=
|
||||
@@ -82,8 +87,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI=
|
||||
github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
|
||||
github.com/hay-kot/httpkit v0.0.9 h1:hu2TPY9awmIYWXxWGubaXl2U61pPvaVsm9YwboBRGu0=
|
||||
github.com/hay-kot/httpkit v0.0.9/go.mod h1:AD22YluZrvBDxmtB3Pw2SOyp3A2PZqcmBZa0+COrhoU=
|
||||
github.com/hay-kot/httpkit v0.0.11 h1:ZdB2uqsFBSDpfUoClGK5c5orjBjQkEVSXh7fZX5FKEk=
|
||||
github.com/hay-kot/httpkit v0.0.11/go.mod h1:0kZdk5/swzdfqfg2c6pBWimcgeJ9PTyO97EbHnYl2Sw=
|
||||
github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc=
|
||||
github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
@@ -111,15 +116,21 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0=
|
||||
github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/olahol/melody v1.1.4 h1:RQHfKZkQmDxI0+SLZRNBCn4LiXdqxLKRGSkT8Dyoe/E=
|
||||
github.com/olahol/melody v1.1.4/go.mod h1:GgkTl6Y7yWj/HtfD48Q5vLKPVoZOH+Qqgfa7CvJgJM4=
|
||||
github.com/olahol/melody v1.2.1 h1:xdwRkzHxf+B0w4TKbGpUSSkV516ZucQZJIWLztOWICQ=
|
||||
github.com/olahol/melody v1.2.1/go.mod h1:GgkTl6Y7yWj/HtfD48Q5vLKPVoZOH+Qqgfa7CvJgJM4=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
|
||||
github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
|
||||
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
|
||||
@@ -133,10 +144,14 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
|
||||
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@@ -145,41 +160,55 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/swaggo/files/v2 v2.0.0 h1:hmAt8Dkynw7Ssz46F6pn8ok6YmGZqHSVLZ+HQM7i0kw=
|
||||
github.com/swaggo/files/v2 v2.0.0/go.mod h1:24kk2Y9NYEJ5lHuCra6iVwkMjIekMCaFq/0JQj66kyM=
|
||||
github.com/swaggo/http-swagger/v2 v2.0.2 h1:FKCdLsl+sFCx60KFsyM0rDarwiUSZ8DqbfSyIKC9OBg=
|
||||
github.com/swaggo/http-swagger/v2 v2.0.2/go.mod h1:r7/GBkAWIfK6E/OLnE8fXnviHiDeAHmgIyooa4xm3AQ=
|
||||
github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg=
|
||||
github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk=
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.2 h1:0comk6jEwi0oWNhKEmzx4JI+Q7XIneAApmFSMKWmSVc=
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.2/go.mod h1:2Qsk2APUCPne0TsRo40DIkI5MYnbzYKCnKGEFWrxd24=
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.2.2 h1:gyzunKXgC0ZUpKqQFUImbAEwewAiwNCkxFEKZV80Kt4=
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.2.2/go.mod h1:bbVRiBJSRPj4UBZP/biLG7JSd9kHqXjErk1eakAMnRA=
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.4 h1:cXdYlrhzHzVAnJHiwr/T6lAUmS9MtEStjEZBjArrvnc=
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.4/go.mod h1:uHpt9CM0V1HeXLz+Wg5MN50/sI/fQhfkZlOM+cOTHxw=
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.2.4 h1:41e/aLr1AMVWlug6oUMkDg2r0+dv5ofB7UaTkekKZBc=
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.2.4/go.mod h1:H8nLSGYUWBpNyBPjDcJzAanMzYBBYMFtrU2lwoSRn+k=
|
||||
github.com/yeqown/reedsolomon v1.0.0 h1:x1h/Ej/uJnNu8jaX7GLHBWmZKCAWjEJTetkqaabr4B0=
|
||||
github.com/yeqown/reedsolomon v1.0.0/go.mod h1:P76zpcn2TCuL0ul1Fso373qHRc69LKwAw/Iy6g1WiiM=
|
||||
github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA=
|
||||
github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8=
|
||||
github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
|
||||
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@@ -194,16 +223,20 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||
modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk=
|
||||
modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY=
|
||||
modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U=
|
||||
modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
|
||||
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
|
||||
modernc.org/sqlite v1.29.2 h1:xgBSyA3gemwgP31PWFfFjtBorQNYpeypGdoSDjXhrgI=
|
||||
modernc.org/sqlite v1.29.2/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
||||
modernc.org/sqlite v1.33.0 h1:WWkA/T2G17okiLGgKAj4/RMIvgyMT19yQ038160IeYk=
|
||||
modernc.org/sqlite v1.33.0/go.mod h1:9uQ9hF/pCZoYZK73D/ud5Z7cIRIILSZI8NdIemVMTX8=
|
||||
modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM=
|
||||
modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -49,7 +49,7 @@ func bootstrap() {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
func MainNoExit(m *testing.M) int {
|
||||
client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
|
||||
if err != nil {
|
||||
log.Fatalf("failed opening connection to sqlite: %v", err)
|
||||
@@ -77,5 +77,9 @@ func TestMain(m *testing.M) {
|
||||
UID: tUser.ID,
|
||||
}
|
||||
|
||||
os.Exit(m.Run())
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(MainNoExit(m))
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ type ExportCSVRow struct {
|
||||
LabelStr LabelString `csv:"HB.labels"`
|
||||
AssetID repo.AssetID `csv:"HB.asset_id"`
|
||||
Archived bool `csv:"HB.archived"`
|
||||
URL string `csv:"HB.url"`
|
||||
|
||||
Name string `csv:"HB.name"`
|
||||
Quantity int `csv:"HB.quantity"`
|
||||
|
||||
@@ -153,7 +153,7 @@ func (s *IOSheet) Read(data io.Reader) error {
|
||||
}
|
||||
|
||||
// ReadItems writes the sheet to a writer.
|
||||
func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.UUID, repos *repo.AllRepos) error {
|
||||
func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, gid uuid.UUID, repos *repo.AllRepos, hbURL string) error {
|
||||
s.Rows = make([]ExportCSVRow, len(items))
|
||||
|
||||
extraHeaders := map[string]struct{}{}
|
||||
@@ -164,7 +164,7 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.
|
||||
// TODO: Support fetching nested locations
|
||||
locID := item.Location.ID
|
||||
|
||||
locPaths, err := repos.Locations.PathForLoc(context.Background(), GID, locID)
|
||||
locPaths, err := repos.Locations.PathForLoc(context.Background(), gid, locID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("could not get location path")
|
||||
return err
|
||||
@@ -178,6 +178,8 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.
|
||||
labelString[i] = l.Name
|
||||
}
|
||||
|
||||
url := generateItemURL(item, hbURL)
|
||||
|
||||
customFields := make([]ExportItemFields, len(item.Fields))
|
||||
|
||||
for i, f := range item.Fields {
|
||||
@@ -201,11 +203,11 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.
|
||||
Description: item.Description,
|
||||
Insured: item.Insured,
|
||||
Archived: item.Archived,
|
||||
URL: url,
|
||||
|
||||
PurchasePrice: item.PurchasePrice,
|
||||
PurchaseMethod: item.PurchaseMethod,
|
||||
PurchaseFrom: item.PurchaseFrom,
|
||||
PurchaseTime: item.PurchaseTime,
|
||||
PurchasePrice: item.PurchasePrice,
|
||||
PurchaseFrom: item.PurchaseFrom,
|
||||
PurchaseTime: item.PurchaseTime,
|
||||
|
||||
Manufacturer: item.Manufacturer,
|
||||
ModelNumber: item.ModelNumber,
|
||||
@@ -220,6 +222,7 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.
|
||||
SoldPrice: item.SoldPrice,
|
||||
SoldNotes: item.SoldNotes,
|
||||
|
||||
Notes: item.Notes,
|
||||
Fields: customFields,
|
||||
}
|
||||
}
|
||||
@@ -253,6 +256,14 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateItemURL(item repo.ItemOut, d string) string {
|
||||
url := ""
|
||||
if item.ID != uuid.Nil {
|
||||
url = fmt.Sprintf("%s/item/%s", d, item.ID.String())
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
// CSV writes the current sheet to a 2d array, for compatibility with TSV/CSV files.
|
||||
func (s *IOSheet) CSV() ([][]string, error) {
|
||||
memcsv := make([][]string, len(s.Rows)+1)
|
||||
|
||||
@@ -38,13 +38,13 @@ func (svc *ItemService) Create(ctx Context, item repo.ItemCreate) (repo.ItemOut,
|
||||
return svc.repo.Items.Create(ctx, ctx.GID, item)
|
||||
}
|
||||
|
||||
func (svc *ItemService) EnsureAssetID(ctx context.Context, GID uuid.UUID) (int, error) {
|
||||
items, err := svc.repo.Items.GetAllZeroAssetID(ctx, GID)
|
||||
func (svc *ItemService) EnsureAssetID(ctx context.Context, gid uuid.UUID) (int, error) {
|
||||
items, err := svc.repo.Items.GetAllZeroAssetID(ctx, gid)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
highest, err := svc.repo.Items.GetHighestAssetID(ctx, GID)
|
||||
highest, err := svc.repo.Items.GetHighestAssetID(ctx, gid)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -53,7 +53,7 @@ func (svc *ItemService) EnsureAssetID(ctx context.Context, GID uuid.UUID) (int,
|
||||
for _, item := range items {
|
||||
highest++
|
||||
|
||||
err = svc.repo.Items.SetAssetID(ctx, GID, item.ID, highest)
|
||||
err = svc.repo.Items.SetAssetID(ctx, gid, item.ID, highest)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -64,8 +64,8 @@ func (svc *ItemService) EnsureAssetID(ctx context.Context, GID uuid.UUID) (int,
|
||||
return finished, nil
|
||||
}
|
||||
|
||||
func (svc *ItemService) EnsureImportRef(ctx context.Context, GID uuid.UUID) (int, error) {
|
||||
ids, err := svc.repo.Items.GetAllZeroImportRef(ctx, GID)
|
||||
func (svc *ItemService) EnsureImportRef(ctx context.Context, gid uuid.UUID) (int, error) {
|
||||
ids, err := svc.repo.Items.GetAllZeroImportRef(ctx, gid)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -74,7 +74,7 @@ func (svc *ItemService) EnsureImportRef(ctx context.Context, GID uuid.UUID) (int
|
||||
for _, itemID := range ids {
|
||||
ref := uuid.New().String()[0:8]
|
||||
|
||||
err = svc.repo.Items.Patch(ctx, GID, itemID, repo.ItemPatch{ImportRef: &ref})
|
||||
err = svc.repo.Items.Patch(ctx, gid, itemID, repo.ItemPatch{ImportRef: &ref})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -96,7 +96,7 @@ func serializeLocation[T ~[]string](location T) string {
|
||||
// 1. If the item does not exist, it is created.
|
||||
// 2. If the item has a ImportRef and it exists it is skipped
|
||||
// 3. Locations and Labels are created if they do not exist.
|
||||
func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Reader) (int, error) {
|
||||
func (svc *ItemService) CsvImport(ctx context.Context, gid uuid.UUID, data io.Reader) (int, error) {
|
||||
sheet := reporting.IOSheet{}
|
||||
|
||||
err := sheet.Read(data)
|
||||
@@ -109,7 +109,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||
|
||||
labelMap := make(map[string]uuid.UUID)
|
||||
{
|
||||
labels, err := svc.repo.Labels.GetAll(ctx, GID)
|
||||
labels, err := svc.repo.Labels.GetAll(ctx, gid)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -124,7 +124,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||
|
||||
locationMap := make(map[string]uuid.UUID)
|
||||
{
|
||||
locations, err := svc.repo.Locations.Tree(ctx, GID, repo.TreeQuery{WithItems: false})
|
||||
locations, err := svc.repo.Locations.Tree(ctx, gid, repo.TreeQuery{WithItems: false})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -153,7 +153,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||
// Asset ID Pre-Check
|
||||
highestAID := repo.AssetID(-1)
|
||||
if svc.autoIncrementAssetID {
|
||||
highestAID, err = svc.repo.Items.GetHighestAssetID(ctx, GID)
|
||||
highestAID, err = svc.repo.Items.GetHighestAssetID(ctx, gid)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -169,7 +169,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||
// ========================================
|
||||
// Preflight check for existing item
|
||||
if row.ImportRef != "" {
|
||||
exists, err := svc.repo.Items.CheckRef(ctx, GID, row.ImportRef)
|
||||
exists, err := svc.repo.Items.CheckRef(ctx, gid, row.ImportRef)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("error checking for existing item with ref %q: %w", row.ImportRef, err)
|
||||
}
|
||||
@@ -188,7 +188,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||
|
||||
id, ok := labelMap[label]
|
||||
if !ok {
|
||||
newLabel, err := svc.repo.Labels.Create(ctx, GID, repo.LabelCreate{Name: label})
|
||||
newLabel, err := svc.repo.Labels.Create(ctx, gid, repo.LabelCreate{Name: label})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -220,7 +220,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||
parentID = locationMap[parentPath]
|
||||
}
|
||||
|
||||
newLocation, err := svc.repo.Locations.Create(ctx, GID, repo.LocationCreate{
|
||||
newLocation, err := svc.repo.Locations.Create(ctx, gid, repo.LocationCreate{
|
||||
ParentID: parentID,
|
||||
Name: pathElement,
|
||||
})
|
||||
@@ -261,12 +261,12 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||
LabelIDs: labelIds,
|
||||
}
|
||||
|
||||
item, err = svc.repo.Items.Create(ctx, GID, newItem)
|
||||
item, err = svc.repo.Items.Create(ctx, gid, newItem)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
default:
|
||||
item, err = svc.repo.Items.GetByRef(ctx, GID, row.ImportRef)
|
||||
item, err = svc.repo.Items.GetByRef(ctx, gid, row.ImportRef)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -298,7 +298,6 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||
Archived: row.Archived,
|
||||
|
||||
PurchasePrice: row.PurchasePrice,
|
||||
PurchaseFrom: row.PurchaseMethod,
|
||||
PurchaseFrom: row.PurchaseFrom,
|
||||
PurchaseTime: row.PurchaseTime,
|
||||
|
||||
@@ -319,7 +318,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||
Fields: fields,
|
||||
}
|
||||
|
||||
item, err = svc.repo.Items.UpdateByGroup(ctx, GID, updateItem)
|
||||
item, err = svc.repo.Items.UpdateByGroup(ctx, gid, updateItem)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -330,15 +329,15 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||
return finished, nil
|
||||
}
|
||||
|
||||
func (svc *ItemService) ExportCSV(ctx context.Context, GID uuid.UUID) ([][]string, error) {
|
||||
items, err := svc.repo.Items.GetAll(ctx, GID)
|
||||
func (svc *ItemService) ExportCSV(ctx context.Context, gid uuid.UUID, hbURL string) ([][]string, error) {
|
||||
items, err := svc.repo.Items.GetAll(ctx, gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sheet := reporting.IOSheet{}
|
||||
|
||||
err = sheet.ReadItems(ctx, items, GID, svc.repo)
|
||||
err = sheet.ReadItems(ctx, items, gid, svc.repo, hbURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -346,8 +345,8 @@ func (svc *ItemService) ExportCSV(ctx context.Context, GID uuid.UUID) ([][]strin
|
||||
return sheet.CSV()
|
||||
}
|
||||
|
||||
func (svc *ItemService) ExportBillOfMaterialsCSV(ctx context.Context, GID uuid.UUID) ([]byte, error) {
|
||||
items, err := svc.repo.Items.GetAll(ctx, GID)
|
||||
func (svc *ItemService) ExportBillOfMaterialsCSV(ctx context.Context, gid uuid.UUID) ([]byte, error) {
|
||||
items, err := svc.repo.Items.GetAll(ctx, gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -132,13 +132,13 @@ func (svc *UserService) GetSelf(ctx context.Context, requestToken string) (repo.
|
||||
return svc.repos.AuthTokens.GetUserFromToken(ctx, hash)
|
||||
}
|
||||
|
||||
func (svc *UserService) UpdateSelf(ctx context.Context, ID uuid.UUID, data repo.UserUpdate) (repo.UserOut, error) {
|
||||
err := svc.repos.Users.Update(ctx, ID, data)
|
||||
func (svc *UserService) UpdateSelf(ctx context.Context, id uuid.UUID, data repo.UserUpdate) (repo.UserOut, error) {
|
||||
err := svc.repos.Users.Update(ctx, id, data)
|
||||
if err != nil {
|
||||
return repo.UserOut{}, err
|
||||
}
|
||||
|
||||
return svc.repos.Users.GetOneID(ctx, ID)
|
||||
return svc.repos.Users.GetOneID(ctx, id)
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -217,8 +217,8 @@ func (svc *UserService) RenewToken(ctx context.Context, token string) (UserAuthT
|
||||
// DeleteSelf deletes the user that is currently logged based of the provided UUID
|
||||
// There is _NO_ protection against deleting the wrong user, as such this should only
|
||||
// be used when the identify of the user has been confirmed.
|
||||
func (svc *UserService) DeleteSelf(ctx context.Context, ID uuid.UUID) error {
|
||||
return svc.repos.Users.Delete(ctx, ID)
|
||||
func (svc *UserService) DeleteSelf(ctx context.Context, id uuid.UUID) error {
|
||||
return svc.repos.Users.Delete(ctx, id)
|
||||
}
|
||||
|
||||
func (svc *UserService) ChangePassword(ctx Context, current string, new string) (ok bool) {
|
||||
|
||||
@@ -50,12 +50,10 @@ type AttachmentEdges struct {
|
||||
// ItemOrErr returns the Item value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e AttachmentEdges) ItemOrErr() (*Item, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Item == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: item.Label}
|
||||
}
|
||||
if e.Item != nil {
|
||||
return e.Item, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: item.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "item"}
|
||||
}
|
||||
@@ -63,12 +61,10 @@ func (e AttachmentEdges) ItemOrErr() (*Item, error) {
|
||||
// DocumentOrErr returns the Document value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e AttachmentEdges) DocumentOrErr() (*Document, error) {
|
||||
if e.loadedTypes[1] {
|
||||
if e.Document == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: document.Label}
|
||||
}
|
||||
if e.Document != nil {
|
||||
return e.Document, nil
|
||||
} else if e.loadedTypes[1] {
|
||||
return nil, &NotFoundError{label: document.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "document"}
|
||||
}
|
||||
|
||||
@@ -191,10 +191,10 @@ func (ac *AttachmentCreate) check() error {
|
||||
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 len(ac.mutation.ItemIDs()) == 0 {
|
||||
return &ValidationError{Name: "item", err: errors.New(`ent: missing required edge "Attachment.item"`)}
|
||||
}
|
||||
if _, ok := ac.mutation.DocumentID(); !ok {
|
||||
if len(ac.mutation.DocumentIDs()) == 0 {
|
||||
return &ValidationError{Name: "document", err: errors.New(`ent: missing required edge "Attachment.document"`)}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -110,7 +111,7 @@ func (aq *AttachmentQuery) QueryDocument() *DocumentQuery {
|
||||
// First returns the first Attachment entity from the query.
|
||||
// Returns a *NotFoundError when no Attachment was found.
|
||||
func (aq *AttachmentQuery) First(ctx context.Context) (*Attachment, error) {
|
||||
nodes, err := aq.Limit(1).All(setContextOp(ctx, aq.ctx, "First"))
|
||||
nodes, err := aq.Limit(1).All(setContextOp(ctx, aq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -133,7 +134,7 @@ func (aq *AttachmentQuery) FirstX(ctx context.Context) *Attachment {
|
||||
// Returns a *NotFoundError when no Attachment ID was found.
|
||||
func (aq *AttachmentQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = aq.Limit(1).IDs(setContextOp(ctx, aq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = aq.Limit(1).IDs(setContextOp(ctx, aq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -156,7 +157,7 @@ func (aq *AttachmentQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Attachment entity is found.
|
||||
// Returns a *NotFoundError when no Attachment entities are found.
|
||||
func (aq *AttachmentQuery) Only(ctx context.Context) (*Attachment, error) {
|
||||
nodes, err := aq.Limit(2).All(setContextOp(ctx, aq.ctx, "Only"))
|
||||
nodes, err := aq.Limit(2).All(setContextOp(ctx, aq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -184,7 +185,7 @@ func (aq *AttachmentQuery) OnlyX(ctx context.Context) *Attachment {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (aq *AttachmentQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = aq.Limit(2).IDs(setContextOp(ctx, aq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = aq.Limit(2).IDs(setContextOp(ctx, aq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -209,7 +210,7 @@ func (aq *AttachmentQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Attachments.
|
||||
func (aq *AttachmentQuery) All(ctx context.Context) ([]*Attachment, error) {
|
||||
ctx = setContextOp(ctx, aq.ctx, "All")
|
||||
ctx = setContextOp(ctx, aq.ctx, ent.OpQueryAll)
|
||||
if err := aq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -231,7 +232,7 @@ func (aq *AttachmentQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error)
|
||||
if aq.ctx.Unique == nil && aq.path != nil {
|
||||
aq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, aq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, aq.ctx, ent.OpQueryIDs)
|
||||
if err = aq.Select(attachment.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -249,7 +250,7 @@ func (aq *AttachmentQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (aq *AttachmentQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, aq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, aq.ctx, ent.OpQueryCount)
|
||||
if err := aq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -267,7 +268,7 @@ func (aq *AttachmentQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (aq *AttachmentQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, aq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, aq.ctx, ent.OpQueryExist)
|
||||
switch _, err := aq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -612,7 +613,7 @@ func (agb *AttachmentGroupBy) Aggregate(fns ...AggregateFunc) *AttachmentGroupBy
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (agb *AttachmentGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, agb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, agb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := agb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -660,7 +661,7 @@ func (as *AttachmentSelect) Aggregate(fns ...AggregateFunc) *AttachmentSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (as *AttachmentSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, as.ctx, "Select")
|
||||
ctx = setContextOp(ctx, as.ctx, ent.OpQuerySelect)
|
||||
if err := as.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -147,10 +147,10 @@ func (au *AttachmentUpdate) check() error {
|
||||
return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "Attachment.type": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := au.mutation.ItemID(); au.mutation.ItemCleared() && !ok {
|
||||
if au.mutation.ItemCleared() && len(au.mutation.ItemIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Attachment.item"`)
|
||||
}
|
||||
if _, ok := au.mutation.DocumentID(); au.mutation.DocumentCleared() && !ok {
|
||||
if au.mutation.DocumentCleared() && len(au.mutation.DocumentIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Attachment.document"`)
|
||||
}
|
||||
return nil
|
||||
@@ -384,10 +384,10 @@ func (auo *AttachmentUpdateOne) check() error {
|
||||
return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "Attachment.type": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := auo.mutation.ItemID(); auo.mutation.ItemCleared() && !ok {
|
||||
if auo.mutation.ItemCleared() && len(auo.mutation.ItemIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Attachment.item"`)
|
||||
}
|
||||
if _, ok := auo.mutation.DocumentID(); auo.mutation.DocumentCleared() && !ok {
|
||||
if auo.mutation.DocumentCleared() && len(auo.mutation.DocumentIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Attachment.document"`)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -39,12 +39,10 @@ type AuthRolesEdges struct {
|
||||
// TokenOrErr returns the Token value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e AuthRolesEdges) TokenOrErr() (*AuthTokens, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Token == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: authtokens.Label}
|
||||
}
|
||||
if e.Token != nil {
|
||||
return e.Token, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: authtokens.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "token"}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -86,7 +87,7 @@ func (arq *AuthRolesQuery) QueryToken() *AuthTokensQuery {
|
||||
// First returns the first AuthRoles entity from the query.
|
||||
// Returns a *NotFoundError when no AuthRoles was found.
|
||||
func (arq *AuthRolesQuery) First(ctx context.Context) (*AuthRoles, error) {
|
||||
nodes, err := arq.Limit(1).All(setContextOp(ctx, arq.ctx, "First"))
|
||||
nodes, err := arq.Limit(1).All(setContextOp(ctx, arq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -109,7 +110,7 @@ func (arq *AuthRolesQuery) FirstX(ctx context.Context) *AuthRoles {
|
||||
// Returns a *NotFoundError when no AuthRoles ID was found.
|
||||
func (arq *AuthRolesQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = arq.Limit(1).IDs(setContextOp(ctx, arq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = arq.Limit(1).IDs(setContextOp(ctx, arq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -132,7 +133,7 @@ func (arq *AuthRolesQuery) FirstIDX(ctx context.Context) int {
|
||||
// Returns a *NotSingularError when more than one AuthRoles entity is found.
|
||||
// Returns a *NotFoundError when no AuthRoles entities are found.
|
||||
func (arq *AuthRolesQuery) Only(ctx context.Context) (*AuthRoles, error) {
|
||||
nodes, err := arq.Limit(2).All(setContextOp(ctx, arq.ctx, "Only"))
|
||||
nodes, err := arq.Limit(2).All(setContextOp(ctx, arq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -160,7 +161,7 @@ func (arq *AuthRolesQuery) OnlyX(ctx context.Context) *AuthRoles {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (arq *AuthRolesQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = arq.Limit(2).IDs(setContextOp(ctx, arq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = arq.Limit(2).IDs(setContextOp(ctx, arq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -185,7 +186,7 @@ func (arq *AuthRolesQuery) OnlyIDX(ctx context.Context) int {
|
||||
|
||||
// All executes the query and returns a list of AuthRolesSlice.
|
||||
func (arq *AuthRolesQuery) All(ctx context.Context) ([]*AuthRoles, error) {
|
||||
ctx = setContextOp(ctx, arq.ctx, "All")
|
||||
ctx = setContextOp(ctx, arq.ctx, ent.OpQueryAll)
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -207,7 +208,7 @@ func (arq *AuthRolesQuery) IDs(ctx context.Context) (ids []int, err error) {
|
||||
if arq.ctx.Unique == nil && arq.path != nil {
|
||||
arq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, arq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, arq.ctx, ent.OpQueryIDs)
|
||||
if err = arq.Select(authroles.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -225,7 +226,7 @@ func (arq *AuthRolesQuery) IDsX(ctx context.Context) []int {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (arq *AuthRolesQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, arq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, arq.ctx, ent.OpQueryCount)
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -243,7 +244,7 @@ func (arq *AuthRolesQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (arq *AuthRolesQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, arq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, arq.ctx, ent.OpQueryExist)
|
||||
switch _, err := arq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -537,7 +538,7 @@ func (argb *AuthRolesGroupBy) Aggregate(fns ...AggregateFunc) *AuthRolesGroupBy
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (argb *AuthRolesGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, argb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, argb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := argb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -585,7 +586,7 @@ func (ars *AuthRolesSelect) Aggregate(fns ...AggregateFunc) *AuthRolesSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ars *AuthRolesSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ars.ctx, "Select")
|
||||
ctx = setContextOp(ctx, ars.ctx, ent.OpQuerySelect)
|
||||
if err := ars.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -49,12 +49,10 @@ type AuthTokensEdges struct {
|
||||
// UserOrErr returns the User value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e AuthTokensEdges) UserOrErr() (*User, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.User == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: user.Label}
|
||||
}
|
||||
if e.User != nil {
|
||||
return e.User, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: user.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "user"}
|
||||
}
|
||||
@@ -62,12 +60,10 @@ func (e AuthTokensEdges) UserOrErr() (*User, error) {
|
||||
// RolesOrErr returns the Roles value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e AuthTokensEdges) RolesOrErr() (*AuthRoles, error) {
|
||||
if e.loadedTypes[1] {
|
||||
if e.Roles == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: authroles.Label}
|
||||
}
|
||||
if e.Roles != nil {
|
||||
return e.Roles, nil
|
||||
} else if e.loadedTypes[1] {
|
||||
return nil, &NotFoundError{label: authroles.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "roles"}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -111,7 +112,7 @@ func (atq *AuthTokensQuery) QueryRoles() *AuthRolesQuery {
|
||||
// First returns the first AuthTokens entity from the query.
|
||||
// Returns a *NotFoundError when no AuthTokens was found.
|
||||
func (atq *AuthTokensQuery) First(ctx context.Context) (*AuthTokens, error) {
|
||||
nodes, err := atq.Limit(1).All(setContextOp(ctx, atq.ctx, "First"))
|
||||
nodes, err := atq.Limit(1).All(setContextOp(ctx, atq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -134,7 +135,7 @@ func (atq *AuthTokensQuery) FirstX(ctx context.Context) *AuthTokens {
|
||||
// Returns a *NotFoundError when no AuthTokens ID was found.
|
||||
func (atq *AuthTokensQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = atq.Limit(1).IDs(setContextOp(ctx, atq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = atq.Limit(1).IDs(setContextOp(ctx, atq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -157,7 +158,7 @@ func (atq *AuthTokensQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one AuthTokens entity is found.
|
||||
// Returns a *NotFoundError when no AuthTokens entities are found.
|
||||
func (atq *AuthTokensQuery) Only(ctx context.Context) (*AuthTokens, error) {
|
||||
nodes, err := atq.Limit(2).All(setContextOp(ctx, atq.ctx, "Only"))
|
||||
nodes, err := atq.Limit(2).All(setContextOp(ctx, atq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -185,7 +186,7 @@ func (atq *AuthTokensQuery) OnlyX(ctx context.Context) *AuthTokens {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (atq *AuthTokensQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = atq.Limit(2).IDs(setContextOp(ctx, atq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = atq.Limit(2).IDs(setContextOp(ctx, atq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -210,7 +211,7 @@ func (atq *AuthTokensQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of AuthTokensSlice.
|
||||
func (atq *AuthTokensQuery) All(ctx context.Context) ([]*AuthTokens, error) {
|
||||
ctx = setContextOp(ctx, atq.ctx, "All")
|
||||
ctx = setContextOp(ctx, atq.ctx, ent.OpQueryAll)
|
||||
if err := atq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -232,7 +233,7 @@ func (atq *AuthTokensQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error
|
||||
if atq.ctx.Unique == nil && atq.path != nil {
|
||||
atq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, atq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, atq.ctx, ent.OpQueryIDs)
|
||||
if err = atq.Select(authtokens.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -250,7 +251,7 @@ func (atq *AuthTokensQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (atq *AuthTokensQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, atq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, atq.ctx, ent.OpQueryCount)
|
||||
if err := atq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -268,7 +269,7 @@ func (atq *AuthTokensQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (atq *AuthTokensQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, atq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, atq.ctx, ent.OpQueryExist)
|
||||
switch _, err := atq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -609,7 +610,7 @@ func (atgb *AuthTokensGroupBy) Aggregate(fns ...AggregateFunc) *AuthTokensGroupB
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (atgb *AuthTokensGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, atgb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, atgb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := atgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -657,7 +658,7 @@ func (ats *AuthTokensSelect) Aggregate(fns ...AggregateFunc) *AuthTokensSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ats *AuthTokensSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ats.ctx, "Select")
|
||||
ctx = setContextOp(ctx, ats.ctx, ent.OpQuerySelect)
|
||||
if err := ats.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -48,12 +48,10 @@ type DocumentEdges struct {
|
||||
// GroupOrErr returns the Group value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e DocumentEdges) GroupOrErr() (*Group, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Group == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
if e.Group != nil {
|
||||
return e.Group, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "group"}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ func (dc *DocumentCreate) check() error {
|
||||
return &ValidationError{Name: "path", err: fmt.Errorf(`ent: validator failed for field "Document.path": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := dc.mutation.GroupID(); !ok {
|
||||
if len(dc.mutation.GroupIDs()) == 0 {
|
||||
return &ValidationError{Name: "group", err: errors.New(`ent: missing required edge "Document.group"`)}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -111,7 +112,7 @@ func (dq *DocumentQuery) QueryAttachments() *AttachmentQuery {
|
||||
// First returns the first Document entity from the query.
|
||||
// Returns a *NotFoundError when no Document was found.
|
||||
func (dq *DocumentQuery) First(ctx context.Context) (*Document, error) {
|
||||
nodes, err := dq.Limit(1).All(setContextOp(ctx, dq.ctx, "First"))
|
||||
nodes, err := dq.Limit(1).All(setContextOp(ctx, dq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -134,7 +135,7 @@ func (dq *DocumentQuery) FirstX(ctx context.Context) *Document {
|
||||
// Returns a *NotFoundError when no Document ID was found.
|
||||
func (dq *DocumentQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = dq.Limit(1).IDs(setContextOp(ctx, dq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = dq.Limit(1).IDs(setContextOp(ctx, dq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -157,7 +158,7 @@ func (dq *DocumentQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Document entity is found.
|
||||
// Returns a *NotFoundError when no Document entities are found.
|
||||
func (dq *DocumentQuery) Only(ctx context.Context) (*Document, error) {
|
||||
nodes, err := dq.Limit(2).All(setContextOp(ctx, dq.ctx, "Only"))
|
||||
nodes, err := dq.Limit(2).All(setContextOp(ctx, dq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -185,7 +186,7 @@ func (dq *DocumentQuery) OnlyX(ctx context.Context) *Document {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (dq *DocumentQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = dq.Limit(2).IDs(setContextOp(ctx, dq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = dq.Limit(2).IDs(setContextOp(ctx, dq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -210,7 +211,7 @@ func (dq *DocumentQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Documents.
|
||||
func (dq *DocumentQuery) All(ctx context.Context) ([]*Document, error) {
|
||||
ctx = setContextOp(ctx, dq.ctx, "All")
|
||||
ctx = setContextOp(ctx, dq.ctx, ent.OpQueryAll)
|
||||
if err := dq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -232,7 +233,7 @@ func (dq *DocumentQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
|
||||
if dq.ctx.Unique == nil && dq.path != nil {
|
||||
dq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, dq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, dq.ctx, ent.OpQueryIDs)
|
||||
if err = dq.Select(document.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -250,7 +251,7 @@ func (dq *DocumentQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (dq *DocumentQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, dq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, dq.ctx, ent.OpQueryCount)
|
||||
if err := dq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -268,7 +269,7 @@ func (dq *DocumentQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (dq *DocumentQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, dq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, dq.ctx, ent.OpQueryExist)
|
||||
switch _, err := dq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -613,7 +614,7 @@ func (dgb *DocumentGroupBy) Aggregate(fns ...AggregateFunc) *DocumentGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (dgb *DocumentGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, dgb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, dgb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := dgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -661,7 +662,7 @@ func (ds *DocumentSelect) Aggregate(fns ...AggregateFunc) *DocumentSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ds *DocumentSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ds.ctx, "Select")
|
||||
ctx = setContextOp(ctx, ds.ctx, ent.OpQuerySelect)
|
||||
if err := ds.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ func (du *DocumentUpdate) check() error {
|
||||
return &ValidationError{Name: "path", err: fmt.Errorf(`ent: validator failed for field "Document.path": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := du.mutation.GroupID(); du.mutation.GroupCleared() && !ok {
|
||||
if du.mutation.GroupCleared() && len(du.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Document.group"`)
|
||||
}
|
||||
return nil
|
||||
@@ -445,7 +445,7 @@ func (duo *DocumentUpdateOne) check() error {
|
||||
return &ValidationError{Name: "path", err: fmt.Errorf(`ent: validator failed for field "Document.path": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := duo.mutation.GroupID(); duo.mutation.GroupCleared() && !ok {
|
||||
if duo.mutation.GroupCleared() && len(duo.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Document.group"`)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -81,7 +81,7 @@ var (
|
||||
columnCheck sql.ColumnCheck
|
||||
)
|
||||
|
||||
// columnChecker checks if the column exists in the given table.
|
||||
// checkColumn checks if the column exists in the given table.
|
||||
func checkColumn(table, column string) error {
|
||||
initCheck.Do(func() {
|
||||
columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -230,7 +231,7 @@ func (gq *GroupQuery) QueryNotifiers() *NotifierQuery {
|
||||
// First returns the first Group entity from the query.
|
||||
// Returns a *NotFoundError when no Group was found.
|
||||
func (gq *GroupQuery) First(ctx context.Context) (*Group, error) {
|
||||
nodes, err := gq.Limit(1).All(setContextOp(ctx, gq.ctx, "First"))
|
||||
nodes, err := gq.Limit(1).All(setContextOp(ctx, gq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -253,7 +254,7 @@ func (gq *GroupQuery) FirstX(ctx context.Context) *Group {
|
||||
// Returns a *NotFoundError when no Group ID was found.
|
||||
func (gq *GroupQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = gq.Limit(1).IDs(setContextOp(ctx, gq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = gq.Limit(1).IDs(setContextOp(ctx, gq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -276,7 +277,7 @@ func (gq *GroupQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Group entity is found.
|
||||
// Returns a *NotFoundError when no Group entities are found.
|
||||
func (gq *GroupQuery) Only(ctx context.Context) (*Group, error) {
|
||||
nodes, err := gq.Limit(2).All(setContextOp(ctx, gq.ctx, "Only"))
|
||||
nodes, err := gq.Limit(2).All(setContextOp(ctx, gq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -304,7 +305,7 @@ func (gq *GroupQuery) OnlyX(ctx context.Context) *Group {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (gq *GroupQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = gq.Limit(2).IDs(setContextOp(ctx, gq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = gq.Limit(2).IDs(setContextOp(ctx, gq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -329,7 +330,7 @@ func (gq *GroupQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Groups.
|
||||
func (gq *GroupQuery) All(ctx context.Context) ([]*Group, error) {
|
||||
ctx = setContextOp(ctx, gq.ctx, "All")
|
||||
ctx = setContextOp(ctx, gq.ctx, ent.OpQueryAll)
|
||||
if err := gq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -351,7 +352,7 @@ func (gq *GroupQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
|
||||
if gq.ctx.Unique == nil && gq.path != nil {
|
||||
gq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, gq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, gq.ctx, ent.OpQueryIDs)
|
||||
if err = gq.Select(group.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -369,7 +370,7 @@ func (gq *GroupQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (gq *GroupQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, gq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, gq.ctx, ent.OpQueryCount)
|
||||
if err := gq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -387,7 +388,7 @@ func (gq *GroupQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (gq *GroupQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, gq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, gq.ctx, ent.OpQueryExist)
|
||||
switch _, err := gq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -981,7 +982,7 @@ func (ggb *GroupGroupBy) Aggregate(fns ...AggregateFunc) *GroupGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ggb *GroupGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ggb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, ggb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := ggb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1029,7 +1030,7 @@ func (gs *GroupSelect) Aggregate(fns ...AggregateFunc) *GroupSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (gs *GroupSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, gs.ctx, "Select")
|
||||
ctx = setContextOp(ctx, gs.ctx, ent.OpQuerySelect)
|
||||
if err := gs.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -48,12 +48,10 @@ type GroupInvitationTokenEdges struct {
|
||||
// GroupOrErr returns the Group value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e GroupInvitationTokenEdges) GroupOrErr() (*Group, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Group == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
if e.Group != nil {
|
||||
return e.Group, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "group"}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -86,7 +87,7 @@ func (gitq *GroupInvitationTokenQuery) QueryGroup() *GroupQuery {
|
||||
// First returns the first GroupInvitationToken entity from the query.
|
||||
// Returns a *NotFoundError when no GroupInvitationToken was found.
|
||||
func (gitq *GroupInvitationTokenQuery) First(ctx context.Context) (*GroupInvitationToken, error) {
|
||||
nodes, err := gitq.Limit(1).All(setContextOp(ctx, gitq.ctx, "First"))
|
||||
nodes, err := gitq.Limit(1).All(setContextOp(ctx, gitq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -109,7 +110,7 @@ func (gitq *GroupInvitationTokenQuery) FirstX(ctx context.Context) *GroupInvitat
|
||||
// Returns a *NotFoundError when no GroupInvitationToken ID was found.
|
||||
func (gitq *GroupInvitationTokenQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = gitq.Limit(1).IDs(setContextOp(ctx, gitq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = gitq.Limit(1).IDs(setContextOp(ctx, gitq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -132,7 +133,7 @@ func (gitq *GroupInvitationTokenQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one GroupInvitationToken entity is found.
|
||||
// Returns a *NotFoundError when no GroupInvitationToken entities are found.
|
||||
func (gitq *GroupInvitationTokenQuery) Only(ctx context.Context) (*GroupInvitationToken, error) {
|
||||
nodes, err := gitq.Limit(2).All(setContextOp(ctx, gitq.ctx, "Only"))
|
||||
nodes, err := gitq.Limit(2).All(setContextOp(ctx, gitq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -160,7 +161,7 @@ func (gitq *GroupInvitationTokenQuery) OnlyX(ctx context.Context) *GroupInvitati
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (gitq *GroupInvitationTokenQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = gitq.Limit(2).IDs(setContextOp(ctx, gitq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = gitq.Limit(2).IDs(setContextOp(ctx, gitq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -185,7 +186,7 @@ func (gitq *GroupInvitationTokenQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of GroupInvitationTokens.
|
||||
func (gitq *GroupInvitationTokenQuery) All(ctx context.Context) ([]*GroupInvitationToken, error) {
|
||||
ctx = setContextOp(ctx, gitq.ctx, "All")
|
||||
ctx = setContextOp(ctx, gitq.ctx, ent.OpQueryAll)
|
||||
if err := gitq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -207,7 +208,7 @@ func (gitq *GroupInvitationTokenQuery) IDs(ctx context.Context) (ids []uuid.UUID
|
||||
if gitq.ctx.Unique == nil && gitq.path != nil {
|
||||
gitq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, gitq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, gitq.ctx, ent.OpQueryIDs)
|
||||
if err = gitq.Select(groupinvitationtoken.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -225,7 +226,7 @@ func (gitq *GroupInvitationTokenQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (gitq *GroupInvitationTokenQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, gitq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, gitq.ctx, ent.OpQueryCount)
|
||||
if err := gitq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -243,7 +244,7 @@ func (gitq *GroupInvitationTokenQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (gitq *GroupInvitationTokenQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, gitq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, gitq.ctx, ent.OpQueryExist)
|
||||
switch _, err := gitq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -537,7 +538,7 @@ func (gitgb *GroupInvitationTokenGroupBy) Aggregate(fns ...AggregateFunc) *Group
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (gitgb *GroupInvitationTokenGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, gitgb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, gitgb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := gitgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -585,7 +586,7 @@ func (gits *GroupInvitationTokenSelect) Aggregate(fns ...AggregateFunc) *GroupIn
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (gits *GroupInvitationTokenSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, gits.ctx, "Select")
|
||||
ctx = setContextOp(ctx, gits.ctx, ent.OpQuerySelect)
|
||||
if err := gits.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -101,12 +101,10 @@ type ItemEdges struct {
|
||||
// GroupOrErr returns the Group value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e ItemEdges) GroupOrErr() (*Group, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Group == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
if e.Group != nil {
|
||||
return e.Group, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "group"}
|
||||
}
|
||||
@@ -114,12 +112,10 @@ func (e ItemEdges) GroupOrErr() (*Group, error) {
|
||||
// ParentOrErr returns the Parent value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e ItemEdges) ParentOrErr() (*Item, error) {
|
||||
if e.loadedTypes[1] {
|
||||
if e.Parent == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: item.Label}
|
||||
}
|
||||
if e.Parent != nil {
|
||||
return e.Parent, nil
|
||||
} else if e.loadedTypes[1] {
|
||||
return nil, &NotFoundError{label: item.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "parent"}
|
||||
}
|
||||
@@ -145,12 +141,10 @@ func (e ItemEdges) LabelOrErr() ([]*Label, error) {
|
||||
// LocationOrErr returns the Location value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e ItemEdges) LocationOrErr() (*Location, error) {
|
||||
if e.loadedTypes[4] {
|
||||
if e.Location == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: location.Label}
|
||||
}
|
||||
if e.Location != nil {
|
||||
return e.Location, nil
|
||||
} else if e.loadedTypes[4] {
|
||||
return nil, &NotFoundError{label: location.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "location"}
|
||||
}
|
||||
|
||||
@@ -633,7 +633,7 @@ func (ic *ItemCreate) check() error {
|
||||
return &ValidationError{Name: "sold_notes", err: fmt.Errorf(`ent: validator failed for field "Item.sold_notes": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := ic.mutation.GroupID(); !ok {
|
||||
if len(ic.mutation.GroupIDs()) == 0 {
|
||||
return &ValidationError{Name: "group", err: errors.New(`ent: missing required edge "Item.group"`)}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -253,7 +254,7 @@ func (iq *ItemQuery) QueryAttachments() *AttachmentQuery {
|
||||
// First returns the first Item entity from the query.
|
||||
// Returns a *NotFoundError when no Item was found.
|
||||
func (iq *ItemQuery) First(ctx context.Context) (*Item, error) {
|
||||
nodes, err := iq.Limit(1).All(setContextOp(ctx, iq.ctx, "First"))
|
||||
nodes, err := iq.Limit(1).All(setContextOp(ctx, iq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -276,7 +277,7 @@ func (iq *ItemQuery) FirstX(ctx context.Context) *Item {
|
||||
// Returns a *NotFoundError when no Item ID was found.
|
||||
func (iq *ItemQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = iq.Limit(1).IDs(setContextOp(ctx, iq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = iq.Limit(1).IDs(setContextOp(ctx, iq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -299,7 +300,7 @@ func (iq *ItemQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Item entity is found.
|
||||
// Returns a *NotFoundError when no Item entities are found.
|
||||
func (iq *ItemQuery) Only(ctx context.Context) (*Item, error) {
|
||||
nodes, err := iq.Limit(2).All(setContextOp(ctx, iq.ctx, "Only"))
|
||||
nodes, err := iq.Limit(2).All(setContextOp(ctx, iq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -327,7 +328,7 @@ func (iq *ItemQuery) OnlyX(ctx context.Context) *Item {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (iq *ItemQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = iq.Limit(2).IDs(setContextOp(ctx, iq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = iq.Limit(2).IDs(setContextOp(ctx, iq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -352,7 +353,7 @@ func (iq *ItemQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Items.
|
||||
func (iq *ItemQuery) All(ctx context.Context) ([]*Item, error) {
|
||||
ctx = setContextOp(ctx, iq.ctx, "All")
|
||||
ctx = setContextOp(ctx, iq.ctx, ent.OpQueryAll)
|
||||
if err := iq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -374,7 +375,7 @@ func (iq *ItemQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
|
||||
if iq.ctx.Unique == nil && iq.path != nil {
|
||||
iq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, iq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, iq.ctx, ent.OpQueryIDs)
|
||||
if err = iq.Select(item.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -392,7 +393,7 @@ func (iq *ItemQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (iq *ItemQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, iq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, iq.ctx, ent.OpQueryCount)
|
||||
if err := iq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -410,7 +411,7 @@ func (iq *ItemQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (iq *ItemQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, iq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, iq.ctx, ent.OpQueryExist)
|
||||
switch _, err := iq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -1090,7 +1091,7 @@ func (igb *ItemGroupBy) Aggregate(fns ...AggregateFunc) *ItemGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (igb *ItemGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, igb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, igb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := igb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1138,7 +1139,7 @@ func (is *ItemSelect) Aggregate(fns ...AggregateFunc) *ItemSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (is *ItemSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, is.ctx, "Select")
|
||||
ctx = setContextOp(ctx, is.ctx, ent.OpQuerySelect)
|
||||
if err := is.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -776,7 +776,7 @@ func (iu *ItemUpdate) check() error {
|
||||
return &ValidationError{Name: "sold_notes", err: fmt.Errorf(`ent: validator failed for field "Item.sold_notes": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := iu.mutation.GroupID(); iu.mutation.GroupCleared() && !ok {
|
||||
if iu.mutation.GroupCleared() && len(iu.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Item.group"`)
|
||||
}
|
||||
return nil
|
||||
@@ -1997,7 +1997,7 @@ func (iuo *ItemUpdateOne) check() error {
|
||||
return &ValidationError{Name: "sold_notes", err: fmt.Errorf(`ent: validator failed for field "Item.sold_notes": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := iuo.mutation.GroupID(); iuo.mutation.GroupCleared() && !ok {
|
||||
if iuo.mutation.GroupCleared() && len(iuo.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Item.group"`)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -56,12 +56,10 @@ type ItemFieldEdges struct {
|
||||
// ItemOrErr returns the Item value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e ItemFieldEdges) ItemOrErr() (*Item, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Item == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: item.Label}
|
||||
}
|
||||
if e.Item != nil {
|
||||
return e.Item, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: item.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "item"}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -86,7 +87,7 @@ func (ifq *ItemFieldQuery) QueryItem() *ItemQuery {
|
||||
// First returns the first ItemField entity from the query.
|
||||
// Returns a *NotFoundError when no ItemField was found.
|
||||
func (ifq *ItemFieldQuery) First(ctx context.Context) (*ItemField, error) {
|
||||
nodes, err := ifq.Limit(1).All(setContextOp(ctx, ifq.ctx, "First"))
|
||||
nodes, err := ifq.Limit(1).All(setContextOp(ctx, ifq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -109,7 +110,7 @@ func (ifq *ItemFieldQuery) FirstX(ctx context.Context) *ItemField {
|
||||
// Returns a *NotFoundError when no ItemField ID was found.
|
||||
func (ifq *ItemFieldQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = ifq.Limit(1).IDs(setContextOp(ctx, ifq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = ifq.Limit(1).IDs(setContextOp(ctx, ifq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -132,7 +133,7 @@ func (ifq *ItemFieldQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one ItemField entity is found.
|
||||
// Returns a *NotFoundError when no ItemField entities are found.
|
||||
func (ifq *ItemFieldQuery) Only(ctx context.Context) (*ItemField, error) {
|
||||
nodes, err := ifq.Limit(2).All(setContextOp(ctx, ifq.ctx, "Only"))
|
||||
nodes, err := ifq.Limit(2).All(setContextOp(ctx, ifq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -160,7 +161,7 @@ func (ifq *ItemFieldQuery) OnlyX(ctx context.Context) *ItemField {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (ifq *ItemFieldQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = ifq.Limit(2).IDs(setContextOp(ctx, ifq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = ifq.Limit(2).IDs(setContextOp(ctx, ifq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -185,7 +186,7 @@ func (ifq *ItemFieldQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of ItemFields.
|
||||
func (ifq *ItemFieldQuery) All(ctx context.Context) ([]*ItemField, error) {
|
||||
ctx = setContextOp(ctx, ifq.ctx, "All")
|
||||
ctx = setContextOp(ctx, ifq.ctx, ent.OpQueryAll)
|
||||
if err := ifq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -207,7 +208,7 @@ func (ifq *ItemFieldQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error)
|
||||
if ifq.ctx.Unique == nil && ifq.path != nil {
|
||||
ifq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, ifq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, ifq.ctx, ent.OpQueryIDs)
|
||||
if err = ifq.Select(itemfield.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -225,7 +226,7 @@ func (ifq *ItemFieldQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (ifq *ItemFieldQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, ifq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, ifq.ctx, ent.OpQueryCount)
|
||||
if err := ifq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -243,7 +244,7 @@ func (ifq *ItemFieldQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (ifq *ItemFieldQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, ifq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, ifq.ctx, ent.OpQueryExist)
|
||||
switch _, err := ifq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -537,7 +538,7 @@ func (ifgb *ItemFieldGroupBy) Aggregate(fns ...AggregateFunc) *ItemFieldGroupBy
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ifgb *ItemFieldGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ifgb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, ifgb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := ifgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -585,7 +586,7 @@ func (ifs *ItemFieldSelect) Aggregate(fns ...AggregateFunc) *ItemFieldSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ifs *ItemFieldSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ifs.ctx, "Select")
|
||||
ctx = setContextOp(ctx, ifs.ctx, ent.OpQuerySelect)
|
||||
if err := ifs.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -50,12 +50,10 @@ type LabelEdges struct {
|
||||
// GroupOrErr returns the Group value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e LabelEdges) GroupOrErr() (*Group, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Group == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
if e.Group != nil {
|
||||
return e.Group, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "group"}
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ func (lc *LabelCreate) check() error {
|
||||
return &ValidationError{Name: "color", err: fmt.Errorf(`ent: validator failed for field "Label.color": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := lc.mutation.GroupID(); !ok {
|
||||
if len(lc.mutation.GroupIDs()) == 0 {
|
||||
return &ValidationError{Name: "group", err: errors.New(`ent: missing required edge "Label.group"`)}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -111,7 +112,7 @@ func (lq *LabelQuery) QueryItems() *ItemQuery {
|
||||
// First returns the first Label entity from the query.
|
||||
// Returns a *NotFoundError when no Label was found.
|
||||
func (lq *LabelQuery) First(ctx context.Context) (*Label, error) {
|
||||
nodes, err := lq.Limit(1).All(setContextOp(ctx, lq.ctx, "First"))
|
||||
nodes, err := lq.Limit(1).All(setContextOp(ctx, lq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -134,7 +135,7 @@ func (lq *LabelQuery) FirstX(ctx context.Context) *Label {
|
||||
// Returns a *NotFoundError when no Label ID was found.
|
||||
func (lq *LabelQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = lq.Limit(1).IDs(setContextOp(ctx, lq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = lq.Limit(1).IDs(setContextOp(ctx, lq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -157,7 +158,7 @@ func (lq *LabelQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Label entity is found.
|
||||
// Returns a *NotFoundError when no Label entities are found.
|
||||
func (lq *LabelQuery) Only(ctx context.Context) (*Label, error) {
|
||||
nodes, err := lq.Limit(2).All(setContextOp(ctx, lq.ctx, "Only"))
|
||||
nodes, err := lq.Limit(2).All(setContextOp(ctx, lq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -185,7 +186,7 @@ func (lq *LabelQuery) OnlyX(ctx context.Context) *Label {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (lq *LabelQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = lq.Limit(2).IDs(setContextOp(ctx, lq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = lq.Limit(2).IDs(setContextOp(ctx, lq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -210,7 +211,7 @@ func (lq *LabelQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Labels.
|
||||
func (lq *LabelQuery) All(ctx context.Context) ([]*Label, error) {
|
||||
ctx = setContextOp(ctx, lq.ctx, "All")
|
||||
ctx = setContextOp(ctx, lq.ctx, ent.OpQueryAll)
|
||||
if err := lq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -232,7 +233,7 @@ func (lq *LabelQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
|
||||
if lq.ctx.Unique == nil && lq.path != nil {
|
||||
lq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, lq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, lq.ctx, ent.OpQueryIDs)
|
||||
if err = lq.Select(label.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -250,7 +251,7 @@ func (lq *LabelQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (lq *LabelQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, lq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, lq.ctx, ent.OpQueryCount)
|
||||
if err := lq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -268,7 +269,7 @@ func (lq *LabelQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (lq *LabelQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, lq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, lq.ctx, ent.OpQueryExist)
|
||||
switch _, err := lq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -643,7 +644,7 @@ func (lgb *LabelGroupBy) Aggregate(fns ...AggregateFunc) *LabelGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (lgb *LabelGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, lgb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, lgb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := lgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -691,7 +692,7 @@ func (ls *LabelSelect) Aggregate(fns ...AggregateFunc) *LabelSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ls *LabelSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ls.ctx, "Select")
|
||||
ctx = setContextOp(ctx, ls.ctx, ent.OpQuerySelect)
|
||||
if err := ls.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ func (lu *LabelUpdate) check() error {
|
||||
return &ValidationError{Name: "color", err: fmt.Errorf(`ent: validator failed for field "Label.color": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := lu.mutation.GroupID(); lu.mutation.GroupCleared() && !ok {
|
||||
if lu.mutation.GroupCleared() && len(lu.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Label.group"`)
|
||||
}
|
||||
return nil
|
||||
@@ -516,7 +516,7 @@ func (luo *LabelUpdateOne) check() error {
|
||||
return &ValidationError{Name: "color", err: fmt.Errorf(`ent: validator failed for field "Label.color": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := luo.mutation.GroupID(); luo.mutation.GroupCleared() && !ok {
|
||||
if luo.mutation.GroupCleared() && len(luo.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Label.group"`)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -53,12 +53,10 @@ type LocationEdges struct {
|
||||
// GroupOrErr returns the Group value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e LocationEdges) GroupOrErr() (*Group, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Group == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
if e.Group != nil {
|
||||
return e.Group, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "group"}
|
||||
}
|
||||
@@ -66,12 +64,10 @@ func (e LocationEdges) GroupOrErr() (*Group, error) {
|
||||
// ParentOrErr returns the Parent value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e LocationEdges) ParentOrErr() (*Location, error) {
|
||||
if e.loadedTypes[1] {
|
||||
if e.Parent == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: location.Label}
|
||||
}
|
||||
if e.Parent != nil {
|
||||
return e.Parent, nil
|
||||
} else if e.loadedTypes[1] {
|
||||
return nil, &NotFoundError{label: location.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "parent"}
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ func (lc *LocationCreate) check() error {
|
||||
return &ValidationError{Name: "description", err: fmt.Errorf(`ent: validator failed for field "Location.description": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := lc.mutation.GroupID(); !ok {
|
||||
if len(lc.mutation.GroupIDs()) == 0 {
|
||||
return &ValidationError{Name: "group", err: errors.New(`ent: missing required edge "Location.group"`)}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -157,7 +158,7 @@ func (lq *LocationQuery) QueryItems() *ItemQuery {
|
||||
// First returns the first Location entity from the query.
|
||||
// Returns a *NotFoundError when no Location was found.
|
||||
func (lq *LocationQuery) First(ctx context.Context) (*Location, error) {
|
||||
nodes, err := lq.Limit(1).All(setContextOp(ctx, lq.ctx, "First"))
|
||||
nodes, err := lq.Limit(1).All(setContextOp(ctx, lq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -180,7 +181,7 @@ func (lq *LocationQuery) FirstX(ctx context.Context) *Location {
|
||||
// Returns a *NotFoundError when no Location ID was found.
|
||||
func (lq *LocationQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = lq.Limit(1).IDs(setContextOp(ctx, lq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = lq.Limit(1).IDs(setContextOp(ctx, lq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -203,7 +204,7 @@ func (lq *LocationQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Location entity is found.
|
||||
// Returns a *NotFoundError when no Location entities are found.
|
||||
func (lq *LocationQuery) Only(ctx context.Context) (*Location, error) {
|
||||
nodes, err := lq.Limit(2).All(setContextOp(ctx, lq.ctx, "Only"))
|
||||
nodes, err := lq.Limit(2).All(setContextOp(ctx, lq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -231,7 +232,7 @@ func (lq *LocationQuery) OnlyX(ctx context.Context) *Location {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (lq *LocationQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = lq.Limit(2).IDs(setContextOp(ctx, lq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = lq.Limit(2).IDs(setContextOp(ctx, lq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -256,7 +257,7 @@ func (lq *LocationQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Locations.
|
||||
func (lq *LocationQuery) All(ctx context.Context) ([]*Location, error) {
|
||||
ctx = setContextOp(ctx, lq.ctx, "All")
|
||||
ctx = setContextOp(ctx, lq.ctx, ent.OpQueryAll)
|
||||
if err := lq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -278,7 +279,7 @@ func (lq *LocationQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
|
||||
if lq.ctx.Unique == nil && lq.path != nil {
|
||||
lq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, lq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, lq.ctx, ent.OpQueryIDs)
|
||||
if err = lq.Select(location.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -296,7 +297,7 @@ func (lq *LocationQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (lq *LocationQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, lq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, lq.ctx, ent.OpQueryCount)
|
||||
if err := lq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -314,7 +315,7 @@ func (lq *LocationQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (lq *LocationQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, lq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, lq.ctx, ent.OpQueryExist)
|
||||
switch _, err := lq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -761,7 +762,7 @@ func (lgb *LocationGroupBy) Aggregate(fns ...AggregateFunc) *LocationGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (lgb *LocationGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, lgb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, lgb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := lgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -809,7 +810,7 @@ func (ls *LocationSelect) Aggregate(fns ...AggregateFunc) *LocationSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ls *LocationSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ls.ctx, "Select")
|
||||
ctx = setContextOp(ctx, ls.ctx, ent.OpQuerySelect)
|
||||
if err := ls.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ func (lu *LocationUpdate) check() error {
|
||||
return &ValidationError{Name: "description", err: fmt.Errorf(`ent: validator failed for field "Location.description": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := lu.mutation.GroupID(); lu.mutation.GroupCleared() && !ok {
|
||||
if lu.mutation.GroupCleared() && len(lu.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Location.group"`)
|
||||
}
|
||||
return nil
|
||||
@@ -656,7 +656,7 @@ func (luo *LocationUpdateOne) check() error {
|
||||
return &ValidationError{Name: "description", err: fmt.Errorf(`ent: validator failed for field "Location.description": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := luo.mutation.GroupID(); luo.mutation.GroupCleared() && !ok {
|
||||
if luo.mutation.GroupCleared() && len(luo.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Location.group"`)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -53,12 +53,10 @@ type MaintenanceEntryEdges struct {
|
||||
// ItemOrErr returns the Item value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e MaintenanceEntryEdges) ItemOrErr() (*Item, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Item == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: item.Label}
|
||||
}
|
||||
if e.Item != nil {
|
||||
return e.Item, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: item.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "item"}
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ func (mec *MaintenanceEntryCreate) check() error {
|
||||
if _, ok := mec.mutation.Cost(); !ok {
|
||||
return &ValidationError{Name: "cost", err: errors.New(`ent: missing required field "MaintenanceEntry.cost"`)}
|
||||
}
|
||||
if _, ok := mec.mutation.ItemID(); !ok {
|
||||
if len(mec.mutation.ItemIDs()) == 0 {
|
||||
return &ValidationError{Name: "item", err: errors.New(`ent: missing required edge "MaintenanceEntry.item"`)}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -85,7 +86,7 @@ func (meq *MaintenanceEntryQuery) QueryItem() *ItemQuery {
|
||||
// First returns the first MaintenanceEntry entity from the query.
|
||||
// Returns a *NotFoundError when no MaintenanceEntry was found.
|
||||
func (meq *MaintenanceEntryQuery) First(ctx context.Context) (*MaintenanceEntry, error) {
|
||||
nodes, err := meq.Limit(1).All(setContextOp(ctx, meq.ctx, "First"))
|
||||
nodes, err := meq.Limit(1).All(setContextOp(ctx, meq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -108,7 +109,7 @@ func (meq *MaintenanceEntryQuery) FirstX(ctx context.Context) *MaintenanceEntry
|
||||
// Returns a *NotFoundError when no MaintenanceEntry ID was found.
|
||||
func (meq *MaintenanceEntryQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = meq.Limit(1).IDs(setContextOp(ctx, meq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = meq.Limit(1).IDs(setContextOp(ctx, meq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -131,7 +132,7 @@ func (meq *MaintenanceEntryQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one MaintenanceEntry entity is found.
|
||||
// Returns a *NotFoundError when no MaintenanceEntry entities are found.
|
||||
func (meq *MaintenanceEntryQuery) Only(ctx context.Context) (*MaintenanceEntry, error) {
|
||||
nodes, err := meq.Limit(2).All(setContextOp(ctx, meq.ctx, "Only"))
|
||||
nodes, err := meq.Limit(2).All(setContextOp(ctx, meq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -159,7 +160,7 @@ func (meq *MaintenanceEntryQuery) OnlyX(ctx context.Context) *MaintenanceEntry {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (meq *MaintenanceEntryQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = meq.Limit(2).IDs(setContextOp(ctx, meq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = meq.Limit(2).IDs(setContextOp(ctx, meq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -184,7 +185,7 @@ func (meq *MaintenanceEntryQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of MaintenanceEntries.
|
||||
func (meq *MaintenanceEntryQuery) All(ctx context.Context) ([]*MaintenanceEntry, error) {
|
||||
ctx = setContextOp(ctx, meq.ctx, "All")
|
||||
ctx = setContextOp(ctx, meq.ctx, ent.OpQueryAll)
|
||||
if err := meq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -206,7 +207,7 @@ func (meq *MaintenanceEntryQuery) IDs(ctx context.Context) (ids []uuid.UUID, err
|
||||
if meq.ctx.Unique == nil && meq.path != nil {
|
||||
meq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, meq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, meq.ctx, ent.OpQueryIDs)
|
||||
if err = meq.Select(maintenanceentry.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -224,7 +225,7 @@ func (meq *MaintenanceEntryQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (meq *MaintenanceEntryQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, meq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, meq.ctx, ent.OpQueryCount)
|
||||
if err := meq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -242,7 +243,7 @@ func (meq *MaintenanceEntryQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (meq *MaintenanceEntryQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, meq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, meq.ctx, ent.OpQueryExist)
|
||||
switch _, err := meq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -529,7 +530,7 @@ func (megb *MaintenanceEntryGroupBy) Aggregate(fns ...AggregateFunc) *Maintenanc
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (megb *MaintenanceEntryGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, megb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, megb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := megb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -577,7 +578,7 @@ func (mes *MaintenanceEntrySelect) Aggregate(fns ...AggregateFunc) *MaintenanceE
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (mes *MaintenanceEntrySelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, mes.ctx, "Select")
|
||||
ctx = setContextOp(ctx, mes.ctx, ent.OpQuerySelect)
|
||||
if err := mes.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ func (meu *MaintenanceEntryUpdate) check() error {
|
||||
return &ValidationError{Name: "description", err: fmt.Errorf(`ent: validator failed for field "MaintenanceEntry.description": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := meu.mutation.ItemID(); meu.mutation.ItemCleared() && !ok {
|
||||
if meu.mutation.ItemCleared() && len(meu.mutation.ItemIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "MaintenanceEntry.item"`)
|
||||
}
|
||||
return nil
|
||||
@@ -498,7 +498,7 @@ func (meuo *MaintenanceEntryUpdateOne) check() error {
|
||||
return &ValidationError{Name: "description", err: fmt.Errorf(`ent: validator failed for field "MaintenanceEntry.description": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := meuo.mutation.ItemID(); meuo.mutation.ItemCleared() && !ok {
|
||||
if meuo.mutation.ItemCleared() && len(meuo.mutation.ItemIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "MaintenanceEntry.item"`)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -54,12 +54,10 @@ type NotifierEdges struct {
|
||||
// GroupOrErr returns the Group value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e NotifierEdges) GroupOrErr() (*Group, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Group == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
if e.Group != nil {
|
||||
return e.Group, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "group"}
|
||||
}
|
||||
@@ -67,12 +65,10 @@ func (e NotifierEdges) GroupOrErr() (*Group, error) {
|
||||
// UserOrErr returns the User value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e NotifierEdges) UserOrErr() (*User, error) {
|
||||
if e.loadedTypes[1] {
|
||||
if e.User == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: user.Label}
|
||||
}
|
||||
if e.User != nil {
|
||||
return e.User, nil
|
||||
} else if e.loadedTypes[1] {
|
||||
return nil, &NotFoundError{label: user.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "user"}
|
||||
}
|
||||
|
||||
@@ -199,10 +199,10 @@ func (nc *NotifierCreate) check() error {
|
||||
if _, ok := nc.mutation.IsActive(); !ok {
|
||||
return &ValidationError{Name: "is_active", err: errors.New(`ent: missing required field "Notifier.is_active"`)}
|
||||
}
|
||||
if _, ok := nc.mutation.GroupID(); !ok {
|
||||
if len(nc.mutation.GroupIDs()) == 0 {
|
||||
return &ValidationError{Name: "group", err: errors.New(`ent: missing required edge "Notifier.group"`)}
|
||||
}
|
||||
if _, ok := nc.mutation.UserID(); !ok {
|
||||
if len(nc.mutation.UserIDs()) == 0 {
|
||||
return &ValidationError{Name: "user", err: errors.New(`ent: missing required edge "Notifier.user"`)}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -109,7 +110,7 @@ func (nq *NotifierQuery) QueryUser() *UserQuery {
|
||||
// First returns the first Notifier entity from the query.
|
||||
// Returns a *NotFoundError when no Notifier was found.
|
||||
func (nq *NotifierQuery) First(ctx context.Context) (*Notifier, error) {
|
||||
nodes, err := nq.Limit(1).All(setContextOp(ctx, nq.ctx, "First"))
|
||||
nodes, err := nq.Limit(1).All(setContextOp(ctx, nq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -132,7 +133,7 @@ func (nq *NotifierQuery) FirstX(ctx context.Context) *Notifier {
|
||||
// Returns a *NotFoundError when no Notifier ID was found.
|
||||
func (nq *NotifierQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = nq.Limit(1).IDs(setContextOp(ctx, nq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = nq.Limit(1).IDs(setContextOp(ctx, nq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -155,7 +156,7 @@ func (nq *NotifierQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Notifier entity is found.
|
||||
// Returns a *NotFoundError when no Notifier entities are found.
|
||||
func (nq *NotifierQuery) Only(ctx context.Context) (*Notifier, error) {
|
||||
nodes, err := nq.Limit(2).All(setContextOp(ctx, nq.ctx, "Only"))
|
||||
nodes, err := nq.Limit(2).All(setContextOp(ctx, nq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -183,7 +184,7 @@ func (nq *NotifierQuery) OnlyX(ctx context.Context) *Notifier {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (nq *NotifierQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = nq.Limit(2).IDs(setContextOp(ctx, nq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = nq.Limit(2).IDs(setContextOp(ctx, nq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -208,7 +209,7 @@ func (nq *NotifierQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Notifiers.
|
||||
func (nq *NotifierQuery) All(ctx context.Context) ([]*Notifier, error) {
|
||||
ctx = setContextOp(ctx, nq.ctx, "All")
|
||||
ctx = setContextOp(ctx, nq.ctx, ent.OpQueryAll)
|
||||
if err := nq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -230,7 +231,7 @@ func (nq *NotifierQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
|
||||
if nq.ctx.Unique == nil && nq.path != nil {
|
||||
nq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, nq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, nq.ctx, ent.OpQueryIDs)
|
||||
if err = nq.Select(notifier.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -248,7 +249,7 @@ func (nq *NotifierQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (nq *NotifierQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, nq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, nq.ctx, ent.OpQueryCount)
|
||||
if err := nq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -266,7 +267,7 @@ func (nq *NotifierQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (nq *NotifierQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, nq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, nq.ctx, ent.OpQueryExist)
|
||||
switch _, err := nq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -604,7 +605,7 @@ func (ngb *NotifierGroupBy) Aggregate(fns ...AggregateFunc) *NotifierGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ngb *NotifierGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ngb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, ngb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := ngb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -652,7 +653,7 @@ func (ns *NotifierSelect) Aggregate(fns ...AggregateFunc) *NotifierSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ns *NotifierSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ns.ctx, "Select")
|
||||
ctx = setContextOp(ctx, ns.ctx, ent.OpQuerySelect)
|
||||
if err := ns.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -182,10 +182,10 @@ func (nu *NotifierUpdate) check() error {
|
||||
return &ValidationError{Name: "url", err: fmt.Errorf(`ent: validator failed for field "Notifier.url": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := nu.mutation.GroupID(); nu.mutation.GroupCleared() && !ok {
|
||||
if nu.mutation.GroupCleared() && len(nu.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Notifier.group"`)
|
||||
}
|
||||
if _, ok := nu.mutation.UserID(); nu.mutation.UserCleared() && !ok {
|
||||
if nu.mutation.UserCleared() && len(nu.mutation.UserIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Notifier.user"`)
|
||||
}
|
||||
return nil
|
||||
@@ -457,10 +457,10 @@ func (nuo *NotifierUpdateOne) check() error {
|
||||
return &ValidationError{Name: "url", err: fmt.Errorf(`ent: validator failed for field "Notifier.url": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := nuo.mutation.GroupID(); nuo.mutation.GroupCleared() && !ok {
|
||||
if nuo.mutation.GroupCleared() && len(nuo.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Notifier.group"`)
|
||||
}
|
||||
if _, ok := nuo.mutation.UserID(); nuo.mutation.UserCleared() && !ok {
|
||||
if nuo.mutation.UserCleared() && len(nuo.mutation.UserIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "Notifier.user"`)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -5,6 +5,6 @@ package runtime
|
||||
// The schema-stitching logic is generated in github.com/sysadminsmedia/homebox/backend/internal/data/ent/runtime.go
|
||||
|
||||
const (
|
||||
Version = "v0.12.5" // Version of ent codegen.
|
||||
Sum = "h1:KREM5E4CSoej4zeGa88Ou/gfturAnpUv0mzAjch1sj4=" // Sum of ent codegen.
|
||||
Version = "v0.14.1" // Version of ent codegen.
|
||||
Sum = "h1:fUERL506Pqr92EPHJqr8EYxbPioflJo6PudkrEA8a/s=" // Sum of ent codegen.
|
||||
)
|
||||
|
||||
@@ -76,8 +76,6 @@ func (Item) Fields() []ent.Field {
|
||||
|
||||
// ------------------------------------
|
||||
// item purchase
|
||||
field.String("purchase_method").
|
||||
Optional(),
|
||||
field.Time("purchase_time").
|
||||
Optional(),
|
||||
field.String("purchase_from").
|
||||
|
||||
@@ -60,12 +60,10 @@ type UserEdges struct {
|
||||
// GroupOrErr returns the Group value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e UserEdges) GroupOrErr() (*Group, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Group == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
if e.Group != nil {
|
||||
return e.Group, nil
|
||||
} else if e.loadedTypes[0] {
|
||||
return nil, &NotFoundError{label: group.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "group"}
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ func (uc *UserCreate) check() error {
|
||||
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "User.role": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := uc.mutation.GroupID(); !ok {
|
||||
if len(uc.mutation.GroupIDs()) == 0 {
|
||||
return &ValidationError{Name: "group", err: errors.New(`ent: missing required edge "User.group"`)}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@@ -135,7 +136,7 @@ func (uq *UserQuery) QueryNotifiers() *NotifierQuery {
|
||||
// First returns the first User entity from the query.
|
||||
// Returns a *NotFoundError when no User was found.
|
||||
func (uq *UserQuery) First(ctx context.Context) (*User, error) {
|
||||
nodes, err := uq.Limit(1).All(setContextOp(ctx, uq.ctx, "First"))
|
||||
nodes, err := uq.Limit(1).All(setContextOp(ctx, uq.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -158,7 +159,7 @@ func (uq *UserQuery) FirstX(ctx context.Context) *User {
|
||||
// Returns a *NotFoundError when no User ID was found.
|
||||
func (uq *UserQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = uq.Limit(1).IDs(setContextOp(ctx, uq.ctx, "FirstID")); err != nil {
|
||||
if ids, err = uq.Limit(1).IDs(setContextOp(ctx, uq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -181,7 +182,7 @@ func (uq *UserQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one User entity is found.
|
||||
// Returns a *NotFoundError when no User entities are found.
|
||||
func (uq *UserQuery) Only(ctx context.Context) (*User, error) {
|
||||
nodes, err := uq.Limit(2).All(setContextOp(ctx, uq.ctx, "Only"))
|
||||
nodes, err := uq.Limit(2).All(setContextOp(ctx, uq.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -209,7 +210,7 @@ func (uq *UserQuery) OnlyX(ctx context.Context) *User {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (uq *UserQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = uq.Limit(2).IDs(setContextOp(ctx, uq.ctx, "OnlyID")); err != nil {
|
||||
if ids, err = uq.Limit(2).IDs(setContextOp(ctx, uq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -234,7 +235,7 @@ func (uq *UserQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Users.
|
||||
func (uq *UserQuery) All(ctx context.Context) ([]*User, error) {
|
||||
ctx = setContextOp(ctx, uq.ctx, "All")
|
||||
ctx = setContextOp(ctx, uq.ctx, ent.OpQueryAll)
|
||||
if err := uq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -256,7 +257,7 @@ func (uq *UserQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
|
||||
if uq.ctx.Unique == nil && uq.path != nil {
|
||||
uq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, uq.ctx, "IDs")
|
||||
ctx = setContextOp(ctx, uq.ctx, ent.OpQueryIDs)
|
||||
if err = uq.Select(user.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -274,7 +275,7 @@ func (uq *UserQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (uq *UserQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, uq.ctx, "Count")
|
||||
ctx = setContextOp(ctx, uq.ctx, ent.OpQueryCount)
|
||||
if err := uq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -292,7 +293,7 @@ func (uq *UserQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (uq *UserQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, uq.ctx, "Exist")
|
||||
ctx = setContextOp(ctx, uq.ctx, ent.OpQueryExist)
|
||||
switch _, err := uq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -687,7 +688,7 @@ func (ugb *UserGroupBy) Aggregate(fns ...AggregateFunc) *UserGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ugb *UserGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ugb.build.ctx, "GroupBy")
|
||||
ctx = setContextOp(ctx, ugb.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := ugb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -735,7 +736,7 @@ func (us *UserSelect) Aggregate(fns ...AggregateFunc) *UserSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (us *UserSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, us.ctx, "Select")
|
||||
ctx = setContextOp(ctx, us.ctx, ent.OpQuerySelect)
|
||||
if err := us.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ func (uu *UserUpdate) check() error {
|
||||
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "User.role": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := uu.mutation.GroupID(); uu.mutation.GroupCleared() && !ok {
|
||||
if uu.mutation.GroupCleared() && len(uu.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "User.group"`)
|
||||
}
|
||||
return nil
|
||||
@@ -753,7 +753,7 @@ func (uuo *UserUpdateOne) check() error {
|
||||
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "User.role": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := uuo.mutation.GroupID(); uuo.mutation.GroupCleared() && !ok {
|
||||
if uuo.mutation.GroupCleared() && len(uuo.mutation.GroupIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "User.group"`)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -17,7 +17,7 @@ CREATE INDEX `documenttoken_token` ON `document_tokens` (`token`);
|
||||
-- create "groups" table
|
||||
CREATE TABLE `groups` (`id` uuid NOT NULL, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, `name` text NOT NULL, `currency` text NOT NULL DEFAULT 'usd', PRIMARY KEY (`id`));
|
||||
-- create "items" table
|
||||
CREATE TABLE `items` (`id` uuid NOT NULL, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, `name` text NOT NULL, `description` text NULL, `import_ref` text NULL, `notes` text NULL, `quantity` integer NOT NULL DEFAULT 1, `insured` bool NOT NULL DEFAULT false, `serial_number` text NULL, `model_number` text NULL, `manufacturer` text NULL, `lifetime_warranty` bool NOT NULL DEFAULT false, `warranty_expires` datetime NULL, `warranty_details` text NULL, `purchase_method` text NULL, `purchase_time` datetime NULL, `purchase_from` text NULL, `purchase_price` real NOT NULL DEFAULT 0, `sold_time` datetime NULL, `sold_to` text NULL, `sold_price` real NOT NULL DEFAULT 0, `sold_notes` text NULL, `group_items` uuid NOT NULL, `location_items` uuid NULL, PRIMARY KEY (`id`), CONSTRAINT `items_groups_items` FOREIGN KEY (`group_items`) REFERENCES `groups` (`id`) ON DELETE CASCADE, CONSTRAINT `items_locations_items` FOREIGN KEY (`location_items`) REFERENCES `locations` (`id`) ON DELETE CASCADE);
|
||||
CREATE TABLE `items` (`id` uuid NOT NULL, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, `name` text NOT NULL, `description` text NULL, `import_ref` text NULL, `notes` text NULL, `quantity` integer NOT NULL DEFAULT 1, `insured` bool NOT NULL DEFAULT false, `serial_number` text NULL, `model_number` text NULL, `manufacturer` text NULL, `lifetime_warranty` bool NOT NULL DEFAULT false, `warranty_expires` datetime NULL, `warranty_details` text NULL, `purchase_time` datetime NULL, `purchase_from` text NULL, `purchase_price` real NOT NULL DEFAULT 0, `sold_time` datetime NULL, `sold_to` text NULL, `sold_price` real NOT NULL DEFAULT 0, `sold_notes` text NULL, `group_items` uuid NOT NULL, `location_items` uuid NULL, PRIMARY KEY (`id`), CONSTRAINT `items_groups_items` FOREIGN KEY (`group_items`) REFERENCES `groups` (`id`) ON DELETE CASCADE, CONSTRAINT `items_locations_items` FOREIGN KEY (`location_items`) REFERENCES `locations` (`id`) ON DELETE CASCADE);
|
||||
-- create index "item_name" to table: "items"
|
||||
CREATE INDEX `item_name` ON `items` (`name`);
|
||||
-- create index "item_manufacturer" to table: "items"
|
||||
|
||||
@@ -16,9 +16,9 @@ func (aid AssetID) Int() int {
|
||||
return int(aid)
|
||||
}
|
||||
|
||||
func ParseAssetIDBytes(d []byte) (AID AssetID, ok bool) {
|
||||
d = bytes.Replace(d, []byte(`"`), []byte(``), -1)
|
||||
d = bytes.Replace(d, []byte(`-`), []byte(``), -1)
|
||||
func ParseAssetIDBytes(d []byte) (aid AssetID, ok bool) {
|
||||
d = bytes.ReplaceAll(d, []byte(`"`), []byte(``))
|
||||
d = bytes.ReplaceAll(d, []byte(`-`), []byte(``))
|
||||
|
||||
aidInt, err := strconv.Atoi(string(d))
|
||||
if err != nil {
|
||||
@@ -28,7 +28,7 @@ func ParseAssetIDBytes(d []byte) (AID AssetID, ok bool) {
|
||||
return AssetID(aidInt), true
|
||||
}
|
||||
|
||||
func ParseAssetID(s string) (AID AssetID, ok bool) {
|
||||
func ParseAssetID(s string) (aid AssetID, ok bool) {
|
||||
return ParseAssetIDBytes([]byte(s))
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ func (aid *AssetID) UnmarshalJSON(d []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
d = bytes.Replace(d, []byte(`"`), []byte(``), -1)
|
||||
d = bytes.Replace(d, []byte(`-`), []byte(``), -1)
|
||||
d = bytes.ReplaceAll(d, []byte(`"`), []byte(``))
|
||||
d = bytes.ReplaceAll(d, []byte(`-`), []byte(``))
|
||||
|
||||
aidInt, err := strconv.Atoi(string(d))
|
||||
if err != nil {
|
||||
|
||||
@@ -39,7 +39,7 @@ func bootstrap() {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
func MainNoExit(m *testing.M) int {
|
||||
client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
|
||||
if err != nil {
|
||||
log.Fatalf("failed opening connection to sqlite: %v", err)
|
||||
@@ -59,6 +59,9 @@ func TestMain(m *testing.M) {
|
||||
defer func() { _ = client.Close() }()
|
||||
|
||||
bootstrap()
|
||||
|
||||
os.Exit(m.Run())
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(MainNoExit(m))
|
||||
}
|
||||
|
||||
@@ -109,12 +109,12 @@ func (r *GroupRepository) GetAllGroups(ctx context.Context) ([]Group, error) {
|
||||
return r.groupMapper.MapEachErr(r.db.Group.Query().All(ctx))
|
||||
}
|
||||
|
||||
func (r *GroupRepository) StatsLocationsByPurchasePrice(ctx context.Context, GID uuid.UUID) ([]TotalsByOrganizer, error) {
|
||||
func (r *GroupRepository) StatsLocationsByPurchasePrice(ctx context.Context, gid uuid.UUID) ([]TotalsByOrganizer, error) {
|
||||
var v []TotalsByOrganizer
|
||||
|
||||
err := r.db.Location.Query().
|
||||
Where(
|
||||
location.HasGroupWith(group.ID(GID)),
|
||||
location.HasGroupWith(group.ID(gid)),
|
||||
).
|
||||
GroupBy(location.FieldID, location.FieldName).
|
||||
Aggregate(func(sq *sql.Selector) string {
|
||||
@@ -131,12 +131,12 @@ func (r *GroupRepository) StatsLocationsByPurchasePrice(ctx context.Context, GID
|
||||
return v, err
|
||||
}
|
||||
|
||||
func (r *GroupRepository) StatsLabelsByPurchasePrice(ctx context.Context, GID uuid.UUID) ([]TotalsByOrganizer, error) {
|
||||
func (r *GroupRepository) StatsLabelsByPurchasePrice(ctx context.Context, gid uuid.UUID) ([]TotalsByOrganizer, error) {
|
||||
var v []TotalsByOrganizer
|
||||
|
||||
err := r.db.Label.Query().
|
||||
Where(
|
||||
label.HasGroupWith(group.ID(GID)),
|
||||
label.HasGroupWith(group.ID(gid)),
|
||||
).
|
||||
GroupBy(label.FieldID, label.FieldName).
|
||||
Aggregate(func(sq *sql.Selector) string {
|
||||
@@ -157,7 +157,7 @@ func (r *GroupRepository) StatsLabelsByPurchasePrice(ctx context.Context, GID uu
|
||||
return v, err
|
||||
}
|
||||
|
||||
func (r *GroupRepository) StatsPurchasePrice(ctx context.Context, GID uuid.UUID, start, end time.Time) (*ValueOverTime, error) {
|
||||
func (r *GroupRepository) StatsPurchasePrice(ctx context.Context, gid uuid.UUID, start, end time.Time) (*ValueOverTime, error) {
|
||||
// Get the Totals for the Start and End of the Given Time Period
|
||||
q := `
|
||||
SELECT
|
||||
@@ -180,7 +180,7 @@ func (r *GroupRepository) StatsPurchasePrice(ctx context.Context, GID uuid.UUID,
|
||||
var maybeStart *float64
|
||||
var maybeEnd *float64
|
||||
|
||||
row := r.db.Sql().QueryRowContext(ctx, q, GID, sqliteDateFormat(start), GID, sqliteDateFormat(end))
|
||||
row := r.db.Sql().QueryRowContext(ctx, q, gid, sqliteDateFormat(start), gid, sqliteDateFormat(end))
|
||||
err := row.Scan(&maybeStart, &maybeEnd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -198,7 +198,7 @@ func (r *GroupRepository) StatsPurchasePrice(ctx context.Context, GID uuid.UUID,
|
||||
// Get Created Date and Price of all items between start and end
|
||||
err = r.db.Item.Query().
|
||||
Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.HasGroupWith(group.ID(gid)),
|
||||
item.CreatedAtGTE(start),
|
||||
item.CreatedAtLTE(end),
|
||||
item.Archived(false),
|
||||
@@ -226,7 +226,7 @@ func (r *GroupRepository) StatsPurchasePrice(ctx context.Context, GID uuid.UUID,
|
||||
return &stats, nil
|
||||
}
|
||||
|
||||
func (r *GroupRepository) StatsGroup(ctx context.Context, GID uuid.UUID) (GroupStatistics, error) {
|
||||
func (r *GroupRepository) StatsGroup(ctx context.Context, gid uuid.UUID) (GroupStatistics, error) {
|
||||
q := `
|
||||
SELECT
|
||||
(SELECT COUNT(*) FROM users WHERE group_users = ?) AS total_users,
|
||||
@@ -242,7 +242,7 @@ func (r *GroupRepository) StatsGroup(ctx context.Context, GID uuid.UUID) (GroupS
|
||||
) AS total_with_warranty
|
||||
`
|
||||
var stats GroupStatistics
|
||||
row := r.db.Sql().QueryRowContext(ctx, q, GID, GID, GID, GID, GID, GID)
|
||||
row := r.db.Sql().QueryRowContext(ctx, q, gid, gid, gid, gid, gid, gid)
|
||||
|
||||
var maybeTotalItemPrice *float64
|
||||
var maybeTotalWithWarranty *int
|
||||
@@ -264,8 +264,8 @@ func (r *GroupRepository) GroupCreate(ctx context.Context, name string) (Group,
|
||||
Save(ctx))
|
||||
}
|
||||
|
||||
func (r *GroupRepository) GroupUpdate(ctx context.Context, ID uuid.UUID, data GroupUpdate) (Group, error) {
|
||||
entity, err := r.db.Group.UpdateOneID(ID).
|
||||
func (r *GroupRepository) GroupUpdate(ctx context.Context, id uuid.UUID, data GroupUpdate) (Group, error) {
|
||||
entity, err := r.db.Group.UpdateOneID(id).
|
||||
SetName(data.Name).
|
||||
SetCurrency(strings.ToLower(data.Currency)).
|
||||
Save(ctx)
|
||||
|
||||
@@ -87,11 +87,11 @@ func (r *AttachmentRepo) Get(ctx context.Context, id uuid.UUID) (*ent.Attachment
|
||||
Only(ctx)
|
||||
}
|
||||
|
||||
func (r *AttachmentRepo) Update(ctx context.Context, itemID uuid.UUID, data *ItemAttachmentUpdate) (*ent.Attachment, error) {
|
||||
func (r *AttachmentRepo) Update(ctx context.Context, id uuid.UUID, data *ItemAttachmentUpdate) (*ent.Attachment, error) {
|
||||
// TODO: execute within Tx
|
||||
typ := attachment.Type(data.Type)
|
||||
|
||||
bldr := r.db.Attachment.UpdateOneID(itemID).
|
||||
bldr := r.db.Attachment.UpdateOneID(id).
|
||||
SetType(typ)
|
||||
|
||||
// Primary only applies to photos
|
||||
@@ -101,7 +101,12 @@ func (r *AttachmentRepo) Update(ctx context.Context, itemID uuid.UUID, data *Ite
|
||||
bldr = bldr.SetPrimary(false)
|
||||
}
|
||||
|
||||
itm, err := bldr.Save(ctx)
|
||||
updatedAttachment, err := bldr.Save(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
attachmentItem, err := updatedAttachment.QueryItem().Only(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -109,8 +114,8 @@ func (r *AttachmentRepo) Update(ctx context.Context, itemID uuid.UUID, data *Ite
|
||||
// Ensure all other attachments are not primary
|
||||
err = r.db.Attachment.Update().
|
||||
Where(
|
||||
attachment.HasItemWith(item.ID(itemID)),
|
||||
attachment.IDNEQ(itm.ID),
|
||||
attachment.HasItemWith(item.ID(attachmentItem.ID)),
|
||||
attachment.IDNEQ(updatedAttachment.ID),
|
||||
).
|
||||
SetPrimary(false).
|
||||
Exec(ctx)
|
||||
@@ -118,7 +123,7 @@ func (r *AttachmentRepo) Update(ctx context.Context, itemID uuid.UUID, data *Ite
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.Get(ctx, itm.ID)
|
||||
return r.Get(ctx, updatedAttachment.ID)
|
||||
}
|
||||
|
||||
func (r *AttachmentRepo) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
|
||||
@@ -133,3 +133,25 @@ func TestAttachmentRepo_Delete(t *testing.T) {
|
||||
_, err = tRepos.Attachments.Get(context.Background(), entity.ID)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestAttachmentRepo_EnsureSinglePrimaryAttachment(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
attachments := useAttachments(t, 2)
|
||||
|
||||
setAndVerifyPrimary := func(primaryAttachmentID, nonPrimaryAttachmentID uuid.UUID) {
|
||||
primaryAttachment, err := tRepos.Attachments.Update(ctx, primaryAttachmentID, &ItemAttachmentUpdate{
|
||||
Type: attachment.TypePhoto.String(),
|
||||
Primary: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
nonPrimaryAttachment, err := tRepos.Attachments.Get(ctx, nonPrimaryAttachmentID)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.True(t, primaryAttachment.Primary)
|
||||
assert.False(t, nonPrimaryAttachment.Primary)
|
||||
}
|
||||
|
||||
setAndVerifyPrimary(attachments[0].ID, attachments[1].ID)
|
||||
setAndVerifyPrimary(attachments[1].ID, attachments[0].ID)
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@ type (
|
||||
ParentID uuid.UUID `json:"parentId" extensions:"x-nullable,x-omitempty"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
AssetID AssetID `json:"assetId" swaggertype:"string"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
Description string `json:"description" validate:"max=1000"`
|
||||
Quantity int `json:"quantity"`
|
||||
Insured bool `json:"insured"`
|
||||
Archived bool `json:"archived"`
|
||||
@@ -91,15 +91,14 @@ type (
|
||||
WarrantyDetails string `json:"warrantyDetails"`
|
||||
|
||||
// Purchase
|
||||
PurchaseMethod string `json:"purchaseMethod"`
|
||||
PurchaseTime types.Date `json:"purchaseTime"`
|
||||
PurchaseFrom string `json:"purchaseFrom"`
|
||||
PurchasePrice float64 `json:"purchasePrice,string"`
|
||||
PurchaseTime types.Date `json:"purchaseTime"`
|
||||
PurchaseFrom string `json:"purchaseFrom" validate:"max=255"`
|
||||
PurchasePrice float64 `json:"purchasePrice" extensions:"x-nullable,x-omitempty"`
|
||||
|
||||
// Sold
|
||||
SoldTime types.Date `json:"soldTime"`
|
||||
SoldTo string `json:"soldTo"`
|
||||
SoldPrice float64 `json:"soldPrice,string"`
|
||||
SoldTo string `json:"soldTo" validate:"max=255"`
|
||||
SoldPrice float64 `json:"soldPrice" extensions:"x-nullable,x-omitempty"`
|
||||
SoldNotes string `json:"soldNotes"`
|
||||
|
||||
// Extras
|
||||
@@ -116,6 +115,7 @@ type (
|
||||
ItemSummary struct {
|
||||
ImportRef string `json:"-"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
AssetID AssetID `json:"assetId,string"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Quantity int `json:"quantity"`
|
||||
@@ -124,7 +124,7 @@ type (
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
|
||||
PurchasePrice float64 `json:"purchasePrice,string"`
|
||||
PurchasePrice float64 `json:"purchasePrice"`
|
||||
|
||||
// Edges
|
||||
Location *LocationSummary `json:"location,omitempty" extensions:"x-nullable,x-omitempty"`
|
||||
@@ -148,14 +148,13 @@ type (
|
||||
WarrantyDetails string `json:"warrantyDetails"`
|
||||
|
||||
// Purchase
|
||||
PurchaseMethod string `json:"purchaseMethod"`
|
||||
PurchaseTime types.Date `json:"purchaseTime"`
|
||||
PurchaseFrom string `json:"purchaseFrom"`
|
||||
PurchaseTime types.Date `json:"purchaseTime"`
|
||||
PurchaseFrom string `json:"purchaseFrom"`
|
||||
|
||||
// Sold
|
||||
SoldTime types.Date `json:"soldTime"`
|
||||
SoldTo string `json:"soldTo"`
|
||||
SoldPrice float64 `json:"soldPrice,string"`
|
||||
SoldPrice float64 `json:"soldPrice"`
|
||||
SoldNotes string `json:"soldNotes"`
|
||||
|
||||
// Extras
|
||||
@@ -192,6 +191,7 @@ func mapItemSummary(item *ent.Item) ItemSummary {
|
||||
|
||||
return ItemSummary{
|
||||
ID: item.ID,
|
||||
AssetID: AssetID(item.AssetID),
|
||||
Name: item.Name,
|
||||
Description: item.Description,
|
||||
ImportRef: item.ImportRef,
|
||||
@@ -263,8 +263,8 @@ func mapItemOut(item *ent.Item) ItemOut {
|
||||
Manufacturer: item.Manufacturer,
|
||||
|
||||
// Purchase
|
||||
PurchaseTime: types.DateFromTime(item.PurchaseTime),
|
||||
PurchaseFrom: item.PurchaseFrom,
|
||||
PurchaseTime: types.DateFromTime(item.PurchaseTime),
|
||||
PurchaseFrom: item.PurchaseFrom,
|
||||
|
||||
// Sold
|
||||
SoldTime: types.DateFromTime(item.SoldTime),
|
||||
@@ -279,9 +279,9 @@ func mapItemOut(item *ent.Item) ItemOut {
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) publishMutationEvent(GID uuid.UUID) {
|
||||
func (e *ItemsRepository) publishMutationEvent(gid uuid.UUID) {
|
||||
if e.bus != nil {
|
||||
e.bus.Publish(eventbus.EventItemMutation, eventbus.GroupMutationEvent{GID: GID})
|
||||
e.bus.Publish(eventbus.EventItemMutation, eventbus.GroupMutationEvent{GID: gid})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,13 +307,13 @@ func (e *ItemsRepository) GetOne(ctx context.Context, id uuid.UUID) (ItemOut, er
|
||||
return e.getOne(ctx, item.ID(id))
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) CheckRef(ctx context.Context, GID uuid.UUID, ref string) (bool, error) {
|
||||
q := e.db.Item.Query().Where(item.HasGroupWith(group.ID(GID)))
|
||||
func (e *ItemsRepository) CheckRef(ctx context.Context, gid uuid.UUID, ref string) (bool, error) {
|
||||
q := e.db.Item.Query().Where(item.HasGroupWith(group.ID(gid)))
|
||||
return q.Where(item.ImportRef(ref)).Exist(ctx)
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) GetByRef(ctx context.Context, GID uuid.UUID, ref string) (ItemOut, error) {
|
||||
return e.getOne(ctx, item.ImportRef(ref), item.HasGroupWith(group.ID(GID)))
|
||||
func (e *ItemsRepository) GetByRef(ctx context.Context, gid uuid.UUID, ref string) (ItemOut, error) {
|
||||
return e.getOne(ctx, item.ImportRef(ref), item.HasGroupWith(group.ID(gid)))
|
||||
}
|
||||
|
||||
// GetOneByGroup returns a single item by ID. If the item does not exist, an error is returned.
|
||||
@@ -424,6 +424,8 @@ func (e *ItemsRepository) QueryByGroup(ctx context.Context, gid uuid.UUID, q Ite
|
||||
qb = qb.Order(ent.Desc(item.FieldCreatedAt))
|
||||
case "updatedAt":
|
||||
qb = qb.Order(ent.Desc(item.FieldUpdatedAt))
|
||||
case "assetId":
|
||||
qb = qb.Order(ent.Asc(item.FieldAssetID))
|
||||
default: // "name"
|
||||
qb = qb.Order(ent.Asc(item.FieldName))
|
||||
}
|
||||
@@ -500,9 +502,9 @@ func (e *ItemsRepository) GetAll(ctx context.Context, gid uuid.UUID) ([]ItemOut,
|
||||
All(ctx))
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) GetAllZeroAssetID(ctx context.Context, GID uuid.UUID) ([]ItemSummary, error) {
|
||||
func (e *ItemsRepository) GetAllZeroAssetID(ctx context.Context, gid uuid.UUID) ([]ItemSummary, error) {
|
||||
q := e.db.Item.Query().Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.HasGroupWith(group.ID(gid)),
|
||||
item.AssetID(0),
|
||||
).Order(
|
||||
ent.Asc(item.FieldCreatedAt),
|
||||
@@ -511,9 +513,9 @@ func (e *ItemsRepository) GetAllZeroAssetID(ctx context.Context, GID uuid.UUID)
|
||||
return mapItemsSummaryErr(q.All(ctx))
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) GetHighestAssetID(ctx context.Context, GID uuid.UUID) (AssetID, error) {
|
||||
func (e *ItemsRepository) GetHighestAssetID(ctx context.Context, gid uuid.UUID) (AssetID, error) {
|
||||
q := e.db.Item.Query().Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.HasGroupWith(group.ID(gid)),
|
||||
).Order(
|
||||
ent.Desc(item.FieldAssetID),
|
||||
).Limit(1)
|
||||
@@ -529,10 +531,10 @@ func (e *ItemsRepository) GetHighestAssetID(ctx context.Context, GID uuid.UUID)
|
||||
return AssetID(result.AssetID), nil
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) SetAssetID(ctx context.Context, GID uuid.UUID, ID uuid.UUID, assetID AssetID) error {
|
||||
func (e *ItemsRepository) SetAssetID(ctx context.Context, gid uuid.UUID, id uuid.UUID, assetID AssetID) error {
|
||||
q := e.db.Item.Update().Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.ID(ID),
|
||||
item.HasGroupWith(group.ID(gid)),
|
||||
item.ID(id),
|
||||
)
|
||||
|
||||
_, err := q.SetAssetID(int(assetID)).Save(ctx)
|
||||
@@ -548,7 +550,7 @@ func (e *ItemsRepository) Create(ctx context.Context, gid uuid.UUID, data ItemCr
|
||||
SetLocationID(data.LocationID).
|
||||
SetAssetID(int(data.AssetID))
|
||||
|
||||
if data.LabelIDs != nil && len(data.LabelIDs) > 0 {
|
||||
if len(data.LabelIDs) > 0 {
|
||||
q.AddLabelIDs(data.LabelIDs...)
|
||||
}
|
||||
|
||||
@@ -586,8 +588,8 @@ func (e *ItemsRepository) DeleteByGroup(ctx context.Context, gid, id uuid.UUID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) UpdateByGroup(ctx context.Context, GID uuid.UUID, data ItemUpdate) (ItemOut, error) {
|
||||
q := e.db.Item.Update().Where(item.ID(data.ID), item.HasGroupWith(group.ID(GID))).
|
||||
func (e *ItemsRepository) UpdateByGroup(ctx context.Context, gid uuid.UUID, data ItemUpdate) (ItemOut, error) {
|
||||
q := e.db.Item.Update().Where(item.ID(data.ID), item.HasGroupWith(group.ID(gid))).
|
||||
SetName(data.Name).
|
||||
SetDescription(data.Description).
|
||||
SetLocationID(data.LocationID).
|
||||
@@ -698,16 +700,16 @@ func (e *ItemsRepository) UpdateByGroup(ctx context.Context, GID uuid.UUID, data
|
||||
}
|
||||
}
|
||||
|
||||
e.publishMutationEvent(GID)
|
||||
e.publishMutationEvent(gid)
|
||||
return e.GetOne(ctx, data.ID)
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) GetAllZeroImportRef(ctx context.Context, GID uuid.UUID) ([]uuid.UUID, error) {
|
||||
func (e *ItemsRepository) GetAllZeroImportRef(ctx context.Context, gid uuid.UUID) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
|
||||
err := e.db.Item.Query().
|
||||
Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.HasGroupWith(group.ID(gid)),
|
||||
item.Or(
|
||||
item.ImportRefEQ(""),
|
||||
item.ImportRefIsNil(),
|
||||
@@ -722,11 +724,11 @@ func (e *ItemsRepository) GetAllZeroImportRef(ctx context.Context, GID uuid.UUID
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) Patch(ctx context.Context, GID, ID uuid.UUID, data ItemPatch) error {
|
||||
func (e *ItemsRepository) Patch(ctx context.Context, gid, id uuid.UUID, data ItemPatch) error {
|
||||
q := e.db.Item.Update().
|
||||
Where(
|
||||
item.ID(ID),
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.ID(id),
|
||||
item.HasGroupWith(group.ID(gid)),
|
||||
)
|
||||
|
||||
if data.ImportRef != nil {
|
||||
@@ -737,11 +739,11 @@ func (e *ItemsRepository) Patch(ctx context.Context, GID, ID uuid.UUID, data Ite
|
||||
q.SetQuantity(*data.Quantity)
|
||||
}
|
||||
|
||||
e.publishMutationEvent(GID)
|
||||
e.publishMutationEvent(gid)
|
||||
return q.Exec(ctx)
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) GetAllCustomFieldValues(ctx context.Context, GID uuid.UUID, name string) ([]string, error) {
|
||||
func (e *ItemsRepository) GetAllCustomFieldValues(ctx context.Context, gid uuid.UUID, name string) ([]string, error) {
|
||||
type st struct {
|
||||
Value string `json:"text_value"`
|
||||
}
|
||||
@@ -750,7 +752,7 @@ func (e *ItemsRepository) GetAllCustomFieldValues(ctx context.Context, GID uuid.
|
||||
|
||||
err := e.db.Item.Query().
|
||||
Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.HasGroupWith(group.ID(gid)),
|
||||
).
|
||||
QueryFields().
|
||||
Where(
|
||||
@@ -771,7 +773,7 @@ func (e *ItemsRepository) GetAllCustomFieldValues(ctx context.Context, GID uuid.
|
||||
return valueStrings, nil
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) GetAllCustomFieldNames(ctx context.Context, GID uuid.UUID) ([]string, error) {
|
||||
func (e *ItemsRepository) GetAllCustomFieldNames(ctx context.Context, gid uuid.UUID) ([]string, error) {
|
||||
type st struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
@@ -780,7 +782,7 @@ func (e *ItemsRepository) GetAllCustomFieldNames(ctx context.Context, GID uuid.U
|
||||
|
||||
err := e.db.Item.Query().
|
||||
Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.HasGroupWith(group.ID(gid)),
|
||||
).
|
||||
QueryFields().
|
||||
Unique(true).
|
||||
@@ -804,9 +806,9 @@ func (e *ItemsRepository) GetAllCustomFieldNames(ctx context.Context, GID uuid.U
|
||||
// This is designed to resolve a long-time bug that has since been fixed with the time selector on the
|
||||
// frontend. This function is intended to be used as a one-time fix for existing databases and may be
|
||||
// removed in the future.
|
||||
func (e *ItemsRepository) ZeroOutTimeFields(ctx context.Context, GID uuid.UUID) (int, error) {
|
||||
func (e *ItemsRepository) ZeroOutTimeFields(ctx context.Context, gid uuid.UUID) (int, error) {
|
||||
q := e.db.Item.Query().Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.HasGroupWith(group.ID(gid)),
|
||||
item.Or(
|
||||
item.PurchaseTimeNotNil(),
|
||||
item.PurchaseFromLT("0002-01-01"),
|
||||
@@ -875,11 +877,11 @@ func (e *ItemsRepository) ZeroOutTimeFields(ctx context.Context, GID uuid.UUID)
|
||||
return updated, nil
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) SetPrimaryPhotos(ctx context.Context, GID uuid.UUID) (int, error) {
|
||||
func (e *ItemsRepository) SetPrimaryPhotos(ctx context.Context, gid uuid.UUID) (int, error) {
|
||||
// All items where there is no primary photo
|
||||
itemIDs, err := e.db.Item.Query().
|
||||
Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.HasGroupWith(group.ID(gid)),
|
||||
item.HasAttachmentsWith(
|
||||
attachment.TypeEQ(attachment.TypePhoto),
|
||||
attachment.Not(
|
||||
|
||||
@@ -236,7 +236,6 @@ func TestItemsRepository_Update(t *testing.T) {
|
||||
ModelNumber: fk.Str(10),
|
||||
Manufacturer: fk.Str(10),
|
||||
PurchaseTime: types.DateFromTime(time.Now()),
|
||||
PurchaseMethod: fk.Str(10),
|
||||
PurchaseFrom: fk.Str(10),
|
||||
PurchasePrice: 300.99,
|
||||
SoldTime: types.DateFromTime(time.Now()),
|
||||
@@ -263,7 +262,6 @@ func TestItemsRepository_Update(t *testing.T) {
|
||||
assert.Equal(t, updateData.Manufacturer, got.Manufacturer)
|
||||
// assert.Equal(t, updateData.PurchaseTime, got.PurchaseTime)
|
||||
assert.Equal(t, updateData.PurchaseFrom, got.PurchaseFrom)
|
||||
assert.Equal(t, updateData.PurchaseMethod, got.PurchaseMethod)
|
||||
assert.InDelta(t, updateData.PurchasePrice, got.PurchasePrice, 0.01)
|
||||
// assert.Equal(t, updateData.SoldTime, got.SoldTime)
|
||||
assert.Equal(t, updateData.SoldTo, got.SoldTo)
|
||||
|
||||
@@ -65,9 +65,9 @@ func mapLabelOut(label *ent.Label) LabelOut {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *LabelRepository) publishMutationEvent(GID uuid.UUID) {
|
||||
func (r *LabelRepository) publishMutationEvent(gid uuid.UUID) {
|
||||
if r.bus != nil {
|
||||
r.bus.Publish(eventbus.EventLabelMutation, eventbus.GroupMutationEvent{GID: GID})
|
||||
r.bus.Publish(eventbus.EventLabelMutation, eventbus.GroupMutationEvent{GID: gid})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,8 +79,8 @@ func (r *LabelRepository) getOne(ctx context.Context, where ...predicate.Label)
|
||||
)
|
||||
}
|
||||
|
||||
func (r *LabelRepository) GetOne(ctx context.Context, ID uuid.UUID) (LabelOut, error) {
|
||||
return r.getOne(ctx, label.ID(ID))
|
||||
func (r *LabelRepository) GetOne(ctx context.Context, id uuid.UUID) (LabelOut, error) {
|
||||
return r.getOne(ctx, label.ID(id))
|
||||
}
|
||||
|
||||
func (r *LabelRepository) GetOneByGroup(ctx context.Context, gid, ld uuid.UUID) (LabelOut, error) {
|
||||
@@ -125,13 +125,13 @@ func (r *LabelRepository) update(ctx context.Context, data LabelUpdate, where ..
|
||||
Save(ctx)
|
||||
}
|
||||
|
||||
func (r *LabelRepository) UpdateByGroup(ctx context.Context, GID uuid.UUID, data LabelUpdate) (LabelOut, error) {
|
||||
_, err := r.update(ctx, data, label.ID(data.ID), label.HasGroupWith(group.ID(GID)))
|
||||
func (r *LabelRepository) UpdateByGroup(ctx context.Context, gid uuid.UUID, data LabelUpdate) (LabelOut, error) {
|
||||
_, err := r.update(ctx, data, label.ID(data.ID), label.HasGroupWith(group.ID(gid)))
|
||||
if err != nil {
|
||||
return LabelOut{}, err
|
||||
}
|
||||
|
||||
r.publishMutationEvent(GID)
|
||||
r.publishMutationEvent(gid)
|
||||
return r.GetOne(ctx, data.ID)
|
||||
}
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ type (
|
||||
LocationOut struct {
|
||||
Parent *LocationSummary `json:"parent,omitempty"`
|
||||
LocationSummary
|
||||
Children []LocationSummary `json:"children"`
|
||||
TotalPrice float64 `json:"totalPrice"`
|
||||
Children []LocationSummary `json:"children"`
|
||||
TotalPrice float64 `json:"totalPrice"`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -90,9 +90,9 @@ func mapLocationOut(location *ent.Location) LocationOut {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *LocationRepository) publishMutationEvent(GID uuid.UUID) {
|
||||
func (r *LocationRepository) publishMutationEvent(gid uuid.UUID) {
|
||||
if r.bus != nil {
|
||||
r.bus.Publish(eventbus.EventLocationMutation, eventbus.GroupMutationEvent{GID: GID})
|
||||
r.bus.Publish(eventbus.EventLocationMutation, eventbus.GroupMutationEvent{GID: gid})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ type LocationQuery struct {
|
||||
}
|
||||
|
||||
// GetAll returns all locations with item count field populated
|
||||
func (r *LocationRepository) GetAll(ctx context.Context, GID uuid.UUID, filter LocationQuery) ([]LocationOutCount, error) {
|
||||
func (r *LocationRepository) GetAll(ctx context.Context, gid uuid.UUID, filter LocationQuery) ([]LocationOutCount, error) {
|
||||
query := `--sql
|
||||
SELECT
|
||||
id,
|
||||
@@ -132,7 +132,7 @@ func (r *LocationRepository) GetAll(ctx context.Context, GID uuid.UUID, filter L
|
||||
query = strings.Replace(query, "{{ FILTER_CHILDREN }}", "", 1)
|
||||
}
|
||||
|
||||
rows, err := r.db.Sql().QueryContext(ctx, query, GID)
|
||||
rows, err := r.db.Sql().QueryContext(ctx, query, gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -168,19 +168,19 @@ func (r *LocationRepository) getOne(ctx context.Context, where ...predicate.Loca
|
||||
Only(ctx))
|
||||
}
|
||||
|
||||
func (r *LocationRepository) Get(ctx context.Context, ID uuid.UUID) (LocationOut, error) {
|
||||
return r.getOne(ctx, location.ID(ID))
|
||||
func (r *LocationRepository) Get(ctx context.Context, id uuid.UUID) (LocationOut, error) {
|
||||
return r.getOne(ctx, location.ID(id))
|
||||
}
|
||||
|
||||
func (r *LocationRepository) GetOneByGroup(ctx context.Context, GID, ID uuid.UUID) (LocationOut, error) {
|
||||
return r.getOne(ctx, location.ID(ID), location.HasGroupWith(group.ID(GID)))
|
||||
func (r *LocationRepository) GetOneByGroup(ctx context.Context, gid, id uuid.UUID) (LocationOut, error) {
|
||||
return r.getOne(ctx, location.ID(id), location.HasGroupWith(group.ID(gid)))
|
||||
}
|
||||
|
||||
func (r *LocationRepository) Create(ctx context.Context, GID uuid.UUID, data LocationCreate) (LocationOut, error) {
|
||||
func (r *LocationRepository) Create(ctx context.Context, gid uuid.UUID, data LocationCreate) (LocationOut, error) {
|
||||
q := r.db.Location.Create().
|
||||
SetName(data.Name).
|
||||
SetDescription(data.Description).
|
||||
SetGroupID(GID)
|
||||
SetGroupID(gid)
|
||||
|
||||
if data.ParentID != uuid.Nil {
|
||||
q.SetParentID(data.ParentID)
|
||||
@@ -191,8 +191,8 @@ func (r *LocationRepository) Create(ctx context.Context, GID uuid.UUID, data Loc
|
||||
return LocationOut{}, err
|
||||
}
|
||||
|
||||
location.Edges.Group = &ent.Group{ID: GID} // bootstrap group ID
|
||||
r.publishMutationEvent(GID)
|
||||
location.Edges.Group = &ent.Group{ID: gid} // bootstrap group ID
|
||||
r.publishMutationEvent(gid)
|
||||
return mapLocationOut(location), nil
|
||||
}
|
||||
|
||||
@@ -216,28 +216,28 @@ func (r *LocationRepository) update(ctx context.Context, data LocationUpdate, wh
|
||||
return r.Get(ctx, data.ID)
|
||||
}
|
||||
|
||||
func (r *LocationRepository) UpdateByGroup(ctx context.Context, GID, ID uuid.UUID, data LocationUpdate) (LocationOut, error) {
|
||||
v, err := r.update(ctx, data, location.ID(ID), location.HasGroupWith(group.ID(GID)))
|
||||
func (r *LocationRepository) UpdateByGroup(ctx context.Context, gid, id uuid.UUID, data LocationUpdate) (LocationOut, error) {
|
||||
v, err := r.update(ctx, data, location.ID(id), location.HasGroupWith(group.ID(gid)))
|
||||
if err != nil {
|
||||
return LocationOut{}, err
|
||||
}
|
||||
|
||||
r.publishMutationEvent(GID)
|
||||
r.publishMutationEvent(gid)
|
||||
return v, err
|
||||
}
|
||||
|
||||
// delete should only be used after checking that the location is owned by the
|
||||
// group. Otherwise, use DeleteByGroup
|
||||
func (r *LocationRepository) delete(ctx context.Context, ID uuid.UUID) error {
|
||||
return r.db.Location.DeleteOneID(ID).Exec(ctx)
|
||||
func (r *LocationRepository) delete(ctx context.Context, id uuid.UUID) error {
|
||||
return r.db.Location.DeleteOneID(id).Exec(ctx)
|
||||
}
|
||||
|
||||
func (r *LocationRepository) DeleteByGroup(ctx context.Context, GID, ID uuid.UUID) error {
|
||||
_, err := r.db.Location.Delete().Where(location.ID(ID), location.HasGroupWith(group.ID(GID))).Exec(ctx)
|
||||
func (r *LocationRepository) DeleteByGroup(ctx context.Context, gid, id uuid.UUID) error {
|
||||
_, err := r.db.Location.Delete().Where(location.ID(id), location.HasGroupWith(group.ID(gid))).Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.publishMutationEvent(GID)
|
||||
r.publishMutationEvent(gid)
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -274,7 +274,7 @@ type ItemPath struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (r *LocationRepository) PathForLoc(ctx context.Context, GID, locID uuid.UUID) ([]ItemPath, error) {
|
||||
func (r *LocationRepository) PathForLoc(ctx context.Context, gid, locID uuid.UUID) ([]ItemPath, error) {
|
||||
query := `WITH RECURSIVE location_path AS (
|
||||
SELECT id, name, location_children
|
||||
FROM locations
|
||||
@@ -291,7 +291,7 @@ func (r *LocationRepository) PathForLoc(ctx context.Context, GID, locID uuid.UUI
|
||||
SELECT id, name
|
||||
FROM location_path`
|
||||
|
||||
rows, err := r.db.Sql().QueryContext(ctx, query, locID, GID)
|
||||
rows, err := r.db.Sql().QueryContext(ctx, query, locID, gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -321,7 +321,7 @@ func (r *LocationRepository) PathForLoc(ctx context.Context, GID, locID uuid.UUI
|
||||
return locations, nil
|
||||
}
|
||||
|
||||
func (r *LocationRepository) Tree(ctx context.Context, GID uuid.UUID, tq TreeQuery) ([]TreeItem, error) {
|
||||
func (r *LocationRepository) Tree(ctx context.Context, gid uuid.UUID, tq TreeQuery) ([]TreeItem, error) {
|
||||
query := `
|
||||
WITH recursive location_tree(id, NAME, parent_id, level, node_type) AS
|
||||
(
|
||||
@@ -403,7 +403,7 @@ func (r *LocationRepository) Tree(ctx context.Context, GID uuid.UUID, tq TreeQue
|
||||
query = strings.ReplaceAll(query, "{{ WITH_ITEMS_FROM }}", "")
|
||||
}
|
||||
|
||||
rows, err := r.db.Sql().QueryContext(ctx, query, GID)
|
||||
rows, err := r.db.Sql().QueryContext(ctx, query, gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
72
backend/internal/data/repo/repo_maintenance.go
Normal file
72
backend/internal/data/repo/repo_maintenance.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/data/ent"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/group"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/item"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry"
|
||||
)
|
||||
|
||||
type (
|
||||
MaintenanceEntryWithDetails struct {
|
||||
MaintenanceEntry
|
||||
ItemName string `json:"itemName"`
|
||||
ItemID uuid.UUID `json:"itemID"`
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
mapEachMaintenanceEntryWithDetails = mapTEachFunc(mapMaintenanceEntryWithDetails)
|
||||
)
|
||||
|
||||
func mapMaintenanceEntryWithDetails(entry *ent.MaintenanceEntry) MaintenanceEntryWithDetails {
|
||||
return MaintenanceEntryWithDetails{
|
||||
MaintenanceEntry: mapMaintenanceEntry(entry),
|
||||
ItemName: entry.Edges.Item.Name,
|
||||
ItemID: entry.ItemID,
|
||||
}
|
||||
}
|
||||
|
||||
type MaintenanceFilterStatus string
|
||||
|
||||
const (
|
||||
MaintenanceFilterStatusScheduled MaintenanceFilterStatus = "scheduled"
|
||||
MaintenanceFilterStatusCompleted MaintenanceFilterStatus = "completed"
|
||||
MaintenanceFilterStatusBoth MaintenanceFilterStatus = "both"
|
||||
)
|
||||
|
||||
type MaintenanceFilters struct {
|
||||
Status MaintenanceFilterStatus `json:"status" schema:"status"`
|
||||
}
|
||||
|
||||
func (r *MaintenanceEntryRepository) GetAllMaintenance(ctx context.Context, groupID uuid.UUID, filters MaintenanceFilters) ([]MaintenanceEntryWithDetails, error) {
|
||||
query := r.db.MaintenanceEntry.Query().Where(
|
||||
maintenanceentry.HasItemWith(
|
||||
item.HasGroupWith(group.IDEQ(groupID)),
|
||||
),
|
||||
)
|
||||
|
||||
if filters.Status == MaintenanceFilterStatusScheduled {
|
||||
query = query.Where(maintenanceentry.Or(
|
||||
maintenanceentry.DateIsNil(),
|
||||
maintenanceentry.DateEQ(time.Time{}),
|
||||
))
|
||||
} else if filters.Status == MaintenanceFilterStatusCompleted {
|
||||
query = query.Where(
|
||||
maintenanceentry.Not(maintenanceentry.Or(
|
||||
maintenanceentry.DateIsNil(),
|
||||
maintenanceentry.DateEQ(time.Time{})),
|
||||
))
|
||||
}
|
||||
entries, err := query.WithItem().Order(maintenanceentry.ByScheduledDate()).All(ctx)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mapEachMaintenanceEntryWithDetails(entries), nil
|
||||
}
|
||||
@@ -59,13 +59,6 @@ type (
|
||||
Description string `json:"description"`
|
||||
Cost float64 `json:"cost,string"`
|
||||
}
|
||||
|
||||
MaintenanceLog struct {
|
||||
ItemID uuid.UUID `json:"itemId"`
|
||||
CostAverage float64 `json:"costAverage"`
|
||||
CostTotal float64 `json:"costTotal"`
|
||||
Entries []MaintenanceEntry `json:"entries"`
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -84,11 +77,11 @@ func mapMaintenanceEntry(entry *ent.MaintenanceEntry) MaintenanceEntry {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *MaintenanceEntryRepository) GetScheduled(ctx context.Context, GID uuid.UUID, dt types.Date) ([]MaintenanceEntry, error) {
|
||||
func (r *MaintenanceEntryRepository) GetScheduled(ctx context.Context, gid uuid.UUID, dt types.Date) ([]MaintenanceEntry, error) {
|
||||
entries, err := r.db.MaintenanceEntry.Query().
|
||||
Where(
|
||||
maintenanceentry.HasItemWith(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.HasGroupWith(group.ID(gid)),
|
||||
),
|
||||
maintenanceentry.ScheduledDate(dt.Time()),
|
||||
maintenanceentry.Or(
|
||||
@@ -118,8 +111,8 @@ func (r *MaintenanceEntryRepository) Create(ctx context.Context, itemID uuid.UUI
|
||||
return mapMaintenanceEntryErr(item, err)
|
||||
}
|
||||
|
||||
func (r *MaintenanceEntryRepository) Update(ctx context.Context, ID uuid.UUID, input MaintenanceEntryUpdate) (MaintenanceEntry, error) {
|
||||
item, err := r.db.MaintenanceEntry.UpdateOneID(ID).
|
||||
func (r *MaintenanceEntryRepository) Update(ctx context.Context, id uuid.UUID, input MaintenanceEntryUpdate) (MaintenanceEntry, error) {
|
||||
item, err := r.db.MaintenanceEntry.UpdateOneID(id).
|
||||
SetDate(input.CompletedDate.Time()).
|
||||
SetScheduledDate(input.ScheduledDate.Time()).
|
||||
SetName(input.Name).
|
||||
@@ -130,78 +123,34 @@ func (r *MaintenanceEntryRepository) Update(ctx context.Context, ID uuid.UUID, i
|
||||
return mapMaintenanceEntryErr(item, err)
|
||||
}
|
||||
|
||||
type MaintenanceLogQuery struct {
|
||||
Completed bool `json:"completed" schema:"completed"`
|
||||
Scheduled bool `json:"scheduled" schema:"scheduled"`
|
||||
}
|
||||
|
||||
func (r *MaintenanceEntryRepository) GetLog(ctx context.Context, groupID, itemID uuid.UUID, query MaintenanceLogQuery) (MaintenanceLog, error) {
|
||||
log := MaintenanceLog{
|
||||
ItemID: itemID,
|
||||
}
|
||||
|
||||
q := r.db.MaintenanceEntry.Query().Where(
|
||||
func (r *MaintenanceEntryRepository) GetMaintenanceByItemID(ctx context.Context, groupID, itemID uuid.UUID, filters MaintenanceFilters) ([]MaintenanceEntryWithDetails, error) {
|
||||
query := r.db.MaintenanceEntry.Query().Where(
|
||||
maintenanceentry.ItemID(itemID),
|
||||
maintenanceentry.HasItemWith(
|
||||
item.HasGroupWith(group.IDEQ(groupID)),
|
||||
),
|
||||
)
|
||||
|
||||
if query.Completed {
|
||||
q = q.Where(maintenanceentry.And(
|
||||
maintenanceentry.DateNotNil(),
|
||||
maintenanceentry.DateNEQ(time.Time{}),
|
||||
if filters.Status == MaintenanceFilterStatusScheduled {
|
||||
query = query.Where(maintenanceentry.Or(
|
||||
maintenanceentry.DateIsNil(),
|
||||
maintenanceentry.DateEQ(time.Time{}),
|
||||
))
|
||||
} else if query.Scheduled {
|
||||
q = q.Where(maintenanceentry.And(
|
||||
maintenanceentry.Or(
|
||||
} else if filters.Status == MaintenanceFilterStatusCompleted {
|
||||
query = query.Where(
|
||||
maintenanceentry.Not(maintenanceentry.Or(
|
||||
maintenanceentry.DateIsNil(),
|
||||
maintenanceentry.DateEQ(time.Time{}),
|
||||
),
|
||||
maintenanceentry.ScheduledDateNotNil(),
|
||||
maintenanceentry.ScheduledDateNEQ(time.Time{}),
|
||||
))
|
||||
maintenanceentry.DateEQ(time.Time{})),
|
||||
))
|
||||
}
|
||||
entries, err := query.WithItem().Order(maintenanceentry.ByScheduledDate()).All(ctx)
|
||||
|
||||
entries, err := q.Order(ent.Desc(maintenanceentry.FieldDate)).
|
||||
All(ctx)
|
||||
if err != nil {
|
||||
return MaintenanceLog{}, err
|
||||
return []MaintenanceEntryWithDetails{}, err
|
||||
}
|
||||
|
||||
log.Entries = mapEachMaintenanceEntry(entries)
|
||||
|
||||
var maybeTotal *float64
|
||||
var maybeAverage *float64
|
||||
|
||||
statement := `
|
||||
SELECT
|
||||
SUM(cost_total) AS total_of_totals,
|
||||
AVG(cost_total) AS avg_of_averages
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
strftime('%m-%Y', date) AS my,
|
||||
SUM(cost) AS cost_total
|
||||
FROM
|
||||
maintenance_entries
|
||||
WHERE
|
||||
item_id = ?
|
||||
GROUP BY
|
||||
my
|
||||
)`
|
||||
|
||||
row := r.db.Sql().QueryRowContext(ctx, statement, itemID)
|
||||
err = row.Scan(&maybeTotal, &maybeAverage)
|
||||
if err != nil {
|
||||
return MaintenanceLog{}, err
|
||||
}
|
||||
|
||||
log.CostAverage = orDefault(maybeAverage, 0)
|
||||
log.CostTotal = orDefault(maybeTotal, 0)
|
||||
return log, nil
|
||||
return mapEachMaintenanceEntryWithDetails(entries), nil
|
||||
}
|
||||
|
||||
func (r *MaintenanceEntryRepository) Delete(ctx context.Context, ID uuid.UUID) error {
|
||||
return r.db.MaintenanceEntry.DeleteOneID(ID).Exec(ctx)
|
||||
func (r *MaintenanceEntryRepository) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
return r.db.MaintenanceEntry.DeleteOneID(id).Exec(ctx)
|
||||
}
|
||||
|
||||
@@ -60,27 +60,14 @@ func TestMaintenanceEntryRepository_GetLog(t *testing.T) {
|
||||
}
|
||||
|
||||
// Get the log for the item
|
||||
log, err := tRepos.MaintEntry.GetLog(context.Background(), tGroup.ID, item.ID, MaintenanceLogQuery{
|
||||
Completed: true,
|
||||
})
|
||||
log, err := tRepos.MaintEntry.GetMaintenanceByItemID(context.Background(), tGroup.ID, item.ID, MaintenanceFilters{Status: MaintenanceFilterStatusCompleted})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get maintenance log: %v", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, item.ID, log.ItemID)
|
||||
assert.Len(t, log.Entries, 10)
|
||||
assert.Len(t, log, 10)
|
||||
|
||||
// Calculate the average cost
|
||||
var total float64
|
||||
|
||||
for _, entry := range log.Entries {
|
||||
total += entry.Cost
|
||||
}
|
||||
|
||||
assert.InDelta(t, total, log.CostTotal, .001, "total cost should be equal to the sum of all entries")
|
||||
assert.InDelta(t, total/2, log.CostAverage, 001, "average cost should be the average of the two months")
|
||||
|
||||
for _, entry := range log.Entries {
|
||||
for _, entry := range log {
|
||||
err := tRepos.MaintEntry.Delete(context.Background(), entry.ID)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ type (
|
||||
|
||||
Name string `json:"name"`
|
||||
IsActive bool `json:"isActive"`
|
||||
URL string `json:"-"` // URL field is not exposed to the client
|
||||
URL string `json:"url"`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -114,7 +114,7 @@ func (r *NotifierRepository) Update(ctx context.Context, userID uuid.UUID, id uu
|
||||
return r.mapper.MapErr(notifier, err)
|
||||
}
|
||||
|
||||
func (r *NotifierRepository) Delete(ctx context.Context, userID uuid.UUID, ID uuid.UUID) error {
|
||||
_, err := r.db.Notifier.Delete().Where(notifier.UserID(userID), notifier.ID(ID)).Exec(ctx)
|
||||
func (r *NotifierRepository) Delete(ctx context.Context, userID uuid.UUID, id uuid.UUID) error {
|
||||
_, err := r.db.Notifier.Delete().Where(notifier.UserID(userID), notifier.ID(id)).Exec(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -60,9 +60,9 @@ func mapUserOut(user *ent.User) UserOut {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *UserRepository) GetOneID(ctx context.Context, ID uuid.UUID) (UserOut, error) {
|
||||
func (r *UserRepository) GetOneID(ctx context.Context, id uuid.UUID) (UserOut, error) {
|
||||
return mapUserOutErr(r.db.User.Query().
|
||||
Where(user.ID(ID)).
|
||||
Where(user.ID(id)).
|
||||
WithGroup().
|
||||
Only(ctx))
|
||||
}
|
||||
@@ -101,9 +101,9 @@ func (r *UserRepository) Create(ctx context.Context, usr UserCreate) (UserOut, e
|
||||
return r.GetOneID(ctx, entUser.ID)
|
||||
}
|
||||
|
||||
func (r *UserRepository) Update(ctx context.Context, ID uuid.UUID, data UserUpdate) error {
|
||||
func (r *UserRepository) Update(ctx context.Context, id uuid.UUID, data UserUpdate) error {
|
||||
q := r.db.User.Update().
|
||||
Where(user.ID(ID)).
|
||||
Where(user.ID(id)).
|
||||
SetName(data.Name).
|
||||
SetEmail(data.Email)
|
||||
|
||||
@@ -130,6 +130,6 @@ func (r *UserRepository) GetSuperusers(ctx context.Context) ([]*ent.User, error)
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (r *UserRepository) ChangePassword(ctx context.Context, UID uuid.UUID, pw string) error {
|
||||
return r.db.User.UpdateOneID(UID).SetPassword(pw).Exec(ctx)
|
||||
func (r *UserRepository) ChangePassword(ctx context.Context, uid uuid.UUID, pw string) error {
|
||||
return r.db.User.UpdateOneID(uid).SetPassword(pw).Exec(ctx)
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@ func (tp *TemplateProps) Set(key, value string) {
|
||||
func DefaultTemplateData() TemplateProps {
|
||||
return TemplateProps{
|
||||
Defaults: TemplateDefaults{
|
||||
CompanyName: "Haybytes.com",
|
||||
CompanyName: "sysadminsmedia.com",
|
||||
CompanyAddress: "123 Main St, Anytown, CA 12345",
|
||||
CompanyURL: "https://haybytes.com",
|
||||
CompanyURL: "https://sysadminsmedia.com",
|
||||
ActivateAccountURL: "https://google.com",
|
||||
UnsubscribeURL: "https://google.com",
|
||||
},
|
||||
|
||||
@@ -1,14 +1,28 @@
|
||||
import { defineConfig } from 'vitepress'
|
||||
import enMenu from "./menus/en.mjs";
|
||||
|
||||
// https://vitepress.dev/reference/site-config
|
||||
export default defineConfig({
|
||||
ignoreDeadLinks: [
|
||||
/^https?:\/\/localhost:7745/,
|
||||
],
|
||||
|
||||
title: "HomeBox",
|
||||
description: "A simple home inventory management software",
|
||||
lastUpdated: true,
|
||||
sitemap: {
|
||||
hostname: 'https://homebox.sysadminsmedia.com',
|
||||
hostname: 'https://homebox.software',
|
||||
},
|
||||
|
||||
head: [
|
||||
['link', { rel: 'icon', href: '/favicon.svg' }],
|
||||
['meta', { name: 'theme-color', content: '#3eaf7c' }],
|
||||
['meta', { name: 'og:title', content: 'HomeBox' }],
|
||||
['meta', { name: 'og:description', content: 'A simple home inventory management software' }],
|
||||
['meta', { name: 'og:image', content: '/homebox-email-banner.jpg' }],
|
||||
['meta', { name: 'twitter:card', content: 'summary' }],
|
||||
],
|
||||
|
||||
locales: {
|
||||
en: {
|
||||
label: 'English',
|
||||
@@ -27,37 +41,17 @@ export default defineConfig({
|
||||
},
|
||||
// https://vitepress.dev/reference/default-theme-config
|
||||
nav: [
|
||||
{ text: 'API', link: 'https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/sysadminsmedia/homebox/main/docs/docs/api/openapi-2.0.json' }
|
||||
{ text: 'API Docs', link: '/en/api' },
|
||||
{ text: 'Demo', link: 'https://demo.homebox.software' },
|
||||
],
|
||||
|
||||
sidebar: {
|
||||
'/en/': [
|
||||
{
|
||||
text: 'Getting Started',
|
||||
items: [
|
||||
{ text: 'Quick Start', link: '/en/quick-start' },
|
||||
{ text: 'Tips and Tricks', link: '/en/tips-tricks' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Advanced',
|
||||
items: [
|
||||
{ text: 'Import CSV', link: '/en/import-csv' },
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Contributing',
|
||||
items: [
|
||||
{ text: 'Get Started', link: '/en/contribute/get-started' },
|
||||
{ text: 'Bounty Program', link: '/en/contribute/bounty' }
|
||||
]
|
||||
}
|
||||
]
|
||||
'/en/': enMenu,
|
||||
},
|
||||
|
||||
socialLinks: [
|
||||
{ icon: 'discord', link: 'https://discord.gg/aY4DCkpNA9' },
|
||||
{ icon: 'github', link: 'https://github.com/sysadminsmedia/homebox' },
|
||||
{ icon: 'discord', link: 'https://discord.homebox.software' },
|
||||
{ icon: 'github', link: 'https://git.homebox.software' },
|
||||
{ icon: 'mastodon', link: 'https://noc.social/@sysadminszone' },
|
||||
]
|
||||
}
|
||||
|
||||
25
docs/.vitepress/menus/en.mts
Normal file
25
docs/.vitepress/menus/en.mts
Normal file
@@ -0,0 +1,25 @@
|
||||
export default [
|
||||
{
|
||||
text: 'Getting Started',
|
||||
items: [
|
||||
{text: 'Quick Start', link: '/en/quick-start'},
|
||||
{text: 'Installation', link: '/en/installation'},
|
||||
{text: 'Organizing Your Items', link: '/en/organizing-items'},
|
||||
{text: 'Configure Homebox', link: '/en/configure-homebox'},
|
||||
{text: 'Tips and Tricks', link: '/en/tips-tricks'}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Advanced',
|
||||
items: [
|
||||
{text: 'Import CSV', link: '/en/import-csv'},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Contributing',
|
||||
items: [
|
||||
{text: 'Get Started', link: '/en/contribute/get-started'},
|
||||
{text: 'Bounty Program', link: '/en/contribute/bounty'}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -910,14 +910,34 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
"Item Maintenance"
|
||||
],
|
||||
"summary": "Get Maintenance Log",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"scheduled",
|
||||
"completed",
|
||||
"both"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
"MaintenanceFilterStatusScheduled",
|
||||
"MaintenanceFilterStatusCompleted",
|
||||
"MaintenanceFilterStatusBoth"
|
||||
],
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceLog"
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryWithDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -932,7 +952,7 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
"Item Maintenance"
|
||||
],
|
||||
"summary": "Create Maintenance Entry",
|
||||
"parameters": [
|
||||
@@ -956,60 +976,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/{id}/maintenance/{entry_id}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Update Maintenance Entry",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Entry Data",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Delete Maintenance Entry",
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/{id}/path": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -1402,6 +1368,104 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/maintenance": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Query All Maintenance",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"scheduled",
|
||||
"completed",
|
||||
"both"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
"MaintenanceFilterStatusScheduled",
|
||||
"MaintenanceFilterStatusCompleted",
|
||||
"MaintenanceFilterStatusBoth"
|
||||
],
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryWithDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/maintenance/{id}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Update Maintenance Entry",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Entry Data",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntryUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Maintenance"
|
||||
],
|
||||
"summary": "Delete Maintenance Entry",
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/notifiers": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -1683,12 +1747,14 @@
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"example": "admin@admin.com",
|
||||
"description": "string",
|
||||
"name": "username",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "admin",
|
||||
"description": "string",
|
||||
"name": "password",
|
||||
"in": "formData"
|
||||
@@ -2140,15 +2206,11 @@
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"purchaseMethod": {
|
||||
"type": "string"
|
||||
},
|
||||
"purchaseFrom": {
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2164,8 +2226,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
@@ -2218,6 +2279,10 @@
|
||||
"archived": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"assetId": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -2253,8 +2318,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "integer"
|
||||
@@ -2277,6 +2341,9 @@
|
||||
},
|
||||
"repo.ItemUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"archived": {
|
||||
"type": "boolean"
|
||||
@@ -2285,7 +2352,8 @@
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 1000
|
||||
},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
@@ -2320,7 +2388,9 @@
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255,
|
||||
"minLength": 1
|
||||
},
|
||||
"notes": {
|
||||
"description": "Extras",
|
||||
@@ -2332,11 +2402,13 @@
|
||||
"x-omitempty": true
|
||||
},
|
||||
"purchaseFrom": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
@@ -2353,15 +2425,17 @@
|
||||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
"type": "number",
|
||||
"x-nullable": true,
|
||||
"x-omitempty": true
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
"type": "string"
|
||||
},
|
||||
"soldTo": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"warrantyDetails": {
|
||||
"type": "string"
|
||||
@@ -2608,26 +2682,49 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"repo.MaintenanceLog": {
|
||||
"repo.MaintenanceEntryWithDetails": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"costAverage": {
|
||||
"type": "number"
|
||||
"completedDate": {
|
||||
"type": "string"
|
||||
},
|
||||
"costTotal": {
|
||||
"type": "number"
|
||||
"cost": {
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"entries": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.MaintenanceEntry"
|
||||
}
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemId": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemID": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemName": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"scheduledDate": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repo.MaintenanceFilterStatus": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"scheduled",
|
||||
"completed",
|
||||
"both"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"MaintenanceFilterStatusScheduled",
|
||||
"MaintenanceFilterStatusCompleted",
|
||||
"MaintenanceFilterStatusBoth"
|
||||
]
|
||||
},
|
||||
"repo.NotifierCreate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -2669,6 +2766,9 @@
|
||||
"updatedAt": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"userId": {
|
||||
"type": "string"
|
||||
}
|
||||
@@ -2711,9 +2811,6 @@
|
||||
},
|
||||
"total": {
|
||||
"type": "integer"
|
||||
},
|
||||
"totalPrice": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2996,4 +3093,4 @@
|
||||
"in": "header"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
37
docs/en/api.md
Normal file
37
docs/en/api.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
layout: page
|
||||
sidebar: false
|
||||
---
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useData } from 'vitepress';
|
||||
|
||||
const elementScript = document.createElement('script');
|
||||
elementScript.src = 'https://unpkg.com/@stoplight/elements/web-components.min.js';
|
||||
document.head.appendChild(elementScript);
|
||||
|
||||
const elementStyle = document.createElement('link');
|
||||
elementStyle.rel = 'stylesheet';
|
||||
elementStyle.href = 'https://unpkg.com/@stoplight/elements/styles.min.css';
|
||||
document.head.appendChild(elementStyle);
|
||||
|
||||
const { isDark } = useData();
|
||||
let theme = 'light';
|
||||
if (isDark.value) {
|
||||
theme = 'dark';
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.TryItPanel {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<elements-api
|
||||
apiDescriptionUrl="https://cdn.jsdelivr.net/gh/sysadminsmedia/homebox@main/docs/docs/api/openapi-2.0.json"
|
||||
router="hash"
|
||||
layout="responsive"
|
||||
hideSchemas="true"
|
||||
:data-theme="theme"
|
||||
/>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user