diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 87730fb5e..719ad6963 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -35,6 +35,6 @@ // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. "remoteUser": "node", "features": { - "golang": "1.21" + "ghcr.io/devcontainers/features/go:1": "1.21" } } diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 462629867..cd9f27c36 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -github: [hay-kot] +github: [tankerkiller125,katosdev] diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 309cf2898..5a68cd6a5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,7 +1,8 @@ --- name: "Bug Report" description: "Submit a bug report for the current release" -labels: ["bug"] +labels: ["🕷️ bug"] +projects: ["sysadminsmedia/2"] body: - type: checkboxes id: checks @@ -19,6 +20,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: @@ -54,6 +57,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: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 550daf4d9..3fa4d8024 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,7 +1,8 @@ --- name: "Feature Request" description: "Submit a feature request for the current release" -labels: ["feature-request"] +labels: ["⬆️ enhancement"] +projects: ["sysadminsmedia/2"] body: - type: textarea id: problem-statement diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index f4e8f0474..a0e38919f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -55,18 +55,4 @@ _(fill-in or delete this section)_ - -## Release Notes - -_(REQUIRED)_ - - -```release-note -``` \ No newline at end of file +--> \ No newline at end of file diff --git a/.github/scripts/update_currencies.py b/.github/scripts/update_currencies.py new file mode 100644 index 000000000..51daf8229 --- /dev/null +++ b/.github/scripts/update_currencies.py @@ -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() \ No newline at end of file diff --git a/.github/workflows/binaries-publish.yaml b/.github/workflows/binaries-publish.yaml new file mode 100644 index 000000000..5184cc05d --- /dev/null +++ b/.github/workflows/binaries-publish.yaml @@ -0,0 +1,47 @@ +name: Publish Release Binaries + +on: + push: + tags: [ 'v*.*.*' ] + +jobs: +# backend-tests: +# name: "Backend Server Tests" +# uses: sysadminsmedia/homebox/.github/workflows/partial-backend.yaml@main + +# frontend-tests: +# name: "Frontend and End-to-End Tests" +# uses: sysadminsmedia/homebox/.github/workflows/partial-frontend.yaml@main + + goreleaser: + name: goreleaser + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v5 + + - uses: pnpm/action-setup@v2 + with: + version: 7.30.1 + + - name: Build Frontend and Copy to Backend + working-directory: frontend + run: | + pnpm install --shamefully-hoist + pnpm run build + cp -r ./.output/public ../backend/app/api/static/ + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + workdir: "backend" + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/docker-publish-rootless.yaml b/.github/workflows/docker-publish-rootless.yaml new file mode 100644 index 000000000..745c089b3 --- /dev/null +++ b/.github/workflows/docker-publish-rootless.yaml @@ -0,0 +1,108 @@ +name: Docker publish rootless + +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 / + IMAGE_NAME: ${{ github.repository }} + + +jobs: + build-rootless: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + # This is used to complete the identity challenge + # with sigstore/fulcio when running outside of PRs. + attestations: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Set up BuildKit Docker container builder to be able to build + # multi-platform images and export cache + # https://github.com/docker/setup-buildx-action + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3.0.0 # v3.0.0 + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@v3.0.0 # v3.0.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: metadata + uses: docker/metadata-action@v5.0.0 # 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,onlatest=true + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@v5.0.0 # v5.0.0 + with: + context: . + 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 + build-args: | + VERSION=${{ github.ref_name }} + COMMIT=${{ github.sha }} + + - 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 diff --git a/.github/workflows/docker-publish.yaml b/.github/workflows/docker-publish.yaml new file mode 100644 index 000000000..cf05d993c --- /dev/null +++ b/.github/workflows/docker-publish.yaml @@ -0,0 +1,105 @@ +name: Docker publish + +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 / + IMAGE_NAME: ${{ github.repository }} + + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + # This is used to complete the identity challenge + # with sigstore/fulcio when running outside of PRs. + attestations: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Set up BuildKit Docker container builder to be able to build + # multi-platform images and export cache + # https://github.com/docker/setup-buildx-action + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3.0.0 # v3.0.0 + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@v3.0.0 # v3.0.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5.0.0 # 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 + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@v5.0.0 # v5.0.0 + with: + context: . + 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 + build-args: | + VERSION=${{ github.ref_name }} + COMMIT=${{ github.sha }} + + - 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 diff --git a/.github/workflows/partial-publish.yaml b/.github/workflows/partial-publish.yaml deleted file mode 100644 index 542171d13..000000000 --- a/.github/workflows/partial-publish.yaml +++ /dev/null @@ -1,89 +0,0 @@ -name: Frontend / E2E - -on: - workflow_call: - inputs: - tag: - required: true - type: string - release: - required: false - type: boolean - default: false - - secrets: - GH_TOKEN: - required: true - -jobs: - publish: - name: "Publish Homebox" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: "1.20" - - - name: Set up QEMU - id: qemu - uses: docker/setup-qemu-action@v3 - with: - image: tonistiigi/binfmt:latest - platforms: all - - - name: install buildx - id: buildx - uses: docker/setup-buildx-action@v3 - with: - install: true - - - name: login to container registry - run: docker login ghcr.io --username hay-kot --password $CR_PAT - env: - CR_PAT: ${{ secrets.GH_TOKEN }} - - - name: build nightly image - if: ${{ inputs.release == false }} - run: | - docker build --push --no-cache \ - --tag=ghcr.io/hay-kot/homebox:${{ inputs.tag }} \ - --build-arg=COMMIT=$(git rev-parse HEAD) \ - --build-arg=BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ - --platform=linux/amd64,linux/arm64,linux/arm/v7 . - - - name: build nightly-rootless image - if: ${{ inputs.release == false }} - run: | - docker build --push --no-cache \ - --tag=ghcr.io/hay-kot/homebox:${{ inputs.tag }}-rootless \ - --build-arg=COMMIT=$(git rev-parse HEAD) \ - --build-arg=BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ - --file Dockerfile.rootless \ - --platform=linux/amd64,linux/arm64,linux/arm/v7 . - - - name: build release tagged the image - if: ${{ inputs.release == true }} - run: | - docker build --push --no-cache \ - --tag ghcr.io/hay-kot/homebox:nightly \ - --tag ghcr.io/hay-kot/homebox:latest \ - --tag ghcr.io/hay-kot/homebox:${{ inputs.tag }} \ - --build-arg VERSION=${{ inputs.tag }} \ - --build-arg COMMIT=$(git rev-parse HEAD) \ - --build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ - --platform linux/amd64,linux/arm64,linux/arm/v7 . - - - name: build release tagged the rootless image - if: ${{ inputs.release == true }} - run: | - docker build --push --no-cache \ - --tag ghcr.io/hay-kot/homebox:nightly-rootless \ - --tag ghcr.io/hay-kot/homebox:latest-rootless \ - --tag ghcr.io/hay-kot/homebox:${{ inputs.tag }}-rootless \ - --build-arg VERSION=${{ inputs.tag }} \ - --build-arg COMMIT=$(git rev-parse HEAD) \ - --build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ - --platform linux/amd64,linux/arm64,linux/arm/v7 \ - --file Dockerfile.rootless . diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml deleted file mode 100644 index e91e8ec12..000000000 --- a/.github/workflows/publish.yaml +++ /dev/null @@ -1,29 +0,0 @@ -name: Publish Dockers - -on: - push: - branches: - - main - -env: - FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} - -jobs: - deploy: - name: "Deploy Nightly to Fly.io" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: superfly/flyctl-actions/setup-flyctl@master - - run: flyctl deploy --remote-only - - publish-nightly: - name: "Publish Nightly" - if: github.event_name != 'release' - uses: hay-kot/homebox/.github/workflows/partial-publish.yaml@main - with: - tag: nightly - secrets: - GH_TOKEN: ${{ secrets.CR_PAT }} - - diff --git a/.github/workflows/pull-requests.yaml b/.github/workflows/pull-requests.yaml index f39539be7..61a148595 100644 --- a/.github/workflows/pull-requests.yaml +++ b/.github/workflows/pull-requests.yaml @@ -5,6 +5,10 @@ on: branches: - main + paths: + - 'backend/**' + - 'frontend/**' + jobs: backend-tests: name: "Backend Server Tests" diff --git a/.github/workflows/tag.yaml b/.github/workflows/tag.yaml deleted file mode 100644 index 8ac7c5478..000000000 --- a/.github/workflows/tag.yaml +++ /dev/null @@ -1,77 +0,0 @@ -name: Publish Release - -on: - push: - tags: - - v* - -env: - FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} - -jobs: - backend-tests: - name: "Backend Server Tests" - uses: hay-kot/homebox/.github/workflows/partial-backend.yaml@main - - frontend-tests: - name: "Frontend and End-to-End Tests" - uses: hay-kot/homebox/.github/workflows/partial-frontend.yaml@main - - goreleaser: - name: goreleaser - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Go - uses: actions/setup-go@v5 - - - uses: pnpm/action-setup@v2 - with: - version: 7.30.1 - - - name: Build Frontend and Copy to Backend - working-directory: frontend - run: | - pnpm install --shamefully-hoist - pnpm run build - cp -r ./.output/public ../backend/app/api/static/ - - - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v5 - with: - workdir: "backend" - distribution: goreleaser - version: latest - args: release --clean - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - publish-tag: - name: "Publish Tag" - uses: hay-kot/homebox/.github/workflows/partial-publish.yaml@main - with: - release: true - tag: ${{ github.ref_name }} - secrets: - GH_TOKEN: ${{ secrets.CR_PAT }} - - deploy-docs: - name: Deploy docs - needs: - - publish-tag - - goreleaser - runs-on: ubuntu-latest - steps: - - name: Checkout main - uses: actions/checkout@v4 - - - name: Deploy docs - uses: mhausenblas/mkdocs-deploy-gh-pages@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CONFIG_FILE: docs/mkdocs.yml - EXTRA_PACKAGES: build-base \ No newline at end of file diff --git a/.github/workflows/update-currencies.yml b/.github/workflows/update-currencies.yml new file mode 100644 index 000000000..1b08a4bc1 --- /dev/null +++ b/.github/workflows/update-currencies.yml @@ -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." diff --git a/.gitignore b/.gitignore index d247138e7..51a835a44 100644 --- a/.gitignore +++ b/.gitignore @@ -48,10 +48,12 @@ dist .pnpm-store backend/app/api/app -backend/app/api/__debug_bin +backend/app/api/__debug_bin* dist/ # Nuxt Publish Dir backend/app/api/static/public/* !backend/app/api/static/public/.gitkeep -backend/api \ No newline at end of file +backend/api + +docs/.vitepress/cache/ \ No newline at end of file diff --git a/.scaffold/model/templates/model.go b/.scaffold/model/templates/model.go index b73ac16ae..f16be5cf3 100644 --- a/.scaffold/model/templates/model.go +++ b/.scaffold/model/templates/model.go @@ -3,7 +3,7 @@ package schema import ( "entgo.io/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) type {{ .Scaffold.model }} struct { diff --git a/.vscode/launch.json b/.vscode/launch.json index d37539585..8c6ce98a1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -25,6 +25,7 @@ "HBOX_STORAGE_DATA": "${workspaceRoot}/backend/.data", "HBOX_STORAGE_SQLITE_URL": "${workspaceRoot}/backend/.data/homebox.db?_fk=1" }, + "console": "integratedTerminal", }, { "name": "Launch Frontend", @@ -38,10 +39,11 @@ "cwd": "${workspaceFolder}/frontend", "serverReadyAction": { "action": "debugWithChrome", - "pattern": "Local: http://localhost:([0-9]+)", + "pattern": "Local: +http://localhost:([0-9]+)", "uriFormat": "http://localhost:%s", "webRoot": "${workspaceFolder}/frontend" - } + }, + "console": "integratedTerminal", } ] } \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..a5ff18626 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[support@sysadminemedia.com](mailto:support@sysadminemedia.com). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +[Contributor Covenant Code of Conduct](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html). + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +[FAQ](https://www.contributor-covenant.org/faq). Translations are available at +[Translations](https://www.contributor-covenant.org/translations). diff --git a/Dockerfile b/Dockerfile index f7525f59a..85097bd76 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,23 @@ +# 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 # Build Nuxt -FROM node:18-alpine as frontend-builder +FROM node:18-alpine AS frontend-builder WORKDIR /app RUN npm install -g pnpm -COPY frontend/package.json frontend/pnpm-lock.yaml ./ -RUN pnpm install --frozen-lockfile --shamefully-hoist COPY frontend . +COPY --from=frontend-dependencies /app/node_modules ./node_modules RUN pnpm build +FROM golang:alpine AS builder-dependencies +WORKDIR /go/src/app +COPY ./backend . +RUN go mod download + # Build API FROM golang:alpine AS builder ARG BUILD_TIME @@ -19,14 +29,17 @@ RUN apk update && \ 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 \ +COPY --from=builder-dependencies /go/pkg/mod /go/pkg/mod +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 @@ -39,11 +52,17 @@ RUN mkdir /app COPY --from=builder /go/bin/api /app RUN chmod +x /app/api +RUN apk add --no-cache wget LABEL Name=homebox Version=0.0.1 -LABEL org.opencontainers.image.source="https://github.com/hay-kot/homebox" +LABEL org.opencontainers.image.source="https://github.com/sysadminsmedia/homebox" 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" ] VOLUME [ "/data" ] ENTRYPOINT [ "/app/api" ] diff --git a/Dockerfile.rootless b/Dockerfile.rootless index e1c98aa01..3a0799d8a 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -1,13 +1,23 @@ +# 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 # Build Nuxt -FROM node:17-alpine as frontend-builder +FROM node:18-alpine AS frontend-builder WORKDIR /app RUN npm install -g pnpm -COPY frontend/package.json frontend/pnpm-lock.yaml ./ -RUN pnpm install --frozen-lockfile --shamefully-hoist COPY frontend . +COPY --from=frontend-dependencies /app/node_modules ./node_modules RUN pnpm build +FROM golang:alpine AS builder-dependencies +WORKDIR /go/src/app +COPY ./backend . +RUN go mod download + # Build API FROM golang:alpine AS builder ARG BUILD_TIME @@ -19,19 +29,19 @@ RUN apk update && \ 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 \ +COPY --from=builder-dependencies /go/pkg/mod /go/pkg/mod +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 && \ - chmod +x /go/bin/api && \ - # create a directory so that we can copy it in the next stage - mkdir /data + -v ./app/api/*.go + +FROM gcr.io/distroless/java:latest # Production Stage -FROM gcr.io/distroless/static +FROM gcr.io/distroless/static:latest ENV HBOX_MODE=production ENV HBOX_STORAGE_DATA=/data/ @@ -42,9 +52,16 @@ ENV HBOX_STORAGE_SQLITE_URL=/data/homebox.db?_fk=1 COPY --from=builder --chown=nonroot /go/bin/api /app COPY --from=builder --chown=nonroot /data /data +RUN apk add --no-cache wget + LABEL Name=homebox Version=0.0.1 -LABEL org.opencontainers.image.source="https://github.com/hay-kot/homebox" +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" ] # Drop root and run as low-privileged user diff --git a/README.md b/README.md index 148322b3d..e45676f6f 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,30 @@
- +

HomeBox

- Docs + Docs | - Demo + Demo | - Discord + Discord

+## What is HomeBox + +Homebox is the inventory and organization system built for the Home User! With a focus on simplicity and ease of use, Homebox is the perfect solution for your home inventory, organization, and management needs. While developing this project, I've tried to keep the following principles in mind: + +- _Simple_ - Homebox is designed to be simple and easy to use. No complicated setup or configuration required. Use either a single docker container, or deploy yourself by compiling the binary for your platform of choice. +- _Blazingly Fast_ - Homebox is written in Go, which makes it extremely fast and requires minimal resources to deploy. In general, idle memory usage is less than 50MB for the whole container. +- _Portable_ - Homebox is designed to be portable and run on anywhere. We use SQLite and an embedded Web UI to make it easy to deploy, use, and backup. + +# Screenshots +Check out screenshots of the project [here](https://imgur.com/a/5gLWt2j). + ## Quick Start -[Configuration & Docker Compose](https://hay-kot.github.io/homebox/quick-start) +[Configuration & Docker Compose](https://homebox.software/en/quick-start.html) ```bash # If using the rootless image, ensure data @@ -26,18 +37,24 @@ docker run -d \ --publish 3100:7745 \ --env TZ=Europe/Bucharest \ --volume /path/to/data/folder/:/data \ - ghcr.io/hay-kot/homebox:latest -# ghcr.io/hay-kot/homebox:latest-rootless + ghcr.io/sysadminsmedia/homebox:latest +# ghcr.io/sysadminsmedia/homebox:latest-rootless ``` + ## Contributing Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. 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. -Buy Me A Coffee +## 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/). + +[![Translation status](http://translate.sysadminsmedia.com/widget/homebox/multi-auto.svg)](http://translate.sysadminsmedia.com/engage/homebox/) + ## Credits +- Original project by [@hay-kot](https://github.com/hay-kot) - Logo by [@lakotelman](https://github.com/lakotelman) diff --git a/SECURITY.md b/SECURITY.md index 56b13b512..58af1f431 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,4 +6,6 @@ Since this software is still considered beta/WIP support is always only given fo ## Reporting a Vulnerability -Please open a normal public issue if you have any security related concerns. \ No newline at end of file +Please open a normal public issue for minor security issues or general security inquires. + +For major or critical security issues, please open a private github security issue. \ No newline at end of file diff --git a/backend/.golangci.yml b/backend/.golangci.yml index 8f6311034..46a451e5a 100644 --- a/backend/.golangci.yml +++ b/backend/.golangci.yml @@ -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 diff --git a/backend/app/api/app.go b/backend/app/api/app.go index 5d285d3c9..319107505 100644 --- a/backend/app/api/app.go +++ b/backend/app/api/app.go @@ -1,12 +1,12 @@ package main import ( - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/sys/config" - "github.com/hay-kot/homebox/backend/pkgs/mailer" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/core/services/reporting/eventbus" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/sys/config" + "github.com/sysadminsmedia/homebox/backend/pkgs/mailer" ) type app struct { diff --git a/backend/app/api/demo.go b/backend/app/api/demo.go index 183e0e006..54b04f071 100644 --- a/backend/app/api/demo.go +++ b/backend/app/api/demo.go @@ -2,14 +2,15 @@ package main import ( "context" + "errors" "strings" "time" - "github.com/hay-kot/homebox/backend/internal/core/services" "github.com/rs/zerolog/log" + "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 } diff --git a/backend/app/api/handlers/v1/controller.go b/backend/app/api/handlers/v1/controller.go index eb6021258..135b1446b 100644 --- a/backend/app/api/handlers/v1/controller.go +++ b/backend/app/api/handlers/v1/controller.go @@ -7,12 +7,12 @@ import ( "time" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus" - "github.com/hay-kot/homebox/backend/internal/data/repo" "github.com/hay-kot/httpkit/errchain" "github.com/hay-kot/httpkit/server" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/core/services/reporting/eventbus" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" "github.com/olahol/melody" ) @@ -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 ( @@ -87,12 +94,6 @@ type ( } ) -func BaseURLFunc(prefix string) func(s string) string { - return func(s string) string { - return prefix + "/v1" + s - } -} - func NewControllerV1(svc *services.AllServices, repos *repo.AllRepos, bus *eventbus.EventBus, options ...func(*V1Controller)) *V1Controller { ctrl := &V1Controller{ repo: repos, diff --git a/backend/app/api/handlers/v1/partials.go b/backend/app/api/handlers/v1/partials.go index 5c81ad5f9..f9e3841f7 100644 --- a/backend/app/api/handlers/v1/partials.go +++ b/backend/app/api/handlers/v1/partials.go @@ -5,7 +5,7 @@ import ( "github.com/go-chi/chi/v5" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/sys/validate" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" ) // routeID extracts the ID from the request URL. If the ID is not in a valid diff --git a/backend/app/api/handlers/v1/v1_ctrl_actions.go b/backend/app/api/handlers/v1/v1_ctrl_actions.go index 75f39a586..2ae25f023 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_actions.go +++ b/backend/app/api/handlers/v1/v1_ctrl_actions.go @@ -5,11 +5,11 @@ import ( "net/http" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/sys/validate" "github.com/hay-kot/httpkit/errchain" "github.com/hay-kot/httpkit/server" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" ) type ActionAmountResult struct { diff --git a/backend/app/api/handlers/v1/v1_ctrl_assets.go b/backend/app/api/handlers/v1/v1_ctrl_assets.go index 91e9a3c9b..4b26467c5 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_assets.go +++ b/backend/app/api/handlers/v1/v1_ctrl_assets.go @@ -6,11 +6,11 @@ import ( "strings" "github.com/go-chi/chi/v5" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/sys/validate" "github.com/hay-kot/httpkit/errchain" "github.com/hay-kot/httpkit/server" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" "github.com/rs/zerolog/log" ) @@ -37,7 +37,7 @@ func (ctrl *V1Controller) HandleAssetGet() errchain.HandlerFunc { pageParam := r.URL.Query().Get("page") var page int64 = -1 if pageParam != "" { - page, err = strconv.ParseInt(pageParam, 10, 64) + page, err = strconv.ParseInt(pageParam, 10, 32) if err != nil { return server.JSON(w, http.StatusBadRequest, "Invalid page number") } @@ -46,7 +46,7 @@ func (ctrl *V1Controller) HandleAssetGet() errchain.HandlerFunc { pageSizeParam := r.URL.Query().Get("pageSize") var pageSize int64 = -1 if pageSizeParam != "" { - pageSize, err = strconv.ParseInt(pageSizeParam, 10, 64) + pageSize, err = strconv.ParseInt(pageSizeParam, 10, 32) if err != nil { return server.JSON(w, http.StatusBadRequest, "Invalid page size") } diff --git a/backend/app/api/handlers/v1/v1_ctrl_auth.go b/backend/app/api/handlers/v1/v1_ctrl_auth.go index 47b69fdcb..de5b6c2b7 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_auth.go +++ b/backend/app/api/handlers/v1/v1_ctrl_auth.go @@ -7,11 +7,11 @@ import ( "strings" "time" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/sys/validate" "github.com/hay-kot/httpkit/errchain" "github.com/hay-kot/httpkit/server" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" ) const ( diff --git a/backend/app/api/handlers/v1/v1_ctrl_group.go b/backend/app/api/handlers/v1/v1_ctrl_group.go index 69bc0249b..62de9165b 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_group.go +++ b/backend/app/api/handlers/v1/v1_ctrl_group.go @@ -4,11 +4,11 @@ import ( "net/http" "time" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/sys/validate" - "github.com/hay-kot/homebox/backend/internal/web/adapters" "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/sys/validate" + "github.com/sysadminsmedia/homebox/backend/internal/web/adapters" ) type ( diff --git a/backend/app/api/handlers/v1/v1_ctrl_items.go b/backend/app/api/handlers/v1/v1_ctrl_items.go index 6a25663fb..1eddc0fc3 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_items.go +++ b/backend/app/api/handlers/v1/v1_ctrl_items.go @@ -4,17 +4,19 @@ import ( "database/sql" "encoding/csv" "errors" + "math/big" "net/http" + "net/url" "strings" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/sys/validate" - "github.com/hay-kot/homebox/backend/internal/web/adapters" "github.com/hay-kot/httpkit/errchain" "github.com/hay-kot/httpkit/server" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" + "github.com/sysadminsmedia/homebox/backend/internal/web/adapters" ) // HandleItemsGetAll godoc @@ -57,6 +59,7 @@ func (ctrl *V1Controller) HandleItemsGetAll() errchain.HandlerFunc { Search: params.Get("q"), LocationIDs: queryUUIDList(params, "locations"), LabelIDs: queryUUIDList(params, "labels"), + NegateLabels: queryBool(params.Get("negateLabels")), ParentItemIDs: queryUUIDList(params, "parentIds"), IncludeArchived: queryBool(params.Get("includeArchived")), Fields: filterFieldItems(params["fields"]), @@ -80,6 +83,14 @@ func (ctrl *V1Controller) HandleItemsGetAll() errchain.HandlerFunc { ctx := services.NewContext(r.Context()) items, err := ctrl.repo.Items.QueryByGroup(ctx, ctx.GID, extractQuery(r)) + totalPrice := new(big.Int) + for _, item := range items.Items { + totalPrice.Add(totalPrice, big.NewInt(int64(item.PurchasePrice*100))) + } + + totalPriceFloat := new(big.Float).SetInt(totalPrice) + totalPriceFloat.Quo(totalPriceFloat, big.NewFloat(100)) + if err != nil { if errors.Is(err, sql.ErrNoRows) { return server.JSON(w, http.StatusOK, repo.PaginationResult[repo.ItemSummary]{ @@ -323,17 +334,40 @@ 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.ExportTSV(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) } - w.Header().Set("Content-Type", "text/tsv") - w.Header().Set("Content-Disposition", "attachment;filename=homebox-items.tsv") + w.Header().Set("Content-Type", "text/csv") + w.Header().Set("Content-Disposition", "attachment;filename=homebox-items.csv") writer := csv.NewWriter(w) - writer.Comma = '\t' + writer.Comma = ',' 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() +} diff --git a/backend/app/api/handlers/v1/v1_ctrl_items_attachments.go b/backend/app/api/handlers/v1/v1_ctrl_items_attachments.go index ae2782af4..61b3b9a59 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_items_attachments.go +++ b/backend/app/api/handlers/v1/v1_ctrl_items_attachments.go @@ -6,13 +6,13 @@ import ( "path/filepath" "strings" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/sys/validate" "github.com/hay-kot/httpkit/errchain" "github.com/hay-kot/httpkit/server" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" ) type ( diff --git a/backend/app/api/handlers/v1/v1_ctrl_labels.go b/backend/app/api/handlers/v1/v1_ctrl_labels.go index dae23db05..888be19d4 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_labels.go +++ b/backend/app/api/handlers/v1/v1_ctrl_labels.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/web/adapters" "github.com/hay-kot/httpkit/errchain" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/web/adapters" ) // HandleLabelsGetAll godoc diff --git a/backend/app/api/handlers/v1/v1_ctrl_locations.go b/backend/app/api/handlers/v1/v1_ctrl_locations.go index d84ce313f..3903bd928 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_locations.go +++ b/backend/app/api/handlers/v1/v1_ctrl_locations.go @@ -1,13 +1,15 @@ package v1 import ( + "context" + "math/big" "net/http" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/web/adapters" "github.com/hay-kot/httpkit/errchain" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/web/adapters" ) // HandleLocationTreeQuery godoc @@ -83,6 +85,43 @@ 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) + 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}}) + if err != nil { + return repo.LocationOut{}, err + } + + for _, item := range items.Items { + // Convert item.Quantity to float64 for multiplication + quantity := float64(item.Quantity) + itemTotal := big.NewInt(int64(item.PurchasePrice * quantity * 100)) + totalPrice.Add(totalPrice, itemTotal) + } + + totalPriceFloat := new(big.Float).SetInt(totalPrice) + totalPriceFloat.Quo(totalPriceFloat, big.NewFloat(100)) + location.TotalPrice, _ = totalPriceFloat.Float64() + + // Add price from child locations + for _, childLocation := range location.Children { + var childLocationWithPrice repo.LocationOut + childLocationWithPrice, err = ctrl.GetLocationWithPrice(auth, gid, childLocation.ID) + if err != nil { + return repo.LocationOut{}, err + } + location.TotalPrice += childLocationWithPrice.TotalPrice + } + + return location, nil +} + // HandleLocationGet godoc // // @Summary Get Location @@ -95,7 +134,9 @@ func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc { func (ctrl *V1Controller) HandleLocationGet() errchain.HandlerFunc { fn := func(r *http.Request, ID uuid.UUID) (repo.LocationOut, error) { auth := services.NewContext(r.Context()) - return ctrl.repo.Locations.GetOneByGroup(auth, auth.GID, ID) + var location, err = ctrl.GetLocationWithPrice(auth, auth.GID, ID) + + return location, err } return adapters.CommandID("id", fn, http.StatusOK) diff --git a/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go b/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go index e94c12a96..e9f1f97c0 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go +++ b/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go @@ -4,24 +4,25 @@ import ( "net/http" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/web/adapters" "github.com/hay-kot/httpkit/errchain" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/web/adapters" ) // 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) -} diff --git a/backend/app/api/handlers/v1/v1_ctrl_maintenance.go b/backend/app/api/handlers/v1/v1_ctrl_maintenance.go new file mode 100644 index 000000000..647bfa703 --- /dev/null +++ b/backend/app/api/handlers/v1/v1_ctrl_maintenance.go @@ -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) +} diff --git a/backend/app/api/handlers/v1/v1_ctrl_notifiers.go b/backend/app/api/handlers/v1/v1_ctrl_notifiers.go index 3c64dc7fd..f46b9102c 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_notifiers.go +++ b/backend/app/api/handlers/v1/v1_ctrl_notifiers.go @@ -5,10 +5,10 @@ import ( "github.com/containrrr/shoutrrr" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/web/adapters" "github.com/hay-kot/httpkit/errchain" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/web/adapters" ) // HandleGetUserNotifiers godoc diff --git a/backend/app/api/handlers/v1/v1_ctrl_qrcode.go b/backend/app/api/handlers/v1/v1_ctrl_qrcode.go index 25f7c75a1..b348420a1 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_qrcode.go +++ b/backend/app/api/handlers/v1/v1_ctrl_qrcode.go @@ -7,8 +7,8 @@ import ( "net/http" "net/url" - "github.com/hay-kot/homebox/backend/internal/web/adapters" "github.com/hay-kot/httpkit/errchain" + "github.com/sysadminsmedia/homebox/backend/internal/web/adapters" "github.com/yeqown/go-qrcode/v2" "github.com/yeqown/go-qrcode/writer/standard" diff --git a/backend/app/api/handlers/v1/v1_ctrl_reporting.go b/backend/app/api/handlers/v1/v1_ctrl_reporting.go index 40f0d22c1..d3b712f8e 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_reporting.go +++ b/backend/app/api/handlers/v1/v1_ctrl_reporting.go @@ -1,10 +1,9 @@ package v1 import ( - "net/http" - - "github.com/hay-kot/homebox/backend/internal/core/services" "github.com/hay-kot/httpkit/errchain" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "net/http" ) // HandleBillOfMaterialsExport godoc @@ -19,13 +18,13 @@ func (ctrl *V1Controller) HandleBillOfMaterialsExport() errchain.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) error { actor := services.UseUserCtx(r.Context()) - csv, err := ctrl.svc.Items.ExportBillOfMaterialsTSV(r.Context(), actor.GroupID) + csv, err := ctrl.svc.Items.ExportBillOfMaterialsCSV(r.Context(), actor.GroupID) if err != nil { return err } - w.Header().Set("Content-Type", "text/tsv") - w.Header().Set("Content-Disposition", "attachment; filename=bill-of-materials.tsv") + w.Header().Set("Content-Type", "text/csv") + w.Header().Set("Content-Disposition", "attachment; filename=bill-of-materials.csv") _, err = w.Write(csv) return err } diff --git a/backend/app/api/handlers/v1/v1_ctrl_statistics.go b/backend/app/api/handlers/v1/v1_ctrl_statistics.go index 0a5a319c2..d66bd9086 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_statistics.go +++ b/backend/app/api/handlers/v1/v1_ctrl_statistics.go @@ -4,12 +4,12 @@ import ( "net/http" "time" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/sys/validate" - "github.com/hay-kot/homebox/backend/internal/web/adapters" "github.com/hay-kot/httpkit/errchain" "github.com/hay-kot/httpkit/server" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" + "github.com/sysadminsmedia/homebox/backend/internal/web/adapters" ) // HandleGroupStatisticsLocations godoc diff --git a/backend/app/api/handlers/v1/v1_ctrl_user.go b/backend/app/api/handlers/v1/v1_ctrl_user.go index 8708d24c8..5704fd911 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_user.go +++ b/backend/app/api/handlers/v1/v1_ctrl_user.go @@ -5,12 +5,12 @@ import ( "net/http" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/sys/validate" "github.com/hay-kot/httpkit/errchain" "github.com/hay-kot/httpkit/server" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" ) // HandleUserRegistration godoc diff --git a/backend/app/api/logger.go b/backend/app/api/logger.go index 34659c649..714cba44f 100644 --- a/backend/app/api/logger.go +++ b/backend/app/api/logger.go @@ -3,9 +3,9 @@ package main import ( "os" - "github.com/hay-kot/homebox/backend/internal/sys/config" "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/sys/config" ) // setupLogger initializes the zerolog config diff --git a/backend/app/api/main.go b/backend/app/api/main.go index 4811bfa03..6247fe6ad 100644 --- a/backend/app/api/main.go +++ b/backend/app/api/main.go @@ -14,21 +14,21 @@ import ( "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" - "github.com/hay-kot/homebox/backend/internal/core/currencies" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/migrations" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/sys/config" - "github.com/hay-kot/homebox/backend/internal/web/mid" "github.com/hay-kot/httpkit/errchain" "github.com/hay-kot/httpkit/graceful" "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/rs/zerolog/pkgerrors" - - _ "github.com/hay-kot/homebox/backend/pkgs/cgofreesqlite" + "github.com/sysadminsmedia/homebox/backend/internal/core/currencies" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/core/services/reporting/eventbus" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/migrations" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/sys/config" + "github.com/sysadminsmedia/homebox/backend/internal/web/mid" + + _ "github.com/sysadminsmedia/homebox/backend/pkgs/cgofreesqlite" ) var ( @@ -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 }) diff --git a/backend/app/api/middleware.go b/backend/app/api/middleware.go index 02b3a6ca8..45495933f 100644 --- a/backend/app/api/middleware.go +++ b/backend/app/api/middleware.go @@ -7,11 +7,11 @@ import ( "net/url" "strings" - v1 "github.com/hay-kot/homebox/backend/app/api/handlers/v1" - "github.com/hay-kot/homebox/backend/internal/core/services" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/sys/validate" "github.com/hay-kot/httpkit/errchain" + v1 "github.com/sysadminsmedia/homebox/backend/app/api/handlers/v1" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" ) type tokenHasKey struct { diff --git a/backend/app/api/providers/extractors.go b/backend/app/api/providers/extractors.go index bc042a494..c7b8fd66f 100644 --- a/backend/app/api/providers/extractors.go +++ b/backend/app/api/providers/extractors.go @@ -4,9 +4,9 @@ import ( "errors" "net/http" - "github.com/hay-kot/homebox/backend/internal/sys/validate" "github.com/hay-kot/httpkit/server" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" ) type LoginForm struct { diff --git a/backend/app/api/providers/local.go b/backend/app/api/providers/local.go index 991f51a6f..b60dbf2f4 100644 --- a/backend/app/api/providers/local.go +++ b/backend/app/api/providers/local.go @@ -3,7 +3,7 @@ package providers import ( "net/http" - "github.com/hay-kot/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" ) type LocalProvider struct { diff --git a/backend/app/api/routes.go b/backend/app/api/routes.go index de10942eb..386675e07 100644 --- a/backend/app/api/routes.go +++ b/backend/app/api/routes.go @@ -3,6 +3,7 @@ package main import ( "embed" "errors" + "fmt" "io" "mime" "net/http" @@ -10,14 +11,14 @@ import ( "path/filepath" "github.com/go-chi/chi/v5" - "github.com/hay-kot/homebox/backend/app/api/handlers/debughandlers" - v1 "github.com/hay-kot/homebox/backend/app/api/handlers/v1" - "github.com/hay-kot/homebox/backend/app/api/providers" - _ "github.com/hay-kot/homebox/backend/app/api/static/docs" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/repo" "github.com/hay-kot/httpkit/errchain" httpSwagger "github.com/swaggo/http-swagger/v2" // http-swagger middleware + "github.com/sysadminsmedia/homebox/backend/app/api/handlers/debughandlers" + v1 "github.com/sysadminsmedia/homebox/backend/app/api/handlers/v1" + "github.com/sysadminsmedia/homebox/backend/app/api/providers" + _ "github.com/sysadminsmedia/homebox/backend/app/api/static/docs" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" ) const prefix = "/api" @@ -47,8 +48,6 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR // ========================================================================= // API Version 1 - v1Base := v1.BaseURLFunc(prefix) - v1Ctrl := v1.NewControllerV1( a.services, a.repos, @@ -56,112 +55,117 @@ 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.Get(v1Base("/status"), chain.ToHandlerFunc(v1Ctrl.HandleBase(func() bool { return true }, v1.Build{ - Version: version, - Commit: commit, - BuildTime: buildTime, - }))) + r.Route(prefix+"/v1", func(r chi.Router) { + r.Get("/status", chain.ToHandlerFunc(v1Ctrl.HandleBase(func() bool { return true }, v1.Build{ + Version: version, + Commit: commit, + BuildTime: buildTime, + }))) - r.Get(v1Base("/currencies"), chain.ToHandlerFunc(v1Ctrl.HandleCurrency())) + r.Get("/currencies", chain.ToHandlerFunc(v1Ctrl.HandleCurrency())) - providers := []v1.AuthProvider{ - providers.NewLocalProvider(a.services.User), - } + providers := []v1.AuthProvider{ + providers.NewLocalProvider(a.services.User), + } - r.Post(v1Base("/users/register"), chain.ToHandlerFunc(v1Ctrl.HandleUserRegistration())) - r.Post(v1Base("/users/login"), chain.ToHandlerFunc(v1Ctrl.HandleAuthLogin(providers...))) + r.Post("/users/register", chain.ToHandlerFunc(v1Ctrl.HandleUserRegistration())) + r.Post("/users/login", chain.ToHandlerFunc(v1Ctrl.HandleAuthLogin(providers...))) - userMW := []errchain.Middleware{ - a.mwAuthToken, - a.mwRoles(RoleModeOr, authroles.RoleUser.String()), - } + userMW := []errchain.Middleware{ + a.mwAuthToken, + a.mwRoles(RoleModeOr, authroles.RoleUser.String()), + } - r.Get(v1Base("/ws/events"), chain.ToHandlerFunc(v1Ctrl.HandleCacheWS(), userMW...)) - r.Get(v1Base("/users/self"), chain.ToHandlerFunc(v1Ctrl.HandleUserSelf(), userMW...)) - r.Put(v1Base("/users/self"), chain.ToHandlerFunc(v1Ctrl.HandleUserSelfUpdate(), userMW...)) - r.Delete(v1Base("/users/self"), chain.ToHandlerFunc(v1Ctrl.HandleUserSelfDelete(), userMW...)) - r.Post(v1Base("/users/logout"), chain.ToHandlerFunc(v1Ctrl.HandleAuthLogout(), userMW...)) - r.Get(v1Base("/users/refresh"), chain.ToHandlerFunc(v1Ctrl.HandleAuthRefresh(), userMW...)) - r.Put(v1Base("/users/self/change-password"), chain.ToHandlerFunc(v1Ctrl.HandleUserSelfChangePassword(), userMW...)) - - r.Post(v1Base("/groups/invitations"), chain.ToHandlerFunc(v1Ctrl.HandleGroupInvitationsCreate(), userMW...)) - r.Get(v1Base("/groups/statistics"), chain.ToHandlerFunc(v1Ctrl.HandleGroupStatistics(), userMW...)) - r.Get(v1Base("/groups/statistics/purchase-price"), chain.ToHandlerFunc(v1Ctrl.HandleGroupStatisticsPriceOverTime(), userMW...)) - r.Get(v1Base("/groups/statistics/locations"), chain.ToHandlerFunc(v1Ctrl.HandleGroupStatisticsLocations(), userMW...)) - r.Get(v1Base("/groups/statistics/labels"), chain.ToHandlerFunc(v1Ctrl.HandleGroupStatisticsLabels(), userMW...)) - - // TODO: I don't like /groups being the URL for users - r.Get(v1Base("/groups"), chain.ToHandlerFunc(v1Ctrl.HandleGroupGet(), userMW...)) - r.Put(v1Base("/groups"), chain.ToHandlerFunc(v1Ctrl.HandleGroupUpdate(), userMW...)) - - r.Post(v1Base("/actions/ensure-asset-ids"), chain.ToHandlerFunc(v1Ctrl.HandleEnsureAssetID(), userMW...)) - r.Post(v1Base("/actions/zero-item-time-fields"), chain.ToHandlerFunc(v1Ctrl.HandleItemDateZeroOut(), userMW...)) - r.Post(v1Base("/actions/ensure-import-refs"), chain.ToHandlerFunc(v1Ctrl.HandleEnsureImportRefs(), userMW...)) - r.Post(v1Base("/actions/set-primary-photos"), chain.ToHandlerFunc(v1Ctrl.HandleSetPrimaryPhotos(), userMW...)) - - r.Get(v1Base("/locations"), chain.ToHandlerFunc(v1Ctrl.HandleLocationGetAll(), userMW...)) - r.Post(v1Base("/locations"), chain.ToHandlerFunc(v1Ctrl.HandleLocationCreate(), userMW...)) - r.Get(v1Base("/locations/tree"), chain.ToHandlerFunc(v1Ctrl.HandleLocationTreeQuery(), userMW...)) - r.Get(v1Base("/locations/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLocationGet(), userMW...)) - r.Put(v1Base("/locations/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLocationUpdate(), userMW...)) - r.Delete(v1Base("/locations/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLocationDelete(), userMW...)) - - r.Get(v1Base("/labels"), chain.ToHandlerFunc(v1Ctrl.HandleLabelsGetAll(), userMW...)) - r.Post(v1Base("/labels"), chain.ToHandlerFunc(v1Ctrl.HandleLabelsCreate(), userMW...)) - r.Get(v1Base("/labels/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLabelGet(), userMW...)) - r.Put(v1Base("/labels/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLabelUpdate(), userMW...)) - r.Delete(v1Base("/labels/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLabelDelete(), userMW...)) - - r.Get(v1Base("/items"), chain.ToHandlerFunc(v1Ctrl.HandleItemsGetAll(), userMW...)) - r.Post(v1Base("/items"), chain.ToHandlerFunc(v1Ctrl.HandleItemsCreate(), userMW...)) - r.Post(v1Base("/items/import"), chain.ToHandlerFunc(v1Ctrl.HandleItemsImport(), userMW...)) - r.Get(v1Base("/items/export"), chain.ToHandlerFunc(v1Ctrl.HandleItemsExport(), userMW...)) - r.Get(v1Base("/items/fields"), chain.ToHandlerFunc(v1Ctrl.HandleGetAllCustomFieldNames(), userMW...)) - r.Get(v1Base("/items/fields/values"), chain.ToHandlerFunc(v1Ctrl.HandleGetAllCustomFieldValues(), userMW...)) - - r.Get(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemGet(), userMW...)) - r.Get(v1Base("/items/{id}/path"), chain.ToHandlerFunc(v1Ctrl.HandleItemFullPath(), userMW...)) - r.Put(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemUpdate(), userMW...)) - r.Patch(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemPatch(), userMW...)) - r.Delete(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemDelete(), userMW...)) - - r.Post(v1Base("/items/{id}/attachments"), chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentCreate(), userMW...)) - r.Put(v1Base("/items/{id}/attachments/{attachment_id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentUpdate(), userMW...)) - r.Delete(v1Base("/items/{id}/attachments/{attachment_id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentDelete(), userMW...)) - - r.Get(v1Base("/items/{id}/maintenance"), chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceLogGet(), userMW...)) - r.Post(v1Base("/items/{id}/maintenance"), chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryCreate(), userMW...)) - r.Put(v1Base("/items/{id}/maintenance/{entry_id}"), chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryUpdate(), userMW...)) - r.Delete(v1Base("/items/{id}/maintenance/{entry_id}"), chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryDelete(), userMW...)) - - r.Get(v1Base("/assets/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleAssetGet(), userMW...)) - - // Notifiers - r.Get(v1Base("/notifiers"), chain.ToHandlerFunc(v1Ctrl.HandleGetUserNotifiers(), userMW...)) - r.Post(v1Base("/notifiers"), chain.ToHandlerFunc(v1Ctrl.HandleCreateNotifier(), userMW...)) - r.Put(v1Base("/notifiers/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleUpdateNotifier(), userMW...)) - r.Delete(v1Base("/notifiers/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleDeleteNotifier(), userMW...)) - r.Post(v1Base("/notifiers/test"), chain.ToHandlerFunc(v1Ctrl.HandlerNotifierTest(), userMW...)) - - // Asset-Like endpoints - assetMW := []errchain.Middleware{ - a.mwAuthToken, - a.mwRoles(RoleModeOr, authroles.RoleUser.String(), authroles.RoleAttachments.String()), - } + r.Get("/ws/events", chain.ToHandlerFunc(v1Ctrl.HandleCacheWS(), userMW...)) + r.Get("/users/self", chain.ToHandlerFunc(v1Ctrl.HandleUserSelf(), userMW...)) + r.Put("/users/self", chain.ToHandlerFunc(v1Ctrl.HandleUserSelfUpdate(), userMW...)) + r.Delete("/users/self", chain.ToHandlerFunc(v1Ctrl.HandleUserSelfDelete(), userMW...)) + r.Post("/users/logout", chain.ToHandlerFunc(v1Ctrl.HandleAuthLogout(), userMW...)) + r.Get("/users/refresh", chain.ToHandlerFunc(v1Ctrl.HandleAuthRefresh(), userMW...)) + r.Put("/users/self/change-password", chain.ToHandlerFunc(v1Ctrl.HandleUserSelfChangePassword(), userMW...)) + + r.Post("/groups/invitations", chain.ToHandlerFunc(v1Ctrl.HandleGroupInvitationsCreate(), userMW...)) + r.Get("/groups/statistics", chain.ToHandlerFunc(v1Ctrl.HandleGroupStatistics(), userMW...)) + r.Get("/groups/statistics/purchase-price", chain.ToHandlerFunc(v1Ctrl.HandleGroupStatisticsPriceOverTime(), userMW...)) + r.Get("/groups/statistics/locations", chain.ToHandlerFunc(v1Ctrl.HandleGroupStatisticsLocations(), userMW...)) + r.Get("/groups/statistics/labels", chain.ToHandlerFunc(v1Ctrl.HandleGroupStatisticsLabels(), userMW...)) + + // TODO: I don't like /groups being the URL for users + r.Get("/groups", chain.ToHandlerFunc(v1Ctrl.HandleGroupGet(), userMW...)) + r.Put("/groups", chain.ToHandlerFunc(v1Ctrl.HandleGroupUpdate(), userMW...)) + + r.Post("/actions/ensure-asset-ids", chain.ToHandlerFunc(v1Ctrl.HandleEnsureAssetID(), userMW...)) + r.Post("/actions/zero-item-time-fields", chain.ToHandlerFunc(v1Ctrl.HandleItemDateZeroOut(), userMW...)) + r.Post("/actions/ensure-import-refs", chain.ToHandlerFunc(v1Ctrl.HandleEnsureImportRefs(), userMW...)) + r.Post("/actions/set-primary-photos", chain.ToHandlerFunc(v1Ctrl.HandleSetPrimaryPhotos(), userMW...)) + + r.Get("/locations", chain.ToHandlerFunc(v1Ctrl.HandleLocationGetAll(), userMW...)) + r.Post("/locations", chain.ToHandlerFunc(v1Ctrl.HandleLocationCreate(), userMW...)) + r.Get("/locations/tree", chain.ToHandlerFunc(v1Ctrl.HandleLocationTreeQuery(), userMW...)) + r.Get("/locations/{id}", chain.ToHandlerFunc(v1Ctrl.HandleLocationGet(), userMW...)) + r.Put("/locations/{id}", chain.ToHandlerFunc(v1Ctrl.HandleLocationUpdate(), userMW...)) + r.Delete("/locations/{id}", chain.ToHandlerFunc(v1Ctrl.HandleLocationDelete(), userMW...)) + + r.Get("/labels", chain.ToHandlerFunc(v1Ctrl.HandleLabelsGetAll(), userMW...)) + r.Post("/labels", chain.ToHandlerFunc(v1Ctrl.HandleLabelsCreate(), userMW...)) + r.Get("/labels/{id}", chain.ToHandlerFunc(v1Ctrl.HandleLabelGet(), userMW...)) + r.Put("/labels/{id}", chain.ToHandlerFunc(v1Ctrl.HandleLabelUpdate(), userMW...)) + r.Delete("/labels/{id}", chain.ToHandlerFunc(v1Ctrl.HandleLabelDelete(), userMW...)) + + r.Get("/items", chain.ToHandlerFunc(v1Ctrl.HandleItemsGetAll(), userMW...)) + r.Post("/items", chain.ToHandlerFunc(v1Ctrl.HandleItemsCreate(), userMW...)) + r.Post("/items/import", chain.ToHandlerFunc(v1Ctrl.HandleItemsImport(), userMW...)) + r.Get("/items/export", chain.ToHandlerFunc(v1Ctrl.HandleItemsExport(), userMW...)) + r.Get("/items/fields", chain.ToHandlerFunc(v1Ctrl.HandleGetAllCustomFieldNames(), userMW...)) + r.Get("/items/fields/values", chain.ToHandlerFunc(v1Ctrl.HandleGetAllCustomFieldValues(), userMW...)) + + r.Get("/items/{id}", chain.ToHandlerFunc(v1Ctrl.HandleItemGet(), userMW...)) + r.Get("/items/{id}/path", chain.ToHandlerFunc(v1Ctrl.HandleItemFullPath(), userMW...)) + r.Put("/items/{id}", chain.ToHandlerFunc(v1Ctrl.HandleItemUpdate(), userMW...)) + r.Patch("/items/{id}", chain.ToHandlerFunc(v1Ctrl.HandleItemPatch(), userMW...)) + r.Delete("/items/{id}", chain.ToHandlerFunc(v1Ctrl.HandleItemDelete(), userMW...)) + + r.Post("/items/{id}/attachments", chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentCreate(), userMW...)) + r.Put("/items/{id}/attachments/{attachment_id}", chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentUpdate(), userMW...)) + r.Delete("/items/{id}/attachments/{attachment_id}", chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentDelete(), userMW...)) + + r.Get("/items/{id}/maintenance", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceLogGet(), userMW...)) + r.Post("/items/{id}/maintenance", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryCreate(), 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...)) + r.Put("/notifiers/{id}", chain.ToHandlerFunc(v1Ctrl.HandleUpdateNotifier(), userMW...)) + r.Delete("/notifiers/{id}", chain.ToHandlerFunc(v1Ctrl.HandleDeleteNotifier(), userMW...)) + r.Post("/notifiers/test", chain.ToHandlerFunc(v1Ctrl.HandlerNotifierTest(), userMW...)) + + // Asset-Like endpoints + assetMW := []errchain.Middleware{ + a.mwAuthToken, + a.mwRoles(RoleModeOr, authroles.RoleUser.String(), authroles.RoleAttachments.String()), + } - r.Get( - v1Base("/qrcode"), - chain.ToHandlerFunc(v1Ctrl.HandleGenerateQRCode(), assetMW...), - ) - r.Get( - v1Base("/items/{id}/attachments/{attachment_id}"), - chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentGet(), assetMW...), - ) + r.Get("/qrcode", chain.ToHandlerFunc(v1Ctrl.HandleGenerateQRCode(), assetMW...)) + r.Get( + "/items/{id}/attachments/{attachment_id}", + chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentGet(), assetMW...), + ) + + // Reporting Services + r.Get("/reporting/bill-of-materials", chain.ToHandlerFunc(v1Ctrl.HandleBillOfMaterialsExport(), userMW...)) - // Reporting Services - r.Get(v1Base("/reporting/bill-of-materials"), chain.ToHandlerFunc(v1Ctrl.HandleBillOfMaterialsExport(), userMW...)) + r.NotFound(http.NotFound) + }) r.NotFound(chain.ToHandlerFunc(notFoundHandler())) } diff --git a/backend/app/api/static/docs/docs.go b/backend/app/api/static/docs/docs.go index 7c9a74864..b5fa2dcb2 100644 --- a/backend/app/api/static/docs/docs.go +++ b/backend/app/api/static/docs/docs.go @@ -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": [ @@ -2476,6 +2540,9 @@ const docTemplate = `{ "parent": { "$ref": "#/definitions/repo.LocationSummary" }, + "totalPrice": { + "type": "number" + }, "updatedAt": { "type": "string" } @@ -2611,26 +2678,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" + }, + "id": { + "type": "string" + }, + "itemID": { + "type": "string" + }, + "itemName": { + "type": "string" + }, + "name": { + "type": "string" }, - "itemId": { + "scheduledDate": { "type": "string" } } }, + "repo.MaintenanceFilterStatus": { + "type": "string", + "enum": [ + "scheduled", + "completed", + "both" + ], + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ] + }, "repo.NotifierCreate": { "type": "object", "required": [ @@ -2672,6 +2762,10 @@ const docTemplate = `{ "updatedAt": { "type": "string" }, + "url": { + "description": "URL field is not exposed to the client", + "type": "string" + }, "userId": { "type": "string" } diff --git a/backend/app/api/static/docs/swagger.json b/backend/app/api/static/docs/swagger.json index b10c93ad1..12e556ceb 100644 --- a/backend/app/api/static/docs/swagger.json +++ b/backend/app/api/static/docs/swagger.json @@ -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": [ @@ -2469,6 +2533,9 @@ "parent": { "$ref": "#/definitions/repo.LocationSummary" }, + "totalPrice": { + "type": "number" + }, "updatedAt": { "type": "string" } @@ -2604,26 +2671,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" + }, + "id": { + "type": "string" + }, + "itemID": { + "type": "string" + }, + "itemName": { + "type": "string" + }, + "name": { + "type": "string" }, - "itemId": { + "scheduledDate": { "type": "string" } } }, + "repo.MaintenanceFilterStatus": { + "type": "string", + "enum": [ + "scheduled", + "completed", + "both" + ], + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ] + }, "repo.NotifierCreate": { "type": "object", "required": [ @@ -2665,6 +2755,10 @@ "updatedAt": { "type": "string" }, + "url": { + "description": "URL field is not exposed to the client", + "type": "string" + }, "userId": { "type": "string" } diff --git a/backend/app/api/static/docs/swagger.yaml b/backend/app/api/static/docs/swagger.yaml index dbb31e6c8..e663b6a64 100644 --- a/backend/app/api/static/docs/swagger.yaml +++ b/backend/app/api/static/docs/swagger.yaml @@ -390,6 +390,8 @@ definitions: type: string parent: $ref: '#/definitions/repo.LocationSummary' + totalPrice: + type: number updatedAt: type: string type: object @@ -479,19 +481,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: @@ -520,6 +539,9 @@ definitions: type: string updatedAt: type: string + url: + description: URL field is not exposed to the client + type: string userId: type: string type: object @@ -1217,18 +1239,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 @@ -1248,39 +1284,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: @@ -1581,6 +1585,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: diff --git a/backend/app/tools/migrations/main.go b/backend/app/tools/migrations/main.go index e53e7ba78..f0bd2c6d2 100644 --- a/backend/app/tools/migrations/main.go +++ b/backend/app/tools/migrations/main.go @@ -6,7 +6,7 @@ import ( "log" "os" - "github.com/hay-kot/homebox/backend/internal/data/ent/migrate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/migrate" atlas "ariga.io/atlas/sql/migrate" _ "ariga.io/atlas/sql/sqlite" diff --git a/backend/go.mod b/backend/go.mod index 8a0f9d953..b2f2d597b 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,31 +1,29 @@ -module github.com/hay-kot/homebox/backend +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.2.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/gorilla/schema v1.4.1 + 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.19.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 ( @@ -62,17 +60,17 @@ require ( github.com/swaggo/files/v2 v2.0.0 // indirect github.com/yeqown/reedsolomon v1.0.0 // indirect github.com/zclconf/go-cty v1.14.1 // indirect - golang.org/x/image v0.14.0 // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/image v0.18.0 // 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 ) diff --git a/backend/go.sum b/backend/go.sum index fec970645..f9a83abcd 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -1,9 +1,11 @@ -ariga.io/atlas v0.19.0 h1:gilVpXabeiGhGI9lj/rQURkXBemnloc41RGOtwVLNc4= -ariga.io/atlas v0.19.0/go.mod h1:uj3pm+hUTVN/X5yfdBexHlZv+1Xu5u5ZbZx7+CDavNU= 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= @@ -12,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= @@ -29,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= @@ -56,42 +58,37 @@ 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.2.1 h1:tjDxcmdb+siIqkTNoV+qRH2mjYdr2hHe5MKXbp61ziM= -github.com/gorilla/schema v1.2.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= +github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= +github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= 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.6 h1:BidC4UrkS7zRhoTdpKLeF8ODJPKcOZkJ2tk2t2ZIQjQ= -github.com/hay-kot/httpkit v0.0.6/go.mod h1:1s/OJwWRyH6tBtTw76jTp6kwBYvjswziXaokPQH7eKQ= -github.com/hay-kot/httpkit v0.0.7 h1:KxGi+MwXFavfFUfJEMpye5cnMef9TlFu3v7UZipUB8U= -github.com/hay-kot/httpkit v0.0.7/go.mod h1:AD22YluZrvBDxmtB3Pw2SOyp3A2PZqcmBZa0+COrhoU= -github.com/hay-kot/httpkit v0.0.8 h1:n+Z5z35YZcdD9cGwbnIPRbrgDw9LY6lqakH4zYr5z+A= -github.com/hay-kot/httpkit v0.0.8/go.mod h1:AD22YluZrvBDxmtB3Pw2SOyp3A2PZqcmBZa0+COrhoU= -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= @@ -119,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= @@ -141,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= @@ -153,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.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= -golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +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/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.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +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= @@ -202,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= diff --git a/backend/internal/core/currencies/currencies.json b/backend/internal/core/currencies/currencies.json index c7b263096..1af92cc11 100644 --- a/backend/internal/core/currencies/currencies.json +++ b/backend/internal/core/currencies/currencies.json @@ -1,638 +1,1610 @@ [ - { - "code": "USD", - "local": "United States", - "symbol": "$", - "name": "United States Dollar" - }, - { - "code": "AED", - "local": "United Arab Emirates", - "symbol": "د.إ", - "name": "United Arab Emirates Dirham" - }, - { - "code": "AFN", - "local": "Afghanistan", - "symbol": "؋", - "name": "Afghan Afghani" - }, - { - "code": "ALL", - "local": "Albania", - "symbol": "L", - "name": "Albanian Lek" - }, - { - "code": "AMD", - "local": "Armenia", - "symbol": "֏", - "name": "Armenian Dram" - }, - { - "code": "ANG", - "local": "Netherlands Antilles", - "symbol": "ƒ", - "name": "Netherlands Antillean Guilder" - }, - { - "code": "AOA", - "local": "Angola", - "symbol": "Kz", - "name": "Angolan Kwanza" - }, - { - "code": "ARS", - "local": "Argentina", - "symbol": "$", - "name": "Argentine Peso" - }, - { - "code": "AUD", - "local": "Australia", - "symbol": "A$", - "name": "Australian Dollar" - }, - { - "code": "AWG", - "local": "Aruba", - "symbol": "ƒ", - "name": "Aruban Florin" - }, - { - "code": "AZN", - "local": "Azerbaijan", - "symbol": "₼", - "name": "Azerbaijani Manat" - }, - { - "code": "BAM", - "local": "Bosnia and Herzegovina", - "symbol": "KM", - "name": "Bosnia and Herzegovina Convertible Mark" - }, - { - "code": "BBD", - "local": "Barbados", - "symbol": "Bds$", - "name": "Barbadian Dollar" - }, - { - "code": "BDT", - "local": "Bangladesh", - "symbol": "৳", - "name": "Bangladeshi Taka" - }, - { - "code": "BGN", - "local": "Bulgaria", - "symbol": "лв", - "name": "Bulgarian lev" - }, - { - "code": "BHD", - "local": "Bahrain", - "symbol": "ب.د", - "name": "Bahraini Dinar" - }, - { - "code": "BIF", - "local": "Burundi", - "symbol": "FBu", - "name": "Burundian Franc" - }, - { - "code": "BMD", - "local": "Bermuda", - "symbol": "BD$", - "name": "Bermudian Dollar" - }, - { - "code": "BND", - "local": "Brunei", - "symbol": "B$", - "name": "Brunei Dollar" - }, - { - "code": "BOB", - "local": "Bolivia", - "symbol": "Bs.", - "name": "Bolivian Boliviano" - }, - { - "code": "BRL", - "local": "Brazil", - "symbol": "R$", - "name": "Brazilian Real" - }, - { - "code": "BSD", - "local": "Bahamas", - "symbol": "B$", - "name": "Bahamian Dollar" - }, - { - "code": "BTN", - "local": "Bhutan", - "symbol": "Nu.", - "name": "Bhutanese Ngultrum" - }, - { - "code": "BWP", - "local": "Botswana", - "symbol": "P", - "name": "Botswana Pula" - }, - { - "code": "BYN", - "local": "Belarus", - "symbol": "Br", - "name": "Belarusian Ruble" - }, - { - "code": "BZD", - "local": "Belize", - "symbol": "BZ$", - "name": "Belize Dollar" - }, - { - "code": "CAD", - "local": "Canada", - "symbol": "C$", - "name": "Canadian Dollar" - }, - { - "code": "CDF", - "local": "Democratic Republic of the Congo", - "symbol": "FC", - "name": "Congolese Franc" - }, - { - "code": "CHF", - "local": "Switzerland", - "symbol": "CHF", - "name": "Swiss Franc" - }, - { - "code": "CLP", - "local": "Chile", - "symbol": "CL$", - "name": "Chilean Peso" - }, - { - "code": "CNY", - "local": "China", - "symbol": "¥", - "name": "Chinese Yuan" - }, - { - "code": "COP", - "local": "Colombia", - "symbol": "COL$", - "name": "Colombian Peso" - }, - { - "code": "CRC", - "local": "Costa Rica", - "symbol": "₡", - "name": "Costa Rican Colón" - }, - { - "code": "CUP", - "local": "Cuba", - "symbol": "₱", - "name": "Cuban Peso" - }, - { - "code": "CVE", - "local": "Cape Verde", - "symbol": "$", - "name": "Cape Verdean Escudo" - }, - { - "code": "CZK", - "local": "Czech Republic", - "symbol": "Kč", - "name": "Czech Koruna" - }, - { - "code": "DJF", - "local": "Djibouti", - "symbol": "Fdj", - "name": "Djiboutian Franc" - }, - { - "code": "DKK", - "local": "Denmark", - "symbol": "kr", - "name": "Danish Krone" - }, - { - "code": "DOP", - "local": "Dominican Republic", - "symbol": "RD$", - "name": "Dominican Peso" - }, - { - "code": "DZD", - "local": "Algeria", - "symbol": "د.ج", - "name": "Algerian Dinar" - }, - { - "code": "EGP", - "local": "Egypt", - "symbol": "£", - "name": "Egyptian Pound" - }, - { - "code": "ERN", - "local": "Eritrea", - "symbol": "Nfk", - "name": "Eritrean Nakfa" - }, - { - "code": "ETB", - "local": "Ethiopia", - "symbol": "Br", - "name": "Ethiopian Birr" - }, - { - "code": "EUR", - "local": "Eurozone", - "symbol": "€", - "name": "Euro" - }, - { - "code": "FJD", - "local": "Fiji", - "symbol": "FJ$", - "name": "Fijian Dollar" - }, - { - "code": "FKP", - "local": "Falkland Islands", - "symbol": "£", - "name": "Falkland Islands Pound" - }, - { - "code": "FOK", - "local": "Faroe Islands", - "symbol": "kr", - "name": "Faroese Króna" - }, - { - "code": "GBP", - "local": "United Kingdom", - "symbol": "£", - "name": "British Pound Sterling" - }, - { - "code": "GEL", - "local": "Georgia", - "symbol": "₾", - "name": "Georgian Lari" - }, - { - "code": "GGP", - "local": "Guernsey", - "symbol": "£", - "name": "Guernsey Pound" - }, - { - "code": "GHS", - "local": "Ghana", - "symbol": "GH₵", - "name": "Ghanaian Cedi" - }, - { - "code": "GIP", - "local": "Gibraltar", - "symbol": "£", - "name": "Gibraltar Pound" - }, - { - "code": "GMD", - "local": "Gambia", - "symbol": "D", - "name": "Gambian Dalasi" - }, - { - "code": "GNF", - "local": "Guinea", - "symbol": "FG", - "name": "Guinean Franc" - }, - { - "code": "GTQ", - "local": "Guatemala", - "symbol": "Q", - "name": "Guatemalan Quetzal" - }, - { - "code": "GYD", - "local": "Guyana", - "symbol": "GY$", - "name": "Guyanese Dollar" - }, - { - "code": "HKD", - "local": "Hong Kong", - "symbol": "HK$", - "name": "Hong Kong Dollar" - }, - { - "code": "HNL", - "local": "Honduras", - "symbol": "L", - "name": "Honduran Lempira" - }, - { - "code": "HRK", - "local": "Croatia", - "symbol": "kn", - "name": "Croatian Kuna" - }, - { - "code": "HTG", - "local": "Haiti", - "symbol": "G", - "name": "Haitian Gourde" - }, - { - "code": "HUF", - "local": "Hungary", - "symbol": "Ft", - "name": "Hungarian Forint" - }, - { - "code": "IDR", - "local": "Indonesia", - "symbol": "Rp", - "name": "Indonesian Rupiah" - }, - { - "code": "ILS", - "local": "Israel", - "symbol": "₪", - "name": "Israeli New Shekel" - }, - { - "code": "IMP", - "local": "Isle of Man", - "symbol": "£", - "name": "Manx Pound" - }, - { - "code": "INR", - "local": "India", - "symbol": "₹", - "name": "Indian Rupee" - }, - { - "code": "IQD", - "local": "Iraq", - "symbol": "ع.د", - "name": "Iraqi Dinar" - }, - { - "code": "IRR", - "local": "Iran", - "symbol": "﷼", - "name": "Iranian Rial" - }, - { - "code": "ISK", - "local": "Iceland", - "symbol": "kr", - "name": "Icelandic Króna" - }, - { - "code": "JEP", - "local": "Jersey", - "symbol": "£", - "name": "Jersey Pound" - }, - { - "code": "JMD", - "local": "Jamaica", - "symbol": "J$", - "name": "Jamaican Dollar" - }, - { - "code": "JOD", - "local": "Jordan", - "symbol": "د.ا", - "name": "Jordanian Dinar" - }, - { - "code": "JPY", - "local": "Japan", - "symbol": "¥", - "name": "Japanese Yen" - }, - { - "code": "KES", - "local": "Kenya", - "symbol": "KSh", - "name": "Kenyan Shilling" - }, - { - "code": "KGS", - "local": "Kyrgyzstan", - "symbol": "с", - "name": "Kyrgyzstani Som" - }, - { - "code": "KHR", - "local": "Cambodia", - "symbol": "៛", - "name": "Cambodian Riel" - }, - { - "code": "KID", - "local": "Kiribati", - "symbol": "$", - "name": "Kiribati Dollar" - }, - { - "code": "KMF", - "local": "Comoros", - "symbol": "CF", - "name": "Comorian Franc" - }, - { - "code": "KRW", - "local": "South Korea", - "symbol": "₩", - "name": "South Korean Won" - }, - { - "code": "KWD", - "local": "Kuwait", - "symbol": "د.ك", - "name": "Kuwaiti Dinar" - }, - { - "code": "KYD", - "local": "Cayman Islands", - "symbol": "CI$", - "name": "Cayman Islands Dollar" - }, - { - "code": "KZT", - "local": "Kazakhstan", - "symbol": "₸", - "name": "Kazakhstani Tenge" - }, - { - "code": "LAK", - "local": "Laos", - "symbol": "₭", - "name": "Lao Kip" - }, - { - "code": "LBP", - "local": "Lebanon", - "symbol": "ل.ل", - "name": "Lebanese Pound" - }, - { - "code": "LKR", - "local": "Sri Lanka", - "symbol": "₨", - "name": "Sri Lankan Rupee" - }, - { - "code": "LRD", - "local": "Liberia", - "symbol": "L$", - "name": "Liberian Dollar" - }, - { - "code": "LSL", - "local": "Lesotho", - "symbol": "M", - "name": "Lesotho Loti" - }, - { - "code": "LYD", - "local": "Libya", - "symbol": "ل.د", - "name": "Libyan Dinar" - }, - { - "code": "MAD", - "local": "Morocco", - "symbol": "د.م.", - "name": "Moroccan Dirham" - }, - { - "code": "MDL", - "local": "Moldova", - "symbol": "lei", - "name": "Moldovan Leu" - }, - { - "code": "MGA", - "local": "Madagascar", - "symbol": "Ar", - "name": "Malagasy Ariary" - }, - { - "code": "MKD", - "local": "North Macedonia", - "symbol": "ден", - "name": "Macedonian Denar" - }, - { - "code": "MMK", - "local": "Myanmar", - "symbol": "K", - "name": "Myanmar Kyat" - }, - { - "code": "MNT", - "local": "Mongolia", - "symbol": "₮", - "name": "Mongolian Tugrik" - }, - { - "code": "MOP", - "local": "Macau", - "symbol": "MOP$", - "name": "Macanese Pataca" - }, - { - "code": "MRU", - "local": "Mauritania", - "symbol": "UM", - "name": "Mauritanian Ouguiya" - }, - { - "code": "MUR", - "local": "Mauritius", - "symbol": "₨", - "name": "Mauritian Rupee" - }, - { - "code": "MVR", - "local": "Maldives", - "symbol": "Rf", - "name": "Maldivian Rufiyaa" - }, - { - "code": "MWK", - "local": "Malawi", - "symbol": "MK", - "name": "Malawian Kwacha" - }, - { - "code": "MXN", - "local": "Mexico", - "symbol": "Mex$", - "name": "Mexican Peso" - }, - { - "code": "MYR", - "local": "Malaysia", - "symbol": "RM", - "name": "Malaysian Ringgit" - }, - { - "code": "MZN", - "local": "Mozambique", - "symbol": "MT", - "name": "Mozambican Metical" - }, - { - "code": "NAD", - "local": "Namibia", - "symbol": "N$", - "name": "Namibian Dollar" - }, - { - "code": "NGN", - "local": "Nigeria", - "symbol": "₦", - "name": "Nigerian Naira" - }, - { - "code": "NIO", - "local": "Nicaragua", - "symbol": "C$", - "name": "Nicaraguan Córdoba" - }, - { - "code": "NOK", - "local": "Norway", - "symbol": "kr", - "name": "Norwegian Krone" - }, - { - "code": "UAH", - "local": "Ukraine", - "symbol": "₴", - "name": "Ukrainian Hryvnia" - } -] + { + "code": "SHP", + "local": "South Georgia", + "symbol": "£", + "name": "Saint Helena pound" + }, + { + "code": "XCD", + "local": "Grenada", + "symbol": "$", + "name": "Eastern Caribbean dollar" + }, + { + "code": "CHF", + "local": "Switzerland", + "symbol": "Fr.", + "name": "Swiss franc" + }, + { + "code": "SLL", + "local": "Sierra Leone", + "symbol": "Le", + "name": "Sierra Leonean leone" + }, + { + "code": "HUF", + "local": "Hungary", + "symbol": "Ft", + "name": "Hungarian forint" + }, + { + "code": "TWD", + "local": "Taiwan", + "symbol": "$", + "name": "New Taiwan dollar" + }, + { + "code": "XPF", + "local": "Wallis and Futuna", + "symbol": "₣", + "name": "CFP franc" + }, + { + "code": "BBD", + "local": "Barbados", + "symbol": "$", + "name": "Barbadian dollar" + }, + { + "code": "NZD", + "local": "Pitcairn Islands", + "symbol": "$", + "name": "New Zealand dollar" + }, + { + "code": "XOF", + "local": "Ivory Coast", + "symbol": "Fr", + "name": "West African CFA franc" + }, + { + "code": "TND", + "local": "Tunisia", + "symbol": "د.ت", + "name": "Tunisian dinar" + }, + { + "code": "EUR", + "local": "Italy", + "symbol": "€", + "name": "Euro" + }, + { + "code": "XOF", + "local": "Benin", + "symbol": "Fr", + "name": "West African CFA franc" + }, + { + "code": "IDR", + "local": "Indonesia", + "symbol": "Rp", + "name": "Indonesian rupiah" + }, + { + "code": "CVE", + "local": "Cape Verde", + "symbol": "Esc", + "name": "Cape Verdean escudo" + }, + { + "code": "XCD", + "local": "Saint Kitts and Nevis", + "symbol": "$", + "name": "Eastern Caribbean dollar" + }, + { + "code": "LAK", + "local": "Laos", + "symbol": "₭", + "name": "Lao kip" + }, + { + "code": "USD", + "local": "Caribbean Netherlands", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "UGX", + "local": "Uganda", + "symbol": "Sh", + "name": "Ugandan shilling" + }, + { + "code": "EUR", + "local": "Andorra", + "symbol": "€", + "name": "Euro" + }, + { + "code": "BIF", + "local": "Burundi", + "symbol": "Fr", + "name": "Burundian franc" + }, + { + "code": "ZAR", + "local": "South Africa", + "symbol": "R", + "name": "South African rand" + }, + { + "code": "EUR", + "local": "France", + "symbol": "€", + "name": "Euro" + }, + { + "code": "LYD", + "local": "Libya", + "symbol": "ل.د", + "name": "Libyan dinar" + }, + { + "code": "MXN", + "local": "Mexico", + "symbol": "$", + "name": "Mexican peso" + }, + { + "code": "XAF", + "local": "Gabon", + "symbol": "Fr", + "name": "Central African CFA franc" + }, + { + "code": "USD", + "local": "Northern Mariana Islands", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "MKD", + "local": "North Macedonia", + "symbol": "den", + "name": "denar" + }, + { + "code": "CNY", + "local": "China", + "symbol": "¥", + "name": "Chinese yuan" + }, + { + "code": "YER", + "local": "Yemen", + "symbol": "﷼", + "name": "Yemeni rial" + }, + { + "code": "EUR", + "local": "Saint Barthélemy", + "symbol": "€", + "name": "Euro" + }, + { + "code": "GBP", + "local": "Guernsey", + "symbol": "£", + "name": "British pound" + }, + { + "code": "GGP", + "local": "Guernsey", + "symbol": "£", + "name": "Guernsey pound" + }, + { + "code": "SBD", + "local": "Solomon Islands", + "symbol": "$", + "name": "Solomon Islands dollar" + }, + { + "code": "NOK", + "local": "Svalbard and Jan Mayen", + "symbol": "kr", + "name": "krone" + }, + { + "code": "DKK", + "local": "Faroe Islands", + "symbol": "kr", + "name": "Danish krone" + }, + { + "code": "FOK", + "local": "Faroe Islands", + "symbol": "kr", + "name": "Faroese króna" + }, + { + "code": "UZS", + "local": "Uzbekistan", + "symbol": "so'm", + "name": "Uzbekistani soʻm" + }, + { + "code": "EGP", + "local": "Egypt", + "symbol": "£", + "name": "Egyptian pound" + }, + { + "code": "XOF", + "local": "Senegal", + "symbol": "Fr", + "name": "West African CFA franc" + }, + { + "code": "LKR", + "local": "Sri Lanka", + "symbol": "Rs රු", + "name": "Sri Lankan rupee" + }, + { + "code": "EGP", + "local": "Palestine", + "symbol": "E£", + "name": "Egyptian pound" + }, + { + "code": "ILS", + "local": "Palestine", + "symbol": "₪", + "name": "Israeli new shekel" + }, + { + "code": "JOD", + "local": "Palestine", + "symbol": "JD", + "name": "Jordanian dinar" + }, + { + "code": "BDT", + "local": "Bangladesh", + "symbol": "৳", + "name": "Bangladeshi taka" + }, + { + "code": "PEN", + "local": "Peru", + "symbol": "S/ ", + "name": "Peruvian sol" + }, + { + "code": "SGD", + "local": "Singapore", + "symbol": "$", + "name": "Singapore dollar" + }, + { + "code": "TRY", + "local": "Turkey", + "symbol": "₺", + "name": "Turkish lira" + }, + { + "code": "AFN", + "local": "Afghanistan", + "symbol": "؋", + "name": "Afghan afghani" + }, + { + "code": "AWG", + "local": "Aruba", + "symbol": "ƒ", + "name": "Aruban florin" + }, + { + "code": "CKD", + "local": "Cook Islands", + "symbol": "$", + "name": "Cook Islands dollar" + }, + { + "code": "NZD", + "local": "Cook Islands", + "symbol": "$", + "name": "New Zealand dollar" + }, + { + "code": "GBP", + "local": "United Kingdom", + "symbol": "£", + "name": "British pound" + }, + { + "code": "ZMW", + "local": "Zambia", + "symbol": "ZK", + "name": "Zambian kwacha" + }, + { + "code": "EUR", + "local": "Finland", + "symbol": "€", + "name": "Euro" + }, + { + "code": "XOF", + "local": "Niger", + "symbol": "Fr", + "name": "West African CFA franc" + }, + { + "code": "AUD", + "local": "Christmas Island", + "symbol": "$", + "name": "Australian dollar" + }, + { + "code": "NZD", + "local": "Tokelau", + "symbol": "$", + "name": "New Zealand dollar" + }, + { + "code": "XOF", + "local": "Guinea-Bissau", + "symbol": "Fr", + "name": "West African CFA franc" + }, + { + "code": "AZN", + "local": "Azerbaijan", + "symbol": "₼", + "name": "Azerbaijani manat" + }, + { + "code": "EUR", + "local": "Réunion", + "symbol": "€", + "name": "Euro" + }, + { + "code": "DJF", + "local": "Djibouti", + "symbol": "Fr", + "name": "Djiboutian franc" + }, + { + "code": "KPW", + "local": "North Korea", + "symbol": "₩", + "name": "North Korean won" + }, + { + "code": "MUR", + "local": "Mauritius", + "symbol": "₨", + "name": "Mauritian rupee" + }, + { + "code": "XCD", + "local": "Montserrat", + "symbol": "$", + "name": "Eastern Caribbean dollar" + }, + { + "code": "USD", + "local": "United States Virgin Islands", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "COP", + "local": "Colombia", + "symbol": "$", + "name": "Colombian peso" + }, + { + "code": "EUR", + "local": "Greece", + "symbol": "€", + "name": "Euro" + }, + { + "code": "EUR", + "local": "Croatia", + "symbol": "€", + "name": "Euro" + }, + { + "code": "MAD", + "local": "Morocco", + "symbol": "د.م.", + "name": "Moroccan dirham" + }, + { + "code": "DZD", + "local": "Algeria", + "symbol": "د.ج", + "name": "Algerian dinar" + }, + { + "code": "EUR", + "local": "Netherlands", + "symbol": "€", + "name": "Euro" + }, + { + "code": "SDG", + "local": "Sudan", + "symbol": "ج.س", + "name": "Sudanese pound" + }, + { + "code": "FJD", + "local": "Fiji", + "symbol": "$", + "name": "Fijian dollar" + }, + { + "code": "CHF", + "local": "Liechtenstein", + "symbol": "Fr", + "name": "Swiss franc" + }, + { + "code": "NPR", + "local": "Nepal", + "symbol": "₨", + "name": "Nepalese rupee" + }, + { + "code": "USD", + "local": "Puerto Rico", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "GEL", + "local": "Georgia", + "symbol": "₾", + "name": "lari" + }, + { + "code": "PKR", + "local": "Pakistan", + "symbol": "₨", + "name": "Pakistani rupee" + }, + { + "code": "EUR", + "local": "Monaco", + "symbol": "€", + "name": "Euro" + }, + { + "code": "BWP", + "local": "Botswana", + "symbol": "P", + "name": "Botswana pula" + }, + { + "code": "LBP", + "local": "Lebanon", + "symbol": "ل.ل", + "name": "Lebanese pound" + }, + { + "code": "PGK", + "local": "Papua New Guinea", + "symbol": "K", + "name": "Papua New Guinean kina" + }, + { + "code": "EUR", + "local": "Mayotte", + "symbol": "€", + "name": "Euro" + }, + { + "code": "DOP", + "local": "Dominican Republic", + "symbol": "$", + "name": "Dominican peso" + }, + { + "code": "AUD", + "local": "Norfolk Island", + "symbol": "$", + "name": "Australian dollar" + }, + { + "code": "QAR", + "local": "Qatar", + "symbol": "ر.ق", + "name": "Qatari riyal" + }, + { + "code": "MGA", + "local": "Madagascar", + "symbol": "Ar", + "name": "Malagasy ariary" + }, + { + "code": "INR", + "local": "India", + "symbol": "₹", + "name": "Indian rupee" + }, + { + "code": "SYP", + "local": "Syria", + "symbol": "£", + "name": "Syrian pound" + }, + { + "code": "EUR", + "local": "Montenegro", + "symbol": "€", + "name": "Euro" + }, + { + "code": "SZL", + "local": "Eswatini", + "symbol": "L", + "name": "Swazi lilangeni" + }, + { + "code": "ZAR", + "local": "Eswatini", + "symbol": "R", + "name": "South African rand" + }, + { + "code": "PYG", + "local": "Paraguay", + "symbol": "₲", + "name": "Paraguayan guaraní" + }, + { + "code": "USD", + "local": "El Salvador", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "UAH", + "local": "Ukraine", + "symbol": "₴", + "name": "Ukrainian hryvnia" + }, + { + "code": "GBP", + "local": "Isle of Man", + "symbol": "£", + "name": "British pound" + }, + { + "code": "IMP", + "local": "Isle of Man", + "symbol": "£", + "name": "Manx pound" + }, + { + "code": "NAD", + "local": "Namibia", + "symbol": "$", + "name": "Namibian dollar" + }, + { + "code": "ZAR", + "local": "Namibia", + "symbol": "R", + "name": "South African rand" + }, + { + "code": "AED", + "local": "United Arab Emirates", + "symbol": "د.إ", + "name": "United Arab Emirates dirham" + }, + { + "code": "BGN", + "local": "Bulgaria", + "symbol": "лв", + "name": "Bulgarian lev" + }, + { + "code": "DKK", + "local": "Greenland", + "symbol": "kr.", + "name": "krone" + }, + { + "code": "EUR", + "local": "Germany", + "symbol": "€", + "name": "Euro" + }, + { + "code": "KHR", + "local": "Cambodia", + "symbol": "៛", + "name": "Cambodian riel" + }, + { + "code": "USD", + "local": "Cambodia", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "IQD", + "local": "Iraq", + "symbol": "ع.د", + "name": "Iraqi dinar" + }, + { + "code": "EUR", + "local": "French Southern and Antarctic Lands", + "symbol": "€", + "name": "Euro" + }, + { + "code": "SEK", + "local": "Sweden", + "symbol": "kr", + "name": "Swedish krona" + }, + { + "code": "CUC", + "local": "Cuba", + "symbol": "$", + "name": "Cuban convertible peso" + }, + { + "code": "CUP", + "local": "Cuba", + "symbol": "$", + "name": "Cuban peso" + }, + { + "code": "KGS", + "local": "Kyrgyzstan", + "symbol": "с", + "name": "Kyrgyzstani som" + }, + { + "code": "RUB", + "local": "Russia", + "symbol": "₽", + "name": "Russian ruble" + }, + { + "code": "MYR", + "local": "Malaysia", + "symbol": "RM", + "name": "Malaysian ringgit" + }, + { + "code": "STN", + "local": "São Tomé and Príncipe", + "symbol": "Db", + "name": "São Tomé and Príncipe dobra" + }, + { + "code": "EUR", + "local": "Cyprus", + "symbol": "€", + "name": "Euro" + }, + { + "code": "CAD", + "local": "Canada", + "symbol": "$", + "name": "Canadian dollar" + }, + { + "code": "MWK", + "local": "Malawi", + "symbol": "MK", + "name": "Malawian kwacha" + }, + { + "code": "SAR", + "local": "Saudi Arabia", + "symbol": "ر.س", + "name": "Saudi riyal" + }, + { + "code": "BAM", + "local": "Bosnia and Herzegovina", + "symbol": "KM", + "name": "Bosnia and Herzegovina convertible mark" + }, + { + "code": "ETB", + "local": "Ethiopia", + "symbol": "Br", + "name": "Ethiopian birr" + }, + { + "code": "EUR", + "local": "Spain", + "symbol": "€", + "name": "Euro" + }, + { + "code": "EUR", + "local": "Slovenia", + "symbol": "€", + "name": "Euro" + }, + { + "code": "OMR", + "local": "Oman", + "symbol": "ر.ع.", + "name": "Omani rial" + }, + { + "code": "EUR", + "local": "Saint Pierre and Miquelon", + "symbol": "€", + "name": "Euro" + }, + { + "code": "MOP", + "local": "Macau", + "symbol": "P", + "name": "Macanese pataca" + }, + { + "code": "EUR", + "local": "San Marino", + "symbol": "€", + "name": "Euro" + }, + { + "code": "LSL", + "local": "Lesotho", + "symbol": "L", + "name": "Lesotho loti" + }, + { + "code": "ZAR", + "local": "Lesotho", + "symbol": "R", + "name": "South African rand" + }, + { + "code": "USD", + "local": "Marshall Islands", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "ANG", + "local": "Sint Maarten", + "symbol": "ƒ", + "name": "Netherlands Antillean guilder" + }, + { + "code": "ISK", + "local": "Iceland", + "symbol": "kr", + "name": "Icelandic króna" + }, + { + "code": "EUR", + "local": "Luxembourg", + "symbol": "€", + "name": "Euro" + }, + { + "code": "ARS", + "local": "Argentina", + "symbol": "$", + "name": "Argentine peso" + }, + { + "code": "USD", + "local": "Turks and Caicos Islands", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "AUD", + "local": "Nauru", + "symbol": "$", + "name": "Australian dollar" + }, + { + "code": "AUD", + "local": "Cocos (Keeling) Islands", + "symbol": "$", + "name": "Australian dollar" + }, + { + "code": "DZD", + "local": "Western Sahara", + "symbol": "دج", + "name": "Algerian dinar" + }, + { + "code": "MAD", + "local": "Western Sahara", + "symbol": "DH", + "name": "Moroccan dirham" + }, + { + "code": "MRU", + "local": "Western Sahara", + "symbol": "UM", + "name": "Mauritanian ouguiya" + }, + { + "code": "XCD", + "local": "Dominica", + "symbol": "$", + "name": "Eastern Caribbean dollar" + }, + { + "code": "CRC", + "local": "Costa Rica", + "symbol": "₡", + "name": "Costa Rican colón" + }, + { + "code": "AUD", + "local": "Australia", + "symbol": "$", + "name": "Australian dollar" + }, + { + "code": "THB", + "local": "Thailand", + "symbol": "฿", + "name": "Thai baht" + }, + { + "code": "HTG", + "local": "Haiti", + "symbol": "G", + "name": "Haitian gourde" + }, + { + "code": "AUD", + "local": "Tuvalu", + "symbol": "$", + "name": "Australian dollar" + }, + { + "code": "TVD", + "local": "Tuvalu", + "symbol": "$", + "name": "Tuvaluan dollar" + }, + { + "code": "HNL", + "local": "Honduras", + "symbol": "L", + "name": "Honduran lempira" + }, + { + "code": "XAF", + "local": "Equatorial Guinea", + "symbol": "Fr", + "name": "Central African CFA franc" + }, + { + "code": "XCD", + "local": "Saint Lucia", + "symbol": "$", + "name": "Eastern Caribbean dollar" + }, + { + "code": "XPF", + "local": "French Polynesia", + "symbol": "₣", + "name": "CFP franc" + }, + { + "code": "BYN", + "local": "Belarus", + "symbol": "Br", + "name": "Belarusian ruble" + }, + { + "code": "EUR", + "local": "Latvia", + "symbol": "€", + "name": "Euro" + }, + { + "code": "USD", + "local": "Palau", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "EUR", + "local": "Guadeloupe", + "symbol": "€", + "name": "Euro" + }, + { + "code": "PHP", + "local": "Philippines", + "symbol": "₱", + "name": "Philippine peso" + }, + { + "code": "GIP", + "local": "Gibraltar", + "symbol": "£", + "name": "Gibraltar pound" + }, + { + "code": "DKK", + "local": "Denmark", + "symbol": "kr", + "name": "Danish krone" + }, + { + "code": "XAF", + "local": "Cameroon", + "symbol": "Fr", + "name": "Central African CFA franc" + }, + { + "code": "GNF", + "local": "Guinea", + "symbol": "Fr", + "name": "Guinean franc" + }, + { + "code": "BHD", + "local": "Bahrain", + "symbol": ".د.ب", + "name": "Bahraini dinar" + }, + { + "code": "SRD", + "local": "Suriname", + "symbol": "$", + "name": "Surinamese dollar" + }, + { + "code": "CDF", + "local": "DR Congo", + "symbol": "FC", + "name": "Congolese franc" + }, + { + "code": "SOS", + "local": "Somalia", + "symbol": "Sh", + "name": "Somali shilling" + }, + { + "code": "CZK", + "local": "Czechia", + "symbol": "Kč", + "name": "Czech koruna" + }, + { + "code": "XPF", + "local": "New Caledonia", + "symbol": "₣", + "name": "CFP franc" + }, + { + "code": "VUV", + "local": "Vanuatu", + "symbol": "Vt", + "name": "Vanuatu vatu" + }, + { + "code": "GBP", + "local": "Saint Helena, Ascension and Tristan da Cunha", + "symbol": "£", + "name": "Pound sterling" + }, + { + "code": "SHP", + "local": "Saint Helena, Ascension and Tristan da Cunha", + "symbol": "£", + "name": "Saint Helena pound" + }, + { + "code": "XOF", + "local": "Togo", + "symbol": "Fr", + "name": "West African CFA franc" + }, + { + "code": "USD", + "local": "British Virgin Islands", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "KES", + "local": "Kenya", + "symbol": "Sh", + "name": "Kenyan shilling" + }, + { + "code": "NZD", + "local": "Niue", + "symbol": "$", + "name": "New Zealand dollar" + }, + { + "code": "RWF", + "local": "Rwanda", + "symbol": "Fr", + "name": "Rwandan franc" + }, + { + "code": "EUR", + "local": "Estonia", + "symbol": "€", + "name": "Euro" + }, + { + "code": "RON", + "local": "Romania", + "symbol": "lei", + "name": "Romanian leu" + }, + { + "code": "TTD", + "local": "Trinidad and Tobago", + "symbol": "$", + "name": "Trinidad and Tobago dollar" + }, + { + "code": "GYD", + "local": "Guyana", + "symbol": "$", + "name": "Guyanese dollar" + }, + { + "code": "USD", + "local": "Timor-Leste", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "VND", + "local": "Vietnam", + "symbol": "₫", + "name": "Vietnamese đồng" + }, + { + "code": "UYU", + "local": "Uruguay", + "symbol": "$", + "name": "Uruguayan peso" + }, + { + "code": "EUR", + "local": "Vatican City", + "symbol": "€", + "name": "Euro" + }, + { + "code": "HKD", + "local": "Hong Kong", + "symbol": "$", + "name": "Hong Kong dollar" + }, + { + "code": "EUR", + "local": "Austria", + "symbol": "€", + "name": "Euro" + }, + { + "code": "XCD", + "local": "Antigua and Barbuda", + "symbol": "$", + "name": "Eastern Caribbean dollar" + }, + { + "code": "TMT", + "local": "Turkmenistan", + "symbol": "m", + "name": "Turkmenistan manat" + }, + { + "code": "MZN", + "local": "Mozambique", + "symbol": "MT", + "name": "Mozambican metical" + }, + { + "code": "PAB", + "local": "Panama", + "symbol": "B/.", + "name": "Panamanian balboa" + }, + { + "code": "USD", + "local": "Panama", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "USD", + "local": "Micronesia", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "EUR", + "local": "Ireland", + "symbol": "€", + "name": "Euro" + }, + { + "code": "ANG", + "local": "Curaçao", + "symbol": "ƒ", + "name": "Netherlands Antillean guilder" + }, + { + "code": "EUR", + "local": "French Guiana", + "symbol": "€", + "name": "Euro" + }, + { + "code": "NOK", + "local": "Norway", + "symbol": "kr", + "name": "Norwegian krone" + }, + { + "code": "EUR", + "local": "Åland Islands", + "symbol": "€", + "name": "Euro" + }, + { + "code": "XAF", + "local": "Central African Republic", + "symbol": "Fr", + "name": "Central African CFA franc" + }, + { + "code": "XOF", + "local": "Burkina Faso", + "symbol": "Fr", + "name": "West African CFA franc" + }, + { + "code": "ERN", + "local": "Eritrea", + "symbol": "Nfk", + "name": "Eritrean nakfa" + }, + { + "code": "TZS", + "local": "Tanzania", + "symbol": "Sh", + "name": "Tanzanian shilling" + }, + { + "code": "KRW", + "local": "South Korea", + "symbol": "₩", + "name": "South Korean won" + }, + { + "code": "JOD", + "local": "Jordan", + "symbol": "د.ا", + "name": "Jordanian dinar" + }, + { + "code": "MRU", + "local": "Mauritania", + "symbol": "UM", + "name": "Mauritanian ouguiya" + }, + { + "code": "EUR", + "local": "Lithuania", + "symbol": "€", + "name": "Euro" + }, + { + "code": "USD", + "local": "United States Minor Outlying Islands", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "EUR", + "local": "Slovakia", + "symbol": "€", + "name": "Euro" + }, + { + "code": "AOA", + "local": "Angola", + "symbol": "Kz", + "name": "Angolan kwanza" + }, + { + "code": "KZT", + "local": "Kazakhstan", + "symbol": "₸", + "name": "Kazakhstani tenge" + }, + { + "code": "MDL", + "local": "Moldova", + "symbol": "L", + "name": "Moldovan leu" + }, + { + "code": "XOF", + "local": "Mali", + "symbol": "Fr", + "name": "West African CFA franc" + }, + { + "code": "FKP", + "local": "Falkland Islands", + "symbol": "£", + "name": "Falkland Islands pound" + }, + { + "code": "AMD", + "local": "Armenia", + "symbol": "֏", + "name": "Armenian dram" + }, + { + "code": "WST", + "local": "Samoa", + "symbol": "T", + "name": "Samoan tālā" + }, + { + "code": "GBP", + "local": "Jersey", + "symbol": "£", + "name": "British pound" + }, + { + "code": "JEP", + "local": "Jersey", + "symbol": "£", + "name": "Jersey pound" + }, + { + "code": "JPY", + "local": "Japan", + "symbol": "¥", + "name": "Japanese yen" + }, + { + "code": "BOB", + "local": "Bolivia", + "symbol": "Bs.", + "name": "Bolivian boliviano" + }, + { + "code": "CLP", + "local": "Chile", + "symbol": "$", + "name": "Chilean peso" + }, + { + "code": "USD", + "local": "United States", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "XCD", + "local": "Saint Vincent and the Grenadines", + "symbol": "$", + "name": "Eastern Caribbean dollar" + }, + { + "code": "BMD", + "local": "Bermuda", + "symbol": "$", + "name": "Bermudian dollar" + }, + { + "code": "SCR", + "local": "Seychelles", + "symbol": "₨", + "name": "Seychellois rupee" + }, + { + "code": "USD", + "local": "British Indian Ocean Territory", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "GTQ", + "local": "Guatemala", + "symbol": "Q", + "name": "Guatemalan quetzal" + }, + { + "code": "USD", + "local": "Ecuador", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "EUR", + "local": "Martinique", + "symbol": "€", + "name": "Euro" + }, + { + "code": "TJS", + "local": "Tajikistan", + "symbol": "ЅМ", + "name": "Tajikistani somoni" + }, + { + "code": "EUR", + "local": "Malta", + "symbol": "€", + "name": "Euro" + }, + { + "code": "GMD", + "local": "Gambia", + "symbol": "D", + "name": "dalasi" + }, + { + "code": "NGN", + "local": "Nigeria", + "symbol": "₦", + "name": "Nigerian naira" + }, + { + "code": "BSD", + "local": "Bahamas", + "symbol": "$", + "name": "Bahamian dollar" + }, + { + "code": "USD", + "local": "Bahamas", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "EUR", + "local": "Kosovo", + "symbol": "€", + "name": "Euro" + }, + { + "code": "KWD", + "local": "Kuwait", + "symbol": "د.ك", + "name": "Kuwaiti dinar" + }, + { + "code": "MVR", + "local": "Maldives", + "symbol": ".ރ", + "name": "Maldivian rufiyaa" + }, + { + "code": "SSP", + "local": "South Sudan", + "symbol": "£", + "name": "South Sudanese pound" + }, + { + "code": "IRR", + "local": "Iran", + "symbol": "﷼", + "name": "Iranian rial" + }, + { + "code": "ALL", + "local": "Albania", + "symbol": "L", + "name": "Albanian lek" + }, + { + "code": "BRL", + "local": "Brazil", + "symbol": "R$", + "name": "Brazilian real" + }, + { + "code": "RSD", + "local": "Serbia", + "symbol": "дин.", + "name": "Serbian dinar" + }, + { + "code": "BZD", + "local": "Belize", + "symbol": "$", + "name": "Belize dollar" + }, + { + "code": "MMK", + "local": "Myanmar", + "symbol": "Ks", + "name": "Burmese kyat" + }, + { + "code": "BTN", + "local": "Bhutan", + "symbol": "Nu.", + "name": "Bhutanese ngultrum" + }, + { + "code": "INR", + "local": "Bhutan", + "symbol": "₹", + "name": "Indian rupee" + }, + { + "code": "VES", + "local": "Venezuela", + "symbol": "Bs.S.", + "name": "Venezuelan bolívar soberano" + }, + { + "code": "LRD", + "local": "Liberia", + "symbol": "$", + "name": "Liberian dollar" + }, + { + "code": "JMD", + "local": "Jamaica", + "symbol": "$", + "name": "Jamaican dollar" + }, + { + "code": "PLN", + "local": "Poland", + "symbol": "zł", + "name": "Polish złoty" + }, + { + "code": "KYD", + "local": "Cayman Islands", + "symbol": "$", + "name": "Cayman Islands dollar" + }, + { + "code": "BND", + "local": "Brunei", + "symbol": "$", + "name": "Brunei dollar" + }, + { + "code": "SGD", + "local": "Brunei", + "symbol": "$", + "name": "Singapore dollar" + }, + { + "code": "KMF", + "local": "Comoros", + "symbol": "Fr", + "name": "Comorian franc" + }, + { + "code": "USD", + "local": "Guam", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "TOP", + "local": "Tonga", + "symbol": "T$", + "name": "Tongan paʻanga" + }, + { + "code": "AUD", + "local": "Kiribati", + "symbol": "$", + "name": "Australian dollar" + }, + { + "code": "KID", + "local": "Kiribati", + "symbol": "$", + "name": "Kiribati dollar" + }, + { + "code": "GHS", + "local": "Ghana", + "symbol": "₵", + "name": "Ghanaian cedi" + }, + { + "code": "XAF", + "local": "Chad", + "symbol": "Fr", + "name": "Central African CFA franc" + }, + { + "code": "ZWL", + "local": "Zimbabwe", + "symbol": "$", + "name": "Zimbabwean dollar" + }, + { + "code": "EUR", + "local": "Saint Martin", + "symbol": "€", + "name": "Euro" + }, + { + "code": "MNT", + "local": "Mongolia", + "symbol": "₮", + "name": "Mongolian tögrög" + }, + { + "code": "EUR", + "local": "Portugal", + "symbol": "€", + "name": "Euro" + }, + { + "code": "USD", + "local": "American Samoa", + "symbol": "$", + "name": "United States dollar" + }, + { + "code": "XAF", + "local": "Republic of the Congo", + "symbol": "Fr", + "name": "Central African CFA franc" + }, + { + "code": "EUR", + "local": "Belgium", + "symbol": "€", + "name": "Euro" + }, + { + "code": "ILS", + "local": "Israel", + "symbol": "₪", + "name": "Israeli new shekel" + }, + { + "code": "NZD", + "local": "New Zealand", + "symbol": "$", + "name": "New Zealand dollar" + }, + { + "code": "NIO", + "local": "Nicaragua", + "symbol": "C$", + "name": "Nicaraguan córdoba" + }, + { + "code": "XCD", + "local": "Anguilla", + "symbol": "$", + "name": "Eastern Caribbean dollar" + } +] \ No newline at end of file diff --git a/backend/internal/core/services/all.go b/backend/internal/core/services/all.go index 3c03a4e97..87cd3feb2 100644 --- a/backend/internal/core/services/all.go +++ b/backend/internal/core/services/all.go @@ -2,8 +2,8 @@ package services import ( - "github.com/hay-kot/homebox/backend/internal/core/currencies" - "github.com/hay-kot/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/core/currencies" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" ) type AllServices struct { diff --git a/backend/internal/core/services/contexts.go b/backend/internal/core/services/contexts.go index d82dcfa7f..096b38664 100644 --- a/backend/internal/core/services/contexts.go +++ b/backend/internal/core/services/contexts.go @@ -4,7 +4,7 @@ import ( "context" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" ) type contextKeys struct { diff --git a/backend/internal/core/services/contexts_test.go b/backend/internal/core/services/contexts_test.go index 8b7dfa44c..b489b4873 100644 --- a/backend/internal/core/services/contexts_test.go +++ b/backend/internal/core/services/contexts_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/repo" "github.com/stretchr/testify/assert" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" ) func Test_SetAuthContext(t *testing.T) { diff --git a/backend/internal/core/services/main_test.go b/backend/internal/core/services/main_test.go index ecb07b0b3..f2e35bb4f 100644 --- a/backend/internal/core/services/main_test.go +++ b/backend/internal/core/services/main_test.go @@ -6,12 +6,12 @@ import ( "os" "testing" - "github.com/hay-kot/homebox/backend/internal/core/currencies" - "github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/pkgs/faker" _ "github.com/mattn/go-sqlite3" + "github.com/sysadminsmedia/homebox/backend/internal/core/currencies" + "github.com/sysadminsmedia/homebox/backend/internal/core/services/reporting/eventbus" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/pkgs/faker" ) var ( @@ -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)) } diff --git a/backend/internal/core/services/reporting/bill_of_materials.go b/backend/internal/core/services/reporting/bill_of_materials.go index 4147d4b05..e6873d702 100644 --- a/backend/internal/core/services/reporting/bill_of_materials.go +++ b/backend/internal/core/services/reporting/bill_of_materials.go @@ -2,8 +2,8 @@ package reporting import ( "github.com/gocarina/gocsv" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/data/types" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/data/types" ) // ================================================================================================= @@ -20,9 +20,9 @@ type BillOfMaterialsEntry struct { TotalPrice float64 `csv:"Total Price"` } -// BillOfMaterialsTSV returns a byte slice of the Bill of Materials for a given GID in TSV format +// BillOfMaterialsCSV returns a byte slice of the Bill of Materials for a given GID in CSV format // See BillOfMaterialsEntry for the format of the output -func BillOfMaterialsTSV(entities []repo.ItemOut) ([]byte, error) { +func BillOfMaterialsCSV(entities []repo.ItemOut) ([]byte, error) { bomEntries := make([]BillOfMaterialsEntry, len(entities)) for i, entity := range entities { bomEntries[i] = BillOfMaterialsEntry{ diff --git a/backend/internal/core/services/reporting/io_row.go b/backend/internal/core/services/reporting/io_row.go index c80e00ddf..1e3415b49 100644 --- a/backend/internal/core/services/reporting/io_row.go +++ b/backend/internal/core/services/reporting/io_row.go @@ -3,8 +3,8 @@ package reporting import ( "strings" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/data/types" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/data/types" ) type ExportItemFields struct { @@ -12,12 +12,13 @@ type ExportItemFields struct { Value string } -type ExportTSVRow struct { +type ExportCSVRow struct { ImportRef string `csv:"HB.import_ref"` Location LocationString `csv:"HB.location"` 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"` diff --git a/backend/internal/core/services/reporting/io_sheet.go b/backend/internal/core/services/reporting/io_sheet.go index 5877f3e89..1db37bc67 100644 --- a/backend/internal/core/services/reporting/io_sheet.go +++ b/backend/internal/core/services/reporting/io_sheet.go @@ -10,21 +10,21 @@ import ( "strings" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/data/types" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/data/types" ) // IOSheet is the representation of a CSV/TSV sheet that is used for importing/exporting // items from homebox. It is used to read/write the data from/to a CSV/TSV file given // the standard format of the file. // -// See ExportTSVRow for the format of the data in the sheet. +// See ExportCSVRow for the format of the data in the sheet. type IOSheet struct { headers []string custom []int index map[string]int - Rows []ExportTSVRow + Rows []ExportCSVRow } func (s *IOSheet) indexHeaders() { @@ -70,16 +70,16 @@ func (s *IOSheet) Read(data io.Reader) error { } s.headers = sheet[0] - s.Rows = make([]ExportTSVRow, len(sheet)-1) + s.Rows = make([]ExportCSVRow, len(sheet)-1) for i, row := range sheet[1:] { if len(row) != len(s.headers) { return fmt.Errorf("row has %d columns, expected %d", len(row), len(s.headers)) } - rowData := ExportTSVRow{} + rowData := ExportCSVRow{} - st := reflect.TypeOf(ExportTSVRow{}) + st := reflect.TypeOf(ExportCSVRow{}) for i := 0; i < st.NumField(); i++ { field := st.Field(i) @@ -153,8 +153,8 @@ 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 { - s.Rows = make([]ExportTSVRow, len(items)) +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 { @@ -189,7 +191,7 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid. } } - s.Rows[i] = ExportTSVRow{ + s.Rows[i] = ExportCSVRow{ // fill struct Location: locString, LabelStr: labelString, @@ -201,6 +203,7 @@ 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, PurchaseFrom: item.PurchaseFrom, @@ -219,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, } } @@ -232,7 +236,7 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid. sort.Strings(customHeaders) - st := reflect.TypeOf(ExportTSVRow{}) + st := reflect.TypeOf(ExportCSVRow{}) // Write headers for i := 0; i < st.NumField(); i++ { @@ -252,8 +256,16 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid. return nil } -// TSV writes the current sheet to a writer in TSV format. -func (s *IOSheet) TSV() ([][]string, error) { +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) memcsv[0] = s.headers diff --git a/backend/internal/core/services/reporting/io_sheet_test.go b/backend/internal/core/services/reporting/io_sheet_test.go index f056e31f1..a489d2f8f 100644 --- a/backend/internal/core/services/reporting/io_sheet_test.go +++ b/backend/internal/core/services/reporting/io_sheet_test.go @@ -7,9 +7,9 @@ import ( _ "embed" - "github.com/hay-kot/homebox/backend/internal/data/repo" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" ) var ( @@ -27,13 +27,13 @@ func TestSheet_Read(t *testing.T) { tests := []struct { name string data []byte - want []ExportTSVRow + want []ExportCSVRow wantErr bool }{ { name: "minimal import", data: minimalImportCSV, - want: []ExportTSVRow{ + want: []ExportCSVRow{ {Location: LocationString{"loc"}, Name: "Item 1", Quantity: 1, Description: "Description 1"}, {Location: LocationString{"loc"}, Name: "Item 2", Quantity: 2, Description: "Description 2"}, {Location: LocationString{"loc"}, Name: "Item 3", Quantity: 3, Description: "Description 3"}, @@ -42,7 +42,7 @@ func TestSheet_Read(t *testing.T) { { name: "custom field import", data: customFieldImportCSV, - want: []ExportTSVRow{ + want: []ExportCSVRow{ { Location: LocationString{"loc"}, Name: "Item 1", Quantity: 1, Description: "Description 1", Fields: []ExportItemFields{ @@ -72,7 +72,7 @@ func TestSheet_Read(t *testing.T) { { name: "custom types import", data: customTypesImportCSV, - want: []ExportTSVRow{ + want: []ExportCSVRow{ { Name: "Item 1", AssetID: repo.AssetID(1), diff --git a/backend/internal/core/services/service_background.go b/backend/internal/core/services/service_background.go index 21ae4c369..1af8e1ba6 100644 --- a/backend/internal/core/services/service_background.go +++ b/backend/internal/core/services/service_background.go @@ -6,9 +6,9 @@ import ( "time" "github.com/containrrr/shoutrrr" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/internal/data/types" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/data/types" ) type BackgroundService struct { diff --git a/backend/internal/core/services/service_group.go b/backend/internal/core/services/service_group.go index 2ca3f86f5..7b90fa298 100644 --- a/backend/internal/core/services/service_group.go +++ b/backend/internal/core/services/service_group.go @@ -4,8 +4,8 @@ import ( "errors" "time" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/pkgs/hasher" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/pkgs/hasher" ) type GroupService struct { diff --git a/backend/internal/core/services/service_items.go b/backend/internal/core/services/service_items.go index 4d510e5c8..650ce6a6c 100644 --- a/backend/internal/core/services/service_items.go +++ b/backend/internal/core/services/service_items.go @@ -8,8 +8,8 @@ import ( "strings" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services/reporting" - "github.com/hay-kot/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/core/services/reporting" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" ) var ( @@ -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 } @@ -318,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 } @@ -329,27 +329,27 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re return finished, nil } -func (svc *ItemService) ExportTSV(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 } - return sheet.TSV() + return sheet.CSV() } -func (svc *ItemService) ExportBillOfMaterialsTSV(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 } - return reporting.BillOfMaterialsTSV(items) + return reporting.BillOfMaterialsCSV(items) } diff --git a/backend/internal/core/services/service_items_attachments.go b/backend/internal/core/services/service_items_attachments.go index 43835c637..5ed2ea6eb 100644 --- a/backend/internal/core/services/service_items_attachments.go +++ b/backend/internal/core/services/service_items_attachments.go @@ -6,10 +6,10 @@ import ( "os" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/repo" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" ) func (svc *ItemService) AttachmentPath(ctx context.Context, attachmentID uuid.UUID) (*ent.Document, error) { diff --git a/backend/internal/core/services/service_items_attachments_test.go b/backend/internal/core/services/service_items_attachments_test.go index 4e2315eb4..e5addae42 100644 --- a/backend/internal/core/services/service_items_attachments_test.go +++ b/backend/internal/core/services/service_items_attachments_test.go @@ -7,9 +7,9 @@ import ( "strings" "testing" - "github.com/hay-kot/homebox/backend/internal/data/repo" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" ) func TestItemService_AddAttachment(t *testing.T) { diff --git a/backend/internal/core/services/service_user.go b/backend/internal/core/services/service_user.go index d86c39b4e..0b67cb310 100644 --- a/backend/internal/core/services/service_user.go +++ b/backend/internal/core/services/service_user.go @@ -6,10 +6,10 @@ import ( "time" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/repo" - "github.com/hay-kot/homebox/backend/pkgs/hasher" "github.com/rs/zerolog/log" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/pkgs/hasher" ) var ( @@ -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) { diff --git a/backend/internal/core/services/service_user_defaults.go b/backend/internal/core/services/service_user_defaults.go index 34344d16b..62a429dc8 100644 --- a/backend/internal/core/services/service_user_defaults.go +++ b/backend/internal/core/services/service_user_defaults.go @@ -1,7 +1,7 @@ package services import ( - "github.com/hay-kot/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" ) func defaultLocations() []repo.LocationCreate { diff --git a/backend/internal/data/ent/attachment.go b/backend/internal/data/ent/attachment.go index bfb7de218..1a28aa6a2 100644 --- a/backend/internal/data/ent/attachment.go +++ b/backend/internal/data/ent/attachment.go @@ -10,9 +10,9 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" ) // Attachment is the model entity for the Attachment schema. diff --git a/backend/internal/data/ent/attachment/where.go b/backend/internal/data/ent/attachment/where.go index f6950f331..732be9b5b 100644 --- a/backend/internal/data/ent/attachment/where.go +++ b/backend/internal/data/ent/attachment/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/attachment_create.go b/backend/internal/data/ent/attachment_create.go index d1a0b5baf..888a7141a 100644 --- a/backend/internal/data/ent/attachment_create.go +++ b/backend/internal/data/ent/attachment_create.go @@ -11,9 +11,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" ) // AttachmentCreate is the builder for creating a Attachment entity. diff --git a/backend/internal/data/ent/attachment_delete.go b/backend/internal/data/ent/attachment_delete.go index 1be608af6..63a9356ad 100644 --- a/backend/internal/data/ent/attachment_delete.go +++ b/backend/internal/data/ent/attachment_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // AttachmentDelete is the builder for deleting a Attachment entity. diff --git a/backend/internal/data/ent/attachment_query.go b/backend/internal/data/ent/attachment_query.go index 976e436b7..0dc087dba 100644 --- a/backend/internal/data/ent/attachment_query.go +++ b/backend/internal/data/ent/attachment_query.go @@ -11,10 +11,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // AttachmentQuery is the builder for querying Attachment entities. diff --git a/backend/internal/data/ent/attachment_update.go b/backend/internal/data/ent/attachment_update.go index bdf10a535..611747f76 100644 --- a/backend/internal/data/ent/attachment_update.go +++ b/backend/internal/data/ent/attachment_update.go @@ -12,10 +12,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // AttachmentUpdate is the builder for updating Attachment entities. diff --git a/backend/internal/data/ent/authroles.go b/backend/internal/data/ent/authroles.go index 4daa0f62f..e996839b4 100644 --- a/backend/internal/data/ent/authroles.go +++ b/backend/internal/data/ent/authroles.go @@ -9,8 +9,8 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" ) // AuthRoles is the model entity for the AuthRoles schema. diff --git a/backend/internal/data/ent/authroles/where.go b/backend/internal/data/ent/authroles/where.go index bb5b54a75..70b41a8e1 100644 --- a/backend/internal/data/ent/authroles/where.go +++ b/backend/internal/data/ent/authroles/where.go @@ -5,7 +5,7 @@ package authroles import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/authroles_create.go b/backend/internal/data/ent/authroles_create.go index 19e594f66..1d2fbe6cd 100644 --- a/backend/internal/data/ent/authroles_create.go +++ b/backend/internal/data/ent/authroles_create.go @@ -10,8 +10,8 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" ) // AuthRolesCreate is the builder for creating a AuthRoles entity. diff --git a/backend/internal/data/ent/authroles_delete.go b/backend/internal/data/ent/authroles_delete.go index 68a0dfc68..5bb902c24 100644 --- a/backend/internal/data/ent/authroles_delete.go +++ b/backend/internal/data/ent/authroles_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // AuthRolesDelete is the builder for deleting a AuthRoles entity. diff --git a/backend/internal/data/ent/authroles_query.go b/backend/internal/data/ent/authroles_query.go index bf47577f7..c850fd1d4 100644 --- a/backend/internal/data/ent/authroles_query.go +++ b/backend/internal/data/ent/authroles_query.go @@ -11,9 +11,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // AuthRolesQuery is the builder for querying AuthRoles entities. diff --git a/backend/internal/data/ent/authroles_update.go b/backend/internal/data/ent/authroles_update.go index fbec4f95d..554f989a2 100644 --- a/backend/internal/data/ent/authroles_update.go +++ b/backend/internal/data/ent/authroles_update.go @@ -11,9 +11,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // AuthRolesUpdate is the builder for updating AuthRoles entities. diff --git a/backend/internal/data/ent/authtokens.go b/backend/internal/data/ent/authtokens.go index 14299bac8..40fdbb474 100644 --- a/backend/internal/data/ent/authtokens.go +++ b/backend/internal/data/ent/authtokens.go @@ -10,9 +10,9 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // AuthTokens is the model entity for the AuthTokens schema. diff --git a/backend/internal/data/ent/authtokens/where.go b/backend/internal/data/ent/authtokens/where.go index d3642d842..5ccd8c0cc 100644 --- a/backend/internal/data/ent/authtokens/where.go +++ b/backend/internal/data/ent/authtokens/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/authtokens_create.go b/backend/internal/data/ent/authtokens_create.go index afddb3b26..4cc0048e2 100644 --- a/backend/internal/data/ent/authtokens_create.go +++ b/backend/internal/data/ent/authtokens_create.go @@ -11,9 +11,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // AuthTokensCreate is the builder for creating a AuthTokens entity. diff --git a/backend/internal/data/ent/authtokens_delete.go b/backend/internal/data/ent/authtokens_delete.go index 4c29851e8..cc9dbec56 100644 --- a/backend/internal/data/ent/authtokens_delete.go +++ b/backend/internal/data/ent/authtokens_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // AuthTokensDelete is the builder for deleting a AuthTokens entity. diff --git a/backend/internal/data/ent/authtokens_query.go b/backend/internal/data/ent/authtokens_query.go index 238ab8846..2f4bd563f 100644 --- a/backend/internal/data/ent/authtokens_query.go +++ b/backend/internal/data/ent/authtokens_query.go @@ -12,10 +12,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // AuthTokensQuery is the builder for querying AuthTokens entities. diff --git a/backend/internal/data/ent/authtokens_update.go b/backend/internal/data/ent/authtokens_update.go index 776888eef..380f9fb64 100644 --- a/backend/internal/data/ent/authtokens_update.go +++ b/backend/internal/data/ent/authtokens_update.go @@ -12,10 +12,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // AuthTokensUpdate is the builder for updating AuthTokens entities. diff --git a/backend/internal/data/ent/client.go b/backend/internal/data/ent/client.go index 2fb9b5399..ed34e984f 100644 --- a/backend/internal/data/ent/client.go +++ b/backend/internal/data/ent/client.go @@ -10,25 +10,25 @@ import ( "reflect" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/migrate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/migrate" "entgo.io/ent" "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // Client is the client that holds all ent builders. diff --git a/backend/internal/data/ent/document.go b/backend/internal/data/ent/document.go index 3141bac78..5acc1c352 100644 --- a/backend/internal/data/ent/document.go +++ b/backend/internal/data/ent/document.go @@ -10,8 +10,8 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" ) // Document is the model entity for the Document schema. diff --git a/backend/internal/data/ent/document/where.go b/backend/internal/data/ent/document/where.go index 3e491add3..8a7c38218 100644 --- a/backend/internal/data/ent/document/where.go +++ b/backend/internal/data/ent/document/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/document_create.go b/backend/internal/data/ent/document_create.go index fe61e985b..9d6663817 100644 --- a/backend/internal/data/ent/document_create.go +++ b/backend/internal/data/ent/document_create.go @@ -11,9 +11,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" ) // DocumentCreate is the builder for creating a Document entity. diff --git a/backend/internal/data/ent/document_delete.go b/backend/internal/data/ent/document_delete.go index 5901c03f1..ce6b0ad4b 100644 --- a/backend/internal/data/ent/document_delete.go +++ b/backend/internal/data/ent/document_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // DocumentDelete is the builder for deleting a Document entity. diff --git a/backend/internal/data/ent/document_query.go b/backend/internal/data/ent/document_query.go index 34f4801be..479eac716 100644 --- a/backend/internal/data/ent/document_query.go +++ b/backend/internal/data/ent/document_query.go @@ -12,10 +12,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // DocumentQuery is the builder for querying Document entities. diff --git a/backend/internal/data/ent/document_update.go b/backend/internal/data/ent/document_update.go index 23e6d9ca9..fac957b5e 100644 --- a/backend/internal/data/ent/document_update.go +++ b/backend/internal/data/ent/document_update.go @@ -12,10 +12,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // DocumentUpdate is the builder for updating Document entities. diff --git a/backend/internal/data/ent/ent.go b/backend/internal/data/ent/ent.go index 6e52ac8b3..8a0ddc4e6 100644 --- a/backend/internal/data/ent/ent.go +++ b/backend/internal/data/ent/ent.go @@ -12,19 +12,19 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // ent aliases to avoid import conflicts in user's code. diff --git a/backend/internal/data/ent/enttest/enttest.go b/backend/internal/data/ent/enttest/enttest.go index 495bddbe2..2d5ce6669 100644 --- a/backend/internal/data/ent/enttest/enttest.go +++ b/backend/internal/data/ent/enttest/enttest.go @@ -5,12 +5,12 @@ package enttest import ( "context" - "github.com/hay-kot/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" // required by schema hooks. - _ "github.com/hay-kot/homebox/backend/internal/data/ent/runtime" + _ "github.com/sysadminsmedia/homebox/backend/internal/data/ent/runtime" "entgo.io/ent/dialect/sql/schema" - "github.com/hay-kot/homebox/backend/internal/data/ent/migrate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/migrate" ) type ( diff --git a/backend/internal/data/ent/group.go b/backend/internal/data/ent/group.go index 69c67de8c..9f7bcfc20 100644 --- a/backend/internal/data/ent/group.go +++ b/backend/internal/data/ent/group.go @@ -10,7 +10,7 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" ) // Group is the model entity for the Group schema. diff --git a/backend/internal/data/ent/group/where.go b/backend/internal/data/ent/group/where.go index d18faa75f..369f363c3 100644 --- a/backend/internal/data/ent/group/where.go +++ b/backend/internal/data/ent/group/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/group_create.go b/backend/internal/data/ent/group_create.go index be56ba016..e0d9f50f5 100644 --- a/backend/internal/data/ent/group_create.go +++ b/backend/internal/data/ent/group_create.go @@ -11,14 +11,14 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // GroupCreate is the builder for creating a Group entity. diff --git a/backend/internal/data/ent/group_delete.go b/backend/internal/data/ent/group_delete.go index b8c3e59cf..430dd5f13 100644 --- a/backend/internal/data/ent/group_delete.go +++ b/backend/internal/data/ent/group_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // GroupDelete is the builder for deleting a Group entity. diff --git a/backend/internal/data/ent/group_query.go b/backend/internal/data/ent/group_query.go index f17bd3bfa..6f8aa70f1 100644 --- a/backend/internal/data/ent/group_query.go +++ b/backend/internal/data/ent/group_query.go @@ -12,15 +12,15 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // GroupQuery is the builder for querying Group entities. diff --git a/backend/internal/data/ent/group_update.go b/backend/internal/data/ent/group_update.go index fdb11a392..ab84ddf50 100644 --- a/backend/internal/data/ent/group_update.go +++ b/backend/internal/data/ent/group_update.go @@ -12,15 +12,15 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // GroupUpdate is the builder for updating Group entities. diff --git a/backend/internal/data/ent/groupinvitationtoken.go b/backend/internal/data/ent/groupinvitationtoken.go index d715cc658..239614a91 100644 --- a/backend/internal/data/ent/groupinvitationtoken.go +++ b/backend/internal/data/ent/groupinvitationtoken.go @@ -10,8 +10,8 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" ) // GroupInvitationToken is the model entity for the GroupInvitationToken schema. diff --git a/backend/internal/data/ent/groupinvitationtoken/where.go b/backend/internal/data/ent/groupinvitationtoken/where.go index d462df0f3..2835369f2 100644 --- a/backend/internal/data/ent/groupinvitationtoken/where.go +++ b/backend/internal/data/ent/groupinvitationtoken/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/groupinvitationtoken_create.go b/backend/internal/data/ent/groupinvitationtoken_create.go index 1d5859f26..8fa97cabc 100644 --- a/backend/internal/data/ent/groupinvitationtoken_create.go +++ b/backend/internal/data/ent/groupinvitationtoken_create.go @@ -11,8 +11,8 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" ) // GroupInvitationTokenCreate is the builder for creating a GroupInvitationToken entity. diff --git a/backend/internal/data/ent/groupinvitationtoken_delete.go b/backend/internal/data/ent/groupinvitationtoken_delete.go index 5878fdfca..e49acf50e 100644 --- a/backend/internal/data/ent/groupinvitationtoken_delete.go +++ b/backend/internal/data/ent/groupinvitationtoken_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // GroupInvitationTokenDelete is the builder for deleting a GroupInvitationToken entity. diff --git a/backend/internal/data/ent/groupinvitationtoken_query.go b/backend/internal/data/ent/groupinvitationtoken_query.go index 89de05432..bebf85332 100644 --- a/backend/internal/data/ent/groupinvitationtoken_query.go +++ b/backend/internal/data/ent/groupinvitationtoken_query.go @@ -11,9 +11,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // GroupInvitationTokenQuery is the builder for querying GroupInvitationToken entities. diff --git a/backend/internal/data/ent/groupinvitationtoken_update.go b/backend/internal/data/ent/groupinvitationtoken_update.go index 3e0db91fd..38f4b2c48 100644 --- a/backend/internal/data/ent/groupinvitationtoken_update.go +++ b/backend/internal/data/ent/groupinvitationtoken_update.go @@ -12,9 +12,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // GroupInvitationTokenUpdate is the builder for updating GroupInvitationToken entities. diff --git a/backend/internal/data/ent/hook/hook.go b/backend/internal/data/ent/hook/hook.go index 4648b23a2..00e3adfb4 100644 --- a/backend/internal/data/ent/hook/hook.go +++ b/backend/internal/data/ent/hook/hook.go @@ -6,7 +6,7 @@ import ( "context" "fmt" - "github.com/hay-kot/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" ) // The AttachmentFunc type is an adapter to allow the use of ordinary diff --git a/backend/internal/data/ent/item.go b/backend/internal/data/ent/item.go index 7b2be8a8a..8ce24934e 100644 --- a/backend/internal/data/ent/item.go +++ b/backend/internal/data/ent/item.go @@ -10,9 +10,9 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" + "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/location" ) // Item is the model entity for the Item schema. diff --git a/backend/internal/data/ent/item/where.go b/backend/internal/data/ent/item/where.go index 7504e6a13..61a8dae00 100644 --- a/backend/internal/data/ent/item/where.go +++ b/backend/internal/data/ent/item/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/item_create.go b/backend/internal/data/ent/item_create.go index 9eb1cb60a..0bdc2c790 100644 --- a/backend/internal/data/ent/item_create.go +++ b/backend/internal/data/ent/item_create.go @@ -11,13 +11,13 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "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/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" ) // ItemCreate is the builder for creating a Item entity. diff --git a/backend/internal/data/ent/item_delete.go b/backend/internal/data/ent/item_delete.go index d634d5da6..12bee5912 100644 --- a/backend/internal/data/ent/item_delete.go +++ b/backend/internal/data/ent/item_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ItemDelete is the builder for deleting a Item entity. diff --git a/backend/internal/data/ent/item_query.go b/backend/internal/data/ent/item_query.go index 12fc3316c..15028b840 100644 --- a/backend/internal/data/ent/item_query.go +++ b/backend/internal/data/ent/item_query.go @@ -12,14 +12,14 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "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/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ItemQuery is the builder for querying Item entities. diff --git a/backend/internal/data/ent/item_update.go b/backend/internal/data/ent/item_update.go index 8cd47221d..57616ab46 100644 --- a/backend/internal/data/ent/item_update.go +++ b/backend/internal/data/ent/item_update.go @@ -12,14 +12,14 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "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/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ItemUpdate is the builder for updating Item entities. diff --git a/backend/internal/data/ent/itemfield.go b/backend/internal/data/ent/itemfield.go index b2b8b8d49..0c1690cc1 100644 --- a/backend/internal/data/ent/itemfield.go +++ b/backend/internal/data/ent/itemfield.go @@ -10,8 +10,8 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/itemfield" ) // ItemField is the model entity for the ItemField schema. diff --git a/backend/internal/data/ent/itemfield/where.go b/backend/internal/data/ent/itemfield/where.go index 8a2d4aa2f..a905ae402 100644 --- a/backend/internal/data/ent/itemfield/where.go +++ b/backend/internal/data/ent/itemfield/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/itemfield_create.go b/backend/internal/data/ent/itemfield_create.go index 65a22fbc7..d84d719f7 100644 --- a/backend/internal/data/ent/itemfield_create.go +++ b/backend/internal/data/ent/itemfield_create.go @@ -11,8 +11,8 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/itemfield" ) // ItemFieldCreate is the builder for creating a ItemField entity. diff --git a/backend/internal/data/ent/itemfield_delete.go b/backend/internal/data/ent/itemfield_delete.go index ba85cbce7..925eaba1b 100644 --- a/backend/internal/data/ent/itemfield_delete.go +++ b/backend/internal/data/ent/itemfield_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ItemFieldDelete is the builder for deleting a ItemField entity. diff --git a/backend/internal/data/ent/itemfield_query.go b/backend/internal/data/ent/itemfield_query.go index 21bffb8e7..3c6072a80 100644 --- a/backend/internal/data/ent/itemfield_query.go +++ b/backend/internal/data/ent/itemfield_query.go @@ -11,9 +11,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ItemFieldQuery is the builder for querying ItemField entities. diff --git a/backend/internal/data/ent/itemfield_update.go b/backend/internal/data/ent/itemfield_update.go index 3f44dc103..aab940a29 100644 --- a/backend/internal/data/ent/itemfield_update.go +++ b/backend/internal/data/ent/itemfield_update.go @@ -12,9 +12,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ItemFieldUpdate is the builder for updating ItemField entities. diff --git a/backend/internal/data/ent/label.go b/backend/internal/data/ent/label.go index fdd6f8d7c..8af41d342 100644 --- a/backend/internal/data/ent/label.go +++ b/backend/internal/data/ent/label.go @@ -10,8 +10,8 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" ) // Label is the model entity for the Label schema. diff --git a/backend/internal/data/ent/label/where.go b/backend/internal/data/ent/label/where.go index 3754ac732..7a2f24039 100644 --- a/backend/internal/data/ent/label/where.go +++ b/backend/internal/data/ent/label/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/label_create.go b/backend/internal/data/ent/label_create.go index 0ad646965..42dab66bf 100644 --- a/backend/internal/data/ent/label_create.go +++ b/backend/internal/data/ent/label_create.go @@ -11,9 +11,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" + "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/label" ) // LabelCreate is the builder for creating a Label entity. diff --git a/backend/internal/data/ent/label_delete.go b/backend/internal/data/ent/label_delete.go index f3b514a97..c95af3835 100644 --- a/backend/internal/data/ent/label_delete.go +++ b/backend/internal/data/ent/label_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // LabelDelete is the builder for deleting a Label entity. diff --git a/backend/internal/data/ent/label_query.go b/backend/internal/data/ent/label_query.go index e3bb6d1e5..e0964fbb4 100644 --- a/backend/internal/data/ent/label_query.go +++ b/backend/internal/data/ent/label_query.go @@ -12,10 +12,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "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/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // LabelQuery is the builder for querying Label entities. diff --git a/backend/internal/data/ent/label_update.go b/backend/internal/data/ent/label_update.go index 0862d2281..10475eea8 100644 --- a/backend/internal/data/ent/label_update.go +++ b/backend/internal/data/ent/label_update.go @@ -12,10 +12,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "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/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // LabelUpdate is the builder for updating Label entities. diff --git a/backend/internal/data/ent/location.go b/backend/internal/data/ent/location.go index 640f05ec7..784b4056b 100644 --- a/backend/internal/data/ent/location.go +++ b/backend/internal/data/ent/location.go @@ -10,8 +10,8 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" ) // Location is the model entity for the Location schema. diff --git a/backend/internal/data/ent/location/where.go b/backend/internal/data/ent/location/where.go index a89ef4d6c..2cf6e5590 100644 --- a/backend/internal/data/ent/location/where.go +++ b/backend/internal/data/ent/location/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/location_create.go b/backend/internal/data/ent/location_create.go index 98f0f7ab1..675de7a1d 100644 --- a/backend/internal/data/ent/location_create.go +++ b/backend/internal/data/ent/location_create.go @@ -11,9 +11,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" + "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/location" ) // LocationCreate is the builder for creating a Location entity. diff --git a/backend/internal/data/ent/location_delete.go b/backend/internal/data/ent/location_delete.go index 451b7f1f4..59ff9509f 100644 --- a/backend/internal/data/ent/location_delete.go +++ b/backend/internal/data/ent/location_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // LocationDelete is the builder for deleting a Location entity. diff --git a/backend/internal/data/ent/location_query.go b/backend/internal/data/ent/location_query.go index 4aae96552..8c7c3e981 100644 --- a/backend/internal/data/ent/location_query.go +++ b/backend/internal/data/ent/location_query.go @@ -12,10 +12,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "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/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // LocationQuery is the builder for querying Location entities. diff --git a/backend/internal/data/ent/location_update.go b/backend/internal/data/ent/location_update.go index d569b21a4..a937d4adf 100644 --- a/backend/internal/data/ent/location_update.go +++ b/backend/internal/data/ent/location_update.go @@ -12,10 +12,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "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/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // LocationUpdate is the builder for updating Location entities. diff --git a/backend/internal/data/ent/maintenanceentry.go b/backend/internal/data/ent/maintenanceentry.go index af35e0ba2..106ec3183 100644 --- a/backend/internal/data/ent/maintenanceentry.go +++ b/backend/internal/data/ent/maintenanceentry.go @@ -10,8 +10,8 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" ) // MaintenanceEntry is the model entity for the MaintenanceEntry schema. diff --git a/backend/internal/data/ent/maintenanceentry/where.go b/backend/internal/data/ent/maintenanceentry/where.go index 85e736da1..1178f4d90 100644 --- a/backend/internal/data/ent/maintenanceentry/where.go +++ b/backend/internal/data/ent/maintenanceentry/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/maintenanceentry_create.go b/backend/internal/data/ent/maintenanceentry_create.go index ea71a4d95..ceeeb2b39 100644 --- a/backend/internal/data/ent/maintenanceentry_create.go +++ b/backend/internal/data/ent/maintenanceentry_create.go @@ -11,8 +11,8 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" ) // MaintenanceEntryCreate is the builder for creating a MaintenanceEntry entity. diff --git a/backend/internal/data/ent/maintenanceentry_delete.go b/backend/internal/data/ent/maintenanceentry_delete.go index 0323ae9a3..88f4dab75 100644 --- a/backend/internal/data/ent/maintenanceentry_delete.go +++ b/backend/internal/data/ent/maintenanceentry_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // MaintenanceEntryDelete is the builder for deleting a MaintenanceEntry entity. diff --git a/backend/internal/data/ent/maintenanceentry_query.go b/backend/internal/data/ent/maintenanceentry_query.go index 8d41f75e1..3c68c1abd 100644 --- a/backend/internal/data/ent/maintenanceentry_query.go +++ b/backend/internal/data/ent/maintenanceentry_query.go @@ -11,9 +11,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // MaintenanceEntryQuery is the builder for querying MaintenanceEntry entities. diff --git a/backend/internal/data/ent/maintenanceentry_update.go b/backend/internal/data/ent/maintenanceentry_update.go index 3616d3240..5aeb6e0d5 100644 --- a/backend/internal/data/ent/maintenanceentry_update.go +++ b/backend/internal/data/ent/maintenanceentry_update.go @@ -12,9 +12,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // MaintenanceEntryUpdate is the builder for updating MaintenanceEntry entities. diff --git a/backend/internal/data/ent/mutation.go b/backend/internal/data/ent/mutation.go index 6fa15d3b5..228de48ee 100644 --- a/backend/internal/data/ent/mutation.go +++ b/backend/internal/data/ent/mutation.go @@ -12,20 +12,20 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) const ( diff --git a/backend/internal/data/ent/notifier.go b/backend/internal/data/ent/notifier.go index 05a267bbd..55b062b9d 100644 --- a/backend/internal/data/ent/notifier.go +++ b/backend/internal/data/ent/notifier.go @@ -10,9 +10,9 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // Notifier is the model entity for the Notifier schema. diff --git a/backend/internal/data/ent/notifier/where.go b/backend/internal/data/ent/notifier/where.go index fa9b3bca1..e6014ea29 100644 --- a/backend/internal/data/ent/notifier/where.go +++ b/backend/internal/data/ent/notifier/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/notifier_create.go b/backend/internal/data/ent/notifier_create.go index 42265e20e..20debb821 100644 --- a/backend/internal/data/ent/notifier_create.go +++ b/backend/internal/data/ent/notifier_create.go @@ -11,9 +11,9 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // NotifierCreate is the builder for creating a Notifier entity. diff --git a/backend/internal/data/ent/notifier_delete.go b/backend/internal/data/ent/notifier_delete.go index 586b09333..2e809fa97 100644 --- a/backend/internal/data/ent/notifier_delete.go +++ b/backend/internal/data/ent/notifier_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // NotifierDelete is the builder for deleting a Notifier entity. diff --git a/backend/internal/data/ent/notifier_query.go b/backend/internal/data/ent/notifier_query.go index c88b4ef4c..dcde6dc37 100644 --- a/backend/internal/data/ent/notifier_query.go +++ b/backend/internal/data/ent/notifier_query.go @@ -11,10 +11,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // NotifierQuery is the builder for querying Notifier entities. diff --git a/backend/internal/data/ent/notifier_update.go b/backend/internal/data/ent/notifier_update.go index ea28f3295..92b87be12 100644 --- a/backend/internal/data/ent/notifier_update.go +++ b/backend/internal/data/ent/notifier_update.go @@ -12,10 +12,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // NotifierUpdate is the builder for updating Notifier entities. diff --git a/backend/internal/data/ent/runtime.go b/backend/internal/data/ent/runtime.go index c3aff001a..12e507bd0 100644 --- a/backend/internal/data/ent/runtime.go +++ b/backend/internal/data/ent/runtime.go @@ -6,19 +6,19 @@ import ( "time" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // The init function reads all schema descriptors with runtime code diff --git a/backend/internal/data/ent/runtime/runtime.go b/backend/internal/data/ent/runtime/runtime.go index b5773b1c2..dcbee86e4 100644 --- a/backend/internal/data/ent/runtime/runtime.go +++ b/backend/internal/data/ent/runtime/runtime.go @@ -2,7 +2,7 @@ package runtime -// The schema-stitching logic is generated in github.com/hay-kot/homebox/backend/internal/data/ent/runtime.go +// 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. diff --git a/backend/internal/data/ent/schema/attachment.go b/backend/internal/data/ent/schema/attachment.go index 589b68433..9457d97d1 100644 --- a/backend/internal/data/ent/schema/attachment.go +++ b/backend/internal/data/ent/schema/attachment.go @@ -4,7 +4,7 @@ import ( "entgo.io/ent" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) // Attachment holds the schema definition for the Attachment entity. diff --git a/backend/internal/data/ent/schema/auth_tokens.go b/backend/internal/data/ent/schema/auth_tokens.go index 71b22d714..616958b3f 100644 --- a/backend/internal/data/ent/schema/auth_tokens.go +++ b/backend/internal/data/ent/schema/auth_tokens.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" "entgo.io/ent/schema/index" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) // AuthTokens holds the schema definition for the AuthTokens entity. diff --git a/backend/internal/data/ent/schema/document.go b/backend/internal/data/ent/schema/document.go index d814f6004..bbdd75853 100644 --- a/backend/internal/data/ent/schema/document.go +++ b/backend/internal/data/ent/schema/document.go @@ -5,7 +5,7 @@ import ( "entgo.io/ent/dialect/entsql" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) // Document holds the schema definition for the Document entity. diff --git a/backend/internal/data/ent/schema/group.go b/backend/internal/data/ent/schema/group.go index 352ac0b23..696aad619 100644 --- a/backend/internal/data/ent/schema/group.go +++ b/backend/internal/data/ent/schema/group.go @@ -7,7 +7,7 @@ import ( "entgo.io/ent/schema/field" "entgo.io/ent/schema/mixin" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) // Group holds the schema definition for the Group entity. diff --git a/backend/internal/data/ent/schema/group_invitation_token.go b/backend/internal/data/ent/schema/group_invitation_token.go index 1150db886..7ed4eb4b3 100644 --- a/backend/internal/data/ent/schema/group_invitation_token.go +++ b/backend/internal/data/ent/schema/group_invitation_token.go @@ -6,7 +6,7 @@ import ( "entgo.io/ent" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) // GroupInvitationToken holds the schema definition for the GroupInvitationToken entity. diff --git a/backend/internal/data/ent/schema/item.go b/backend/internal/data/ent/schema/item.go index 344829fac..43f4859f2 100644 --- a/backend/internal/data/ent/schema/item.go +++ b/backend/internal/data/ent/schema/item.go @@ -6,7 +6,7 @@ import ( "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" "entgo.io/ent/schema/index" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) // Item holds the schema definition for the Item entity. diff --git a/backend/internal/data/ent/schema/item_field.go b/backend/internal/data/ent/schema/item_field.go index 405b99c45..c88c8fa6a 100644 --- a/backend/internal/data/ent/schema/item_field.go +++ b/backend/internal/data/ent/schema/item_field.go @@ -6,7 +6,7 @@ import ( "entgo.io/ent" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) // ItemField holds the schema definition for the ItemField entity. diff --git a/backend/internal/data/ent/schema/label.go b/backend/internal/data/ent/schema/label.go index c54c713c5..2ec791645 100644 --- a/backend/internal/data/ent/schema/label.go +++ b/backend/internal/data/ent/schema/label.go @@ -4,7 +4,7 @@ import ( "entgo.io/ent" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) // Label holds the schema definition for the Label entity. diff --git a/backend/internal/data/ent/schema/location.go b/backend/internal/data/ent/schema/location.go index b52cb7a1a..3bc9d80b7 100644 --- a/backend/internal/data/ent/schema/location.go +++ b/backend/internal/data/ent/schema/location.go @@ -4,7 +4,7 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/entsql" "entgo.io/ent/schema/edge" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) // Location holds the schema definition for the Location entity. diff --git a/backend/internal/data/ent/schema/maintenance_entry.go b/backend/internal/data/ent/schema/maintenance_entry.go index 1c623cf0f..9232d17ab 100644 --- a/backend/internal/data/ent/schema/maintenance_entry.go +++ b/backend/internal/data/ent/schema/maintenance_entry.go @@ -5,7 +5,7 @@ import ( "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) type MaintenanceEntry struct { diff --git a/backend/internal/data/ent/schema/notifier.go b/backend/internal/data/ent/schema/notifier.go index c3561d0f9..8b176497f 100755 --- a/backend/internal/data/ent/schema/notifier.go +++ b/backend/internal/data/ent/schema/notifier.go @@ -5,7 +5,7 @@ import ( "entgo.io/ent/schema/field" "entgo.io/ent/schema/index" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) type Notifier struct { diff --git a/backend/internal/data/ent/schema/user.go b/backend/internal/data/ent/schema/user.go index 10b0a8a99..bd747aead 100644 --- a/backend/internal/data/ent/schema/user.go +++ b/backend/internal/data/ent/schema/user.go @@ -7,7 +7,7 @@ import ( "entgo.io/ent/schema/field" "entgo.io/ent/schema/mixin" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/schema/mixins" ) // User holds the schema definition for the User entity. diff --git a/backend/internal/data/ent/user.go b/backend/internal/data/ent/user.go index 3331de755..b00f838b0 100644 --- a/backend/internal/data/ent/user.go +++ b/backend/internal/data/ent/user.go @@ -10,8 +10,8 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // User is the model entity for the User schema. diff --git a/backend/internal/data/ent/user/where.go b/backend/internal/data/ent/user/where.go index 8686e737a..f70676bcf 100644 --- a/backend/internal/data/ent/user/where.go +++ b/backend/internal/data/ent/user/where.go @@ -8,7 +8,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) // ID filters vertices based on their ID field. diff --git a/backend/internal/data/ent/user_create.go b/backend/internal/data/ent/user_create.go index 2cfe2d182..7367ddb76 100644 --- a/backend/internal/data/ent/user_create.go +++ b/backend/internal/data/ent/user_create.go @@ -11,10 +11,10 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // UserCreate is the builder for creating a User entity. diff --git a/backend/internal/data/ent/user_delete.go b/backend/internal/data/ent/user_delete.go index 08fd3efed..2a81709a9 100644 --- a/backend/internal/data/ent/user_delete.go +++ b/backend/internal/data/ent/user_delete.go @@ -8,8 +8,8 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // UserDelete is the builder for deleting a User entity. diff --git a/backend/internal/data/ent/user_query.go b/backend/internal/data/ent/user_query.go index 7205e9b1c..dce4037d2 100644 --- a/backend/internal/data/ent/user_query.go +++ b/backend/internal/data/ent/user_query.go @@ -12,11 +12,11 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // UserQuery is the builder for querying User entities. diff --git a/backend/internal/data/ent/user_update.go b/backend/internal/data/ent/user_update.go index 0e4c01ac9..3277713d3 100644 --- a/backend/internal/data/ent/user_update.go +++ b/backend/internal/data/ent/user_update.go @@ -12,11 +12,11 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) // UserUpdate is the builder for updating User entities. diff --git a/backend/internal/data/repo/asset_id_type.go b/backend/internal/data/repo/asset_id_type.go index 0a53a4a1f..1181b89d3 100644 --- a/backend/internal/data/repo/asset_id_type.go +++ b/backend/internal/data/repo/asset_id_type.go @@ -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 { diff --git a/backend/internal/data/repo/id_set.go b/backend/internal/data/repo/id_set.go index a39ac4081..233bd15d8 100644 --- a/backend/internal/data/repo/id_set.go +++ b/backend/internal/data/repo/id_set.go @@ -2,7 +2,7 @@ package repo import ( "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/pkgs/set" + "github.com/sysadminsmedia/homebox/backend/pkgs/set" ) // HasID is an interface to entities that have an ID uuid.UUID field and a GetID() method. diff --git a/backend/internal/data/repo/main_test.go b/backend/internal/data/repo/main_test.go index 47e5ec05a..a633d63c1 100644 --- a/backend/internal/data/repo/main_test.go +++ b/backend/internal/data/repo/main_test.go @@ -6,10 +6,10 @@ import ( "os" "testing" - "github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/pkgs/faker" _ "github.com/mattn/go-sqlite3" + "github.com/sysadminsmedia/homebox/backend/internal/core/services/reporting/eventbus" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/pkgs/faker" ) var ( @@ -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() + return m.Run() +} - os.Exit(m.Run()) +func TestMain(m *testing.M) { + os.Exit(MainNoExit(m)) } diff --git a/backend/internal/data/repo/repo_documents.go b/backend/internal/data/repo/repo_documents.go index 587a4f19a..d8e34ccdd 100644 --- a/backend/internal/data/repo/repo_documents.go +++ b/backend/internal/data/repo/repo_documents.go @@ -8,10 +8,10 @@ import ( "path/filepath" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/document" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/pkgs/pathlib" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/document" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/pkgs/pathlib" ) var ErrInvalidDocExtension = errors.New("invalid document extension") diff --git a/backend/internal/data/repo/repo_documents_test.go b/backend/internal/data/repo/repo_documents_test.go index 463423567..b1d7beba9 100644 --- a/backend/internal/data/repo/repo_documents_test.go +++ b/backend/internal/data/repo/repo_documents_test.go @@ -9,9 +9,9 @@ import ( "testing" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" ) func useDocs(t *testing.T, num int) []DocumentOut { diff --git a/backend/internal/data/repo/repo_group.go b/backend/internal/data/repo/repo_group.go index 8f93c7804..2498052e4 100644 --- a/backend/internal/data/repo/repo_group.go +++ b/backend/internal/data/repo/repo_group.go @@ -7,12 +7,12 @@ import ( "entgo.io/ent/dialect/sql" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" + "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/groupinvitationtoken" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" ) type GroupRepository struct { @@ -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) diff --git a/backend/internal/data/repo/repo_item_attachments.go b/backend/internal/data/repo/repo_item_attachments.go index da57b31c3..7be4d7fec 100644 --- a/backend/internal/data/repo/repo_item_attachments.go +++ b/backend/internal/data/repo/repo_item_attachments.go @@ -5,9 +5,9 @@ import ( "time" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" ) // AttachmentRepo is a repository for Attachments table that links Items to Documents diff --git a/backend/internal/data/repo/repo_item_attachments_test.go b/backend/internal/data/repo/repo_item_attachments_test.go index 9007b2ed4..22a2256c0 100644 --- a/backend/internal/data/repo/repo_item_attachments_test.go +++ b/backend/internal/data/repo/repo_item_attachments_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" ) func TestAttachmentRepo_Create(t *testing.T) { diff --git a/backend/internal/data/repo/repo_items.go b/backend/internal/data/repo/repo_items.go index 72ba90407..73d72a89f 100644 --- a/backend/internal/data/repo/repo_items.go +++ b/backend/internal/data/repo/repo_items.go @@ -6,16 +6,16 @@ import ( "time" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/attachment" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/itemfield" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" - "github.com/hay-kot/homebox/backend/internal/data/types" + "github.com/sysadminsmedia/homebox/backend/internal/core/services/reporting/eventbus" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment" + "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/itemfield" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/data/types" ) type ItemsRepository struct { @@ -36,6 +36,7 @@ type ( AssetID AssetID `json:"assetId"` LocationIDs []uuid.UUID `json:"locationIds"` LabelIDs []uuid.UUID `json:"labelIds"` + NegateLabels bool `json:"negateLabels"` ParentItemIDs []uuid.UUID `json:"parentIds"` SortBy string `json:"sortBy"` IncludeArchived bool `json:"includeArchived"` @@ -69,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,12 +92,12 @@ type ( // Purchase PurchaseTime types.Date `json:"purchaseTime"` - PurchaseFrom string `json:"purchaseFrom"` + PurchaseFrom string `json:"purchaseFrom" validate:"max=255"` PurchasePrice float64 `json:"purchasePrice,string"` // Sold SoldTime types.Date `json:"soldTime"` - SoldTo string `json:"soldTo"` + SoldTo string `json:"soldTo" validate:"max=255"` SoldPrice float64 `json:"soldPrice,string"` SoldNotes string `json:"soldNotes"` @@ -276,9 +277,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}) } } @@ -304,13 +305,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. @@ -365,10 +366,17 @@ func (e *ItemsRepository) QueryByGroup(ctx context.Context, gid uuid.UUID, q Ite if len(q.LabelIDs) > 0 { labelPredicates := make([]predicate.Item, 0, len(q.LabelIDs)) for _, l := range q.LabelIDs { - labelPredicates = append(labelPredicates, item.HasLabelWith(label.ID(l))) + if !q.NegateLabels { + labelPredicates = append(labelPredicates, item.HasLabelWith(label.ID(l))) + } else { + labelPredicates = append(labelPredicates, item.Not(item.HasLabelWith(label.ID(l)))) + } + } + if !q.NegateLabels { + andPredicates = append(andPredicates, item.Or(labelPredicates...)) + } else { + andPredicates = append(andPredicates, item.And(labelPredicates...)) } - - andPredicates = append(andPredicates, item.Or(labelPredicates...)) } if len(q.LocationIDs) > 0 { @@ -490,9 +498,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), @@ -501,9 +509,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) @@ -519,10 +527,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) @@ -538,7 +546,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...) } @@ -576,8 +584,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). @@ -665,7 +673,7 @@ func (e *ItemsRepository) UpdateByGroup(ctx context.Context, GID uuid.UUID, data SetTextValue(f.TextValue). SetNumberValue(f.NumberValue). SetBooleanValue(f.BooleanValue) - // SetTimeValue(f.TimeValue) + // SetTimeValue(f.TimeValue) _, err = opt.Save(ctx) if err != nil { @@ -688,16 +696,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(), @@ -712,11 +720,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 { @@ -727,11 +735,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"` } @@ -740,7 +748,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( @@ -761,7 +769,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"` } @@ -770,7 +778,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). @@ -794,9 +802,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"), @@ -865,11 +873,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( diff --git a/backend/internal/data/repo/repo_items_test.go b/backend/internal/data/repo/repo_items_test.go index 9d60596a6..870bcd0c8 100644 --- a/backend/internal/data/repo/repo_items_test.go +++ b/backend/internal/data/repo/repo_items_test.go @@ -6,9 +6,9 @@ import ( "time" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/sysadminsmedia/homebox/backend/internal/data/types" ) func itemFactory() ItemCreate { diff --git a/backend/internal/data/repo/repo_labels.go b/backend/internal/data/repo/repo_labels.go index 2358f9c63..03e2b4c15 100644 --- a/backend/internal/data/repo/repo_labels.go +++ b/backend/internal/data/repo/repo_labels.go @@ -5,11 +5,11 @@ import ( "time" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/label" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/core/services/reporting/eventbus" + "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/label" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) type LabelRepository struct { @@ -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) } diff --git a/backend/internal/data/repo/repo_locations.go b/backend/internal/data/repo/repo_locations.go index fd98fd78e..7ece91b20 100644 --- a/backend/internal/data/repo/repo_locations.go +++ b/backend/internal/data/repo/repo_locations.go @@ -6,11 +6,11 @@ import ( "time" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/location" - "github.com/hay-kot/homebox/backend/internal/data/ent/predicate" + "github.com/sysadminsmedia/homebox/backend/internal/core/services/reporting/eventbus" + "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/location" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/predicate" ) type LocationRepository struct { @@ -48,7 +48,8 @@ type ( LocationOut struct { Parent *LocationSummary `json:"parent,omitempty"` LocationSummary - Children []LocationSummary `json:"children"` + Children []LocationSummary `json:"children"` + TotalPrice float64 `json:"totalPrice"` } ) @@ -89,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}) } } @@ -100,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, @@ -131,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 } @@ -167,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) @@ -190,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 } @@ -215,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 } @@ -273,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 @@ -290,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 } @@ -320,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 ( @@ -402,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 } diff --git a/backend/internal/data/repo/repo_locations_test.go b/backend/internal/data/repo/repo_locations_test.go index e8b353cec..4b3ab21a1 100644 --- a/backend/internal/data/repo/repo_locations_test.go +++ b/backend/internal/data/repo/repo_locations_test.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" ) func locationFactory() LocationCreate { diff --git a/backend/internal/data/repo/repo_maintenance.go b/backend/internal/data/repo/repo_maintenance.go new file mode 100644 index 000000000..c488efd7a --- /dev/null +++ b/backend/internal/data/repo/repo_maintenance.go @@ -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 +} diff --git a/backend/internal/data/repo/repo_maintenance_entry.go b/backend/internal/data/repo/repo_maintenance_entry.go index 2714bbdd0..6f5c135b0 100644 --- a/backend/internal/data/repo/repo_maintenance_entry.go +++ b/backend/internal/data/repo/repo_maintenance_entry.go @@ -6,11 +6,11 @@ import ( "time" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/group" - "github.com/hay-kot/homebox/backend/internal/data/ent/item" - "github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry" - "github.com/hay-kot/homebox/backend/internal/data/types" + "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" + "github.com/sysadminsmedia/homebox/backend/internal/data/types" ) // MaintenanceEntryRepository is a repository for maintenance entries that are @@ -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{}), - )) - } - - entries, err := q.Order(ent.Desc(maintenanceentry.FieldDate)). - All(ctx) - if err != nil { - return MaintenanceLog{}, err + maintenanceentry.DateEQ(time.Time{})), + )) } + entries, err := query.WithItem().Order(maintenanceentry.ByScheduledDate()).All(ctx) - 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 + return []MaintenanceEntryWithDetails{}, 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) } diff --git a/backend/internal/data/repo/repo_maintenance_entry_test.go b/backend/internal/data/repo/repo_maintenance_entry_test.go index 0fa288c2d..6f6bc0fdc 100644 --- a/backend/internal/data/repo/repo_maintenance_entry_test.go +++ b/backend/internal/data/repo/repo_maintenance_entry_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/hay-kot/homebox/backend/internal/data/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/sysadminsmedia/homebox/backend/internal/data/types" ) // get the previous month from the current month, accounts for errors when run @@ -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) } diff --git a/backend/internal/data/repo/repo_notifier.go b/backend/internal/data/repo/repo_notifier.go index f31be4b49..867271b78 100644 --- a/backend/internal/data/repo/repo_notifier.go +++ b/backend/internal/data/repo/repo_notifier.go @@ -5,8 +5,8 @@ import ( "time" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/notifier" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/notifier" ) type NotifierRepository struct { @@ -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 } diff --git a/backend/internal/data/repo/repo_tokens.go b/backend/internal/data/repo/repo_tokens.go index 42843e0d4..f6b93260f 100644 --- a/backend/internal/data/repo/repo_tokens.go +++ b/backend/internal/data/repo/repo_tokens.go @@ -5,11 +5,11 @@ import ( "time" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/authroles" - "github.com/hay-kot/homebox/backend/internal/data/ent/authtokens" - "github.com/hay-kot/homebox/backend/pkgs/hasher" - "github.com/hay-kot/homebox/backend/pkgs/set" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authtokens" + "github.com/sysadminsmedia/homebox/backend/pkgs/hasher" + "github.com/sysadminsmedia/homebox/backend/pkgs/set" ) type TokenRepository struct { diff --git a/backend/internal/data/repo/repo_tokens_test.go b/backend/internal/data/repo/repo_tokens_test.go index a0b4375d7..6af4656ab 100644 --- a/backend/internal/data/repo/repo_tokens_test.go +++ b/backend/internal/data/repo/repo_tokens_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/hay-kot/homebox/backend/pkgs/hasher" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/sysadminsmedia/homebox/backend/pkgs/hasher" ) func TestAuthTokenRepo_CreateToken(t *testing.T) { diff --git a/backend/internal/data/repo/repo_users.go b/backend/internal/data/repo/repo_users.go index 68b1eb569..8007fbc04 100644 --- a/backend/internal/data/repo/repo_users.go +++ b/backend/internal/data/repo/repo_users.go @@ -4,8 +4,8 @@ import ( "context" "github.com/google/uuid" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/data/ent/user" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/user" ) type UserRepository struct { @@ -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) } diff --git a/backend/internal/data/repo/repos_all.go b/backend/internal/data/repo/repos_all.go index 2ccc0227b..51c921fa0 100644 --- a/backend/internal/data/repo/repos_all.go +++ b/backend/internal/data/repo/repos_all.go @@ -2,8 +2,8 @@ package repo import ( - "github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus" - "github.com/hay-kot/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/core/services/reporting/eventbus" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" ) // AllRepos is a container for all the repository interfaces diff --git a/backend/internal/web/adapters/decoders.go b/backend/internal/web/adapters/decoders.go index ad5b82b24..e9c9b3480 100644 --- a/backend/internal/web/adapters/decoders.go +++ b/backend/internal/web/adapters/decoders.go @@ -8,8 +8,8 @@ import ( "github.com/go-chi/chi/v5" "github.com/google/uuid" "github.com/gorilla/schema" - "github.com/hay-kot/homebox/backend/internal/sys/validate" "github.com/hay-kot/httpkit/server" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" ) var queryDecoder = schema.NewDecoder() diff --git a/backend/internal/web/mid/errors.go b/backend/internal/web/mid/errors.go index c8b04d67e..f9a98cec8 100644 --- a/backend/internal/web/mid/errors.go +++ b/backend/internal/web/mid/errors.go @@ -4,11 +4,11 @@ import ( "net/http" "github.com/go-chi/chi/v5/middleware" - "github.com/hay-kot/homebox/backend/internal/data/ent" - "github.com/hay-kot/homebox/backend/internal/sys/validate" "github.com/hay-kot/httpkit/errchain" "github.com/hay-kot/httpkit/server" "github.com/rs/zerolog" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/sys/validate" ) type ErrorResponse struct { diff --git a/backend/pkgs/mailer/templates.go b/backend/pkgs/mailer/templates.go index cc5049f74..033023857 100644 --- a/backend/pkgs/mailer/templates.go +++ b/backend/pkgs/mailer/templates.go @@ -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", }, diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts new file mode 100644 index 000000000..19535d27f --- /dev/null +++ b/docs/.vitepress/config.mts @@ -0,0 +1,58 @@ +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.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', + lang: 'en', + } + }, + + themeConfig: { + logo: '/lilbox.svg', + + search: { + provider: 'local' + }, + editLink: { + pattern: 'https://github.com/sysadminsmedia/homebox/edit/main/docs/:path' + }, + // 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: 'Demo', link: 'https://demo.homebox.software' }, + ], + + sidebar: { + '/en/': enMenu, + }, + + socialLinks: [ + { icon: 'discord', link: 'https://discord.homebox.software' }, + { icon: 'github', link: 'https://git.homebox.software' }, + { icon: 'mastodon', link: 'https://noc.social/@sysadminszone' }, + ] + } +}) diff --git a/docs/.vitepress/menus/en.mts b/docs/.vitepress/menus/en.mts new file mode 100644 index 000000000..9063d7730 --- /dev/null +++ b/docs/.vitepress/menus/en.mts @@ -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'} + ] + } +] \ No newline at end of file diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 000000000..def4cfc87 --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,17 @@ +// https://vitepress.dev/guide/custom-theme +import { h } from 'vue' +import type { Theme } from 'vitepress' +import DefaultTheme from 'vitepress/theme' +import './style.css' + +export default { + extends: DefaultTheme, + Layout: () => { + return h(DefaultTheme.Layout, null, { + // https://vitepress.dev/guide/extending-default-theme#layout-slots + }) + }, + enhanceApp({ app, router, siteData }) { + // ... + } +} satisfies Theme diff --git a/docs/.vitepress/theme/style.css b/docs/.vitepress/theme/style.css new file mode 100644 index 000000000..d63aee82d --- /dev/null +++ b/docs/.vitepress/theme/style.css @@ -0,0 +1,139 @@ +/** + * Customize default theme styling by overriding CSS variables: + * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + +/** + * Colors + * + * Each colors have exact same color scale system with 3 levels of solid + * colors with different brightness, and 1 soft color. + * + * - `XXX-1`: The most solid color used mainly for colored text. It must + * satisfy the contrast ratio against when used on top of `XXX-soft`. + * + * - `XXX-2`: The color used mainly for hover state of the button. + * + * - `XXX-3`: The color for solid background, such as bg color of the button. + * It must satisfy the contrast ratio with pure white (#ffffff) text on + * top of it. + * + * - `XXX-soft`: The color used for subtle background such as custom container + * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors + * on top of it. + * + * The soft color must be semi transparent alpha channel. This is crucial + * because it allows adding multiple "soft" colors on top of each other + * to create a accent, such as when having inline code block inside + * custom containers. + * + * - `default`: The color used purely for subtle indication without any + * special meanings attched to it such as bg color for menu hover state. + * + * - `brand`: Used for primary brand colors, such as link text, button with + * brand theme, etc. + * + * - `tip`: Used to indicate useful information. The default theme uses the + * brand color for this by default. + * + * - `warning`: Used to indicate warning to the users. Used in custom + * container, badges, etc. + * + * - `danger`: Used to show error, or dangerous message to the users. Used + * in custom container, badges, etc. + * -------------------------------------------------------------------------- */ + + :root { + --vp-c-default-1: var(--vp-c-gray-1); + --vp-c-default-2: var(--vp-c-gray-2); + --vp-c-default-3: var(--vp-c-gray-3); + --vp-c-default-soft: var(--vp-c-gray-soft); + + --vp-c-brand-1: var(--vp-c-indigo-1); + --vp-c-brand-2: var(--vp-c-indigo-2); + --vp-c-brand-3: var(--vp-c-indigo-3); + --vp-c-brand-soft: var(--vp-c-indigo-soft); + + --vp-c-tip-1: var(--vp-c-brand-1); + --vp-c-tip-2: var(--vp-c-brand-2); + --vp-c-tip-3: var(--vp-c-brand-3); + --vp-c-tip-soft: var(--vp-c-brand-soft); + + --vp-c-warning-1: var(--vp-c-yellow-1); + --vp-c-warning-2: var(--vp-c-yellow-2); + --vp-c-warning-3: var(--vp-c-yellow-3); + --vp-c-warning-soft: var(--vp-c-yellow-soft); + + --vp-c-danger-1: var(--vp-c-red-1); + --vp-c-danger-2: var(--vp-c-red-2); + --vp-c-danger-3: var(--vp-c-red-3); + --vp-c-danger-soft: var(--vp-c-red-soft); +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: transparent; + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand-3); + --vp-button-brand-hover-border: transparent; + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-2); + --vp-button-brand-active-border: transparent; + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-c-brand-1); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + #bd34fe 30%, + #41d1ff + ); + + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + #bd34fe 50%, + #47caff 50% + ); + --vp-home-hero-image-filter: blur(44px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(68px); + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: transparent; + --vp-custom-block-tip-text: var(--vp-c-text-1); + --vp-custom-block-tip-bg: var(--vp-c-brand-soft); + --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand-1) !important; +} + diff --git a/docs/docs/api/openapi-2.0.json b/docs/docs/api/openapi-2.0.json index b10c93ad1..12e556ceb 100644 --- a/docs/docs/api/openapi-2.0.json +++ b/docs/docs/api/openapi-2.0.json @@ -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": [ @@ -2469,6 +2533,9 @@ "parent": { "$ref": "#/definitions/repo.LocationSummary" }, + "totalPrice": { + "type": "number" + }, "updatedAt": { "type": "string" } @@ -2604,26 +2671,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" + }, + "id": { + "type": "string" + }, + "itemID": { + "type": "string" + }, + "itemName": { + "type": "string" + }, + "name": { + "type": "string" }, - "itemId": { + "scheduledDate": { "type": "string" } } }, + "repo.MaintenanceFilterStatus": { + "type": "string", + "enum": [ + "scheduled", + "completed", + "both" + ], + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ] + }, "repo.NotifierCreate": { "type": "object", "required": [ @@ -2665,6 +2755,10 @@ "updatedAt": { "type": "string" }, + "url": { + "description": "URL field is not exposed to the client", + "type": "string" + }, "userId": { "type": "string" } diff --git a/docs/docs/assets/stylesheets/extras.css b/docs/docs/assets/stylesheets/extras.css deleted file mode 100644 index d49058848..000000000 --- a/docs/docs/assets/stylesheets/extras.css +++ /dev/null @@ -1,25 +0,0 @@ -[data-md-color-scheme="homebox"] { - --md-primary-fg-color: #5b7f67; - --md-primary-fg-color--light: #5b7f67; - --md-primary-fg-color--dark: #90030c; -} - - - -/* Site width etc.*/ -.md-grid { - max-width: 64rem !important; -} - -.md-typeset table:not([class]) th { - color: white; - background-color: var(--md-primary-fg-color--light); -} - -th { - font-weight: bold; -} - -.md-button { - padding: 0.2rem 0.75rem !important; -} \ No newline at end of file diff --git a/docs/docs/build.md b/docs/docs/build.md deleted file mode 100644 index e9af902bb..000000000 --- a/docs/docs/build.md +++ /dev/null @@ -1,15 +0,0 @@ -# Building The Binary - -This document describes how to build the project from source code. - -## Prerequisites - -TODO - -## Building - -TODO - -## Running - -TODO \ No newline at end of file diff --git a/docs/docs/quick-start.md b/docs/docs/quick-start.md deleted file mode 100644 index 278b44295..000000000 --- a/docs/docs/quick-start.md +++ /dev/null @@ -1,109 +0,0 @@ -# Quick Start - -## Docker Run - -Great for testing out the application, but not recommended for stable use. Checkout the docker-compose for the recommended deployment. - -For each image there are two tags, respectively the regular tag and $TAG-rootless, which uses a non-root image. - -```sh -# If using the rootless image, ensure data -# folder has correct permissions -$ mkdir -p /path/to/data/folder -$ chown 65532:65532 -R /path/to/data/folder -# --------------------------------------- -# Run the image -$ docker run -d \ - --name homebox \ - --restart unless-stopped \ - --publish 3100:7745 \ - --env TZ=Europe/Bucharest \ - --volume /path/to/data/folder/:/data \ - ghcr.io/hay-kot/homebox:latest -# ghcr.io/hay-kot/homebox:latest-rootless - -``` - -## Docker-Compose - -```yaml -services: - homebox: - image: ghcr.io/hay-kot/homebox:latest -# image: ghcr.io/hay-kot/homebox:latest-rootless - container_name: homebox - restart: always - environment: - - HBOX_LOG_LEVEL=info - - HBOX_LOG_FORMAT=text - - HBOX_WEB_MAX_UPLOAD_SIZE=10 - volumes: - - homebox-data:/data/ - ports: - - 3100:7745 - -volumes: - homebox-data: - driver: local -``` - -!!! note - If you use the `rootless` image, and instead of using named volumes you would prefer using a hostMount directly (e.g., `volumes: [ /path/to/data/folder:/data ]`) you need to `chown` the chosen directory in advance to the `65532` user (as shown in the Docker example above). - -## Env Variables & Configuration - -| Variable | Default | Description | -| ------------------------------------ | ---------------------- | ---------------------------------------------------------------------------------- | -| HBOX_MODE | production | application mode used for runtime behavior can be one of: development, production | -| HBOX_WEB_PORT | 7745 | port to run the web server on, if you're using docker do not change this | -| HBOX_WEB_HOST | | host to run the web server on, if you're using docker do not change this | -| HBOX_OPTIONS_ALLOW_REGISTRATION | true | allow users to register themselves | -| HBOX_OPTIONS_AUTO_INCREMENT_ASSET_ID | true | auto increments the asset_id field for new items | -| HBOX_OPTIONS_CURRENCY_CONFIG | | json configuration file containing additional currencie | -| HBOX_WEB_MAX_UPLOAD_SIZE | 10 | maximum file upload size supported in MB | -| HBOX_WEB_READ_TIMEOUT | 10 | Read timeout of HTTP sever | -| HBOX_WEB_WRITE_TIMEOUT | 10 | Write timeout of HTTP server | -| HBOX_WEB_IDLE_TIMEOUT | 30 | Idle timeout of HTTP server | -| HBOX_STORAGE_DATA | /data/ | path to the data directory, do not change this if you're using docker | -| HBOX_STORAGE_SQLITE_URL | /data/homebox.db?_fk=1 | sqlite database url, if you're using docker do not change this | -| HBOX_LOG_LEVEL | info | log level to use, can be one of: trace, debug, info, warn, error, critical | -| HBOX_LOG_FORMAT | text | log format to use, can be one of: text, json | -| HBOX_MAILER_HOST | | email host to use, if not set no email provider will be used | -| HBOX_MAILER_PORT | 587 | email port to use | -| HBOX_MAILER_USERNAME | | email user to use | -| HBOX_MAILER_PASSWORD | | email password to use | -| HBOX_MAILER_FROM | | email from address to use | -| HBOX_SWAGGER_HOST | 7745 | swagger host to use, if not set swagger will be disabled | -| HBOX_SWAGGER_SCHEMA | http | swagger schema to use, can be one of: http, https | - -!!! tip "CLI Arguments" - If you're deploying without docker you can use command line arguments to configure the application. Run `homebox --help` for more information. - - ```sh - Usage: api [options] [arguments] - - OPTIONS - --mode/$HBOX_MODE (default: development) - --web-port/$HBOX_WEB_PORT (default: 7745) - --web-host/$HBOX_WEB_HOST - --web-max-upload-size/$HBOX_WEB_MAX_UPLOAD_SIZE (default: 10) - --storage-data/$HBOX_STORAGE_DATA (default: ./.data) - --storage-sqlite-url/$HBOX_STORAGE_SQLITE_URL (default: ./.data/homebox.db?_fk=1) - --log-level/$HBOX_LOG_LEVEL (default: info) - --log-format/$HBOX_LOG_FORMAT (default: text) - --mailer-host/$HBOX_MAILER_HOST - --mailer-port/$HBOX_MAILER_PORT - --mailer-username/$HBOX_MAILER_USERNAME - --mailer-password/$HBOX_MAILER_PASSWORD - --mailer-from/$HBOX_MAILER_FROM - --swagger-host/$HBOX_SWAGGER_HOST (default: localhost:7745) - --swagger-scheme/$HBOX_SWAGGER_SCHEME (default: http) - --demo/$HBOX_DEMO - --debug-enabled/$HBOX_DEBUG_ENABLED (default: false) - --debug-port/$HBOX_DEBUG_PORT (default: 4000) - --options-allow-registration/$HBOX_OPTIONS_ALLOW_REGISTRATION (default: true) - --options-auto-increment-asset-id/$HBOX_OPTIONS_AUTO_INCREMENT_ASSET_ID (default: true) - --options-currency-config/$HBOX_OPTIONS_CURRENCY_CONFIG - --help/-h - display this help message - ``` diff --git a/docs/en/configure-homebox.md b/docs/en/configure-homebox.md new file mode 100644 index 000000000..138193e83 --- /dev/null +++ b/docs/en/configure-homebox.md @@ -0,0 +1,59 @@ +# Configure Homebox + +## Env Variables & Configuration + +| Variable | Default | Description | +| ------------------------------------ | ---------------------- | ---------------------------------------------------------------------------------- | +| HBOX_MODE | `production` | application mode used for runtime behavior can be one of: `development`, `production` | +| HBOX_WEB_PORT | 7745 | port to run the web server on, if you're using docker do not change this | +| HBOX_WEB_HOST | | host to run the web server on, if you're using docker do not change this | +| HBOX_OPTIONS_ALLOW_REGISTRATION | true | allow users to register themselves | +| HBOX_OPTIONS_AUTO_INCREMENT_ASSET_ID | true | auto-increments the asset_id field for new items | +| HBOX_OPTIONS_CURRENCY_CONFIG | | json configuration file containing additional currencie | +| HBOX_WEB_MAX_UPLOAD_SIZE | 10 | maximum file upload size supported in MB | +| HBOX_WEB_READ_TIMEOUT | 10s | Read timeout of HTTP sever | +| HBOX_WEB_WRITE_TIMEOUT | 10s | Write timeout of HTTP server | +| HBOX_WEB_IDLE_TIMEOUT | 30s | Idle timeout of HTTP server | +| HBOX_STORAGE_DATA | /data/ | path to the data directory, do not change this if you're using docker | +| HBOX_STORAGE_SQLITE_URL | /data/homebox.db?_fk=1 | sqlite database url, if you're using docker do not change this | +| HBOX_LOG_LEVEL | `info` | log level to use, can be one of `trace`, `debug`, `info`, `warn`, `error`, `critical` | +| HBOX_LOG_FORMAT | `text` | log format to use, can be one of: `text`, `json` | +| HBOX_MAILER_HOST | | email host to use, if not set no email provider will be used | +| HBOX_MAILER_PORT | 587 | email port to use | +| HBOX_MAILER_USERNAME | | email user to use | +| HBOX_MAILER_PASSWORD | | email password to use | +| HBOX_MAILER_FROM | | email from address to use | +| HBOX_SWAGGER_HOST | 7745 | swagger host to use, if not set swagger will be disabled | +| HBOX_SWAGGER_SCHEMA | `http` | swagger schema to use, can be one of: `http`, `https` | + +::: tip "CLI Arguments" +If you're deploying without docker you can use command line arguments to configure the application. Run `homebox --help` for more information. + +```sh +Usage: api [options] [arguments] + +OPTIONS +--mode/$HBOX_MODE (default: development) +--web-port/$HBOX_WEB_PORT (default: 7745) +--web-host/$HBOX_WEB_HOST +--web-max-upload-size/$HBOX_WEB_MAX_UPLOAD_SIZE (default: 10) +--storage-data/$HBOX_STORAGE_DATA (default: ./.data) +--storage-sqlite-url/$HBOX_STORAGE_SQLITE_URL (default: ./.data/homebox.db?_fk=1) +--log-level/$HBOX_LOG_LEVEL (default: info) +--log-format/$HBOX_LOG_FORMAT (default: text) +--mailer-host/$HBOX_MAILER_HOST +--mailer-port/$HBOX_MAILER_PORT +--mailer-username/$HBOX_MAILER_USERNAME +--mailer-password/$HBOX_MAILER_PASSWORD +--mailer-from/$HBOX_MAILER_FROM +--swagger-host/$HBOX_SWAGGER_HOST (default: localhost:7745) +--swagger-scheme/$HBOX_SWAGGER_SCHEME (default: http) +--demo/$HBOX_DEMO +--debug-enabled/$HBOX_DEBUG_ENABLED (default: false) +--debug-port/$HBOX_DEBUG_PORT (default: 4000) +--options-allow-registration/$HBOX_OPTIONS_ALLOW_REGISTRATION (default: true) +--options-auto-increment-asset-id/$HBOX_OPTIONS_AUTO_INCREMENT_ASSET_ID (default: true) +--options-currency-config/$HBOX_OPTIONS_CURRENCY_CONFIG +--help/-h display this help message +``` +::: diff --git a/docs/en/contribute/bounty.md b/docs/en/contribute/bounty.md new file mode 100644 index 000000000..bb1eab62b --- /dev/null +++ b/docs/en/contribute/bounty.md @@ -0,0 +1,19 @@ +# Bounty Program + +## About +As part of our commitment to open source, and building an active community around Homebox (and hopefully active pool of developers), we are enabling bounties on issues. + +After digging through several platforms, we ended up settling on [boss.dev](https://www.boss.dev/) as it has some of the lowest fees we could possibly find for any of these platforms other than spinning one up ourselves (which we currently aren't in a position to do). + +While it's not the perfect solution, we think it's about the best one we could find at the moment to lower the rates as much as possible to make sure everyone get's the highest payouts possible. (Some we found were as high as a combined 16%!!!) + +We hope that by enabling bounties on issues, people who have the means and want certain features implemented quicker can now sponsor issues, and in turn everyone contributing code can potentially earn some money for their hard work. + +## Contributor +As a contributor wanting to accept money from bounties all you need to do is simply register for an account via GitHub, and attach a bank account (or debit card in the USA). + +## Sponsor +Sign in with a GitHub account, and then attach a credit card to your account. + +## Commands to use boss.dev +There is documentation on their website regarding commands that you can put in comments to use the bounty system. [boss.dev Documentation](https://www.boss.dev/doc) diff --git a/docs/en/contribute/get-started.md b/docs/en/contribute/get-started.md new file mode 100644 index 000000000..d335e7ad9 --- /dev/null +++ b/docs/en/contribute/get-started.md @@ -0,0 +1,79 @@ +# Getting Started With Contributing + +## Get Started + +### Prerequisites + +There is a devcontainer available for this project. If you are using VSCode, you can use the devcontainer to get started. If you are not using VSCode, you need to ensure that you have the following tools installed: + +- [Go 1.19+](https://golang.org/doc/install) +- [Swaggo](https://github.com/swaggo/swag) +- [Node.js 16+](https://nodejs.org/en/download/) +- [pnpm](https://pnpm.io/installation) +- [Taskfile](https://taskfile.dev/#/installation) (Optional but recommended) +- For code generation, you'll need to have `python3` available on your path. In most cases, this is already installed and available. + +If you're using `taskfile` you can run `task --list-all` for a list of all commands and their descriptions. + +### Setup + +If you're using the taskfile, you can use the `task setup` command to run the required setup commands. Otherwise, you can review the commands required in the `Taskfile.yml` file. + +Note that when installing dependencies with pnpm, you must use the `--shamefully-hoist` flag. If you don't use this flag, you will get an error when running the frontend server. + +### API Development Notes +start command `task go:run` + +1. API Server does not auto reload. You'll need to restart the server after making changes. +2. Unit tests should be written in Go, however, end-to-end or user story tests should be written in TypeScript using the client library in the frontend directory. + +test command `task go:test` + +lint command `task go:lint` + +swagger update command `task swag` + +### Frontend Development Notes + +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`. +3. Tests require the API server to be running, and in some cases the first run will fail due to a race condition. If this happens, just run the tests again and they should pass. + +fix/lint code `task ui:fix` + +type checking `task ui:check` + +## Documentation +We use [Vitepress](https://vitepress.dev/) for the web documentation of homebox. Anyone is welcome to contribute the documentation if they wish. +For documentation contributions, you only need Node.js and PNPM. + +::: info Notes +- Languages are separated by folder (e.g `/en`, `/fr`, etc.) +- The Sidebar must be updated on a per language basis +- Each language's files can be named independently (slugs can match the language) +- The `public/_redirects` file is used to redirect the default to english +- Redirects can also be configured per language by adding `Language=` after the redirect code +::: + +## Translations +We use our own [Weblate instance](https://translate.sysadminsmedia.com/projects/homebox/) for translations. If you would like to help translate Homebox, please visit the +Weblate instance and help us translate the project. We accept translations for any language. + +If you add a new language, please go to the English translation, press the `Add new translation string` button and then +use `languages.` as the key. For example, if you are adding a French translation, the key would be `languages.fr`. +And then the string should be the name of the language in English. This is used to display the language in the language switcher. + +[![Translation status](http://translate.sysadminsmedia.com/widget/homebox/multi-auto.svg)](http://translate.sysadminsmedia.com/engage/homebox/) + +## Branch Flow +We use the `main` branch as the development branch. All PRs should be made to the `main` branch from a feature branch. +To create a pull request you can use the following steps: + +1. Fork the repo and create a new branch from `main` +2. If you added code that should be tested, add tests +3. If you've changed APIs, update the documentation +4. Ensure that the test suite and linters pass +5. Create your PR + diff --git a/docs/en/images/home-screen.png b/docs/en/images/home-screen.png new file mode 100644 index 000000000..b85edd1d1 Binary files /dev/null and b/docs/en/images/home-screen.png differ diff --git a/docs/docs/import-csv.md b/docs/en/import-csv.md similarity index 80% rename from docs/docs/import-csv.md rename to docs/en/import-csv.md index 6ed4f4b5e..03fe28526 100644 --- a/docs/docs/import-csv.md +++ b/docs/en/import-csv.md @@ -11,8 +11,9 @@ Using the CSV import is the recommended way for adding items to the database. It - CSV Exports do not support nested path exports (e.g. `Home / Office / Desk`) and will only export the Items direct parent, (though imports _do_ support nested paths) - Cannot specify item-to-item relationships (e.g. `Item A` is a child of `Item B`) -!!! tip "File Formats" - The CSV import supports both CSV and TSV files. The only difference is the delimiter used. CSV files use a comma `,` as the delimiter and TSV files use a tab `\t` as the delimiter. The file extension does not matter. +::: tip "File Formats" +The CSV import supports both CSV and TSV files. The only difference is the delimiter used. CSV files use a comma `,` as the delimiter and TSV files use a tab `\t` as the delimiter. The file extension does not matter. +::: ## CSV Reference @@ -24,20 +25,20 @@ Below are the supported columns. They are case-sensitive, can be in any ordered : Import Refs are unique strings that can be used to deduplicate imports. Before an item is imported, we check the database for a matching ref. If the ref exists, we skip the creation of that item. - * String Type - * Max 100 Characters + * String Type + * Max 100 Characters - Import Refs are used to de-duplicate imports. It is HIGHLY recommended that you use them to manage your items if you intend to manage your inventory via CSV import/export. If you do not use import refs, you will end up with duplicate items in your database on subsequent imports. + Import Refs are used to de-duplicate imports. It is HIGHLY recommended that you use them to manage your items if you intend to manage your inventory via CSV import/export. If you do not use import refs, you will end up with duplicate items in your database on subsequent imports. - !!! tip - - Specifying import refs also allows you to update existing items via the CSV import. If you specify an import ref that already exists in the database, we will update the existing item instead of creating a new one. +::: tip +Specifying import refs also allows you to update existing items via the CSV import. If you specify an import ref that already exists in the database, we will update the existing item instead of creating a new one. +::: `HB.location` : This is the location of the item that will be created. These are de-duplicated and won't create another instance when reused. - * Supports Path Separators for nested locations (e.g. `Home / Office / Desk`) + * Supports Path Separators for nested locations (e.g. `Home / Office / Desk`) `HB.labels` @@ -47,7 +48,7 @@ Below are the supported columns. They are case-sensitive, can be in any ordered : This is a special column that allows you to add custom fields to the item. The column name must start with `HB.field.` followed by the name of the field. The value of the column will be the value of the field. - - If the cell value is empty, it will be ignored. + - If the cell value is empty, it will be ignored. ### Standard Columns diff --git a/docs/docs/index.md b/docs/en/index.md similarity index 68% rename from docs/docs/index.md rename to docs/en/index.md index 188dac5cc..c52f9c329 100644 --- a/docs/docs/index.md +++ b/docs/en/index.md @@ -1,19 +1,40 @@ -

-
- -
- Homebox -
-

-

- Docs - | - Demo - | - Discord -

- - +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "HomeBox" + text: "A simple home inventory management software" + image: + src: /lilbox.svg + alt: HomeBox logo + actions: + - theme: brand + text: Quick Start + link: /en/quick-start + - theme: alt + text: Tips and Tricks + link: /en/tips-tricks + - theme: alt + text: Try It Out + link: https://demo.homebox.software + +features: + - title: Add/Update/Delete Items + details: You can add, update and delete your own items in inventory simply + - title: Optional details + details: Optional extra details like warranty information, and item identifications + - title: CSV Import/Export + details: Import a CSV file to quickly get started with existing information, or export to save information + - title: Custom Report + details: Export bill of materials, or generate QR codes for items + - title: Custom labeling and locations + details: Use custom labels and locations to organize items + - title: Multi-Tenant Support + details: All users are in a group, and can only see what's in the group. Invite family members or share an instance with friends. +--- + +![HomeBox Home Screen Screenshot](images/home-screen.png) Homebox is the inventory and organization system built for the Home User! With a focus on simplicity and ease of use, Homebox is the perfect solution for your home inventory, organization, and management needs. While developing this project, I've tried to keep the following principles in mind: @@ -25,23 +46,6 @@ Homebox is the inventory and organization system built for the Home User! With a Homebox is currently in early active development and is currently in **beta** stage. This means that the project may still be unstable and clunky. Overall, we are striving to not introduce any breaking changes and have checks in place to ensure migrations and upgrades are smooth. However, we do not guarantee that there will be no breaking changes. We will try to keep the documentation up to date as we make changes. -## Features - -- Create and Manage _Items_ by providing a name and a description - That's it! Homebox requires only a few details to be provided to create an item, after that you can specify as much detail as you want, or hide away some of the things you won't ever need. -- Optional Details for Items include - - Warranty Information - - Sold To Information - - Purchased From Information - - Item Identifications (Serial, Model, etc) - - Categorized Attachments (Images, Manuals, General) - - Arbitrary/Custom Fields -- CSV Import/Export for quickly creating and managing items -- Custom Reporting - - Bill of Materials Export - - QR Code Label Generator -- Organize _Items_ by creating _Labels_ and _Locations_ and assigning them to items. -- Multi-Tenant Support - All users are placed in a group and can only see items in their group. Invite family members to your group, or share an instance among friends! - ## Why Not Use Something Else? @@ -53,4 +57,4 @@ That's a fair point. If your needs can be fulfilled by a Spreadsheet, I'd sugges ### Snipe-It? -Snipe-It is the gold standard for IT management. If your use-case is to manage consumables and IT physical infrastructure, I highly suggest you look at Snipe-It over Homebox, it's just more purpose built for that use case. Homebox is, in contrast, purpose built for the home user, which means that we try to focus on keeping things simple and easy to use. Lowering the friction for creating items and managing them is a key goal of Homebox which means you lose out on some of the more advanced features. In most cases, this is a good trade-off. \ No newline at end of file +Snipe-It is the gold standard for IT management. If your use-case is to manage consumables and IT physical infrastructure, I highly suggest you look at Snipe-It over Homebox, it's just more purpose built for that use case. Homebox is, in contrast, purpose built for the home user, which means that we try to focus on keeping things simple and easy to use. Lowering the friction for creating items and managing them is a key goal of Homebox which means you lose out on some of the more advanced features. In most cases, this is a good trade-off. diff --git a/docs/en/installation.md b/docs/en/installation.md new file mode 100644 index 000000000..292391971 --- /dev/null +++ b/docs/en/installation.md @@ -0,0 +1,99 @@ +# Installation + +There are two main ways to run the application. + +1. As a [Docker](https://www.docker.com/) container. +2. Using the correct executable for your platform by downloading it from the [Releases](https://github.com/sysadminsmedia/homebox/releases). + + +## Docker + +The following instructions assume Docker is already installed on your system. See [(Docker's official installation guide)](https://docs.docker.com/engine/install/) + +The official image is `ghcr.io/sysadminsmedia/homebox:latest`. For each image there are two tags, respectively the regular tag and $TAG-rootless, which uses a non-root image. + +### Docker Run + +Great for testing out the application, but not recommended for stable use. Checkout the docker-compose below for the recommended deployment. + + +```sh +# If using the rootless image, ensure data +# folder has correct permissions +$ mkdir -p /path/to/data/folder +$ chown 65532:65532 -R /path/to/data/folder +# --------------------------------------- +# Run the image +$ docker run -d \ + --name homebox \ + --restart unless-stopped \ + --publish 3100:7745 \ + --env TZ=Europe/Bucharest \ + --volume /path/to/data/folder/:/data \ + ghcr.io/sysadminsmedia/homebox:latest +# ghcr.io/sysadminsmedia/homebox:latest-rootless +``` + +### Docker Compose + +1. Create a `docker-compose.yml` file. + +```yaml +services: + homebox: + image: ghcr.io/sysadminsmedia/homebox:latest +# image: ghcr.io/sysadminsmedia/homebox:latest-rootless + container_name: homebox + restart: always + environment: + - HBOX_LOG_LEVEL=info + - HBOX_LOG_FORMAT=text + - HBOX_WEB_MAX_UPLOAD_SIZE=10 + volumes: + - homebox-data:/data/ + ports: + - 3100:7745 + +volumes: + homebox-data: + driver: local +``` + +::: info +If you use the `rootless` image, and instead of using named volumes you would prefer using a hostMount directly (e.g., `volumes: [ /path/to/data/folder:/data ]`) you need to `chown` the chosen directory in advance to the `65532` user (as shown in the Docker example above). +::: + +::: warning +If you have previously set up docker compose with the `HBOX_WEB_READ_TIMEOUT`, `HBOX_WEB_WRITE_TIMEOUT`, or `HBOX_IDLE_TIMEOUT` options, and you were previously using the hay-kot image, please note that you will have to add an `s` for seconds or `m` for minutes to the end of the integers. A dependency update removed the defaultation to seconds and it now requires an explicit duration time. +::: + +2. While in the same folder as docker-compose.yml, start the container by running: + +```bash +docker compose up --detach +``` + +3. Navigate to `http://server.local.ip.address:3100/` to access the web interface. (replace with the right IP address). + +You can learn more about Docker by [reading the official Docker documentation.](https://docs.docker.com/) + +## Windows + +1. Download the appropriate release for your CPU architecture from the [releases page on GitHub](https://github.com/sysadminsmedia/homebox/releases). +2. Extract the archive. +3. Run `homebox.exe`. This will start the server on port 7745. +4. You can test it by accessing http://localhost:7745. + +## Linux + +1. Download the appropriate release for your CPU architecture from the [releases page on GitHub](https://github.com/sysadminsmedia/homebox/releases). +2. Extract the archive. +3. Run the `homebox` executable. +4. The web interface will be accessible on port 7745 by default. Access the page by navigating to `http://server.local.ip.address:7745/` (replace with the right ip address) + +## macOS + +1. Download the appropriate release for your CPU architecture from the [releases page on GitHub](https://github.com/sysadminsmedia/homebox/releases). (Use `homebox_Darwin_x86_64.tar.gz` for Intel-based macs and `homebox_Darwin_arm64.tar.gz` for Apple Silicon) +2. Extract the archive. +3. Run the `homebox` executable. +4. The web interface will be accessible on port 7745 by default. Access the page by navigating to `http://local.ip.address:7745/` (replace with the right ip address) \ No newline at end of file diff --git a/docs/en/organizing-items.md b/docs/en/organizing-items.md new file mode 100644 index 000000000..15f1cc34e --- /dev/null +++ b/docs/en/organizing-items.md @@ -0,0 +1,80 @@ +# Organizing Your Items + +Homebox allows you to organize your items using locations and labels. + +## Items + +Items represent an item or asset you want to track in Homebox. + +To create an item, click on the Create button in the main menu, the select Item / Asset. The following parameters are available: +- Parent Location (Required) - The location in which the item is stored +- Item Name (Required) - Name of the item +- Item Description (Optional) - Description of the item +- Labels (Optional) - Here, you can add as many Labels to the item as you like for further organization +- Photo (Optional) - Allows you to add a photo of the item. Additional photos can be added after the item has been created. + +::: details Additional Fields +Once the item is created, additional fields become available. These are: + +**Details Section** +- Quantity +- Serial Number +- Model Number +- Manufacturer +- Notes +- Insured (Checkbox) +- Archived (Checkbox) +- Asset-ID (Populated by default) + +**Purchase Details Section** +- Purchased From +- Purchase Price +- Purchase Date + +**Warranty Details Section** +- Lifetime Warranty (Checkbox) +- Warranty Expires +- Warranty Notes + +**Sold Details Section** +- Sold to +- Sold Price +- Sold At +::: + +You can also add custom fields by scrolling down to the Custom Fields section and clicking the add button. Custom fields are added on a per-item basis, not globally. + +You might want to add attachments to an item (such as photos, a user manual, a warranty, a receipt, etc.) Scroll down to the Attachments section, and either click on the box or drag and drop to add files. Once a file has been added, click edit to edit its details. + +> [!TIP] +> To set the primary image (the image that appears in the Search view) for the item, click on the edit button next to the uploaded image and ensure the Primary Photo checkbox is checked. By default, the first photo you upload will automatically be the Primary Photo. + + +## Locations + +*Items* are stored in *locations*. Locations can be nested to create as many locations as you need. Homebox creates some default locations initially, but you can easily change, delete or rearrange them. + +To create a location, click the Create button in the main menu, then select Location. + +Locations have 3 parameters: +- Name +- Description (Optional) +- Parent Location (Optional -Leave blank if this should be a top-level Location, or select the location you want this location to be nested under) + +To view all locations and the items stored in them, select Locations in the main menu. + +## Labels + +Labels allow you to organize items independently of location. For example, you might have electronic devices all over your house. What if you wanted to see a list of every Electronic Device you own without having to go through every single location? + +Labels enable this. In the example above, if you tag all electronic devices with the "Electronics" label when you create them, you can easily see the list of all your Electronics by going to the related page. + +To create a Label, click the Create button in the menu, then select Label. Labels have the following parameters: +- Name +- Description (Optional) + +To see all items related to a specific label (or specific combination of labels): +- From the Home page, scroll to the bottom and select the Label you want to see. +- Alternatively, navigate to the Search page and use the Labels dropdown to filter by one or more labels. + +Items can have as many labels as you wish. The example above is only one example of how labels can be used for organization. Experiment with what labels work best for you! diff --git a/docs/en/quick-start.md b/docs/en/quick-start.md new file mode 100644 index 000000000..0048251f8 --- /dev/null +++ b/docs/en/quick-start.md @@ -0,0 +1,12 @@ +# Quick Start + +1. Install Homebox either by using [the latest Docker image](https://ghcr.io/sysadminsmedia/homebox:latest), or by downloading the correct executable for your Operating System from the [Releases](https://github.com/sysadminsmedia/homebox/releases). (See [Installation](./installation) for more details) + +2. Browse to `http://SERVER_IP:3100` (if Using Docker) or `http://SERVER_IP:7745` (if installed locally) to access the included web User Interface. + +3. Register your first user. + +4. Login with the user you just created and start adding your locations and items! + +> [!TIP] +> If you want other users to see your items and locations, they will need to sign up using your invite link, otherwise they will only see their own items. Go to the **Profile** section in the left navigation bar and under **User Profile**, click **Generate Invite Link**. \ No newline at end of file diff --git a/docs/docs/tips-tricks.md b/docs/en/tips-tricks.md similarity index 78% rename from docs/docs/tips-tricks.md rename to docs/en/tips-tricks.md index a5ed05a99..5dc90d5bd 100644 --- a/docs/docs/tips-tricks.md +++ b/docs/en/tips-tricks.md @@ -11,15 +11,18 @@ Custom fields are a great way to add any extra information to your item. The fol Custom fields are appended to the main details section of your item. -!!! tip - Homebox Custom Fields also have special support for URLs. Provide a URL (`https://google.com`) and it will be automatically converted to a clickable link in the UI. Optionally, you can also use Markdown syntax to add a custom text to the button. `[Google](https://google.com)` +::: tip +Homebox Custom Fields also have special support for URLs. Provide a URL (`https://google.com`) and it will be automatically converted to a clickable link in the UI. Optionally, you can also use Markdown syntax to add a custom text to the button. `[Google](https://google.com)` +::: ## Managing Asset IDs -Homebox provides the option to auto-set asset IDs, this is the default behavior. These can be used for tracking assets with printable tags or labels. You can disable this behavior via a command line flag or ENV variable. See [configuration](../quick-start#env-variables-configuration) for more details. +Homebox provides the option to auto-set asset IDs, this is the default behavior. These can be used for tracking assets with printable tags or labels. You can disable this behavior via a command line flag or ENV variable. See [configuration](/en/quick-start.md#env-variables-configuration) for more details. Example ID: `000-001` +To search for an Asset ID: type `#` in the search bar followed by the ID you're searching for, e.g. `#000-001`. + Asset IDs are partially managed by Homebox, but have a flexible implementation to allow for unique use cases. IDs are non-unique at the database level, so there is nothing stopping a user from manually setting duplicate IDs for various items. There are two recommended approaches to manage Asset IDs: ### 1. Auto Incrementing IDs @@ -30,18 +33,19 @@ This is the default behavior likely to experience the most consistency. Whenever In some cases, you may want to skip some items such as consumables, or items that are loosely tracked. In this case, we recommend that you leave auto-incrementing IDs enabled _however_ when you create a new item that you want to skip, you can go to that item and reset the ID to 0. This will remove it from the auto-incrementing sequence, and the next item will receive the next available ID. -!!! tip - If you're migrating from an older version, there is an action on the user's profile page to assign IDs to all items. This will assign the next available ID to all items in order of their creation. You should __only do this once__ during the migration process. You should be especially cautious with this if you're using the reset feature described in [option number 2](#2-auto-incrementing-ids-with-reset) +::: tip +If you're migrating from an older version, there is an action on the user's profile page to assign IDs to all items. This will assign the next available ID to all items in order of their creation. You should __only do this once__ during the migration process. You should be especially cautious with this if you're using the reset feature described in [option number 2](#2-auto-incrementing-ids-with-reset) +::: ## QR Codes -:octicons-tag-24: 0.7.0 +:label: 0.7.0 Homebox has a built-in QR code generator that can be used to generate QR codes for your items. This is useful for tracking items with a mobile device. You can generate a QR code for any item by clicking the QR code icon in the top right of the item details page. The same can be done for the Labels and Locations page. Currently, support is limited to generating one-off QR Codes. However, the API endpoint is available for generating QR codes on the fly for any item (or any other data) if you provide a valid API key in the query parameters. An example url would look like `/api/v1/qrcode?data=https://homebox.fly.dev/item/{uuid}`. Currently, the easiest way to get an API token is to use one from an existing URL of the QR Code in the API key, but this will be improved in the future. -:octicons-tag-24: v0.8.0 +:label: v0.8.0 In version 0.8.0 We've added a custom label generation. On the tools page, there is now a link to the label-generator page where you can generate labels based on Asset ID for your inventory. These are still in early development, so please provide feedback. There's also more information on the implementation on the label generator page. @@ -49,7 +53,7 @@ In version 0.8.0 We've added a custom label generation. On the tools page, there ## Scheduled Maintenance Notifications -:octicons-tag-24: v0.9.0 +:label: v0.9.0 Homebox uses [shoutrrr](https://containrrr.dev/shoutrrr/0.7/) to send notifications. This allows you to send notifications to a variety of services. On your profile page, you can add notification URLs to your profile which will be used to send notifications when a maintenance event is scheduled. @@ -60,7 +64,7 @@ As of `v0.9.0` we have limited support for complex scheduling of maintenance eve ## Custom Currencies -:octicons-tag-24: v0.11.0 +:label: v0.11.0 Homebox allows you to add additional currencies to your instance by specify a JSON file containing the currencies you want to add. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml deleted file mode 100644 index 65bd2e1c3..000000000 --- a/docs/mkdocs.yml +++ /dev/null @@ -1,57 +0,0 @@ -site_name: Homebox -site_url: https://hay-kot.github.io/homebox/ -repo_name: Homebox -repo_url: https://github.com/hay-kot/homebox -use_directory_urls: true -theme: - name: material - palette: - # Palette toggle for light mode - - scheme: homebox - toggle: - icon: material/brightness-7 - name: Switch to dark mode - - # Palette toggle for dark mode - - scheme: slate - toggle: - icon: material/brightness-4 - name: Switch to light mode - - features: - - content.code.annotate - - navigation.instant - - navigation.expand - - navigation.sections - - navigation.tabs.sticky - - navigation.tabs - favicon: assets/img/favicon.svg - logo: assets/img/favicon.svg - -plugins: - - tags - -extra_css: - - assets/stylesheets/extras.css - -markdown_extensions: - - pymdownx.emoji: - emoji_index: !!python/name:materialx.emoji.twemoji - emoji_generator: !!python/name:materialx.emoji.to_svg - - def_list - - pymdownx.highlight - - pymdownx.superfences - - pymdownx.tasklist: - custom_checkbox: true - - admonition - - attr_list - - pymdownx.superfences - -nav: - - Home: - - Home: index.md - - Quick Start: quick-start.md - - Tips and Tricks: tips-tricks.md - - Import and Export: import-csv.md - - Building The Binary: build.md - - API: "https://redocly.github.io/redoc/?url=https://hay-kot.github.io/homebox/api/openapi-2.0.json" diff --git a/docs/public/_redirects b/docs/public/_redirects new file mode 100644 index 000000000..5735b3746 --- /dev/null +++ b/docs/public/_redirects @@ -0,0 +1,4 @@ +/ /en/ 302 + +# This is an example for a french redirect +# /* /fr/:splat 302 Language=fr \ No newline at end of file diff --git a/docs/docs/assets/img/favicon.svg b/docs/public/favicon.svg similarity index 100% rename from docs/docs/assets/img/favicon.svg rename to docs/public/favicon.svg diff --git a/docs/docs/assets/img/homebox-email-banner.jpg b/docs/public/homebox-email-banner.jpg similarity index 100% rename from docs/docs/assets/img/homebox-email-banner.jpg rename to docs/public/homebox-email-banner.jpg diff --git a/docs/docs/assets/img/lilbox.svg b/docs/public/lilbox.svg similarity index 100% rename from docs/docs/assets/img/lilbox.svg rename to docs/public/lilbox.svg diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index d7301edf9..000000000 --- a/docs/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -mkdocs-material==9.5.12 \ No newline at end of file diff --git a/fly.toml b/fly.toml deleted file mode 100644 index 22dca66a2..000000000 --- a/fly.toml +++ /dev/null @@ -1,44 +0,0 @@ -# fly.toml file generated for homebox on 2022-09-08T16:00:08-08:00 - -app = "homebox" -kill_signal = "SIGINT" -kill_timeout = 5 -processes = [] - -[build.args] - COMMIT = "HEAD" - VERSION = "nightly" - -[env] - PORT = "7745" - HBOX_DEMO = "true" - -[experimental] - allowed_public_ports = [] - auto_rollback = true - -[[services]] - http_checks = [] - internal_port = 7745 - processes = ["app"] - protocol = "tcp" - script_checks = [] - [services.concurrency] - hard_limit = 25 - soft_limit = 20 - type = "connections" - - [[services.ports]] - force_https = true - handlers = ["http"] - port = 80 - - [[services.ports]] - handlers = ["tls", "http"] - port = 443 - - [[services.tcp_checks]] - grace_period = "1s" - interval = "15s" - restart_limit = 0 - timeout = "2s" diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index c567952cf..e018b4b1c 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -11,6 +11,7 @@ module.exports = { "@nuxtjs/eslint-config-typescript", "plugin:vue/vue3-recommended", "plugin:prettier/recommended", + "plugin:tailwindcss/recommended", ], parserOptions: { ecmaVersion: "latest", diff --git a/frontend/.npmrc b/frontend/.npmrc new file mode 100644 index 000000000..bf2e7648b --- /dev/null +++ b/frontend/.npmrc @@ -0,0 +1 @@ +shamefully-hoist=true diff --git a/frontend/assets/css/main.css b/frontend/assets/css/main.css index 89b2e1cf7..8a9d8fa72 100644 --- a/frontend/assets/css/main.css +++ b/frontend/assets/css/main.css @@ -6,6 +6,10 @@ text-transform: none !important; } +.tooltip { + overflow-wrap: break-word; +} + /* transparent subtle scrollbar */ ::-webkit-scrollbar { width: 0.2em; @@ -23,4 +27,4 @@ ::-webkit-scrollbar-thumb:hover { background-color: #9B9B9B; -} \ No newline at end of file +} diff --git a/frontend/components/App/Header.vue b/frontend/components/App/Header.vue index b42da7f66..c3703730b 100644 --- a/frontend/components/App/Header.vue +++ b/frontend/components/App/Header.vue @@ -68,23 +68,23 @@ -
+
- + -

+

HomeB - + x

-
+
-
+