[
  {
    "path": ".dockerignore",
    "content": ".git\n.idea/\ndownloads\nmigrations\nREADME.md\ndocker-compose.yml\napp/.env\n*.log\n*.pyc\n__pychache__\n"
  },
  {
    "path": ".github/workflows/python-app.yml",
    "content": "# This workflow will install Python dependencies, run tests and lint with a single version of Python\n\nname: Python Code Quality and Tests\n\non:\n  push:\n    branches: [ \"master\" ]\n  pull_request:\n    branches: [ \"master\" ]\n\npermissions:\n  contents: read\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v4\n    - name: Set up Python 3.12\n      uses: actions/setup-python@v3\n      with:\n        python-version: \"3.12\"\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install flake8 black pytest\n        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n    - name: Format check with Black\n      run: |\n        # Check if any files would be reformatted\n        black --check --diff .\n    - name: Lint with flake8\n      run: |\n        # stop the build if there are Python syntax errors or undefined names\n        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics\n        # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide\n        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics\n    # - name: Test with pytest\n    #  run: |\n    #    pytest"
  },
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\napp/downloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\ncover/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\napp/docs/_build/\n\n# PyBuilder\n.pybuilder/\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n#   For a library or package, you might want to ignore these files since the code is\n#   intended to run in multiple environments; otherwise, check them in:\n# .python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# poetry\n#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.\n#   This is especially recommended for binary packages to ensure reproducibility, and is more\n#   commonly ignored for libraries.\n#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control\n#poetry.lock\n\n# pdm\n#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.\n#pdm.lock\n#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it\n#   in version control.\n#   https://pdm.fming.dev/#use-with-ide\n.pdm.toml\n\n# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm\n__pypackages__/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\napp/.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# pytype static type analyzer\n.pytype/\n\n# Cython debug symbols\ncython_debug/\n\n# PyCharm\n#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can\n#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore\n#  and can be added to the global gitignore or merged into this file.  For a more nuclear\n#  option (not recommended) you can uncomment the following to ignore the entire idea folder.\n.idea/\n\n# .pem file\n*.pem\ndownloads/"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"ui\"]\n\tpath = ui\n\turl = https://github.com/jiisanda/docflow-ui.git\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity\nand orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the\n  overall community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or\n  advances of any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email\n  address, without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\n.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series\nof actions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior,  harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within\nthe community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\nhttps://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by [Mozilla's code of conduct\nenforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at\nhttps://www.contributor-covenant.org/faq. Translations are available at\nhttps://www.contributor-covenant.org/translations.\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 jiisanda\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# DocFlow - Document Management API\n\n<div align=\"center\">\n    <img src=\"app/docs/github-banner.png\"><br>\n</div>\n\n![Python](https://img.shields.io/badge/python-3670A0?style=for-the-badge&logo=python&logoColor=ffdd54)\n![FastAPI](https://img.shields.io/badge/FastAPI-005571?style=for-the-badge&logo=fastapi)\n![Postgres](https://img.shields.io/badge/postgres-%23316192.svg?style=for-the-badge&logo=postgresql&logoColor=white)\n![AWS](https://img.shields.io/badge/AWS-%23FF9900.svg?style=for-the-badge&logo=amazon-aws&logoColor=white)\n![JWT](https://img.shields.io/badge/JWT-black?style=for-the-badge&logo=JSON%20web%20tokens)\n![Swagger](https://img.shields.io/badge/-Swagger-%23Clojure?style=for-the-badge&logo=swagger&logoColor=white)\n![Github Pages](https://img.shields.io/badge/github%20pages-121013?style=for-the-badge&logo=github&logoColor=white)\n![GMail](https://img.shields.io/badge/Gmail-D14836?style=for-the-badge&logo=gmail&logoColor=white)\n\nDocFlow is a powerful Document Management API designed to streamline document handling, including seamless uploading, downloading, organization, versioning, sharing, and more.\n\n## 😎 Upcoming Updates\n\n- 🟨 Document Interactions - Adding Comments and Tags\n- 🟨 Import documents from unread emails\n- 🟨 Video Preview\n- 🟨 Adding custom metadata fields to document\n- 🟨 2-factor authentication\n- 🟨 Storage quota per user? (Maybe to enable limit storage per user)\n- 🟨 Bulk file importer\n\n## 🚀 Key Features\n\n- 💡 Document Upload and Download\n- 💡 Organization and Searching\n- 💡 Versioning\n- 💡 Sharing\n- 💡 Authentication and Authorization\n- 💡 Access Control List\n- 💡 Deletion and Archiving\n- 💡 Document Preview\n- 💡 Send file via Email\n- 💡 Minio Support—for on-premise object storage\n\n\n## 📖 API Documentation and Image\n\nExplore the [API Documentation](https://documenter.getpostman.com/view/20984268/2s9YRGxUcp) for detailed information on how to use DocFlow's features.\n\nDetails about features and commands can be found [here](app/docs).\n\nDownload docker image from [docker-hub](https://hub.docker.com/r/jiisanda/docflow).\n\nOr just run\n```commandline\ndocker pull jiisanda/docflow:1\n```\n\n## 🔸 Setup Docflow \n\nFollow the steps outlined in the [setup.md](app/docs/setup.md) file.\n\n## 🧩 Implementation Detail\n\n\n| Features                         | Implementation Detail                                            |\n|----------------------------------|------------------------------------------------------------------|\n| Upload                           | [Detail](https://github.com/jiisanda/docflow#-document-upload)   |\n| Download                         | [Detail](https://github.com/jiisanda/docflow#-document-download) |\n| Sharing                          | [Detail](https://github.com/jiisanda/docflow#-document-sharing)  |\n| Document Preview                 | [Detail](https://github.com/jiisanda/docflow#-document-preview)  |\n\n\n### 📤 Document Upload\n\nHere's how documents are uploaded in DocFlow:\n\n![upload-document](app/docs/imgs/document/document_upload.png)\n\nFor a detailed explanation, visit the [Document Upload Documentation](app/docs/features/upload.md).\n\n### 📥 Document Download\n\nHere's how a user can download a file in DocFlow.\n\n![download-document](app/docs/imgs/document/docflow_download.png)\n\nFor detailed explanation, visit the [Document Download Documentation](). \n\n### 📨 Document Sharing\n\nLearn how to share documents in DocFlow:\n\n![share-document](app/docs/imgs/sharing/document_sharing.png)\n\nFor detailed instructions, visit the [Document Sharing Documentation](app/docs/features/sharing.md).\n\n### 👀 Document Preview\n\nHere's how the preview of docs works in DocFlow.\n\n![preview-document](app/docs/imgs/document/document_preview.png)\n\nFor detailed instructions, visit the [Document Preview Documentation](app/docs/features/preview.md)\n\n## 📜 License\n\n[![Licence](https://img.shields.io/github/license/Ileriayo/markdown-badges?style=for-the-badge)](./LICENSE)\n\n## 📧 Contact Us\n\nFor any questions or support, please [contact](mailto:harshjaiswal2307@gmail.com).\n\nTest DocFlow to manage documents seamlessly!\n"
  },
  {
    "path": "TODO.md",
    "content": "# ✨ TODO \n\nFollowing features are to be added and open for contributions:\n\n- 🟨 Document Interactions - Adding Comments and Tags\n- 🟨 Import documents from unread emails\n- 🟨 Video Preview\n- 🟨 Adding custom metadata fields to document\n- 🟨 2-factor authentication\n- 🟨 Storage quota per user? (Maybe to enable limit storage per user)\n- 🟨 Bulk file importer\n- ⭕ Group Share : Share a document to a group of users Needs: Group creation\n- ⭕ Shared file history: History of all the shared files"
  },
  {
    "path": "__init__.py",
    "content": ""
  },
  {
    "path": "alembic.ini",
    "content": "# A generic, single database configuration.\n\n[alembic]\n# path to migration scripts\nscript_location = migrations\n\n# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s\n# Uncomment the line below if you want the files to be prepended with date and time\n# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file\n# for all available tokens\n# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s\n\n# sys.path path, will be prepended to sys.path if present.\n# defaults to the current working directory.\nprepend_sys_path = .\n\n# timezone to use when rendering the date within the migration file\n# as well as the filename.\n# If specified, requires the python-dateutil library that can be\n# installed by adding `alembic[tz]` to the pip requirements\n# string value is passed to dateutil.tz.gettz()\n# leave blank for localtime\n# timezone =\n\n# max length of characters to apply to the\n# \"slug\" field\n# truncate_slug_length = 40\n\n# set to 'true' to run the environment during\n# the 'revision' command, regardless of autogenerate\n# revision_environment = false\n\n# set to 'true' to allow .pyc and .pyo files without\n# a source .py file to be detected as revisions in the\n# versions/ directory\n# sourceless = false\n\n# version location specification; This defaults\n# to migrations/versions.  When using multiple version\n# directories, initial revisions must be specified with --version-path.\n# The path separator used here should be the separator specified by \"version_path_separator\" below.\n# version_locations = %(here)s/bar:%(here)s/bat:migrations/versions\n\n# version path separator; As mentioned above, this is the character used to split\n# version_locations. The default within new alembic.ini files is \"os\", which uses os.pathsep.\n# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas.\n# Valid values for version_path_separator are:\n#\n# version_path_separator = :\n# version_path_separator = ;\n# version_path_separator = space\nversion_path_separator = os  # Use os.pathsep. Default configuration used for new projects.\n\n# set to 'true' to search source files recursively\n# in each \"version_locations\" directory\n# new in Alembic version 1.10\n# recursive_version_locations = false\n\n# the output encoding used when revision files\n# are written from script.py.mako\n# output_encoding = utf-8\n\nsqlalchemy.url =\n\n\n[post_write_hooks]\n# post_write_hooks defines scripts or Python functions that are run\n# on newly generated revision scripts.  See the documentation for further\n# detail and examples\n\n# format using \"black\" - use the console_scripts runner, against the \"black\" entrypoint\n# hooks = black\n# black.type = console_scripts\n# black.entrypoint = black\n# black.options = -l 79 REVISION_SCRIPT_FILENAME\n\n# lint with attempts to fix using \"ruff\" - use the exec runner, execute a binary\n# hooks = ruff\n# ruff.type = exec\n# ruff.executable = %(here)s/.venv/bin/ruff\n# ruff.options = --fix REVISION_SCRIPT_FILENAME\n\n# Logging configuration\n[loggers]\nkeys = root,sqlalchemy,alembic\n\n[handlers]\nkeys = console\n\n[formatters]\nkeys = generic\n\n[logger_root]\nlevel = WARN\nhandlers = console\nqualname =\n\n[logger_sqlalchemy]\nlevel = WARN\nhandlers =\nqualname = sqlalchemy.engine\n\n[logger_alembic]\nlevel = INFO\nhandlers =\nqualname = alembic\n\n[handler_console]\nclass = StreamHandler\nargs = (sys.stderr,)\nlevel = NOTSET\nformatter = generic\n\n[formatter_generic]\nformat = %(levelname)-5.5s [%(name)s] %(message)s\ndatefmt = %H:%M:%S\n"
  },
  {
    "path": "api.Dockerfile",
    "content": "FROM python:3.12\nLABEL authors=\"jiisanda\"\n\nWORKDIR /usr/src/app\n\nCOPY requirements/api.txt ./\n\nRUN pip install --upgrade pip\nRUN pip install --no-cache-dir -r api.txt  # Fix the path here too\n\nCOPY . .\n\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n"
  },
  {
    "path": "app/__init__.py",
    "content": ""
  },
  {
    "path": "app/api/__init__.py",
    "content": ""
  },
  {
    "path": "app/api/dependencies/__init__.py",
    "content": ""
  },
  {
    "path": "app/api/dependencies/auth_utils.py",
    "content": "from datetime import datetime, timedelta\nfrom typing import Any, Dict\n\nfrom fastapi import Depends\nfrom fastapi.security import OAuth2PasswordBearer\nfrom jose import jwt, JWTError\nfrom passlib.context import CryptContext\n\nfrom app.core.config import settings\nfrom app.core.exceptions import http_401\nfrom app.schemas.auth.bands import TokenData\n\n\n# Password Hashing\npassword_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\n# oauth2 scheme\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"api/u/login\", scheme_name=\"JWT\")\n\n\ndef get_hashed_password(password: str) -> str:\n    return password_context.hash(password)\n\n\ndef verify_password(password: str, hashed_password: str) -> bool:\n    return password_context.verify(password, hashed_password)\n\n\ndef create_access_token(\n    subject: Dict[str, Any], expires_delta: timedelta = None\n) -> str:\n    if expires_delta is not None:\n        expires_delta = datetime.utcnow() + expires_delta\n    else:\n        expires_delta = datetime.utcnow() + timedelta(\n            minutes=settings.access_token_expire_min\n        )\n\n    to_encode = {\n        \"exp\": expires_delta,\n        \"id\": subject.get(\"id\"),\n        \"username\": subject.get(\"username\"),\n    }\n\n    return jwt.encode(to_encode, settings.jwt_secret_key, settings.algorithm)\n\n\ndef create_refresh_token(\n    subject: Dict[str, Any], expires_delta: timedelta = None\n) -> str:\n    if expires_delta is not None:\n        expires_delta = datetime.utcnow() + expires_delta\n    else:\n        expires_delta = datetime.utcnow() + timedelta(\n            minutes=settings.refresh_token_expire_min\n        )\n\n    to_encode = {\n        \"exp\": expires_delta,\n        \"id\": subject.get(\"id\"),\n        \"username\": subject.get(\"username\"),\n    }\n\n    return jwt.encode(to_encode, settings.jwt_secret_key, settings.algorithm)\n\n\ndef verify_access_token(token: str, credentials_exception):\n    try:\n        payload = jwt.decode(\n            token, settings.jwt_secret_key, algorithms=[settings.algorithm]\n        )\n        uid = payload.get(\"id\")\n        username = payload.get(\"username\")\n        if username is None:\n            raise credentials_exception\n        token_data = TokenData(id=uid, username=username)\n    except JWTError as e:\n        raise credentials_exception from e\n\n    return token_data\n\n\ndef get_current_user(token: str = Depends(oauth2_scheme)):\n    credentials_exception = http_401(\n        msg=\"Could not validate credentials\", headers={\"WWW-Authenticate\": \"Bearer\"}\n    )\n\n    return verify_access_token(token=token, credentials_exception=credentials_exception)\n"
  },
  {
    "path": "app/api/dependencies/constants.py",
    "content": "SUPPORTED_FILE_TYPES = {\n    \"image/jpeg\": \"jpg\",\n    \"image/png\": \"png\",\n    \"image/gif\": \"gif\",\n    \"image/bmp\": \"bmp\",\n    \"image/tiff\": \"tiff\",\n    \"application/pdf\": \"pdf\",\n    \"text/plain\": \"txt\",\n    \"application/msword\": \"doc\",\n    \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": \"docx\",\n    \"application/vnd.ms-excel\": \"xls\",\n    \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \"xlsx\",\n    \"application/vnd.ms-powerpoint\": \"ppt\",\n    \"application/vnd.openxmlformats-officedocument.presentationml.presentation\": \"pptx\",\n    \"application/zip\": \"zip\",\n    \"application/x-gzip\": \"gzip\",\n    \"application/x-tar\": \"tar\",\n    \"application/x-bzip2\": \"bz2\",\n    \"application/x-7z-compressed\": \"7z\",\n    \"application/xml\": \"xml\",\n    \"application/json\": \"json\",\n    \"video/mp4\": \"mp4\",\n    \"video/mpeg\": \"mpeg\",\n    \"video/quicktime\": \"mov\",\n    \"audio/mpeg\": \"mp3\",\n    \"audio/wav\": \"wav\",\n    \"audio/x-ms-wma\": \"wma\",\n}\n"
  },
  {
    "path": "app/api/dependencies/mail_service.py",
    "content": "import os.path\nimport smtplib\nimport ssl\n\nfrom email import encoders\nfrom email.mime.base import MIMEBase\nfrom email.mime.multipart import MIMEMultipart\nfrom email.mime.text import MIMEText\n\nfrom app.core.config import settings\nfrom app.core.exceptions import http_500\n\n\ndef mail_service(\n    mail_to: str, subject: str, content: str, file_path: str = None\n) -> None:\n    port = settings.smtp_port  # For starttls\n    smtp_server = settings.smtp_server\n    sender_email = settings.email\n    receiver_email = mail_to\n    password = settings.app_pw\n\n    # Creating Multipart message and headers\n    message = MIMEMultipart()\n    message[\"Subject\"] = subject\n    message.attach(MIMEText(content, _subtype=\"plain\"))\n\n    # Open file in binary mode\n    if file_path is not None:\n        with open(file_path, \"rb\") as attachment:\n            # Below line adds file as application/octet_stream\n            part = MIMEBase(\"application\", \"octet_stream\")\n            part.set_payload(attachment.read())\n\n        # Encoding file in ASCII characters for sending emails\n        encoders.encode_base64(part)\n\n        # header as attachment\n        part.add_header(\n            \"Content-Disposition\",\n            f\"attachment; filename= {os.path.basename(file_path)}\",\n        )\n\n        message.attach(part)\n\n    try:\n        context = ssl.create_default_context()\n        with smtplib.SMTP(smtp_server, port) as server:\n            server.ehlo()\n            server.starttls(context=context)\n            server.ehlo()\n            server.login(sender_email, password)\n            server.sendmail(sender_email, receiver_email, message.as_string())\n    except Exception as e:\n        raise http_500(msg=\"There was some error sending email...\") from e\n"
  },
  {
    "path": "app/api/dependencies/repositories.py",
    "content": "import os.path\nimport re\nfrom typing import Optional\n\nimport ulid\n\nfrom fastapi import Depends\nfrom fastapi.responses import FileResponse\n\nfrom sqlalchemy.ext.asyncio import AsyncSession\n\nfrom app.core.config import settings\nfrom app.db.models import async_session\n\n\nclass TempFileResponse(FileResponse):\n    def __init__(self, path, *args, **kwargs):\n        super().__init__(path, *args, **kwargs)\n        self.file_path = path\n\n    def __del__(self):\n        if os.path.exists(self.file_path):\n            os.remove(self.file_path)\n\n\nasync def get_db() -> AsyncSession:\n    async with async_session() as session:\n        yield session\n        await session.commit()\n\n\ndef get_repository(repository):\n    def _get_repository(session: AsyncSession = Depends(get_db)):\n        return repository(session)\n\n    return _get_repository\n\n\nasync def get_s3_url(key: str) -> str:\n    if settings.s3_endpoint_url:\n        # minio URL format\n        return f\"{settings.s3_endpoint_url}/{settings.s3_bucket}/{key}\"\n    return f\"https://{settings.s3_bucket}.s3.{settings.aws_region}.amazonaws.com/{key}\"\n\n\nasync def get_key(s3_url: str) -> Optional[str]:\n    if settings.s3_endpoint_url:\n        # minio url format: http://host:9000/bucket/key\n        # remove the endpoint and bucket form the URL\n        url_without_endpoint = s3_url.replace(settings.s3_endpoint_url, \"\")\n        url_without_bucket = url_without_endpoint.replace(f\"/{settings.s3_bucket}/\", \"\")\n        return url_without_bucket.lstrip(\"/\")\n    else:\n        pattern = (\n            f\"https://{settings.s3_bucket}\"\n            + r\"\\.s3\\.\"\n            + settings.aws_region\n            + r\"\\.amazonaws\\.com/\"\n            + r\"(.+)\"\n        )\n        if match := re.search(pattern, s3_url):\n            return match[1]\n        return None\n\n\ndef get_ulid():\n    return str(ulid.ULID())\n"
  },
  {
    "path": "app/api/router.py",
    "content": "from fastapi import APIRouter\n\nfrom app.api.routes.auth.auth import router as auth_router\nfrom app.api.routes.documents.documents_metadata import (\n    router as documents_metadata_router,\n)\nfrom app.api.routes.documents.document import router as documents_router\nfrom app.api.routes.documents.document_organization import (\n    router as document_organization_router,\n)\nfrom app.api.routes.documents.document_sharing import router as document_sharing_router\nfrom app.api.routes.documents.notify import router as notify_router\n\nrouter = APIRouter()\n\nrouter.include_router(auth_router, prefix=\"/u\")\nrouter.include_router(documents_router, prefix=\"\")\nrouter.include_router(notify_router, prefix=\"/notifications\")\nrouter.include_router(documents_metadata_router, prefix=\"/metadata\")\nrouter.include_router(document_organization_router, prefix=\"/filter\")\nrouter.include_router(document_sharing_router)\n"
  },
  {
    "path": "app/api/routes/__init__.py",
    "content": ""
  },
  {
    "path": "app/api/routes/auth/__init__.py",
    "content": ""
  },
  {
    "path": "app/api/routes/auth/auth.py",
    "content": "from fastapi import APIRouter, status, Depends\nfrom fastapi.security import OAuth2PasswordRequestForm\n\nfrom app.api.dependencies.auth_utils import get_current_user\nfrom app.api.dependencies.repositories import get_repository\nfrom app.schemas.auth.bands import UserOut, UserAuth, TokenData\nfrom app.db.repositories.auth.auth import AuthRepository\n\nrouter = APIRouter(tags=[\"User Auth\"])\n\n\n@router.post(\n    \"/signup\",\n    response_model=UserOut,\n    status_code=status.HTTP_201_CREATED,\n    name=\"signup\",\n    summary=\"Create new user\",\n)\nasync def signup(\n    data: UserAuth, repository: AuthRepository = Depends(get_repository(AuthRepository))\n):\n\n    return await repository.signup(userdata=data)\n\n\n@router.post(\n    \"/login\",\n    status_code=status.HTTP_200_OK,\n    name=\"login\",\n    summary=\"Create access and refresh tokens for user\",\n)\nasync def login(\n    form_data: OAuth2PasswordRequestForm = Depends(),\n    repository: AuthRepository = Depends(get_repository(AuthRepository)),\n):\n\n    return await repository.login(ipdata=form_data)\n\n\n@router.get(\n    \"/me\",\n    status_code=status.HTTP_200_OK,\n    response_model=TokenData,\n    name=\"get_user_data\",\n    summary=\"Get details of currently logged in user\",\n)\nasync def get_me(user: TokenData = Depends(get_current_user)):\n\n    return user\n"
  },
  {
    "path": "app/api/routes/documents/__init__.py",
    "content": ""
  },
  {
    "path": "app/api/routes/documents/document.py",
    "content": "from typing import Dict, List, Optional, Union\nfrom uuid import UUID\n\nfrom fastapi import APIRouter, status, File, UploadFile, Depends\nfrom fastapi.responses import FileResponse\nfrom sqlalchemy.engine import Row\n\nfrom app.api.dependencies.auth_utils import get_current_user\nfrom app.api.dependencies.repositories import get_repository\nfrom app.core.exceptions import http_400, http_404\nfrom app.db.repositories.auth.auth import AuthRepository\nfrom app.db.repositories.documents.documents import (\n    DocumentRepository,\n    perm_delete as perm_delete_file,\n)\nfrom app.db.repositories.documents.documents_metadata import DocumentMetadataRepository\nfrom app.schemas.auth.bands import TokenData\nfrom app.schemas.documents.documents_metadata import DocumentMetadataRead\n\n\nrouter = APIRouter(tags=[\"Document\"])\n\n\n@router.post(\n    \"/upload\",\n    response_model=None,\n    status_code=status.HTTP_201_CREATED,\n    name=\"upload_document\",\n)\nasync def upload(\n    files: List[UploadFile] = File(...),\n    folder: Optional[str] = None,\n    repository: DocumentRepository = Depends(DocumentRepository),\n    metadata_repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user_repository: AuthRepository = Depends(get_repository(AuthRepository)),\n    user: TokenData = Depends(get_current_user),\n) -> Union[List[DocumentMetadataRead], List[Dict[str, str]]]:\n    \"\"\"\n    Uploads a document to the specified folder.\n\n    Args:\n        files (List[UploadFile]): The files to be uploaded.\n        folder (Optional[str]): The folder where the document will be stored. Defaults to None.\n        repository (DocumentRepository): The repository for managing documents.\n        metadata_repository (DocumentMetadataRepository): The repository for managing document\n            metadata.\n        user_repository (AuthRepository): The repository for managing user authentication.\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        Union[DocumentMetadataRead, Dict[str, str]]: If the file is added, returns the\n            uploaded document metadata.\n            If the file is updated, returns the patched document metadata.\n            Otherwise, returns a response dictionary.\n\n    Raises:\n        HTTP_400: If no input file is provided.\n    \"\"\"\n\n    if not files:\n        raise http_400(msg=\"No input files provided...\")\n\n    responses = []\n    for file in files:\n        response = await repository.upload(\n            metadata_repo=metadata_repository,\n            user_repo=user_repository,\n            file=file,\n            folder=folder,\n            user=user,\n        )\n        if response[\"response\"] == \"file_added\":\n            responses.append(\n                await metadata_repository.upload(document_upload=response[\"upload\"])\n            )\n        elif response[\"response\"] == \"file_updated\":\n            responses.append(\n                await metadata_repository.patch(\n                    document=response[\"upload\"][\"name\"],\n                    document_patch=response[\"upload\"],\n                    owner=user,\n                    user_repo=user_repository,\n                    is_owner=response[\"is_owner\"],\n                )\n            )\n    return responses\n\n\n@router.get(\n    \"/file/{file_name}/download\",\n    status_code=status.HTTP_200_OK,\n    name=\"download_document\",\n)\nasync def download(\n    file_name: str,\n    repository: DocumentRepository = Depends(DocumentRepository),\n    metadata_repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> object:\n    \"\"\"\n    Downloads a document with the specified file name.\n\n    Args:\n        file_name (str): The name of the file to be downloaded.\n        repository (DocumentRepository): The repository for managing documents.\n        metadata_repository (DocumentMetadataRepository): The repository for managing document metadata.\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        object: The downloaded document.\n\n    Raises:\n        HTTP_400: If no file name is provided.\n        HTTP_404: If no file with the specified name is found.\n    \"\"\"\n\n    if not file_name:\n        raise http_400(msg=\"No file name...\")\n    try:\n        get_document_metadata = dict(\n            await metadata_repository.get(document=file_name, owner=user)\n        )\n\n        return await repository.download(\n            s3_url=get_document_metadata[\"s3_url\"], name=get_document_metadata[\"name\"]\n        )\n    except Exception as e:\n        raise http_404(msg=f\"No file with {file_name}\") from e\n\n\n@router.get(\n    \"/trash\",\n    status_code=status.HTTP_200_OK,\n    response_model=None,\n    name=\"list_of_bin\",\n)\nasync def list_bin(\n    metadata_repo: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    owner: TokenData = Depends(get_current_user),\n) -> Dict[str, List[Row | Row] | int]:\n    \"\"\"\n    List bin.\n\n    Args:\n        metadata_repo: The document metadata repository.\n        owner: The token data of the owner.\n\n    Returns:\n        Dict[str, List[Row | Row] | int]: The list of bin.\n\n    \"\"\"\n\n    return await metadata_repo.bin_list(owner=owner)\n\n\n@router.delete(\n    \"/trash\",\n    status_code=status.HTTP_204_NO_CONTENT,\n    name=\"empty_trash\",\n)\nasync def empty_trash(\n    metadata_repo: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> None:\n    \"\"\"\n    Deletes all documents in the trash bin for the authenticated user.\n\n    Args:\n        metadata_repo (DocumentMetadataRepository): The repository for accessing document metadata.\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        None\n    \"\"\"\n\n    return await metadata_repo.empty_bin(owner=user)\n\n\n@router.delete(\n    \"/trash/{file_name}\",\n    status_code=status.HTTP_204_NO_CONTENT,\n    name=\"permanently_delete_doc\",\n)\nasync def perm_delete(\n    file_name: str = None,\n    delete_all: bool = False,\n    metadata_repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> None:\n    \"\"\"\n    Permanently deletes a document.\n\n    Args:\n        file_name (str, optional): The name of the file to be permanently deleted. Defaults to None.\n        delete_all (bool): Flag indicating whether to delete all documents in the bin. Defaults to False.\n        metadata_repository (DocumentMetadataRepository): The repository for managing document metadata.\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        None: If the file is permanently deleted.\n\n    Raises:\n        HTTP_404: If no file with the specified name is found.\n    \"\"\"\n\n    try:\n        get_documents_metadata = dict(await metadata_repository.bin_list(owner=user))\n        if len(get_documents_metadata[\"response\"]) > 0:\n            return await perm_delete_file(\n                file=file_name,\n                delete_all=delete_all,\n                meta_repo=metadata_repository,\n                user=user,\n            )\n\n    except Exception as e:\n        raise http_404(msg=f\"No file with {file_name}\") from e\n\n\n@router.post(\n    \"/restore/{file}\",\n    status_code=status.HTTP_200_OK,\n    response_model=DocumentMetadataRead,\n    name=\"restore_from_bin\",\n)\nasync def restore_bin(\n    file: str,\n    metadata_repo: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> DocumentMetadataRead:\n    \"\"\"\n    Restore bin.\n\n    Args:\n        file: The file to restore.\n        metadata_repo: The document metadata repository.\n        user: The token data of the user.\n\n    Returns:\n        DocumentMetadataRead: The restored document metadata.\n\n    \"\"\"\n\n    return await metadata_repo.restore(file=file, owner=user)\n\n\n@router.delete(\n    \"/{file_name}\", status_code=status.HTTP_204_NO_CONTENT, name=\"add_to_bin\"\n)\nasync def add_to_bin(\n    file_name: str,\n    metadata_repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> None:\n    \"\"\"\n    Adds a document to the bin for deletion.\n\n    Args:\n        file_name (str): The name of the file to be added to the bin.\n        metadata_repository (DocumentMetadataRepository): The repository for managing document metadata.\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        None: If the file is added to the bin.\n    \"\"\"\n\n    return await metadata_repository.delete(document=file_name, owner=user)\n\n\n@router.get(\n    \"/preview/{document}\",\n    status_code=status.HTTP_200_OK,\n    name=\"preview_document\",\n)\nasync def get_document_preview(\n    document: Union[str, UUID],\n    repository: DocumentRepository = Depends(DocumentRepository),\n    metadata_repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> FileResponse:\n    \"\"\"\n    Get the preview of a document.\n\n    Args:\n        document (Union[str, UUID]): The ID or name of the document.\n        repository (DocumentRepository): The repository for accessing document data.\n        metadata_repository (DocumentMetadataRepository): The repository for accessing document metadata.\n        user (TokenData): The user token data.\n\n    Returns:\n        FileResponse: The file response containing the document preview.\n\n    Raises:\n        HTTP_404: If the document ID or name is not provided or if the document does not exist.\n        HTTP_400: If the file type is not supported for preview.\n    \"\"\"\n\n    if not document:\n        raise http_404(msg=\"Enter document id or name.\")\n    try:\n        get_document_metadata = dict(\n            await metadata_repository.get(document=document, owner=user)\n        )\n        return await repository.preview(document=get_document_metadata)\n    except TypeError as e:\n        raise http_404(msg=\"Document does not exists.\") from e\n    except ValueError as e:\n        raise http_400(msg=\"File type is not supported for preview\") from e\n"
  },
  {
    "path": "app/api/routes/documents/document_organization.py",
    "content": "from fastapi import APIRouter, Depends, status, Query\n\nfrom app.api.dependencies.repositories import get_repository\nfrom app.api.dependencies.auth_utils import get_current_user\nfrom app.db.repositories.documents.documents_metadata import DocumentMetadataRepository\nfrom app.db.repositories.documents.document_organization import DocumentOrgRepository\nfrom app.schemas.auth.bands import TokenData\n\nrouter = APIRouter(tags=[\"Document Search\"])\n\n\n@router.get(\n    \"\",\n    # response_model=List[DocumentMetadataRead],\n    status_code=status.HTTP_200_OK,\n    name=\"search_document\",\n)\nasync def search_document(\n    limit: int = Query(default=10, lt=100),\n    offset: int = Query(default=0),\n    tag: str = None,\n    category: str = None,\n    file_types: str = None,\n    doc_status: str = None,\n    repository: DocumentOrgRepository = Depends(DocumentOrgRepository),\n    repository_metadata: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n):\n    \"\"\"\n    Searches for documents based on specified criteria.\n\n    Args:\n        limit (int): The maximum number of documents to retrieve. Defaults to 10.\n        offset (int): The number of documents to skip. Defaults to 0.\n        tag (str, optional): The tag to filter documents by. Defaults to None.\n        category (str, optional): The category to filter documents by. Defaults to None.\n        file_types (str, optional): The file types to filter documents by. Defaults to None.\n        doc_status (str, optional): The status of documents to filter by. Defaults to None.\n        repository (DocumentOrgRepository): The repository for managing document organization.\n        repository_metadata (DocumentMetadataRepository): The repository for managing\n            document metadata.\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        List[DocumentMetadataRead] or List[Dict[str, Any]]: The list of matching documents.\n    \"\"\"\n\n    doc_list = await repository_metadata.doc_list(\n        limit=limit, offset=offset, owner=user\n    )\n    doc_list = doc_list[f\"documents of {user.username}\"]\n    if tag is None and category is None and file_types is None and doc_status is None:\n        return doc_list\n\n    return await repository.search_doc(\n        docs=doc_list,\n        tags=tag,\n        categories=category,\n        file_types=file_types,\n        status=doc_status,\n    )\n"
  },
  {
    "path": "app/api/routes/documents/document_sharing.py",
    "content": "from typing import Union\nfrom uuid import UUID\n\nfrom fastapi import APIRouter, Depends, status\nfrom fastapi.responses import RedirectResponse\n\nfrom app.api.dependencies.auth_utils import get_current_user\nfrom app.api.dependencies.repositories import get_repository, get_key\nfrom app.core.exceptions import http_404\nfrom app.db.repositories.auth.auth import AuthRepository\nfrom app.db.repositories.documents.documents import DocumentRepository\nfrom app.db.repositories.documents.documents_metadata import DocumentMetadataRepository\nfrom app.db.repositories.documents.document_sharing import DocumentSharingRepository\nfrom app.db.repositories.documents.notify import NotifyRepo\nfrom app.schemas.auth.bands import TokenData\nfrom app.schemas.documents.document_sharing import SharingRequest\n\n\nrouter = APIRouter(tags=[\"Document Sharing\"])\n\n\n@router.post(\n    \"/share-link/{document}\", status_code=status.HTTP_200_OK, name=\"share_document_link\"\n)\nasync def share_link_document(\n    document: Union[str, UUID],\n    share_request: SharingRequest,\n    repository: DocumentSharingRepository = Depends(\n        get_repository(DocumentSharingRepository)\n    ),\n    auth_repository: AuthRepository = Depends(get_repository(AuthRepository)),\n    metadata_repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    notify_repository: NotifyRepo = Depends(get_repository(NotifyRepo)),\n    user: TokenData = Depends(get_current_user),\n):\n    \"\"\"\n    Shares a document link with another user, sends mail and notifies the receiver.\n\n    Args:\n        document (Union[str, UUID]): The ID or name of the document to be shared.\n        share_request (SharingRequest): The sharing request containing the\n                details of the sharing operation.\n        repository (DocumentSharingRepository): The repository for managing document sharing.\n        auth_repository (AuthRepository): The repository for managing User-related queries.\n        metadata_repository (DocumentMetadataRepository): The repository for managing\n            document metadata.\n        notify_repository (NotifyRepo): The repository for managing notification\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        Dict[str, str]: A dictionary containing the personal URL and shareable link.\n\n    Raises:\n        HTTP_404: If no document with the specified ID or name is found.\n    \"\"\"\n\n    try:\n        doc = await metadata_repository.get(document=document, owner=user)\n\n        visits = share_request.visits\n        share_to = share_request.share_to\n        pre_signed_url = await repository.get_presigned_url(doc=doc.__dict__)\n        shareable_link = await repository.get_shareable_link(\n            owner_id=user.id,\n            url=pre_signed_url,\n            visits=visits,\n            filename=doc.__dict__[\"name\"],\n            share_to=share_to,\n        )\n\n        if len(share_to) > 0:\n            # Send email to the receiver\n            await repository.send_mail(user=user, mail_to=share_to, link=shareable_link)\n\n            # send a notification to the receiver\n            await notify_repository.notify(\n                user=user,\n                receivers=share_to,\n                filename=doc.__dict__[\"name\"],\n                auth_repo=auth_repository,\n            )\n\n        return {\"personal_url\": pre_signed_url, \"share_this\": shareable_link}\n\n    except KeyError as e:\n        raise http_404(msg=f\"No doc: {document}\") from e\n\n\n@router.get(\"/doc/{url_id}\", tags=[\"Document Sharing\"])\nasync def redirect_to_share(\n    url_id: str,\n    repository: DocumentSharingRepository = Depends(\n        get_repository(DocumentSharingRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n):\n    \"\"\"\n    Redirects to a shared document URL.\n\n    Args:\n        url_id (str): The ID of the shared document URL.\n        repository (DocumentSharingRepository): The repository for managing document sharing.\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        RedirectResponse: A redirect response to the shared document URL.\n    \"\"\"\n\n    if await repository.confirm_access(user=user, url_id=url_id):\n        redirect_url = await repository.get_redirect_url(url_id=url_id)\n\n        return RedirectResponse(redirect_url)\n\n\n@router.post(\"/share/{document}\", status_code=status.HTTP_200_OK, name=\"share_document\")\nasync def share_document(\n    document: Union[str, UUID],\n    share_request: SharingRequest,\n    notify: bool = True,\n    repository: DocumentSharingRepository = Depends(\n        get_repository(DocumentSharingRepository)\n    ),\n    document_repo: DocumentRepository = Depends(DocumentRepository),\n    metadata_repo: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    notify_repo: NotifyRepo = Depends(get_repository(NotifyRepo)),\n    auth_repo: AuthRepository = Depends(get_repository(AuthRepository)),\n    user: TokenData = Depends(get_current_user),\n) -> None:\n    \"\"\"\n    Share a document with other users, and notifies if notify is set to True (default).\n\n    Args:\n    document (Union[str, UUID]): The ID or UUID of the document to be shared.\n    share_request (SharingRequest): The sharing request containing the recipients and permissions.\n    notify (bool, optional): Whether to send notifications to the recipients. Defaults to True.\n    repository (DocumentSharingRepository, optional): The repository for document sharing\n        operations.\n    document_repo (DocumentRepository, optional): The repository for document operations.\n    metadata_repo (DocumentMetadataRepository, optional): The repository for document metadata\n        operations.\n    notify_repo (NotifyRepo, optional): The repository for notification operations.\n    auth_repo (AuthRepository, optional): The repository for authentication operations.\n    user (TokenData, optional): The authenticated user.\n\n    Raises:\n        HTTP_404: If the document is not found.\n\n    Returns:\n        None\n    \"\"\"\n\n    if not document:\n        raise http_404(msg=\"Enter document id or UUID.\")\n    try:\n        get_document_metadata = dict(\n            await metadata_repo.get(document=document, owner=user)\n        )\n        key = await get_key(s3_url=get_document_metadata[\"s3_url\"])\n\n        file = await document_repo.get_s3_file_object_body(key=key)\n\n        return await repository.share_document(\n            filename=get_document_metadata[\"name\"],\n            document_key=key,\n            file=file,\n            share_request=share_request,\n            notify=notify,\n            owner=user,\n            notify_repo=notify_repo,\n            auth_repo=auth_repo,\n        )\n    except Exception as e:\n        raise http_404() from e\n"
  },
  {
    "path": "app/api/routes/documents/documents_metadata.py",
    "content": "from typing import Any, Dict, List, Union\nfrom uuid import UUID\n\nfrom fastapi import APIRouter, status, Body, Depends, Query, HTTPException\n\nfrom app.api.dependencies.repositories import get_repository\nfrom app.api.dependencies.auth_utils import get_current_user\nfrom app.core.exceptions import http_404\nfrom app.db.repositories.auth.auth import AuthRepository\nfrom app.db.repositories.documents.documents_metadata import DocumentMetadataRepository\nfrom app.schemas.auth.bands import TokenData\nfrom app.schemas.documents.bands import DocumentMetadataPatch\nfrom app.schemas.documents.documents_metadata import (\n    DocumentMetadataCreate,\n    DocumentMetadataRead,\n)\n\n\nrouter = APIRouter(tags=[\"Document MetaData\"])\n\n\n@router.post(\n    \"/upload\",\n    response_model=DocumentMetadataRead,\n    status_code=status.HTTP_201_CREATED,\n    name=\"upload_documents_metadata\",\n)\nasync def upload_document_metadata(\n    document_upload: DocumentMetadataCreate = Body(...),\n    repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> DocumentMetadataRead:\n    \"\"\"\n    Uploads document metadata.\n\n    Args:\n        document_upload (DocumentMetadataCreate): The document metadata to be uploaded.\n        repository (DocumentMetadataRepository): The repository for managing document metadata.\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        DocumentMetadataRead: The uploaded document metadata.\n    \"\"\"\n\n    document_upload.owner_id = user.id\n    return await repository.upload(document_upload=document_upload)\n\n\n@router.get(\n    \"\",\n    response_model=Dict[str, Union[List[DocumentMetadataRead], Any]],\n    status_code=status.HTTP_200_OK,\n    name=\"get_documents_metadata\",\n)\nasync def get_documents_metadata(\n    limit: int = Query(default=10, lt=100),\n    offset: int = Query(default=0),\n    repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> Dict[str, Union[List[DocumentMetadataRead], Any]]:\n    \"\"\"\n    Retrieves a list of document metadata.\n\n    Args:\n        limit (int): The maximum number of documents to retrieve. Defaults to 10.\n        offset (int): The number of documents to skip. Defaults to 0.\n        repository (DocumentMetadataRepository): The repository for managing document metadata.\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        Dict[str, Union[List[DocumentMetadataRead], Any]]: A dictionary containing the list of document metadata.\n    \"\"\"\n\n    return await repository.doc_list(limit=limit, offset=offset, owner=user)\n\n\n@router.get(\n    \"/{document}/detail\",\n    response_model=None,\n    status_code=status.HTTP_200_OK,\n    name=\"get_document-metadata\",\n)\nasync def get_document_metadata(\n    document: Union[str, UUID],\n    repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> Union[DocumentMetadataRead, HTTPException]:\n    \"\"\"\n    Retrieves the metadata of a specific document.\n\n    Args:\n        document (Union[str, UUID]): The ID or name of the document.\n        repository (DocumentMetadataRepository): The repository for managing document metadata.\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        Union[DocumentMetadataRead, HTTPException]: The document metadata if found, otherwise an HTTPException.\n    \"\"\"\n\n    return await repository.get(document=document, owner=user)\n\n\n@router.put(\n    \"/{document}\",\n    response_model=None,\n    status_code=status.HTTP_200_OK,\n    name=\"update_doc_metadata_details\",\n)\nasync def update_doc_metadata_details(\n    document: Union[str, UUID],\n    document_patch: DocumentMetadataPatch = Body(...),\n    repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user_repository: AuthRepository = Depends(get_repository(AuthRepository)),\n    user: TokenData = Depends(get_current_user),\n) -> Union[DocumentMetadataRead, HTTPException]:\n    \"\"\"\n    Updates the details of a document's metadata.\n\n    Args:\n        document (Union[str, UUID]): The ID or name of the document.\n        document_patch (DocumentMetadataPatch): The document metadata patch containing the updated details.\n        repository (DocumentMetadataRepository): The repository for managing document metadata.\n        user_repository (AuthRepository): The repository for managing user authentication.\n        user (TokenData): The token data of the authenticated user.\n\n    Returns:\n        Union[DocumentMetadataRead, HTTPException]: The updated document metadata if successful,\n        otherwise an HTTPException.\n\n    Raises:\n        HTTP_404: If no document with the specified ID or name is found.\n    \"\"\"\n\n    try:\n        await repository.get(document=document, owner=user)\n    except Exception as e:\n        raise http_404(msg=f\"No Document with: {document}\") from e\n\n    return await repository.patch(\n        document=document,\n        document_patch=document_patch,\n        owner=user,\n        user_repo=user_repository,\n        is_owner=True,\n    )\n\n\n@router.delete(\n    \"/{document}\",\n    status_code=status.HTTP_204_NO_CONTENT,\n    name=\"delete_document_metadata\",\n)\nasync def delete_document_metadata(\n    document: Union[str, UUID],\n    repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> None:\n    \"\"\"\n    Deletes the metadata of a document and moves it to the bin.\n\n    Args:\n        document (Union[str, UUID]): The identifier of the document to delete.\n        repository (DocumentMetadataRepository): The repository for accessing document metadata.\n            Defaults to the result of the `get_repository` function with `DocumentMetadataRepository` as the argument.\n        user (TokenData): The token data of the current user. Defaults to the result of the `get_current_user` function.\n\n    Returns:\n        None (204_NO_CONTENT)\n\n    Raises:\n        HTTP_404: If no document with the specified identifier is found.\n    \"\"\"\n\n    try:\n        await repository.get(document=document, owner=user)\n    except Exception as e:\n        raise http_404(msg=f\"No document with the detail: {document}.\") from e\n\n    return await repository.delete(document=document, owner=user)\n\n\n# Archiving\n\n\n@router.post(\n    \"/archive/{file_name}\",\n    response_model=DocumentMetadataRead,\n    status_code=status.HTTP_200_OK,\n    name=\"archive_a_document\",\n)\nasync def archive(\n    file_name: str,\n    repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> DocumentMetadataRead:\n    \"\"\"\n    Archive a document.\n\n    Args:\n        file_name (str): The name of the file to be archived.\n        repository (DocumentMetadataRepository): The repository for document metadata.\n        user (TokenData): The user token data.\n\n    Returns:\n        DocumentMetadataRead: The archived document metadata.\n\n    \"\"\"\n\n    return await repository.archive(file=file_name, user=user)\n\n\n@router.get(\n    \"/archive/list\",\n    response_model=None,\n    status_code=status.HTTP_200_OK,\n    name=\"archived_doc_list\",\n)\nasync def archive_list(\n    repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> Dict[str, List[str] | int]:\n    \"\"\"\n    Get the list of archived documents.\n\n    Args:\n        repository (DocumentMetadataRepository): The repository for document metadata.\n        user (TokenData): The user token data.\n\n    Returns:\n        Dict[str, List[str] | int]: A dictionary containing the list of archived documents.\n\n    \"\"\"\n\n    return await repository.archive_list(user=user)\n\n\n@router.post(\n    \"/un-archive/{file}\",\n    response_model=DocumentMetadataRead,\n    status_code=status.HTTP_200_OK,\n    name=\"remove_doc_from_archive\",\n)\nasync def un_archive(\n    file: str,\n    repository: DocumentMetadataRepository = Depends(\n        get_repository(DocumentMetadataRepository)\n    ),\n    user: TokenData = Depends(get_current_user),\n) -> DocumentMetadataRead:\n    \"\"\"\n    Un-archive a document.\n\n    Args:\n        file (str): The name of the file to be un-archived.\n        repository (DocumentMetadataRepository): The repository for document metadata.\n        user (TokenData): The user token data.\n\n    Returns:\n        DocumentMetadataRead: The un-archived document metadata.\n\n    \"\"\"\n\n    return await repository.un_archive(file=file, user=user)\n"
  },
  {
    "path": "app/api/routes/documents/notify.py",
    "content": "from typing import List, Union\nfrom uuid import UUID\n\nfrom fastapi import APIRouter, status, Depends\n\nfrom app.api.dependencies.auth_utils import get_current_user\nfrom app.api.dependencies.repositories import get_repository\nfrom app.core.exceptions import http_404\nfrom app.db.repositories.documents.notify import NotifyRepo\nfrom app.schemas.auth.bands import TokenData\nfrom app.schemas.documents.bands import Notification, NotifyPatchStatus\n\nrouter = APIRouter(tags=[\"Notification\"])\n\n\n@router.get(\"\", status_code=status.HTTP_200_OK, name=\"get_notifications\")\nasync def get_notifications(\n    repository: NotifyRepo = Depends(get_repository(NotifyRepo)),\n    user: TokenData = Depends(get_current_user),\n) -> List[Notification]:\n    \"\"\"\n    Get notifications for a user.\n\n    Args:\n        repository (NotifyRepo): The repository for accessing notification data.\n        user (TokenData): The authenticated user.\n\n    Returns:\n        List[Notification]: A list of notifications for the user.\n    \"\"\"\n\n    return await repository.get_notifications(user=user)\n\n\n@router.put(\n    path=\"/{notification_id}\",\n    status_code=status.HTTP_200_OK,\n    name=\"patch_status\",\n)\nasync def patch_status(\n    updated_status: NotifyPatchStatus = None,\n    notification_id: UUID = None,\n    repository: NotifyRepo = Depends(get_repository(NotifyRepo)),\n    user: TokenData = Depends(get_current_user),\n) -> Union[List[Notification], Notification]:\n    \"\"\"\n    Patch the status of a notification or mark all notifications as read.\n\n    Args:\n        updated_status (NotifyPatchStatus, optional): The updated status for the notification. Defaults to None.\n        notification_id (UUID, optional): The ID of the notification to update. Defaults to None.\n        repository (NotifyRepo): The repository for accessing notification data.\n        user (TokenData): The authenticated user.\n\n    Returns:\n        Union[List[Notification], Notification]: If `mark_as_all_read` is True, returns a list of all notifications\n            marked as read. If `notification_id` is provided, returns the updated notification.\n            Otherwise, raises an HTTP_404 exception.\n\n    Raises:\n        HTTP_404: If 'notification_id' is not provided and update_status.mark_all is set to False.\n    \"\"\"\n\n    if updated_status.mark_all:\n        return await repository.mark_all_read(user=user)\n    if notification_id:\n        return await repository.update_status(\n            n_id=notification_id, updated_status=updated_status, user=user\n        )\n    raise http_404(\n        msg=\"Bad Request: Make sure to either flag mark_all \"\n        \"or enter notification_id along with correct status as payload.\"\n    )\n\n\n@router.delete(\n    path=\"\",\n    status_code=status.HTTP_204_NO_CONTENT,\n    name=\"clear_all_notifications\",\n)\nasync def clear_all_notifications(\n    repository: NotifyRepo = Depends(get_repository(NotifyRepo)),\n    user: TokenData = Depends(get_current_user),\n) -> None:\n    \"\"\"\n    Clear all notifications for a user.\n\n    Args:\n        repository (NotifyRepo): The repository for accessing notification data.\n        user (TokenData): The authenticated user.\n\n    Returns:\n        None\n    \"\"\"\n\n    return await repository.clear_notification(user=user)\n"
  },
  {
    "path": "app/core/__init__.py",
    "content": ""
  },
  {
    "path": "app/core/config.py",
    "content": "import os\nfrom typing import Optional\n\nfrom dotenv import load_dotenv\nfrom pydantic_settings import BaseSettings\n\nload_dotenv()\n\n\nclass GlobalConfig(BaseSettings):\n    \"\"\"\n    Global Configuration for the FastAPI application.\n    \"\"\"\n\n    title: str = os.environ.get(\"TITLE\", \"DocFlow\")\n    version: str = \"1.0.0\"\n    description: str = os.environ.get(\"DESCRIPTION\", \"Document Management API\")\n    host_url: str = \"http://localhost:8000\"\n    docs_url: str = \"/docs\"\n    redoc_url: str = \"/redoc\"\n    openapi_url: str = \"/openapi.json\"\n    api_prefix: str = \"/v2\"\n    debug: bool = str(os.environ.get(\"DEBUG\", \"False\")).lower() == \"true\"\n    postgres_user: str = os.environ.get(\"POSTGRES_USER\", \"\")\n    postgres_password: str = os.environ.get(\"POSTGRES_PASSWORD\", \"\")\n    postgres_hostname: str = os.environ.get(\"DATABASE_HOSTNAME\", \"\")\n    postgres_port: int = int(os.environ.get(\"POSTGRES_PORT\", \"5432\"))\n    postgres_db: str = os.environ.get(\"POSTGRES_DB\", \"\")\n    # s3 / minio configurations\n    aws_access_key_id: str = os.environ.get(\"AWS_ACCESS_KEY_ID\", \"\")\n    aws_secret_key: str = os.environ.get(\"AWS_SECRET_ACCESS_KEY\", \"\")\n    aws_region: str = os.environ.get(\"AWS_REGION\", \"us-east-1\")  # minio doesn't care about a region\n    s3_endpoint_url: Optional[str] = os.environ.get(\"S3_ENDPOINT_URL\") or None\n    s3_bucket: str = os.environ.get(\"S3_BUCKET\", \"\")\n    s3_test_bucket: Optional[str] = os.environ.get(\"S3_TEST_BUCKET\") or None\n    # user config\n    access_token_expire_min: int = int(os.environ.get(\"ACCESS_TOKEN_EXPIRE_MIN\", \"30\"))\n    refresh_token_expire_min: int = int(os.environ.get(\"REFRESH_TOKEN_EXPIRE_MIN\", \"1440\"))\n    algorithm: str = os.environ.get(\"ALGORITHM\", \"HS256\")\n    jwt_secret_key: str = os.environ.get(\"JWT_SECRET_KEY\", \"\")\n    jwt_refresh_secret_key: str = os.environ.get(\"JWT_REFRESH_SECRET_KEY\", \"\")\n    # Email Service\n    smtp_server: str = os.environ.get(\"SMTP_SERVER\", \"\")\n    smtp_port: int = int(os.environ.get(\"SMTP_PORT\", \"587\"))\n    email: str = os.environ.get(\"EMAIL\", \"\")\n    app_pw: str = os.environ.get(\"APP_PASSWORD\", \"\")\n\n    @property\n    def db_echo_log(self) -> bool:\n        return self.debug\n\n    @property\n    def sync_database_url(self) -> str:\n        return (\n            f\"postgresql://{self.postgres_user}:{self.postgres_password}@\"\n            f\"{self.postgres_hostname}:{self.postgres_port}/{self.postgres_db}\"\n        )\n\n    @property\n    def async_database_url(self) -> str:\n        return (\n            f\"postgresql+asyncpg://{self.postgres_user}:{self.postgres_password}@\"\n            f\"{self.postgres_hostname}:{self.postgres_port}/{self.postgres_db}\"\n        )\n\n\nsettings = GlobalConfig()\n"
  },
  {
    "path": "app/core/exceptions.py",
    "content": "from typing import Dict\n\nfrom fastapi.exceptions import HTTPException\nfrom starlette import status\n\n\ndef http_400(msg: str = \"Bad Request...\") -> HTTPException:\n    \"\"\"Invalid Input\"\"\"\n    return HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=msg)\n\n\ndef http_401(\n    msg: str = \"Unauthorized\", headers: Dict[str, str] = None\n) -> HTTPException:\n    \"\"\"Unauthorized Access\"\"\"\n    return HTTPException(\n        status_code=status.HTTP_401_UNAUTHORIZED, detail=msg, headers=headers\n    )\n\n\ndef http_403(msg: str = \"Forbidden\") -> HTTPException:\n    \"\"\"Forbidden access\"\"\"\n    return HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=msg)\n\n\ndef http_404(msg: str = \"Entity does not exists...\") -> HTTPException:\n    \"\"\"Raised when entity was not found on database.\"\"\"\n    return HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=msg)\n\n\ndef http_409(msg: str = \"Entity already exists...\") -> HTTPException:\n    \"\"\"Raised when entity already exists on database.\"\"\"\n    return HTTPException(status_code=status.HTTP_409_CONFLICT, detail=msg)\n\n\ndef http_500(msg: str = \"Internal Server Error\") -> HTTPException:\n    \"\"\"Raised when error caused due to internal server\"\"\"\n    return HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=msg)\n"
  },
  {
    "path": "app/db/__init__.py",
    "content": ""
  },
  {
    "path": "app/db/models.py",
    "content": "import logging\n\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.exc import OperationalError\nfrom sqlalchemy.ext.asyncio import create_async_engine, AsyncSession\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker, Session\n\nfrom app.core.config import settings\nfrom app.core.exceptions import http_500\n\nlogger = logging.getLogger(\"sqlalchemy\")\n\nengine = create_engine(\n    url=settings.sync_database_url,\n    echo=settings.db_echo_log,\n)\n\nasync_engine = create_async_engine(\n    url=settings.async_database_url,\n    echo=settings.db_echo_log,\n    query_cache_size=0,\n)\n\nsession = sessionmaker(bind=engine, autocommit=False, autoflush=False)\n\nasync_session = sessionmaker(\n    bind=async_engine,\n    class_=AsyncSession,\n    autocommit=False,\n    autoflush=False,\n    expire_on_commit=False,\n)\n\nBase = declarative_base()\nmetadata = Base.metadata\n\n\nasync def check_tables():\n    try:\n        with Session(engine) as _session:\n            # Create tables\n            metadata.create_all(engine)\n            _session.commit()\n            logger.info(\"Tables created if they didn't already exist.\")\n    except OperationalError as e:\n        logger.error(\"Error Creating table: %s\", e)\n        raise http_500(msg=\"An error occurred while creating tables.\") from e\n"
  },
  {
    "path": "app/db/repositories/__init__.py",
    "content": ""
  },
  {
    "path": "app/db/repositories/auth/__init__.py",
    "content": ""
  },
  {
    "path": "app/db/repositories/auth/auth.py",
    "content": "from typing import Any, Coroutine\n\nfrom sqlalchemy import select\nfrom sqlalchemy.ext.asyncio import AsyncSession\n\nfrom app.api.dependencies.auth_utils import (\n    get_hashed_password,\n    verify_password,\n    create_access_token,\n    create_refresh_token,\n)\nfrom app.core.exceptions import http_400, http_403\nfrom app.db.tables.auth.auth import User\nfrom app.schemas.auth.bands import UserOut, UserAuth\n\n\nclass AuthRepository:\n    def __init__(self, session: AsyncSession) -> None:\n        self.session = session\n\n    async def _check_user_or_none(\n        self, userdata: UserAuth\n    ) -> Coroutine[Any, Any, Any | None]:\n        stmt = select(User).where(\n            User.username == userdata.username or User.email == userdata.email\n        )\n        result = await self.session.execute(stmt)\n        return result.scalar_one_or_none()\n\n    async def get_user(self, field: str, detail: str):\n        stmt = \"\"\n        if field == \"username\":\n            stmt = select(User).where(User.username == detail)\n        elif field == \"email\":\n            stmt = select(User).where(User.email == detail)\n        result = await self.session.execute(stmt)\n        return result.scalar_one_or_none()\n\n    async def signup(self, userdata: UserAuth) -> UserOut:\n        # Checking if the user already exists\n        if await self._check_user_or_none(userdata) is not None:\n            raise http_400(msg=\"User with details already exists\")\n\n        # hashing the password\n        hashed_password = get_hashed_password(password=userdata.password)\n        userdata.password = hashed_password\n\n        new_user = User(**userdata.model_dump())\n\n        self.session.add(new_user)\n        await self.session.commit()\n        await self.session.refresh(new_user)\n\n        return new_user\n\n    async def login(self, ipdata):\n        user = await self.get_user(field=\"username\", detail=ipdata.username)\n        if user is None:\n            raise http_403(msg=\"Recheck the credentials\")\n        user = user.__dict__\n        hashed_password = user.get(\"password\")\n        if not verify_password(\n            password=ipdata.password, hashed_password=hashed_password\n        ):\n            raise http_403(\"Incorrect Password\")\n\n        return {\n            \"token_type\": \"bearer\",\n            \"access_token\": create_access_token(\n                subject={\"id\": user.get(\"id\"), \"username\": user.get(\"username\")}\n            ),\n            \"refresh_token\": create_refresh_token(\n                subject={\"id\": user.get(\"id\"), \"username\": user.get(\"username\")}\n            ),\n        }\n"
  },
  {
    "path": "app/db/repositories/documents/__init__.py",
    "content": ""
  },
  {
    "path": "app/db/repositories/documents/document_organization.py",
    "content": "from typing import Any, Dict, List, Union\n\nfrom app.api.dependencies.constants import SUPPORTED_FILE_TYPES\nfrom app.schemas.documents.documents_metadata import DocumentMetadataRead\n\n\nclass DocumentOrgRepository:\n    \"\"\"\n    Repository for managing document organization.\n    \"\"\"\n\n    def __init__(self): ...\n\n    @staticmethod\n    async def _search_tags(\n        docs: List[DocumentMetadataRead], tags: List[str]\n    ) -> List[Dict[str, str]]:\n\n        result = []\n        for doc in docs:\n            doc = doc.__dict__\n            result.extend(\n                doc\n                for tag in tags\n                if doc[\"tags\"] and \"\".join(tag.split()) in doc[\"tags\"]\n            )\n\n        return result or None\n\n    @staticmethod\n    async def _search_category(\n        docs: List[DocumentMetadataRead], categories: List[str]\n    ) -> List[Dict[str, str]]:\n\n        result = []\n        for doc in docs:\n            doc = doc.__dict__\n            result.extend(\n                doc\n                for category in categories\n                if doc[\"categories\"] and \"\".join(category.split()) in doc[\"categories\"]\n            )\n\n        return result or None\n\n    @staticmethod\n    async def _search_file_type(\n        docs: List[DocumentMetadataRead], file_types: List[str]\n    ) -> List[Dict[str, str]]:\n\n        result = []\n        for doc in docs:\n            doc = doc.__dict__\n            for ftype in file_types:\n                ftype = \"\".join(ftype.split())\n                result.extend(\n                    doc\n                    for key, val in SUPPORTED_FILE_TYPES.items()\n                    if val == ftype and key == doc[\"file_type\"]\n                )\n\n        return result or None\n\n    @staticmethod\n    async def _search_by_status(\n        docs: List[DocumentMetadataRead], status: List[str]\n    ) -> List[Dict[str, str]]:\n\n        result = []\n        for doc in docs:\n            doc = doc.__dict__\n            result.extend(\n                doc for stat in status if str(doc[\"status\"]) == f\"StatusEnum.{stat}\"\n            )\n\n        return result or None\n\n    async def search_doc(\n        self,\n        docs: List[DocumentMetadataRead],\n        tags: str,\n        categories: str,\n        file_types: str,\n        status: str,\n    ) -> Union[List[List[Dict[str, Any]]], None]:\n\n        results = []\n\n        if tags:\n            tags = tags.split(\",\")\n            results.append(await self._search_tags(docs=docs, tags=tags))\n\n        if categories:\n            categories = categories.split(\",\")\n            results.append(\n                await self._search_category(docs=docs, categories=categories)\n            )\n\n        if file_types:\n            file_type = file_types.split(\",\")\n            results.append(\n                await self._search_file_type(docs=docs, file_types=file_type)\n            )\n\n        if status:\n            _status = status.split(\",\")\n            results.append(await self._search_by_status(docs=docs, status=_status))\n\n        return results\n"
  },
  {
    "path": "app/db/repositories/documents/document_sharing.py",
    "content": "import asyncio\nimport os\nimport secrets\nimport tempfile\nfrom datetime import datetime, timedelta, timezone\nfrom typing import Dict, Any, Union, List\n\nimport boto3\nfrom botocore.exceptions import NoCredentialsError\nfrom sqlalchemy import select, update, delete\nfrom sqlalchemy.ext.asyncio import AsyncSession\n\nfrom app.api.dependencies.mail_service import mail_service\nfrom app.api.dependencies.repositories import get_key\nfrom app.core.config import settings\nfrom app.core.exceptions import http_404, http_500\nfrom app.db.tables.auth.auth import User\nfrom app.db.tables.documents.document_sharing import DocumentSharing\nfrom app.db.repositories.auth.auth import AuthRepository\nfrom app.db.repositories.documents.notify import NotifyRepo\nfrom app.logs.logger import docflow_logger\nfrom app.schemas.auth.bands import TokenData\nfrom app.schemas.documents.document_sharing import SharingRequest\n\n\nclass DocumentSharingRepository:\n    \"\"\"\n    Repository for managing document sharing.\n    \"\"\"\n\n    def __init__(self, session: AsyncSession) -> None:\n        boto3_config = {\n            \"aws_access_key_id\": settings.aws_access_key_id,\n            \"aws_secret_access_key\": settings.aws_secret_key,\n            \"region_name\": settings.aws_region,\n        }\n        if settings.s3_endpoint_url:\n            boto3_config[\"endpoint_url\"] = settings.s3_endpoint_url\n\n        self.client = boto3.client(\"s3\", **boto3_config)\n        self.session = session\n\n    async def get_user_mail(self, user: TokenData):\n\n        stmt = select(User).where(User.id == user.id)\n\n        execute = await self.session.execute(stmt)\n\n        return execute.scalar_one_or_none().__dict__[\"email\"]\n\n    @staticmethod\n    async def _generate_id() -> str:\n        return secrets.token_urlsafe(8)\n\n    async def _get_saved_links(self, filename: str) -> Dict[str, Any]:\n\n        stmt = select(DocumentSharing).where(DocumentSharing.filename == filename)\n\n        result = await self.session.execute(stmt)\n        return result.scalar_one_or_none()\n\n    async def update_visits(self, filename: str, visits_left: int):\n        if visits_left > 1:\n            await self.session.execute(\n                update(DocumentSharing)\n                .where(DocumentSharing.filename == filename)\n                .values(visits=visits_left - 1)\n            )\n        elif visits_left == 1:\n            await self.session.execute(\n                delete(DocumentSharing).where(DocumentSharing.filename == filename)\n            )\n        await self.session.commit()\n\n    async def cleanup_expired_links(self):\n\n        now = datetime.now(timezone.utc)\n\n        stmt = delete(DocumentSharing).where(DocumentSharing.expires_at <= now)\n        try:\n            await self.session.execute(stmt)\n        except Exception as e:\n            raise http_500() from e\n\n    async def get_presigned_url(\n        self, doc: Dict[str, Any]\n    ) -> Union[str, Dict[str, str]]:\n        try:\n            params = {\n                \"Bucket\": settings.s3_bucket,\n                \"Key\": await get_key(s3_url=doc[\"s3_url\"]),\n            }\n            response = await asyncio.to_thread(\n                self.client.generate_presigned_url,\n                \"get_object\",\n                Params=params,\n                ExpiresIn=3600,\n            )\n        except NoCredentialsError as e:\n            return {\"error\": f\"Invalid AWS Credentials: {e}\"}\n\n        return response\n\n    async def get_shareable_link(\n        self, owner_id: str, url: str, visits: int, filename: str, share_to: List[str]\n    ):\n\n        # task to clean uo the database for expired links\n        await self.cleanup_expired_links()\n\n        if ans := await self._get_saved_links(filename=filename):\n            ans = ans.__dict__\n            return {\n                \"note\": f\"Links already shared... valid Till {ans['expires_at']}\",\n                \"response\": {\n                    \"shareable_link\": f\"{settings.host_url}{settings.api_prefix}/doc/{ans['url_id']}\",\n                    \"visits_left\": ans[\"visits\"],\n                },\n            }\n\n        url_id = await self._generate_id()\n        share_entry = DocumentSharing(\n            url_id=url_id,\n            owner_id=owner_id,\n            filename=filename,\n            url=url,\n            expires_at=datetime.now(timezone.utc) + timedelta(seconds=3599),\n            visits=visits,\n            share_to=share_to,\n        )\n        try:\n            self.session.add(share_entry)\n            await self.session.commit()\n            await self.session.refresh(share_entry)\n\n            response = share_entry.__dict__\n            return {\n                \"shareable_link\": f\"{settings.host_url}{settings.api_prefix}/doc/{response['url_id']}\",\n                \"visits\": response[\"visits\"],\n            }\n        except Exception as e:\n            raise http_500() from e\n\n    async def get_redirect_url(self, url_id: str):\n\n        stmt = select(DocumentSharing).where(DocumentSharing.url_id == url_id)\n\n        result = await self.session.execute(stmt)\n        try:\n            result = result.scalar_one_or_none().__dict__\n\n            await self.update_visits(\n                filename=result[\"filename\"], visits_left=result[\"visits\"]\n            )\n\n            return result[\"url\"]\n        except AttributeError as e:\n            raise http_404(\n                msg=\"Shared URL link either expired or reached the limit of visits...\"\n            ) from e\n\n    async def send_mail(\n        self, user: TokenData, mail_to: Union[List[str], None], link: str\n    ) -> None:\n\n        if mail_to:\n\n            user_mail = await self.get_user_mail(user)\n            subj = f\"DocFlow: {user.username} share a document\"\n            content = f\"\"\"\n                    Visit the link: {link}, to access the document\n                    shared by {user.username} | {user_mail}.\n                    \"\"\"\n\n            for mails in mail_to:\n                mail_service(\n                    mail_to=mails, subject=subj, content=content, file_path=None\n                )\n\n    async def confirm_access(self, user: TokenData, url_id: str | None) -> bool:\n        # check if login user is owner or to whom it is shared\n        stmt = select(DocumentSharing).where(DocumentSharing.url_id == url_id)\n\n        result = await self.session.execute(stmt)\n        try:\n            result = result.scalar_one_or_none().__dict__\n            user_mail = await self.get_user_mail(user)\n\n            return (\n                result.get(\"owner_id\") == user.id\n                or user_mail in result.get(\"share_to\")\n                or user.username in result.get(\"share_to\")\n            )\n        except Exception as e:\n            raise http_404(msg=\"The link has expired...\") from e\n\n    async def share_document(\n        self,\n        filename: str,\n        document_key: str,\n        file: Any,\n        share_request: SharingRequest,\n        notify: bool,\n        owner: TokenData,\n        notify_repo: NotifyRepo,\n        auth_repo: AuthRepository,\n    ) -> None:\n\n        user_mail = await self.get_user_mail(owner)\n        share_to = share_request.share_to\n\n        # Determining extension\n        _, extension = os.path.splitext(document_key)\n\n        # Creating temp file to share; delete=False so the file exists when mail_service reads it\n        temp = tempfile.NamedTemporaryFile(delete=False, suffix=extension)\n        try:\n            temp.write(file)\n            temp.close()\n            temp_path = temp.name\n\n            subject = f\"{owner.username} shared a file with you using DocFlow\"\n            for mails in share_to:\n                content = f\"\"\"\n                Hello {mails}!\n\n                Hope you are well? {owner.username} | {user_mail} shared a file\n                with you as an attachment.\n\n                Message: {share_request.message}\n\n                Regards,\n                DocFlow\n                \"\"\"\n                mail_service(\n                    mail_to=mails, subject=subject, content=content, file_path=temp_path\n                )\n        finally:\n            os.unlink(temp_path)\n\n        if notify:\n            return await notify_repo.notify(\n                user=owner, receivers=share_to, filename=filename, auth_repo=auth_repo\n            )\n        return None\n"
  },
  {
    "path": "app/db/repositories/documents/documents.py",
    "content": "import asyncio\nimport hashlib\nimport os\nimport tempfile\nfrom typing import Dict, Any\n\nimport boto3\nfrom botocore.exceptions import ClientError\nfrom fastapi import File\nfrom starlette.responses import FileResponse\n\nfrom app.api.dependencies.constants import SUPPORTED_FILE_TYPES\nfrom app.api.dependencies.repositories import TempFileResponse, get_key, get_s3_url\nfrom app.core.config import settings\nfrom app.core.exceptions import http_400, http_404\nfrom app.db.repositories.documents.documents_metadata import DocumentMetadataRepository\nfrom app.logs.logger import docflow_logger\nfrom app.schemas.auth.bands import TokenData\n\n\ndef _build_boto3_config() -> dict:\n    config = {\n        \"aws_access_key_id\": settings.aws_access_key_id,\n        \"aws_secret_access_key\": settings.aws_secret_key,\n        \"region_name\": settings.aws_region,\n    }\n    if settings.s3_endpoint_url:\n        config[\"endpoint_url\"] = settings.s3_endpoint_url\n    return config\n\n\n_boto3_config = _build_boto3_config()\n_s3_resource = boto3.resource(\"s3\", **_boto3_config)\n_s3_client = boto3.client(\"s3\", **_boto3_config)\n_s3_bucket = _s3_resource.Bucket(settings.s3_bucket)\n\ntry:\n    _s3_client.put_bucket_versioning(\n        Bucket=settings.s3_bucket, VersioningConfiguration={\"Status\": \"Enabled\"}\n    )\nexcept Exception:\n    # MinIO does not support versioning in all configurations\n    pass\n\n\nasync def perm_delete(\n    file: str, delete_all: bool, meta_repo: DocumentMetadataRepository, user: TokenData\n) -> None:\n\n    if delete_all:\n        await meta_repo.empty_bin(owner=user)\n    else:\n        doc = await meta_repo.bin_list(owner=user)\n        for docs in doc.get(\"response\"):\n            if docs.DocumentMetadata.name == file:\n                doc_id = docs.DocumentMetadata.id\n                await meta_repo.perm_delete_a_doc(document=doc_id, owner=user)\n\n\nclass DocumentRepository:\n\n    def __init__(self):\n        self.s3_client = _s3_resource\n        self.client = _s3_client\n        self.s3_bucket = _s3_bucket\n\n    @staticmethod\n    async def _calculate_file_hash(file: File) -> str:\n\n        file.file.seek(0)\n        contents = file.file.read()\n        file.file.seek(0)\n\n        return hashlib.sha256(contents).hexdigest()\n\n    async def get_s3_file_object_body(self, key: str):\n        def _get():\n            obj = self.client.get_object(Bucket=settings.s3_bucket, Key=key)\n            return obj[\"Body\"].read()\n\n        return await asyncio.to_thread(_get)\n\n    async def _delete_object(self, key: str) -> None:\n        await asyncio.to_thread(\n            self.client.delete_object, Bucket=settings.s3_bucket, Key=key\n        )\n\n    async def _upload_new_file(\n        self, file: File, folder: str, contents, file_type: str, user: TokenData\n    ) -> Dict[str, Any]:\n\n        from ulid import ULID\n\n        if folder is None:\n            key = f\"{user.id}/{str(ULID())}.{SUPPORTED_FILE_TYPES[file_type]}\"\n        else:\n            key = f\"{user.id}/{folder}/{str(ULID())}.{SUPPORTED_FILE_TYPES[file_type]}\"\n\n        await asyncio.to_thread(self.s3_bucket.put_object, Key=key, Body=contents)\n\n        return {\n            \"response\": \"file_added\",\n            \"upload\": {\n                \"owner_id\": user.id,\n                \"name\": file.filename,\n                \"s3_url\": await get_s3_url(key=key),\n                \"size\": len(contents),\n                \"file_type\": file_type,\n                \"file_hash\": await self._calculate_file_hash(file=file),\n            },\n        }\n\n    async def _upload_new_version(\n        self,\n        doc: dict,\n        file: File,\n        contents,\n        file_type: str,\n        new_file_hash: str,\n        is_owner: bool,\n    ) -> Dict[str, Any]:\n\n        key = await get_key(s3_url=doc[\"s3_url\"])\n\n        await asyncio.to_thread(self.s3_bucket.put_object, Key=key, Body=contents)\n\n        return {\n            \"response\": \"file_updated\",\n            \"is_owner\": is_owner,\n            \"upload\": {\n                \"name\": file.filename,\n                \"s3_url\": await get_s3_url(key=key),\n                \"size\": len(contents),\n                \"file_type\": file_type,\n                \"file_hash\": new_file_hash,\n            },\n        }\n\n    async def upload(\n        self, metadata_repo, user_repo, file: File, folder: str, user: TokenData\n    ) -> Dict[str, Any]:\n        \"\"\"\n        Uploads a file to the specified folder in the document repository.\n\n        Args:\n            metadata_repo: The repository for accessing metadata.\n            user_repo: The repository for accessing user information.\n            file: The file to be uploaded.\n            folder: The folder in which the file should be uploaded.\n            user: The token data of the user.\n\n        Returns:\n            @return: A dictionary containing the response and upload information.\n\n        Raises:\n            HTTP_400: If the file type is not supported.\n        \"\"\"\n\n        file_type = file.content_type\n        if file_type not in SUPPORTED_FILE_TYPES:\n            raise http_400(msg=f\"File type {file_type} not supported.\")\n\n        contents = await file.read()\n\n        doc = (await metadata_repo.get(document=file.filename, owner=user)).__dict__\n        new_file_hash: str = await self._calculate_file_hash(file=file)\n\n        if \"status_code\" in doc.keys():\n            # getting document irrespective of user\n            if get_doc := await metadata_repo.get_doc(filename=file.filename):\n                get_doc = get_doc.__dict__\n                # Check if logged-in user has update access\n                logged_in_user = (\n                    await user_repo.get_user(field=\"username\", detail=user.username)\n                ).__dict__\n                if (get_doc[\"access_to\"] is not None) and logged_in_user[\n                    \"email\"\n                ] in get_doc[\"access_to\"]:\n                    if get_doc[\"file_hash\"] != new_file_hash:\n                        docflow_logger.info(\n                            f\"User has update access to file owned by: {get_doc['owner_id']}\"\n                        )\n                        return await self._upload_new_version(\n                            doc=get_doc,\n                            file=file,\n                            contents=contents,\n                            file_type=file_type,\n                            new_file_hash=await self._calculate_file_hash(file=file),\n                            is_owner=False,\n                        )\n                else:\n                    return await self._upload_new_file(\n                        file=file,\n                        folder=folder,\n                        contents=contents,\n                        file_type=file_type,\n                        user=user,\n                    )\n            return await self._upload_new_file(\n                file=file,\n                folder=folder,\n                contents=contents,\n                file_type=file_type,\n                user=user,\n            )\n\n        docflow_logger.info(\n            f\"File {file.filename} already present, checking for updates...\"\n        )\n\n        if doc[\"file_hash\"] != new_file_hash:\n            docflow_logger.info(\"File has been updated, uploading new version...\")\n            return await self._upload_new_version(\n                doc=doc,\n                file=file,\n                contents=contents,\n                file_type=file_type,\n                new_file_hash=new_file_hash,\n                is_owner=True,\n            )\n\n        return {\n            \"response\": \"File already present and no changes detected.\",\n            \"upload\": \"Nothing to update...\",\n        }\n\n    async def download(self, s3_url: str, name: str) -> Dict[str, str]:\n\n        key = get_key(s3_url=s3_url)\n\n        try:\n            await asyncio.to_thread(\n                self.s3_client.meta.client.download_file,\n                settings.s3_bucket,\n                await key,\n                r\"/app/downloads/docflow_\" + f\"{name}\",\n            )\n        except ClientError as e:\n            raise http_404(msg=f\"File not found: {e}\") from e\n\n        return {\"message\": f\"successfully downloaded {name} in downloads folder.\"}\n\n    async def preview(self, document: Dict[str, Any]) -> FileResponse:\n\n        key = await get_key(s3_url=document[\"s3_url\"])\n\n        file = await self.get_s3_file_object_body(key)\n\n        _, extension = os.path.splitext(key)\n        ext = extension.lower()\n        if ext in [\".jpg\", \".jpeg\", \".png\", \".gif\"]:\n            media_type = \"image/\" + ext.lstrip(\".\")\n        elif ext == \".pdf\":\n            media_type = \"application/pdf\"\n        elif ext == \".json\":\n            media_type = \"application/json\"\n        elif ext == \".xml\":\n            media_type = \"application/xml\"\n        elif ext == \".txt\":\n            media_type = \"text/plain\"\n        else:\n            raise ValueError(\"Unsupported file type.\")\n\n        with tempfile.NamedTemporaryFile(delete=False, suffix=extension) as temp:\n            temp.write(file)\n            temp_path = temp.name\n\n        return TempFileResponse(temp_path, media_type=media_type)\n"
  },
  {
    "path": "app/db/repositories/documents/documents_metadata.py",
    "content": "from datetime import datetime, timezone, timedelta\nfrom typing import Any, Dict, List, Union\nfrom uuid import UUID\n\nfrom fastapi import HTTPException\nfrom sqlalchemy import select, update, insert, delete\nfrom sqlalchemy.engine import Row\nfrom sqlalchemy.exc import IntegrityError\nfrom sqlalchemy.ext.asyncio import AsyncSession\nfrom sqlalchemy.orm import aliased\n\nfrom app.core.exceptions import http_409, http_404\nfrom app.db.repositories.auth.auth import AuthRepository\nfrom app.db.tables.documents.documents_metadata import DocumentMetadata, doc_user_access\nfrom app.db.tables.base_class import StatusEnum\nfrom app.schemas.auth.bands import TokenData\nfrom app.schemas.documents.bands import DocumentMetadataPatch\nfrom app.schemas.documents.documents_metadata import (\n    DocumentMetadataCreate,\n    DocumentMetadataRead,\n)\n\n\nclass DocumentMetadataRepository:\n\n    def __init__(self, session: AsyncSession) -> None:\n        self.session = session\n        self.doc_cls = aliased(DocumentMetadata, name=\"doc_cls\")\n\n    async def _get_instance(self, document: Union[str, UUID], owner: TokenData):\n\n        try:\n            UUID(str(document))\n            stmt = (\n                select(self.doc_cls)\n                .where(self.doc_cls.owner_id == owner.id)\n                .where(self.doc_cls.id == document)\n                .where(self.doc_cls.status != StatusEnum.deleted)\n            )\n        except ValueError:\n            stmt = (\n                select(self.doc_cls)\n                .where(self.doc_cls.owner_id == owner.id)\n                .where(self.doc_cls.name == document)\n                .where(self.doc_cls.status != StatusEnum.deleted)\n            )\n\n        result = await self.session.execute(stmt)\n\n        return result.scalar_one_or_none()\n\n    @staticmethod\n    async def _extract_changes(document_patch: DocumentMetadataPatch) -> dict:\n\n        if isinstance(document_patch, dict):\n            return document_patch\n        return document_patch.model_dump(exclude_unset=True)\n\n    async def _execute_update(\n        self, db_document: DocumentMetadata | Dict[str, Any], changes: dict\n    ) -> None:\n\n        if isinstance(db_document, dict):\n            stmt = (\n                update(DocumentMetadata)\n                .where(DocumentMetadata.id == db_document.get(\"id\"))\n                .values(changes)\n            )\n            doc_name = db_document.get(\"name\")\n        else:\n            stmt = (\n                update(DocumentMetadata)\n                .where(DocumentMetadata.id == db_document.id)\n                .values(changes)\n            )\n            doc_name = db_document.name\n\n        try:\n            await self.session.execute(stmt)\n        except Exception as e:\n            raise http_409(msg=f\"Error while updating document: {doc_name}\") from e\n\n    async def _update_access_and_permission(self, db_document, changes, user_repo):\n\n        access_given_to = changes.get(\"access_to\", [])\n        # if access_to has email ids, update doc_user_access table with doc_id and user_id\n        for user_email in access_given_to:\n            try:\n                user_id = (\n                    await user_repo.get_user(field=\"email\", detail=user_email)\n                ).__dict__[\"id\"]\n                # update doc_user_access table with doc_id and user_id\n                await self._update_doc_user_access(db_document, user_id)\n\n            except IntegrityError as e:\n                raise http_409(msg=f\"User '{user_email}' already has access...\") from e\n            except AttributeError as e:\n                raise http_404(\n                    msg=f\"The user with '{user_email}' does not exists, make sure user has account in DocFlow.\"\n                ) from e\n\n    async def _update_doc_user_access(self, db_document, user_id):\n\n        stmt = insert(doc_user_access).values(\n            doc_id=db_document.__dict__[\"id\"], user_id=user_id\n        )\n        await self.session.execute(stmt)\n        await self.session.commit()\n\n    async def _delete_access(self, document) -> None:\n        await self.session.execute(\n            doc_user_access.delete().where(doc_user_access.c.doc_id == document.id)\n        )\n\n    async def _auto_delete(self, bin_items: List) -> bool:\n\n        now = datetime.now(timezone.utc)\n        deleted_any = False\n        for doc in bin_items:\n            if doc.deleted_at is not None and doc.deleted_at <= now:\n                stmt = delete(DocumentMetadata).where(DocumentMetadata.id == doc.id)\n                await self.session.execute(stmt)\n                deleted_any = True\n        if deleted_any:\n            await self.session.commit()\n        return deleted_any\n\n    async def get_doc(self, filename: str) -> Dict[str, Any]:\n        \"\"\"\n        Get document by filename irrespective of logged-in user.\n\n        Args:\n            self: The instance of the class.\n            filename (str): The name of the document.\n\n        Returns:\n            Dict[str, Any]: The document metadata.\n        \"\"\"\n\n        stmt = (\n            select(DocumentMetadata)\n            .where(DocumentMetadata.name == filename)\n            .where(self.doc_cls.status != StatusEnum.deleted)\n        )\n        result = await self.session.execute(stmt)\n\n        return result.scalar_one_or_none()\n\n    async def upload(\n        self, document_upload: DocumentMetadataCreate\n    ) -> DocumentMetadataRead:\n\n        if not isinstance(document_upload, dict):\n            db_document = DocumentMetadata(**document_upload.model_dump())\n        else:\n            db_document = DocumentMetadata(**document_upload)\n\n        try:\n            self.session.add(db_document)\n            await self.session.commit()\n            await self.session.refresh(db_document)\n        except IntegrityError as e:\n            raise http_404(\n                msg=f\"Document with name: {document_upload.name} already exists.\",\n            ) from e\n\n        return DocumentMetadataRead(**db_document.__dict__)\n\n    async def doc_list(\n        self, owner: TokenData, limit: int = 10, offset: int = 0\n    ) -> Dict[str, Union[List[DocumentMetadataRead], Any]]:\n\n        stmt = (\n            select(self.doc_cls)\n            .join(DocumentMetadata, DocumentMetadata.id == self.doc_cls.id)\n            .where(DocumentMetadata.owner_id == owner.id)\n            .where(DocumentMetadata.status != StatusEnum.deleted)\n            .offset(offset)\n            .limit(limit)\n        )\n\n        try:\n            result = await self.session.execute(stmt)\n            result_list = result.fetchall()\n\n            for row in result_list:\n                row.doc_cls.__dict__.pop(\"_sa_instance_state\", None)\n\n            result = [\n                DocumentMetadataRead(**row.doc_cls.__dict__) for row in result_list\n            ]\n            return {\"response\": result, \"no_of_docs\": len(result)}\n        except Exception as e:\n            raise http_404(msg=\"No Documents found\") from e\n\n    async def get(\n        self, document: Union[str, UUID], owner: TokenData\n    ) -> Union[DocumentMetadataRead, HTTPException]:\n\n        db_document = await self._get_instance(document=document, owner=owner)\n        if db_document is None:\n            return http_409(msg=f\"No Document with {document}\")\n\n        return DocumentMetadataRead(**db_document.__dict__)\n\n    async def patch(\n        self,\n        document: Union[str, UUID],\n        document_patch: DocumentMetadataPatch,\n        owner: TokenData,\n        user_repo: AuthRepository,\n        is_owner: bool,\n    ) -> Union[DocumentMetadataRead, HTTPException]:\n\n        if is_owner:\n            db_document = await self._get_instance(document=document, owner=owner)\n            changes = await self._extract_changes(document_patch)\n\n            await self._update_access_and_permission(db_document, changes, user_repo)\n\n            await self._execute_update(db_document, changes)\n\n        else:\n            # This condition will be activated when, the new version of file is added by a privileged member\n            # here privileged member is one who have access to update the document.\n            db_document = await self.get_doc(filename=document)\n            changes = await self._extract_changes(document_patch)\n\n            if changes:\n                await self._execute_update(db_document, changes)\n\n        return DocumentMetadataRead(**db_document.__dict__)\n\n    async def delete(self, document: Union[str, UUID], owner: TokenData) -> None:\n\n        try:\n            db_document = await self._get_instance(document=document, owner=owner)\n\n            setattr(db_document, \"status\", StatusEnum.deleted)\n            setattr(db_document, \"tags\", None)\n            setattr(db_document, \"access_to\", None)\n            setattr(db_document, \"file_type\", None)\n            setattr(db_document, \"categories\", None)\n            setattr(\n                db_document,\n                \"deleted_at\",\n                datetime.now(timezone.utc) + timedelta(days=30),\n            )\n\n            # delete entry from doc_user_access table\n            await self._delete_access(document=db_document)\n\n            self.session.add(db_document)\n\n            await self.session.commit()\n        except Exception as e:\n            raise http_404(msg=f\"No file with {document}\") from e\n\n    async def bin_list(self, owner: TokenData) -> Dict[str, List[Row | Row] | int]:\n\n        stmt = (\n            select(DocumentMetadata)\n            .where(DocumentMetadata.owner_id == owner.id)\n            .where(DocumentMetadata.status == StatusEnum.deleted)\n        )\n\n        result = (await self.session.execute(stmt)).scalars().all()\n        if await self._auto_delete(result):\n            result = (await self.session.execute(stmt)).scalars().all()\n\n        serialized = []\n        for doc in result:\n            d = {k: v for k, v in doc.__dict__.items() if k != \"_sa_instance_state\"}\n            serialized.append(DocumentMetadataRead(**d))\n\n        return {\"response\": serialized, \"no_of_docs\": len(serialized)}\n\n    async def restore(self, file: str, owner: TokenData) -> DocumentMetadataRead:\n\n        stmt = (\n            select(DocumentMetadata)\n            .where(DocumentMetadata.owner_id == owner.id)\n            .where(DocumentMetadata.name == file)\n            .where(DocumentMetadata.status == StatusEnum.deleted)\n        )\n        db_doc = (await self.session.execute(stmt)).scalar_one_or_none()\n        if db_doc is None:\n            raise http_404(msg=f\"'{file}' not found in trash\")\n\n        await self._execute_update(db_document=db_doc, changes={\"status\": StatusEnum.private, \"deleted_at\": None})\n        await self.session.commit()\n        d = {k: v for k, v in db_doc.__dict__.items() if k != \"_sa_instance_state\"}\n        return DocumentMetadataRead(**d)\n\n    async def perm_delete_a_doc(self, document: UUID | None, owner: TokenData) -> None:\n\n        stmt = (\n            delete(DocumentMetadata)\n            .where(DocumentMetadata.owner_id == owner.id)\n            .where(DocumentMetadata.id == document)\n            .where(DocumentMetadata.status == StatusEnum.deleted)\n        )\n\n        await self.session.execute(stmt)\n\n    async def empty_bin(self, owner: TokenData):\n\n        stmt = (\n            delete(DocumentMetadata)\n            .where(DocumentMetadata.owner_id == owner.id)\n            .where(DocumentMetadata.status == StatusEnum.deleted)\n        )\n\n        await self.session.execute(stmt)\n\n    async def archive(self, file: str, user: TokenData):\n\n        doc = await self._get_instance(document=file, owner=user)\n\n        if doc and doc.status == StatusEnum.archived:\n            raise http_409(msg=\"Doc is already archived\")\n\n        if doc is None:\n            raise http_404(msg=\"Doc does not exist\")\n\n        await self._execute_update(db_document=doc, changes={\"status\": StatusEnum.archived})\n        await self.session.commit()\n        d = {k: v for k, v in doc.__dict__.items() if k != \"_sa_instance_state\"}\n        return DocumentMetadataRead(**d)\n\n    async def archive_list(self, user: TokenData) -> Dict[str, List[str] | int]:\n\n        stmt = (\n            select(DocumentMetadata)\n            .where(DocumentMetadata.owner_id == user.id)\n            .where(DocumentMetadata.status == StatusEnum.archived)\n        )\n\n        result = (await self.session.execute(stmt)).scalars().all()\n        serialized = [\n            DocumentMetadataRead(**{k: v for k, v in doc.__dict__.items() if k != \"_sa_instance_state\"})\n            for doc in result\n        ]\n        return {\"response\": serialized, \"no_of_docs\": len(serialized)}\n\n    async def un_archive(self, file: str, user: TokenData) -> DocumentMetadataRead:\n\n        doc = await self._get_instance(document=file, owner=user)\n\n        if doc and doc.status == StatusEnum.archived:\n            change = {\"status\": \"private\"}\n            await self._execute_update(db_document=doc, changes=change)\n            return DocumentMetadataRead(**doc.__dict__)\n        if doc and doc.status != StatusEnum.archived:\n            raise http_409(msg=\"Doc is not archived\")\n        raise http_404(msg=\"Doc does not exits\")\n"
  },
  {
    "path": "app/db/repositories/documents/notify.py",
    "content": "from typing import List\nfrom uuid import UUID\n\nfrom sqlalchemy import select, update, delete\nfrom sqlalchemy.ext.asyncio import AsyncSession\n\nfrom app.core.exceptions import http_500, http_409, http_404\nfrom app.db.repositories.auth.auth import AuthRepository\nfrom app.db.tables.base_class import NotifyEnum\nfrom app.db.tables.documents.notify import Notify\nfrom app.schemas.auth.bands import TokenData\nfrom app.schemas.documents.bands import Notification, NotifyPatchStatus\n\n\nclass NotifyRepo:\n\n    def __init__(self, session: AsyncSession) -> None:\n        self.session = session\n\n    async def notify(\n        self,\n        user: TokenData,\n        receivers: List[str],\n        filename: str,\n        auth_repo: AuthRepository,\n    ) -> None:\n        \"\"\"\n        Notify users about a shared file.\n\n        Args:\n            user (TokenData): The authenticated user who shared the file.\n            receivers (List[str]): The list of email addresses of the users to be notified.\n            filename (str): The name of the shared file.\n            auth_repo (AuthRepository): The repository for accessing user authentication data.\n\n        Returns:\n            None\n\n        Raises:\n            HTTP_500: If an error occurs while adding the notification entry.\n        \"\"\"\n\n        for receiver in receivers:\n\n            receiver_details = await auth_repo.get_user(field=\"email\", detail=receiver)\n            try:\n                notify_entry = Notify(\n                    receiver_id=receiver_details.__dict__[\"id\"],\n                    message=f\"{user.username} shared {filename} with you! Access the shared file via mail...\",\n                    status=NotifyEnum.unread,\n                )\n\n                try:\n                    self.session.add(notify_entry)\n                    await self.session.commit()\n                    await self.session.refresh(notify_entry)\n                except Exception as e:\n                    raise http_500(\n                        msg=\"Error notifying the user, but the mail has been sent successfully.\"\n                    ) from e\n            except Exception as e:\n                raise http_404(\n                    msg=\"The user does not exists, make sure the user has an account on docflow...\"\n                ) from e\n\n    async def get_notification_by_id(self, n_id: UUID, user: TokenData) -> Notification:\n        \"\"\"\n        Get a notification by its ID for a specific user.\n\n        Args:\n            n_id (UUID): The ID of the notification.\n            user (TokenData): The authenticated user.\n\n        Returns:\n            Notification: The notification object.\n\n        Raises:\n            HTTP_404: If no notification with the given ID is found.\n        \"\"\"\n\n        stmt = select(Notify).where(Notify.receiver_id == user.id and Notify.id == n_id)\n\n        try:\n            result = (await self.session.execute(stmt)).scalar_one_or_none()\n            return Notification(**result.__dict__)\n        except Exception as e:\n            raise http_404(msg=f\"No notification with id: {n_id}\") from e\n\n    async def get_notifications(self, user: TokenData) -> List[Notification]:\n        \"\"\"\n        Get all notifications for a specific user.\n\n        Args:\n            user (TokenData): The authenticated user.\n\n        Returns:\n            List[Notification]: A list of notification objects.\n        \"\"\"\n\n        stmt = select(Notify).where(Notify.receiver_id == user.id)\n\n        notifications = (await self.session.execute(stmt)).fetchall()\n\n        return [\n            Notification(**notification.Notify.__dict__)\n            for notification in notifications\n        ]\n\n    async def mark_all_read(self, user: TokenData) -> List[Notification]:\n        \"\"\"\n        Mark all notifications as read for a specific user.\n\n        Args:\n            user (TokenData): The authenticated user.\n\n        Returns:\n            List[Notification]: A list of notification objects that have been marked as read.\n\n        Raises:\n            HTTP_409: If an error occurs while updating the notification status.\n        \"\"\"\n\n        stmt = (\n            update(Notify)\n            .where(Notify.receiver_id == user.id and Notify.status != NotifyEnum.read)\n            .values({Notify.status: NotifyEnum.read})\n        )\n\n        try:\n            await self.session.execute(stmt)\n            return await self.get_notifications(user=user)\n        except Exception as e:\n            raise http_409(msg=\"Error updating marking notification read...\") from e\n\n    async def update_status(\n        self, n_id: UUID, updated_status: NotifyPatchStatus, user: TokenData\n    ):\n        \"\"\"\n        Update the status of a notification for a specific user.\n\n        Args:\n            n_id (UUID): The ID of the notification to update.\n            updated_status (NotifyPatchStatus): The updated status for the notification.\n            user (TokenData): The authenticated user.\n\n        Returns:\n            Notification: The updated notification object.\n\n        Raises:\n            HTTP_409: If an error occurs while updating the notification status.\n        \"\"\"\n        stmt = (\n            update(Notify)\n            .where(\n                Notify.receiver_id == user.id\n                and Notify.id == n_id\n                and Notify.status != updated_status.status\n            )\n            .values({Notify.status: updated_status.status})\n        )\n\n        try:\n            await self.session.execute(stmt)\n            return await self.get_notification_by_id(n_id=n_id, user=user)\n        except Exception as e:\n            raise http_409(msg=\"Error updating notification status...\") from e\n\n    async def clear_notification(self, user: TokenData) -> None:\n        \"\"\"\n        Clear all notifications for a specific user.\n\n        Args:\n            user (TokenData): The authenticated user.\n\n        Returns:\n            None\n\n        Raises:\n            Exception: If an error occurs while clearing the notifications.\n        \"\"\"\n\n        stmt = delete(Notify).where(Notify.receiver_id == user.id)\n\n        try:\n            await self.session.execute(stmt)\n        except Exception as e:\n            raise e\n"
  },
  {
    "path": "app/db/tables/__init__.py",
    "content": ""
  },
  {
    "path": "app/db/tables/auth/__init__.py",
    "content": ""
  },
  {
    "path": "app/db/tables/auth/auth.py",
    "content": "from sqlalchemy import Column, String, Text, TIMESTAMP\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy.sql.expression import text\n\nfrom app.api.dependencies.repositories import get_ulid\nfrom app.db.models import Base\n\n\nclass User(Base):\n    __tablename__ = \"users\"\n\n    id = Column(\n        String(26),\n        primary_key=True,\n        default=get_ulid,\n        unique=True,\n        index=True,\n        nullable=False,\n    )\n    username: str = Column(String, unique=True, nullable=False)\n    email = Column(String, unique=True, nullable=False)\n    password = Column(Text, nullable=False)\n    user_since = Column(\n        TIMESTAMP(timezone=True), nullable=False, server_default=text(\"now()\")\n    )\n\n    owner_of = relationship(\"DocumentMetadata\", back_populates=\"owner\")\n"
  },
  {
    "path": "app/db/tables/base_class.py",
    "content": "import enum\n\n\nclass StatusEnum(enum.Enum):\n    \"\"\"\n    Enum for status of document\n    \"\"\"\n\n    public = \"public\"\n    private = \"private\"\n    shared = \"shared\"\n    deleted = \"deleted\"\n    archived = \"archived\"\n\n\nclass NotifyEnum(enum.Enum):\n    \"\"\"\n    Enum for status of notification\n    \"\"\"\n\n    read = \"read\"\n    unread = \"unread\"\n\n    @classmethod\n    def has_value(cls, value):\n        return value in cls._value2member_map_\n"
  },
  {
    "path": "app/db/tables/documents/__init__.py",
    "content": ""
  },
  {
    "path": "app/db/tables/documents/document_sharing.py",
    "content": "from typing import List, Optional\n\nfrom datetime import datetime, timezone\nfrom sqlalchemy import Column, Integer, String, DateTime, ARRAY, ForeignKey\nfrom sqlalchemy.orm import Mapped\n\nfrom app.db.models import Base\n\n\nclass DocumentSharing(Base):\n    __tablename__ = \"share_url\"\n\n    url_id: str = Column(String, primary_key=True, nullable=False, unique=True)\n    filename: str = Column(String, unique=True, nullable=False)\n    owner_id: Mapped[str] = Column(String, ForeignKey(\"users.id\"), nullable=False)\n    url: str = Column(String, unique=True)\n    expires_at = Column(\n        DateTime(timezone=True),\n        default=datetime.now(timezone.utc),\n    )\n    visits: int = Column(Integer)\n    share_to: Optional[List[str]] = Column(ARRAY(String))\n"
  },
  {
    "path": "app/db/tables/documents/documents_metadata.py",
    "content": "from datetime import datetime, timezone\nfrom uuid import uuid4\n\nfrom typing import List, Optional\nfrom sqlalchemy import (\n    Column,\n    String,\n    Integer,\n    ARRAY,\n    text,\n    DateTime,\n    Enum,\n    ForeignKey,\n    Table,\n    UniqueConstraint,\n)\nfrom sqlalchemy.dialects.postgresql import UUID\nfrom sqlalchemy.orm import Mapped, relationship\n\nfrom app.db.models import Base\nfrom app.db.tables.base_class import StatusEnum\n\n\ndoc_user_access = Table(\n    \"doc_user_access\",\n    Base.metadata,\n    Column(\n        \"doc_id\",\n        UUID(as_uuid=True),\n        ForeignKey(\"document_metadata.id\", ondelete=\"CASCADE\"),\n    ),\n    Column(\"user_id\", String(26), ForeignKey(\"users.id\")),\n    UniqueConstraint(\"doc_id\", \"user_id\", name=\"uq_doc_user_access_doc_user\"),\n)\n\n\nclass DocumentMetadata(Base):\n    __tablename__ = \"document_metadata\"\n\n    id: UUID = Column(\n        UUID(as_uuid=True), default=uuid4, primary_key=True, index=True, nullable=False\n    )\n    owner_id: Mapped[str] = Column(String, ForeignKey(\"users.id\"), nullable=False)\n    name: str = Column(String)\n    s3_url: str = Column(String, unique=True)\n    created_at = Column(\n        DateTime(timezone=True),\n        default=datetime.now(timezone.utc),\n        nullable=False,\n        server_default=text(\"NOW()\"),\n    )\n    size: Optional[int] = Column(Integer)\n    file_type: Optional[str] = Column(String)\n    tags: Optional[List[str]] = Column(ARRAY(String))\n    categories: Optional[List[str]] = Column(ARRAY(String))\n    status: Enum = Column(Enum(StatusEnum), default=StatusEnum.private)\n    file_hash: Optional[str] = Column(String)\n    access_to: Optional[List[str]] = Column(ARRAY(String))\n    deleted_at = Column(DateTime(timezone=True), nullable=True)\n\n    update_access = relationship(\n        \"User\", secondary=doc_user_access, passive_deletes=True\n    )\n    owner = relationship(\"User\", back_populates=\"owner_of\")\n"
  },
  {
    "path": "app/db/tables/documents/notify.py",
    "content": "from datetime import datetime, timezone\nfrom uuid import uuid4\n\nfrom sqlalchemy import Column, String, Text, Enum, DateTime, text\nfrom sqlalchemy.dialects.postgresql import UUID\n\nfrom app.db.tables.base_class import NotifyEnum\nfrom app.db.models import Base\n\n\nclass Notify(Base):\n    __tablename__ = \"notify\"\n\n    id: UUID = Column(\n        UUID(as_uuid=True), default=uuid4, primary_key=True, index=True, nullable=False\n    )\n    receiver_id: str = Column(String, nullable=False)\n    message: str = Column(Text, nullable=False)\n    status: NotifyEnum = Column(Enum(NotifyEnum), default=NotifyEnum.unread)\n    notified_at = Column(\n        DateTime(timezone=True),\n        default=datetime.now(timezone.utc),\n        nullable=False,\n        server_default=text(\"NOW()\"),\n    )\n"
  },
  {
    "path": "app/docs/DocFlow-DocumentManagementAPI.postman_collection.json",
    "content": "{\n\t\"info\": {\n\t\t\"_postman_id\": \"fb26f538-c78a-4354-a392-7d77e3bf78ad\",\n\t\t\"name\": \"DocFlow - Document Management API\",\n\t\t\"description\": \"DocFlow is a powerful Document Management API designed to streamline document handling, including seamless uploading, downloading, organization, versioning, sharing, and more.\\n\\n## 🚀 Key Features\\n\\n💡 Document Upload and Download  \\n💡 Organization and Searching  \\n💡 Versioning  \\n💡 Sharing  \\n💡 Authentication and Authorization  \\n💡 Access Control List  \\n💡 Deletion and Archiving  \\n💡 Document Preview  \\n💡 Send file via Email  \\n💡 Conversion to PDF  \\n💡 Full Text Search  \\n💡 Text Analysis and OCR\\n\\n## 🐙 Githib\\n\\nLink: [https://www.github.com/jiisanda/docflow](https://www.github.com/jiisanda/docflow)\\n\\n## 🛟 Help and Suppor\\n\\nFor any questions or support, please [contact](https://harshjaiswal2307@gmail.com).\\n\\nEnjoy using DocFlow to manage your documents seamlessly!\",\n\t\t\"schema\": \"https://schema.getpostman.com/json/collection/v2.1.0/collection.json\",\n\t\t\"_exporter_id\": \"20984268\"\n\t},\n\t\"item\": [\n\t\t{\n\t\t\t\"name\": \"🦕 api\",\n\t\t\t\"item\": [\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"👤 user\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🆕👤 Create new user\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"username\\\": \\\"\\\",\\n  \\\"email\\\": \\\"\\\",\\n  \\\"password\\\": \\\"\\\"\\n}\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/u/signup\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"u\",\n\t\t\t\t\t\t\t\t\t\t\"signup\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"username\\\": \\\"<string>\\\",\\n  \\\"email\\\": \\\"<email>\\\",\\n  \\\"password\\\": \\\"<string>\\\"\\n}\",\n\t\t\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/u/signup\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"u\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"signup\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Created\",\n\t\t\t\t\t\t\t\t\t\"code\": 201,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"id\\\": \\\"<string>\\\",\\n  \\\"email\\\": \\\"<email>\\\",\\n  \\\"user_since\\\": \\\"<dateTime>\\\"\\n}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"username\\\": \\\"<string>\\\",\\n  \\\"email\\\": \\\"<email>\\\",\\n  \\\"password\\\": \\\"<string>\\\"\\n}\",\n\t\t\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/u/signup\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"u\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"signup\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🔑♻️ Create access and refresh tokens for user\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/x-www-form-urlencoded\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"urlencoded\",\n\t\t\t\t\t\t\t\t\t\"urlencoded\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"username\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\",\n\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"password\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\",\n\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"scope\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"client_id\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"client_secret\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/u/login\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"u\",\n\t\t\t\t\t\t\t\t\t\t\"login\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"urlencoded\",\n\t\t\t\t\t\t\t\t\t\t\t\"urlencoded\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"username\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"password\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"scope\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"client_id\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"client_secret\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"u\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"login\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"urlencoded\",\n\t\t\t\t\t\t\t\t\t\t\t\"urlencoded\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"username\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"password\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"scope\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"client_id\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"client_secret\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"u\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"login\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"👤 Get details of currently logged in user\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/u/me\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"u\",\n\t\t\t\t\t\t\t\t\t\t\"me\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"~TODO: Add an extra db for user profile then return details\\n    For now returning {Userid and Username}\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/u/me\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"u\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"me\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"id\\\": \\\"<string>\\\",\\n  \\\"username\\\": \\\"<string>\\\"\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"📝 Document\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"📤 Upload Document\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"multipart/form-data\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"formdata\",\n\t\t\t\t\t\t\t\t\t\"formdata\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"files\",\n\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"file\",\n\t\t\t\t\t\t\t\t\t\t\t\"src\": []\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/upload\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"upload\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"folder\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\",\n\t\t\t\t\t\t\t\t\t\t\t\"disabled\": true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Uploads a document to the specified folder.\\n\\nArgs:\\n    file (UploadFile): The file to be uploaded.\\n    folder (Optional[str]): The folder where the document will be stored. Defaults to None.\\n    repository (DocumentRepository): The repository for managing documents.\\n    metadata_repository (DocumentMetadataRepository): The repository for managing document metadata.\\n    user_repository (AuthRepository): The repository for managing user authentication.\\n    user (TokenData): The token data of the authenticated user.\\n\\nReturns:\\n    Union[DocumentMetadataRead, Dict[str, str]]: If the file is added, returns the uploaded document metadata.\\n        If the file is updated, returns the patched document metadata.\\n        Otherwise, returns a response dictionary.\\n\\nRaises:\\n    HTTP_400: If no input file is provided.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"formdata\",\n\t\t\t\t\t\t\t\t\t\t\t\"formdata\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<binary>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"text\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/upload?folder=\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"upload\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"folder\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Created\",\n\t\t\t\t\t\t\t\t\t\"code\": 201,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"formdata\",\n\t\t\t\t\t\t\t\t\t\t\t\"formdata\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<binary>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"text\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/upload?folder=\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"upload\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"folder\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"📥 Download Document\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/file/:file_name/download\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"file\",\n\t\t\t\t\t\t\t\t\t\t\":file_name\",\n\t\t\t\t\t\t\t\t\t\t\"download\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Downloads a document with the specified file name.\\n\\nArgs:\\n    file_name (str): The name of the file to be downloaded.\\n    repository (DocumentRepository): The repository for managing documents.\\n    metadata_repository (DocumentMetadataRepository): The repository for managing document metadata.\\n    user (TokenData): The token data of the authenticated user.\\n\\nReturns:\\n    object: The downloaded document.\\n\\nRaises:\\n    HTTP_400: If no file name is provided.\\n    HTTP_404: If no file with the specified name is found.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/:file_name/download\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"download\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/:file_name/download\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"download\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🚮 Add To Bin\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/:file_name\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\":file_name\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Adds a document to the bin for deletion.\\n\\nArgs:\\n    file_name (str): The name of the file to be added to the bin.\\n    metadata_repository (DocumentMetadataRepository): The repository for managing document metadata.\\n    user (TokenData): The token data of the authenticated user.\\n\\nReturns:\\n    None: If the file is added to the bin.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/:file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":file_name\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"No Content\",\n\t\t\t\t\t\t\t\t\t\"code\": 204,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"text\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"text/plain\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/:file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":file_name\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🗑️💥 Permanently Delete Doc\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/trash/:file_name\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"trash\",\n\t\t\t\t\t\t\t\t\t\t\":file_name\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Permanently deletes a document.\\n\\nArgs:\\n    file_name (str, optional): The name of the file to be permanently deleted. Defaults to None.\\n    delete_all (bool): Flag indicating whether to delete all documents in the bin. Defaults to False.\\n    repository (DocumentRepository): The repository for managing documents.\\n    metadata_repository (DocumentMetadataRepository): The repository for managing document metadata.\\n    user (TokenData): The token data of the authenticated user.\\n\\nReturns:\\n    None: If the file is permanently deleted.\\n\\nRaises:\\n    HTTP_404: If no file with the specified name is found.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/trash/:file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"trash\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":file_name\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"No Content\",\n\t\t\t\t\t\t\t\t\t\"code\": 204,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"text\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"text/plain\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/trash/:file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"trash\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":file_name\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"👀 Preview Document\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"addTokenTo\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"header\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/preview/:document\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"preview\",\n\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"article1.png\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"```\\nGet the preview of a document.\\nArgs:\\n    document (Union[str, UUID]): The ID or name of the document.\\n    repository (DocumentRe\\npository): The repository for accessing document data.\\n    metadata_repository (DocumentMetadataRepository): The repository for accessing document metadata.\\n    user (TokenData): The user token data.\\nReturns:\\n    FileResponse: The file response containing the document preview.\\nRaises:\\n    HTTP_404: If the document ID or name is not provided or if the document does not exist.\\n    HTTP_400: If the file type is not supported for preview.\\n\\n ```\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"text\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/preview/:document\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"preview\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"article1.png\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": null,\n\t\t\t\t\t\t\t\t\t\"header\": null,\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": null\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"📃🗑️  List Of Bin\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/trash\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"trash\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"List bin.\\n\\nArgs:\\n    repository: The document metadata repository.\\n    owner: The token data of the owner.\\n\\nReturns:\\n    Dict[str, List[Row | Row] | int]: The list of bin.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/trash\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"trash\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🗑️🔄️ Restore From Bin\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/restore/:file\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"restore\",\n\t\t\t\t\t\t\t\t\t\t\":file\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Restore bin.\\n\\nArgs:\\n    file: The file to restore.\\n    repository: The document metadata repository.\\n    user: The token data of the user.\\n\\nReturns:\\n    DocumentMetadataRead: The restored document metadata.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/restore/:file\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"restore\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":file\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"owner_id\\\": \\\"<string>\\\",\\n  \\\"name\\\": \\\"<string>\\\",\\n  \\\"s3_url\\\": \\\"<string>\\\",\\n  \\\"created_at\\\": \\\"<dateTime>\\\",\\n  \\\"size\\\": \\\"<integer>\\\",\\n  \\\"file_type\\\": \\\"<string>\\\",\\n  \\\"tags\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"categories\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"status\\\": \\\"<string>\\\",\\n  \\\"file_hash\\\": \\\"<string>\\\",\\n  \\\"access_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"id\\\": \\\"<uuid>\\\"\\n}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/restore/:file\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"restore\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":file\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🫗 Empty bin\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"addTokenTo\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"header\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/trash\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"trash\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"text\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/trash\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"trash\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"No Content\",\n\t\t\t\t\t\t\t\t\t\"code\": 204,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": null,\n\t\t\t\t\t\t\t\t\t\"header\": null,\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": null\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"🔔 notifications\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"📫 Get Notifications\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/notifications\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"notifications\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Get notifications for a user.\\n\\nArgs:  \\nrepository (NotifyRepo): The repository for accessing notification data.  \\nuser (TokenData): The authenticated user.\\n\\nReturns:  \\nList\\\\[Notification\\\\]: A list of notifications for the user.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/notifications\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"notifications\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"[\\n  {\\n    \\\"id\\\": \\\"<uuid>\\\",\\n    \\\"receiver_id\\\": \\\"<string>\\\",\\n    \\\"message\\\": \\\"<string>\\\",\\n    \\\"status\\\": \\\"<string>\\\",\\n    \\\"notified_at\\\": \\\"<dateTime>\\\"\\n  },\\n  {\\n    \\\"id\\\": \\\"<uuid>\\\",\\n    \\\"receiver_id\\\": \\\"<string>\\\",\\n    \\\"message\\\": \\\"<string>\\\",\\n    \\\"status\\\": \\\"<string>\\\",\\n    \\\"notified_at\\\": \\\"<dateTime>\\\"\\n  }\\n]\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🧩🔔 Patch Status\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"PUT\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"status\\\": \\\"unread\\\",\\n  \\\"mark_all\\\": false\\n}\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/notifications/:notification_id\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"notifications\",\n\t\t\t\t\t\t\t\t\t\t\":notification_id\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"notification_id\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Patch the status of a notification or mark all notifications as read.\\n\\nArgs:\\n    updated_status (NotifyPatchStatus, optional): The updated status for the notification. Defaults to None.\\n    mark_as_all_read (bool, optional): Flag indicating whether to mark all notifications as read. Defaults to False.\\n    notification_id (UUID, optional): The ID of the notification to update. Defaults to None.\\n    repository (NotifyRepo): The repository for accessing notification data.\\n    user (TokenData): The authenticated user.\\n\\nReturns:\\n    Union[List[Notification], Notification]: If `mark_as_all_read` is True, returns a list of all notifications\\n        marked as read. If `notification_id` is provided, returns the updated notification.\\n        Otherwise, raises an HTTP_404 exception.\\n\\nRaises:\\n    HTTP_404: If neither `mark_as_all_read` nor `notification_id` is provided.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"PUT\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"status\\\": \\\"unread\\\"\\n}\",\n\t\t\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/notifications/:notification_id\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"notifications\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":notification_id\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"notification_id\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"[\\n  {\\n    \\\"id\\\": \\\"<uuid>\\\",\\n    \\\"receiver_id\\\": \\\"<string>\\\",\\n    \\\"message\\\": \\\"<string>\\\",\\n    \\\"status\\\": \\\"<string>\\\",\\n    \\\"notified_at\\\": \\\"<dateTime>\\\"\\n  },\\n  {\\n    \\\"id\\\": \\\"<uuid>\\\",\\n    \\\"receiver_id\\\": \\\"<string>\\\",\\n    \\\"message\\\": \\\"<string>\\\",\\n    \\\"status\\\": \\\"<string>\\\",\\n    \\\"notified_at\\\": \\\"<dateTime>\\\"\\n  }\\n]\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"PUT\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"status\\\": \\\"unread\\\"\\n}\",\n\t\t\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/notifications/:notification_id\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"notifications\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":notification_id\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"notification_id\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🗑️ Clear All Notifications\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\"header\": [],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/notifications\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"notifications\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Clear all notifications for a user.\\n\\nArgs:\\n    repository (NotifyRepo): The repository for accessing notification data.\\n    user (TokenData): The authenticated user.\\n\\nReturns:\\n    None\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/notifications\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"notifications\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"No Content\",\n\t\t\t\t\t\t\t\t\t\"code\": 204,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"text\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"text/plain\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"description\": \"Simple Notification System\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"🏷️ Documents Metadata\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"📚 archive\",\n\t\t\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"📚📃 Archive A Document\",\n\t\t\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/archive/:file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"archive\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":file_name\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Archive a document.\\n\\nArgs:\\n    file_name (str): The name of the file to be archived.\\n    repository (DocumentMetadataRepository): The repository for document metadata.\\n    user (TokenData): The user token data.\\n\\nReturns:\\n    DocumentMetadataRead: The archived document metadata.\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/archive/:file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"archive\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\":file_name\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"owner_id\\\": \\\"<string>\\\",\\n  \\\"name\\\": \\\"<string>\\\",\\n  \\\"s3_url\\\": \\\"<string>\\\",\\n  \\\"created_at\\\": \\\"<dateTime>\\\",\\n  \\\"size\\\": \\\"<integer>\\\",\\n  \\\"file_type\\\": \\\"<string>\\\",\\n  \\\"tags\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"categories\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"status\\\": \\\"<string>\\\",\\n  \\\"file_hash\\\": \\\"<string>\\\",\\n  \\\"access_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"id\\\": \\\"<uuid>\\\"\\n}\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/api/document-metadata/archive?file_name=<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"api\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"document-metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"archive\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"📃📚 Archived Doc List\",\n\t\t\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/archive/list\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"archive\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"list\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Get the list of archived documents.\\n\\nArgs:\\n    repository (DocumentMetadataRepository): The repository for document metadata.\\n    user (TokenData): The user token data.\\n\\nReturns:\\n    Dict[str, List[str] | int]: A dictionary containing the list of archived documents.\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/archive/list\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"archive\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"list\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\t\t\"body\": \"{}\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"🔄️📚 Remove Doc From Archive\",\n\t\t\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/un-archive/:file\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"un-archive\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":file\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"description\": \"Un-archive a document.\\n\\nArgs:\\n    file (str): The name of the file to be un-archived.\\n    repository (DocumentMetadataRepository): The repository for document metadata.\\n    user (TokenData): The user token data.\\n\\nReturns:\\n    DocumentMetadataRead: The un-archived document metadata.\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/un-archive/:file\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"un-archive\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\":file\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"owner_id\\\": \\\"<string>\\\",\\n  \\\"name\\\": \\\"<string>\\\",\\n  \\\"s3_url\\\": \\\"<string>\\\",\\n  \\\"created_at\\\": \\\"<dateTime>\\\",\\n  \\\"size\\\": \\\"<integer>\\\",\\n  \\\"file_type\\\": \\\"<string>\\\",\\n  \\\"tags\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"categories\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"status\\\": \\\"<string>\\\",\\n  \\\"file_hash\\\": \\\"<string>\\\",\\n  \\\"access_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"id\\\": \\\"<uuid>\\\"\\n}\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/un-archive/:file\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"un-archive\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\":file\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"📃🏷️ Get Documents Metadata\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata?limit=10&offset=0\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"metadata\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"limit\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"10\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"offset\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"0\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Retrieves a list of document metadata.\\n\\nArgs:\\n    limit (int): The maximum number of documents to retrieve. Defaults to 10.\\n    offset (int): The number of documents to skip. Defaults to 0.\\n    repository (DocumentMetadataRepository): The repository for managing document metadata.\\n    user (TokenData): The token data of the authenticated user.\\n\\nReturns:\\n    Dict[str, Union[List[DocumentMetadataRead], Any]]: A dictionary containing the list of document metadata.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata?limit=10&offset=0\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"limit\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"10\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"offset\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"0\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"in_f\\\": [\\n    {\\n      \\\"owner_id\\\": \\\"<string>\\\",\\n      \\\"name\\\": \\\"<string>\\\",\\n      \\\"s3_url\\\": \\\"<string>\\\",\\n      \\\"created_at\\\": \\\"<dateTime>\\\",\\n      \\\"size\\\": \\\"<integer>\\\",\\n      \\\"file_type\\\": \\\"<string>\\\",\\n      \\\"tags\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"categories\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"status\\\": \\\"<string>\\\",\\n      \\\"file_hash\\\": \\\"<string>\\\",\\n      \\\"access_to\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"id\\\": \\\"<uuid>\\\"\\n    },\\n    {\\n      \\\"owner_id\\\": \\\"<string>\\\",\\n      \\\"name\\\": \\\"<string>\\\",\\n      \\\"s3_url\\\": \\\"<string>\\\",\\n      \\\"created_at\\\": \\\"<dateTime>\\\",\\n      \\\"size\\\": \\\"<integer>\\\",\\n      \\\"file_type\\\": \\\"<string>\\\",\\n      \\\"tags\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"categories\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"status\\\": \\\"<string>\\\",\\n      \\\"file_hash\\\": \\\"<string>\\\",\\n      \\\"access_to\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"id\\\": \\\"<uuid>\\\"\\n    }\\n  ],\\n  \\\"ex40\\\": [\\n    {\\n      \\\"owner_id\\\": \\\"<string>\\\",\\n      \\\"name\\\": \\\"<string>\\\",\\n      \\\"s3_url\\\": \\\"<string>\\\",\\n      \\\"created_at\\\": \\\"<dateTime>\\\",\\n      \\\"size\\\": \\\"<integer>\\\",\\n      \\\"file_type\\\": \\\"<string>\\\",\\n      \\\"tags\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"categories\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"status\\\": \\\"<string>\\\",\\n      \\\"file_hash\\\": \\\"<string>\\\",\\n      \\\"access_to\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"id\\\": \\\"<uuid>\\\"\\n    },\\n    {\\n      \\\"owner_id\\\": \\\"<string>\\\",\\n      \\\"name\\\": \\\"<string>\\\",\\n      \\\"s3_url\\\": \\\"<string>\\\",\\n      \\\"created_at\\\": \\\"<dateTime>\\\",\\n      \\\"size\\\": \\\"<integer>\\\",\\n      \\\"file_type\\\": \\\"<string>\\\",\\n      \\\"tags\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"categories\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"status\\\": \\\"<string>\\\",\\n      \\\"file_hash\\\": \\\"<string>\\\",\\n      \\\"access_to\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"id\\\": \\\"<uuid>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata?limit=10&offset=0\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"limit\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"10\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"offset\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"0\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"📤🏷️ Upload Documents Metadata\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"name\\\": \\\"<string>\\\",\\n  \\\"s3_url\\\": \\\"<string>\\\",\\n  \\\"created_at\\\": \\\"<dateTime>\\\",\\n  \\\"size\\\": \\\"<integer>\\\",\\n  \\\"file_type\\\": \\\"<string>\\\",\\n  \\\"tags\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"categories\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"status\\\": \\\"<string>\\\",\\n  \\\"file_hash\\\": \\\"<string>\\\",\\n  \\\"owner_id\\\": \\\"<string>\\\",\\n  \\\"access_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ]\\n}\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/upload\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\"upload\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Uploads document metadata.\\n\\nArgs:\\n    document_upload (DocumentMetadataCreate): The document metadata to be uploaded.\\n    repository (DocumentMetadataRepository): The repository for managing document metadata.\\n    user (TokenData): The token data of the authenticated user.\\n\\nReturns:\\n    DocumentMetadataRead: The uploaded document metadata.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"name\\\": \\\"<string>\\\",\\n  \\\"s3_url\\\": \\\"<string>\\\",\\n  \\\"created_at\\\": \\\"<dateTime>\\\",\\n  \\\"size\\\": \\\"<integer>\\\",\\n  \\\"file_type\\\": \\\"<string>\\\",\\n  \\\"tags\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"categories\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"status\\\": \\\"<string>\\\",\\n  \\\"file_hash\\\": \\\"<string>\\\",\\n  \\\"owner_id\\\": \\\"<string>\\\",\\n  \\\"access_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ]\\n}\",\n\t\t\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/upload\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"upload\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Created\",\n\t\t\t\t\t\t\t\t\t\"code\": 201,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"owner_id\\\": \\\"<string>\\\",\\n  \\\"name\\\": \\\"<string>\\\",\\n  \\\"s3_url\\\": \\\"<string>\\\",\\n  \\\"created_at\\\": \\\"<dateTime>\\\",\\n  \\\"size\\\": \\\"<integer>\\\",\\n  \\\"file_type\\\": \\\"<string>\\\",\\n  \\\"tags\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"categories\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"status\\\": \\\"<string>\\\",\\n  \\\"file_hash\\\": \\\"<string>\\\",\\n  \\\"access_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"id\\\": \\\"<uuid>\\\"\\n}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"name\\\": \\\"<string>\\\",\\n  \\\"s3_url\\\": \\\"<string>\\\",\\n  \\\"created_at\\\": \\\"<dateTime>\\\",\\n  \\\"size\\\": \\\"<integer>\\\",\\n  \\\"file_type\\\": \\\"<string>\\\",\\n  \\\"tags\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"categories\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"status\\\": \\\"<string>\\\",\\n  \\\"file_hash\\\": \\\"<string>\\\",\\n  \\\"owner_id\\\": \\\"<string>\\\",\\n  \\\"access_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ]\\n}\",\n\t\t\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/upload\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"upload\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"📃 Get Document-Metadata\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/:document/detail\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\":document\",\n\t\t\t\t\t\t\t\t\t\t\"detail\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Retrieves the metadata of a specific document.\\n\\nArgs:\\n    document (Union[str, UUID]): The ID or name of the document.\\n    repository (DocumentMetadataRepository): The repository for managing document metadata.\\n    user (TokenData): The token data of the authenticated user.\\n\\nReturns:\\n    Union[DocumentMetadataRead, HTTPException]: The document metadata if found, otherwise an HTTPException.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/:document/detail\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"detail\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/:document/detail\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"detail\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🧩📃 Update Doc Metadata Details\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"PUT\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"name\\\": \\\"\\\",\\n  \\\"tags\\\": [\\n    \\\"\\\"\\n  ],\\n  \\\"categories\\\": [\\n    \\\"\\\"\\n  ],\\n  \\\"access_to\\\": [\\n    \\\"\\\"\\n  ]\\n}\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/:document\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\",\n\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Updates the details of a document's metadata.\\n\\nArgs:\\n    document (Union[str, UUID]): The ID or name of the document.\\n    document_patch (DocumentMetadataPatch): The document metadata patch containing the updated details.\\n    repository (DocumentMetadataRepository): The repository for managing document metadata.\\n    user_repository (AuthRepository): The repository for managing user authentication.\\n    user (TokenData): The token data of the authenticated user.\\n\\nReturns:\\n    Union[DocumentMetadataRead, HTTPException]: The updated document metadata if successful,\\n    otherwise an HTTPException.\\n\\nRaises:\\n    HTTP_404: If no document with the specified ID or name is found.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"PUT\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"name\\\": \\\"<string>\\\",\\n  \\\"tags\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"categories\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"access_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ]\\n}\",\n\t\t\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/:document\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"PUT\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"name\\\": \\\"<string>\\\",\\n  \\\"tags\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"categories\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ],\\n  \\\"access_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ]\\n}\",\n\t\t\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/:document\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🗑️📃 Delete Document Metadata\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/:document\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\",\n\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Deletes the metadata of a document and moves it to the bin.\\n\\nArgs:\\n    document (Union[str, UUID]): The identifier of the document to delete.\\n    repository (DocumentMetadataRepository): The repository for accessing document metadata.\\n        Defaults to the result of the `get_repository` function with `DocumentMetadataRepository` as the argument.\\n    user (TokenData): The token data of the current user. Defaults to the result of the `get_current_user` function.\\n\\nReturns:\\n    None (204_NO_CONTENT)\\n\\nRaises:\\n    HTTP_404: If no document with the specified identifier is found.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/:document\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"No Content\",\n\t\t\t\t\t\t\t\t\t\"code\": 204,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"text\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"text/plain\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"DELETE\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/metadata/:document\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"metadata\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"description\": \"Handles updating the databases\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"📨 Sharing\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"📃📨🔗 Share Document Link\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"visits\\\": 1,\\n  \\\"share_to\\\": [\\n    \\\"\\\"\\n  ]\\n}\",\n\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/share-link/:document\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"share-link\",\n\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Shares a documents link with another user, sends a mail and notifies the receiver.\\n\\nArgs:  \\ndocument (Union\\\\[str, UUID\\\\]): The ID or name of the document to be shared.  \\nshare_request (SharingRequest): The sharing request containing the details of the sharing operation.  \\nrepository (DocumentSharingRepository): The repository for managing document sharing.  \\nauth_repository (AuthRepository): The repository for managing User related queries.  \\nmetadata_repository (DocumentMetadataRepository): The repository for managing document metadata.  \\nnotify_repository (NotifyRepo): The repository for managing notification  \\nuser (TokenData): The token data of the authenticated user.\\n\\nReturns:  \\nDict\\\\[str, str\\\\]: A dictionary containing the personal URL and shareable link.\\n\\nRaises:  \\nHTTP_404: If no document with the specified ID or name is found.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"visits\\\": 1,\\n  \\\"share_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ]\\n}\",\n\t\t\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/share-link/:document\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"share-link\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"visits\\\": 1,\\n  \\\"share_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ]\\n}\",\n\t\t\t\t\t\t\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"raw\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"language\": \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/share-link/:document\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"share-link\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🔄️📤 Redirect To Share\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/doc/:url_id\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"doc\",\n\t\t\t\t\t\t\t\t\t\t\":url_id\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"url_id\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\",\n\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Redirects to a shared document URL.\\n\\nArgs:\\n    url_id (str): The ID of the shared document URL.\\n    repository (DocumentSharingRepository): The repository for managing document sharing.\\n    user (TokenData): The token data of the authenticated user.\\n\\nReturns:\\n    RedirectResponse: A redirect response to the shared document URL.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/doc/:url_id\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"doc\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":url_id\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"url_id\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/doc/:url_id\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"doc\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":url_id\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"url_id\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"<string>\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"(Required) \"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"📃📨 Share Document\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"addTokenTo\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"header\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"visits\\\": 1,\\n  \\\"share_to\\\": [\\n    \\\"\\\"\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/share/:document?notify=true\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"share\",\n\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"notify\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"true\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"```\\nShare a document with other users, and notifies if notify is set to True (default).\\nArgs:    \\n    document (Union[str, UUID]): The ID or UUID of the document to be shared.    \\n    share_request (SharingRequest): The sharing request containing the recipients and permissions.    \\n    notify (bool, optional): Whether to send notifications to the recipients. Defaults to True.    \\n    repository (DocumentSharingRepository, optional): The repository for document sharing operations.    \\n    document_repo (DocumentRepository, optional): The repository for document operations.    \\n    metadata_repo (DocumentMetadataRepository, optional): The repository for document metadata operations.    \\n    notify_repo (NotifyRepo, optional): The repository for notification operations.    \\n    auth_repo (AuthRepository, optional): The repository for authentication operations.    \\n    user (TokenData, optional): The authenticated user.\\nRaises:    \\n    HTTP_404: If the document is not found.\\nReturns:    \\n    None\\n\\n ```\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"POST\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\t\t\"mode\": \"raw\",\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{\\n  \\\"visits\\\": 1,\\n  \\\"share_to\\\": [\\n    \\\"<string>\\\",\\n    \\\"<string>\\\"\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/share/:document?notify=true\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"share\",\n\t\t\t\t\t\t\t\t\t\t\t\t\":document\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"notify\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"true\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"variable\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": null,\n\t\t\t\t\t\t\t\t\t\"header\": null,\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": null\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"description\": \"Sharing a Document\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"🔍 Searching\",\n\t\t\t\t\t\"item\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"name\": \"🔎📃 Search Document\",\n\t\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\t\t\t\t\t\"oauth2\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"accessTokenUrl\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"api/u/login\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"grant_type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"password_credentials\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/filter?limit=10&offset=0&tag=&category=&file_types=&doc_status=\",\n\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\"filter\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"limit\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"10\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"offset\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"0\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"tag\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"category\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_types\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"doc_status\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"description\": \"Searches for documents based on specified criteria.\\n\\nArgs:\\n    limit (int): The maximum number of documents to retrieve. Defaults to 10.\\n    offset (int): The number of documents to skip. Defaults to 0.\\n    tag (str, optional): The tag to filter documents by. Defaults to None.\\n    category (str, optional): The category to filter documents by. Defaults to None.\\n    file_types (str, optional): The file types to filter documents by. Defaults to None.\\n    doc_status (str, optional): The status of documents to filter by. Defaults to None.\\n    repository (DocumentOrgRepository): The repository for managing document organization.\\n    repository_metadata (DocumentMetadataRepository): The repository for managing document metadata.\\n    user (TokenData): The token data of the authenticated user.\\n\\nReturns:\\n    List[DocumentMetadataRead] or List[Dict[str, Any]]: The list of matching documents.\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"response\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/filter?limit=10&offset=0&tag=&category=&file_types=&doc_status=\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"filter\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"limit\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"10\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"offset\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"0\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"tag\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"category\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_types\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"doc_status\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{}\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Validation Error\",\n\t\t\t\t\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"description\": \"Added as a part of security scheme: oauth2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Authorization\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"{{token}}\"\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/v2/filter?limit=10&offset=0&tag=&category=&file_types=&doc_status=\",\n\t\t\t\t\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"v2\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"filter\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"query\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"limit\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"10\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"offset\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"0\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"tag\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"category\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"file_types\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"key\": \"doc_status\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"status\": \"Unprocessable Entity (WebDAV) (RFC 4918)\",\n\t\t\t\t\t\t\t\t\t\"code\": 422,\n\t\t\t\t\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\t\t\t\t\"body\": \"{\\n  \\\"detail\\\": [\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    },\\n    {\\n      \\\"loc\\\": [\\n        \\\"<string>\\\",\\n        \\\"<string>\\\"\\n      ],\\n      \\\"msg\\\": \\\"<string>\\\",\\n      \\\"type\\\": \\\"<string>\\\"\\n    }\\n  ]\\n}\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"description\": \"Searching a document with tags, categories, file type and status...\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"description\": \"Contains all the APIs...\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Root\",\n\t\t\t\"request\": {\n\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\"header\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"url\": {\n\t\t\t\t\t\"raw\": \"{{baseUrl}}/\",\n\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t],\n\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\"\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"response\": [\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"Successful Response\",\n\t\t\t\t\t\"originalRequest\": {\n\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"key\": \"Accept\",\n\t\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"url\": {\n\t\t\t\t\t\t\t\"raw\": \"{{baseUrl}}/\",\n\t\t\t\t\t\t\t\"host\": [\n\t\t\t\t\t\t\t\t\"{{baseUrl}}\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"path\": [\n\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"status\": \"OK\",\n\t\t\t\t\t\"code\": 200,\n\t\t\t\t\t\"_postman_previewlanguage\": \"json\",\n\t\t\t\t\t\"header\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"key\": \"Content-Type\",\n\t\t\t\t\t\t\t\"value\": \"application/json\"\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"cookie\": [],\n\t\t\t\t\t\"body\": \"{}\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t],\n\t\"variable\": [\n\t\t{\n\t\t\t\"key\": \"baseUrl\",\n\t\t\t\"value\": \"/\",\n\t\t\t\"type\": \"string\"\n\t\t}\n\t]\n}"
  },
  {
    "path": "app/docs/commands/docker.md",
    "content": "# Docker Commands\n\nDownload the image from [DockerHub](https://hub.docker.com/r/jiisanda/docflow).\n\nOR\n\n```commandline\ndocker pull jiisanda/docflow\n```\n\n### Get all containers\n```commandline\ndocker ps\n```\n\n### Docker-compose up\nFor development, following  will by default reads two files, a `docker-compose.yml` and an optional \n`docker-compose.override.yml` file.\n```commandline\ndocker-compose up\n```\nFor production, you can use the `-f` option to specify the files to use.\n```commandline\ndocker-compose -f docker-compose.yml -f docker-compose.prod.yml up\n```\n### docker-compose up in detach mode\n```commandline\ndocker-compose up -d\n```\n\n### Building an image\nBuild an image if there are changes in the code\n```commandline\ndocker-compose up --build\n```\n\n### Stopping/Deleting all containers\n```commandline\ndocker-compose down\n```\n\n\n### To access databases created inside docker container of docflow\n```commandline\ndocker exec -it <postgres_container_id> psql -U <username>\n```\n"
  },
  {
    "path": "app/docs/commands/postgres.md",
    "content": "# PostgreSQL command\n\n##### Connect to psql inside docker container\n```commandline\ndocker exec -it <postgres_container_id> psql -U <username>\n```\n\n##### Lists all databases\n```commandline\npostgres-# \\l\n```\n\n##### Connect to a postgres table\n```commandline\npostgres-# \\c <database_name>\n```\n\n##### List of tables in database\n```commandline\npostgres-# \\dt\n```\n"
  },
  {
    "path": "app/docs/features/postman.md",
    "content": "# 👨‍💻 Postman Setup Guide\n\nExplore DocFlow's API endpoints effortlessly using Postman! 🚀\n\n> ## Currently, facing issues with postman online documentation!\nCan directly export to postman using [Import for Postman](../DocFlow-DocumentManagementAPI.postman_collection.json)\n\n---\n\nTo access the complete list of API endpoints, visit our [Postman Documentation](https://documenter.getpostman.com/view/20984268/2s9YRGxUcp).\n\n## 📥 Importing the Collection\nFollow these simple steps to import the Postman collection:\n\n1. Click the link.\n2. In the top right corner, click Run in Postman.\n3. Select Postman for Windows.\n4. Import the collection.\n\nNow you're ready to dive into DocFlow's powerful APIs!\n\n## 🌐 Set Up Environment Variable\nConfigure the environment variable basicUrl with the value localhost:8000. This variable will be used as the base URL for your API requests.\n\n## 🚀 Try It Out!\nWith the collection imported and the environment set up, explore DocFlow's features by testing the various endpoints. Get a hands-on experience with the power of DocFlow's API.\n\nHappy testing! If you have any questions or need assistance, feel free to reach out. 📞"
  },
  {
    "path": "app/docs/features/preview.md",
    "content": "# Preview in Docflow\n\nLet's see how the preview feature of DocFlow works. 🚀\n\n- 🎯 Endpoint:\n`GET /v2/preview/:document`\n- ⚙️ Params:\n`{document: <docuent_id_or_name>}`\n- 🔐 Authorization:\n`Bearer <token>`\n\n➰ cURL: \n```shell\ncurl --location 'localhost:8000/v2/preview/:document' \\\n--header 'Authorization: Bearer <token>'\n```\n\nHere in Preview we use two important models, `fastapi.response`'s `FileResponse` amd `tempfile`'s `NamedTemporaryFile`.\n\n`FileResponse` is used to return files.\n\n`NamedTemporaryFile` is a function in Python's `tempfile` module that creates a temporary file with a unique name in the \nsystem's default location for temporary files.\nThis function returns a file-like object that can be used in a similar way to other file objects.\n\nHere is the brief explanation on how it works:\n- When we call `NameTemporaryFile()`, it creates a new file in you system's temporary directory.\n- The temporary file is opened in binary mode (`wb+`) by default, and it can be read from and written to like any other\nfile object.\n- The temporary file is deleted as soon as it is closed. This is controlled by the `delete` parameter, which is `True` \nby default. This is important to set it `True`, as if not done then it could fill up the server's storage.\n\n\nIn our case, we have set `delete=False`, and we have override the `FileResponse` to add a `__del__` method, which\nwill be deleting the file once the response is sent (see: `api/dependencies/repositories`). \nIssue we were experiencing is because the temporary file was getting deleted as soon as it's closed, which \nhappens when `with` block is exited. We were getting the following error `RuntimeError: File at path /tmp/tmpuc5ru1oh.png \ndoes not exist.` And this is expected behaviour when `delete=True` is set in `tempfile.NamedTemporaryFile`.\n\n\nThe following figure describes how the Preview in DocFlow works. \n\n![preview-document](../imgs/document/document_preview.png)\n\nDocFlow allows, preview of only two media types, `image/` and `application/pdf`.\n"
  },
  {
    "path": "app/docs/features/sharing.md",
    "content": "# Document Sharing in DocFlow\n\nLet's see how sharing happens in Docflow. 🚀\n\nFor sharing DocFlow has 3-endpoints:\n1) **Share Document Link**: Share document as a link.\n2) **Redirect To Share**: Redirects the shared link to the document.\n3) **Share Document**: Shares document.\n\n### Share Document Link\n\n- 🎯 Endpoint: \n`POST /v2/share-link/:document`\n- ⚙️ Params:\n`Path Params=document`\n- 📦 Payload:\n`\n{\n  \"visits\": 1,\n  \"share_to\": [\n    \"\"\n  ]\n}\n`\n- 🔐 Authorization:\n`Bearer <token>`\n\n➰ cURL:\n```shell\ncurl --location 'localhost:8000/v2/share-link/:document' \\\n--header 'Content-Type: application/json' \\\n--header 'Accept: application/json' \\\n--header 'Authorization: Bearer <token>' \\\n--data '{\n  \"visits\": 1,\n  \"share_to\": [\n    \"\"\n  ]\n}'\n```\n\nLet's see how this endpoint works, the code for the following endpoint is on [app/api/routes/document_sharing.py](https://github.com/jiisanda/docflow/blob/master/app/api/routes/documents/document_sharing.py)\nunder `share_link_document()`.\n\nIt takes in the following arguments...\n\n```text\ndocument (Union[str, UUID]): The ID or name of the document to be shared.\nshare_request (SharingRequest): The sharing request containing the details of the sharing operation.\nrepository (DocumentSharingRepository): The repository for managing document sharing.\nauth_repository (AuthRepository): The repository for managing User related queries.\nmetadata_repository (DocumentMetadataRepository): The repository for managing document metadata.\nnotify_repository (NotifyRepo): The repository for managing notification\nuser (TokenData): The token data of the authenticated user.\n```\n\nAnd returns:\n```json\n{\n    \"personal_url\": \"<pre_signed_url>\",\n    \"share_this\": \"<shareable_link>\"\n}\n```\n\nSo when we share a document by link, the shared email/username should hold an account on docflow (`share_to`); \nalso we limit the link's usage with `visits`. \n\n`personal_url`, which is noting but a `pre_signed_url`, which gets generated by `aws`. and `share_this`, which is a \nshareable link, generates a link as `/api/doc/<url_id>` which has fixed number of visits and can only be accessed by users,\nspecified by owner of the file with `share_to`. This shared url acts as shortened url to access the document, in a controlled manner.\n\nNow this `share_this` link can be accessed with the second endpoint, **Redirect to share**.\n\n### Redirect to Share\n\n- 🎯 Endpoint: \n`POST /v2/doc/:url_id`\n- ⚙️ Params:\n`Path Params=url_id`\n- 🔐 Authorization:\n`Bearer <token>`\n\n➰ cURL:\n```shell\ncurl --location 'localhost:8000/v2/doc/:url_id' \\\n--header 'Accept: application/json' \\\n--header 'Authorization: Bearer <token>'\n```\n\nThe code for the following endpoint is on [app/api/routes/document_sharing.py](https://github.com/jiisanda/docflow/blob/master/app/api/routes/documents/document_sharing.py).\ncalled `redirect_to_share()`. It takes in the following arguments\n\n```text\nurl_id (str): The ID of the shared document URL.\nrepository (DocumentSharingRepository): The repository for managing document sharing.\nuser (TokenData): The token data of the authenticated user.\n```\n\nAnd returns:\n\nA `RedirectResponse()` to a file, which downloads the document.\n\nNow when the user tries to access the endpoint with the valid `url_id`, the user is able to download the file. As the number\nof clicks reaches the limit `visits`, the link is no longer valid. \n\n### Share Document\n- 🎯 Endpoint: \n`POST /v2/share/document?document=&notify=true`\n- ⚙️ Params:\n`document: <str>\nnotify:true`\n- 🔐 Authorization:\n`Bearer <token>`\n\n➰ cURL:\n```shell\ncurl --location 'localhost:8000/v2/share/document?document=&notify=true' \\\n--header 'accept: application/json' \\\n--header 'Content-Type: application/json' \\\n--header 'Authorization: Bearer <token>' \\\n--data '{\n  \"visits\": 1,\n  \"share_to\": [\n    \"\"\n  ]\n}'\n```\n\nThe code for the following endpoint can be reviewed from \n[app/api/routes/document_sharing.py](https://github.com/jiisanda/docflow/blob/master/app/api/routes/documents/document_sharing.py)\nunder `share_document`.\n\nIt takes the following argument:\n\n```text\ndocument (Union[str, UUID]): The ID or UUID of the document to be shared.\nshare_request (SharingRequest): The sharing request containing the recipients and permissions.\nnotify (bool, optional): Whether to send notifications to the recipients. Defaults to True.\nrepository (DocumentSharingRepository, optional): The repository for document sharing operations.\ndocument_repo (DocumentRepository, optional): The repository for document operations.\nmetadata_repo (DocumentMetadataRepository, optional): The repository for document metadata operations.\nnotify_repo (NotifyRepo, optional): The repository for notification operations.\nauth_repo (AuthRepository, optional): The repository for authentication operations.\nuser (TokenData, optional): The authenticated user.\n```\n\nHere, we send a file to users via mail as an attachment, and here it's not mandatory for user to whome we are sharing a\nfile to have a account on docflow. \n\nHow sharing as attachment works is, we use `tempfile`, a python library for creating a temporary file.\nHere is a code snippet of how its done.\n\n```python\n# Creating temp file to share\nwith tempfile.NamedTemporaryFile(delete=True, suffix=extension) as temp:\n    temp.write(file)\n    temp_path = temp.name\n\n    subject = f\"{owner.username} shared a file with you using DocFlow\"\n    for mails in share_to:\n        content = f\"\"\"\n        Hello {mails}! \n        \n        Hope you are well? {owner.username} | {user_mail} shared a file with you as an attachment. \n        \n        Regards,\n        DocFlow\n        \"\"\"\n        mail_service(mail_to=mails, subject=subject, content=content, file_path=temp_path)\n```\n\nSo for all the mail ids the user enters in `share_to`, `mail_service()` is called.\n\nAnd this is how mailing in DocFlow works...\n***"
  },
  {
    "path": "app/docs/features/upload.md",
    "content": "# Document Upload in DocFlow\n\n- 🎯 Endpoint:\n`POST /v2/upload`\n- ⚙️ Params:\n`{\n    folder: <folder_name>,\n    file=@\"/path/to/file\n}`\n- 🔐 Authorization:\n`Bearer <token>`\n\n➰ cURL:\n```commandline\ncurl --location 'localhost:8000/v2/upload?folder=' \\\n--header 'Content-Type: multipart/form-data' \\\n--header 'Accept: application/json' \\\n--header 'Authorization: Bearer <token>' \\\n--form 'file=@\"/path/to/file\"'\n```\n\nSo the following API, upload the file to s3 and adds the metadata to the database, so how this works:\n\nThe endpoint returns a `DocumentMetadataRead` object, which contains metadata about the uploaded document, or a \nDict[str, str] object in case of an error or other non-standard situation. The response of `DocumentRepository.upload`\nhas two cases, `file_added` and `file_updated`. `file_added` is the case when the uploaded file does not exist for that\nuser. And `file_updated`, when the file with the same name, exits and the new version of the file is added (details about\nversioning is mentioned [here]()).\n\n\n### Code Explanation\n\n```python\n1.     async def upload(self, metadata_repo, user_repo, file: File, folder: str, user: TokenData) -> Dict[str, Any]:\n2.         \"\"\"\n3.         Uploads a file to the specified folder in the document repository.\n4. \n5.         Args:\n6.             @param metadata_repo: The repository for accessing metadata.\n7.             @param user_repo: The repository for accessing user information.\n8.             @param file: The file to be uploaded.\n9.             @param folder: The folder in which the file should be uploaded.\n10.            @param user: The token data of the user.\n11.\n12.        Returns:\n13.            @return: A dictionary containing the response and upload information.\n14.\n15.        Raises:\n16.            HTTP_400: If the file type is not supported.\n17.        \"\"\"\n18.\n19.        file_type = file.content_type\n20.        if file_type not in SUPPORTED_FILE_TYPES:\n21.            raise HTTP_400(\n22.                msg=f\"File type {file_type} not supported.\"\n23.            )\n24.\n25.        contents = file.file.read()\n26.\n27.        doc = (await metadata_repo.get(document=file.filename, owner=user)).__dict__\n28.        # hash of the file uploaded to check if change in file\n29.        new_file_hash: str = await self._calculate_file_hash(file=file)\n30.        if \"status_code\" in doc.keys():\n31.            # getting document irrespective of user\n32.            if get_doc := (await metadata_repo.get_doc(filename=file.filename)):\n33.                get_doc = get_doc.__dict__\n34.                # Check if logged-in user has update access\n35.                logged_in_user = (await user_repo.get_user(field=\"username\", detail=user.username)).__dict__\n36.                if (get_doc[\"access_to\"] is not None) and logged_in_user[\"email\"] in get_doc[\"access_to\"]:\n37.                    if get_doc['file_hash'] != new_file_hash:\n38.                        # can upload a version to a file...\n39.                        print(f\"Have update access, to a file... owner: {get_doc['owner_id']}\")\n40.                        return await self._upload_new_version(\n41.                            doc=get_doc, file=file, contents=contents, file_type=file_type,\n42.                            new_file_hash=await self._calculate_file_hash(file=file),\n43.                            is_owner=False\n44.                        )\n45.                else:\n46.                    return await self._upload_new_file(\n47.                        file=file, folder=folder, contents=contents, file_type=file_type, user=user\n48.                    )\n49.            return await self._upload_new_file(\n50.                file=file, folder=folder, contents=contents, file_type=file_type, user=user\n51.            )\n52.\n53.        print(\"File already present, checking if there is an update...\")\n54.\n55.        if doc[\"file_hash\"] != new_file_hash:\n56.            print(\"File has been updated, uploading new version...\")\n57.            return await self._upload_new_version(doc=doc, file=file, contents=contents, file_type=file_type,\n58.                                                  new_file_hash=new_file_hash, is_owner=True)\n59.\n60.        return {\n61.            \"response\": \"File already present and no changes detected.\",\n62.            \"upload\": \"Noting to update...\"\n63.        }\n```\n\nThis the biggest chunk of code we have in docflow and handles multiple conditions, and cases.\n\n#### Parameters:\n```\nfile: File  -> File to be uploaded\nfolder: str -> Folder to upload in...\n```\n\nFrom line 19-23, we are checking if the file type is supported for upload. \n\nLine 27, gets the document if the document is already present in the database of the logged-in user. It returns the\nfollowing response if new file is uploaded.\n```json\n{\n  \"status_code\": 409, \n  \"detail\": \"No Document with <file_name>\", \n  \"headers\": null\n}\n```\nAnd below is the response if the file is already present.\n```json\n{\n    \"owner_id\": \"<ulid>\",\n    \"name\": \"<file_name>\",\n    \"s3_url\": \"<s3_link>\",\n    \"created_at\": \"2023-12-24T07:05:51.971123Z\",\n    \"id\": \"<uuid>\",\n    ...\n}\n```\n\nLine 29, calculates the hash of the file uploaded, to check if there is any change in file, if the file with same name\nis uploaded. \n\nSo in line 30, we check if we have `status_code`, in the response of doc, if we does then it means the user does not have \nthe document with the following name, which brings us to next case, i.e., have another user given the logged-in user permission\nto update the file, so we check that from line 31-39, and if the user had permissions, then uploads the new version with line \n40 (using `_upload_new_version`), or uploads a new file (using `_upload_new_file`). \n\nNow if the file is already present, and we get some doc response from line 27, then we check if the file is updated if yes,\nupload a new version (using `_upload_new_version`) else, return \n```json \n{\n  \"response\": \"File already present and no changes detected.\", \n  \"upload\": \"Noting to update...\"\n}\n```\n\n#### Returns:\nThe upload function returns one of the few things:\n\nA json response, with `\"response\"` as the key, with value `\"file updated\"`, if new version of file is uploaded, `\"file added\"`,\nif new file is added. along with the metadata of the uploaded file.\n\nThat's too much to handle for one method, I know but will try to improve the quality of the upload functionality.\n\nThe following is the figure explaining the complete flow:\n\n![UploadDoc](../imgs/document/document_upload.png)\n\n***"
  },
  {
    "path": "app/docs/issues.txt",
    "content": "# Alembic Issues\n\nIssue101:\n\nTitle: Alembic Migration Error Duplicate PostgresSQL ENUM Type\n\nDescription:\nWhile running migrations, encountered an error related to presence of duplicate ENUM type.\n\nDetails:\nError msg: sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateObject) type \"<enum-name>\" already exists\n\nResolution:\nResolved the issue with manually deleting the existing '<enum-name' ENUM Type from the Postgres database, using the\nfollowing SQL command: ```DROP TYPE IF EXISTS <enum-name>;```\nAlternative approach: would be to update the migrations file created after\n```alembic revision --autogenerate -m \"<msg\"``` and add\n```\nop.create_type(\n    '<enum-name>',\n    sa.Enum('<option1>', '<option2>', name='<enum-name>'),\n    schema='public',\n    checkfirst=True\n)\n```\n\nPrevention:\n...\n"
  },
  {
    "path": "app/docs/setup.md",
    "content": "# 🚀 Setting up Docflow Locally\n\nJust a 3-step process to get Docflow up and running on your local machine! 🌐\n\n### 1️⃣ Clone the repository\n\n```bash\ngit clone https://www.github.com/jiisanda/docflow.git\n```\n\n### 2️⃣ Configure Your Environment\n\nStart by creating your environment file using the provided [.env.template](https://github.com/jiisanda/docflow/blob/master/.env.template).\nThis file contains all the necessary environment variables for Docflow. Save it inside the app/ directory.\n\n#### PostgreSQL Setup\n\nSet up your PostgreSQL environment variables:\n\n- `DATABASE_HOSTNAME`: By default, set to `postgres`.\n- `POSTGRES_USER`, `POSTGRES_PASSWORD` and `POSTGRES_PORT`:  Enter your PostgreSQL username, password, and port \n(default is `5432`).\n- `POSTGRES_DB` and `POSTGRES_DB_TESTS`: Specify your database names (`POSTGRES_DB_TESTS` can be left blank).\n\n#### AWS Setup\nFor AWS credentials (`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`), follow these steps:\n\n>1. Sign in to the [AWS Management Console]() using your AWS account's root user credentials.\n>2. Navigate to Security Credentials and create an access key.\n>3. Copy the access key ID and secret key securely.\n>4. For S3 bucket setup, refer to creating a [bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-bucket.html).\n>\n> Source: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user_manage_add-key.html\n\n#### User Environment\n\nKeep `ACCESS_TOKEN_EXPIRE_MIN` and `REFRESH_TOKEN_EXPIRE_MIN` as default. Update the `ALGORITHM` of your choice (e.g., `HS256` or `RS256`).\n\nGenerate `JWT_SECRET_KEY` and `JWT_REFRESH_SECRET_KEY` using Python:\n```bash\ndocflow$ python\n>> import secrets\n>> secrets.token_urlsafe(32)\n'some-random-secret-of-length-32'\n>> secrets.token_hex(32)\n'some-random-secret-of-length-32'\n```\n#### Email Service\n\nThis section explains how to set up the email service using Gmail. Configure the following variables:\n```.ignorelang\nSMTP_SERVER=smtp.gmail.com\nSMTP_PORT=587\nEMAIL=Your email address used to create the app\nAPP_PASSWORD=Generate an app password from your Google Account\n```\n\nBefore starting, ensure you have enabled \"Two-Factor Authentication\" and \"Less secure app access\" for your Gmail account.\n\n>For a deeper understanding of environment variables in Python, check out this article: \n>[@dev.to/jiisanda](https://dev.to/jiisanda/how-does-python-dotenv-simplify-configuration-management-3ne6)\n\n\n### 3️⃣ Run with Docker-Compose\n\nEnsure Docker is installed, then run:\n\n```commandline\ndocker-compose up --build\n```\n\nThat's it! Docflow is now running on localhost:8000. \n\nIf you face any issues, contact me I will help you set up or start an EC2 instance for testing docflow.\n\n## ⏭️ Next Step\n\nTo test it, use Postman following the steps in \n[postman.md](features/postman.md).\n***\n"
  },
  {
    "path": "app/logs/__init__.py",
    "content": ""
  },
  {
    "path": "app/logs/logger.py",
    "content": "import os\nimport logging\nimport logging.config\nfrom pathlib import Path\n\nLOGGER_NAME: str = \"docflow\"\nLOG_FORMAT: str = (\n    \"%(asctime)s [%(levelname)s] | %(name)s | %(filename)s | %(funcName)s | %(lineno)d | %(message)s\"\n)\nLOG_LEVEL: int = logging.DEBUG\n\n\ndef get_log_file_path():\n    \"\"\"\n    Get a writable log file path, trying multiple locations.\n    Returns None if no writable location is found.\n    \"\"\"\n    possible_locations = [\n        \"/usr/src/app/logs/docflow.log\",\n        \"/app/logs/docflow.log\",\n        \"/tmp/docflow.log\",\n        \"docflow.log\",\n    ]\n\n    for log_path in possible_locations:\n        try:\n            log_file = Path(log_path)\n            log_file.parent.mkdir(parents=True, exist_ok=True)\n\n            test_write = log_file.parent / f\"test_write_{os.getpid()}.tmp\"\n            test_write.touch()\n            test_write.unlink()\n\n            return str(log_file)\n        except (OSError, PermissionError):\n            continue\n\n    return None\n\n\nLOG_FILE = get_log_file_path()\n\nLOGGING = {\n    \"version\": 1,\n    \"disable_existing_loggers\": False,\n    \"formatters\": {\n        \"standard\": {\n            \"format\": LOG_FORMAT,\n            \"datefmt\": \"%Y-%m-%d %H:%M:%S\",\n        },\n        \"console\": {\n            \"format\": \"%(asctime)s [%(levelname)s] | %(name)s | %(message)s\",\n            \"datefmt\": \"%Y-%m-%d %H:%M:%S\",\n        },\n    },\n    \"handlers\": {\n        \"console\": {\n            \"level\": \"INFO\",\n            \"formatter\": \"console\",\n            \"class\": \"logging.StreamHandler\",\n            \"stream\": \"ext://sys.stdout\",\n        },\n        \"error_console\": {\n            \"level\": \"ERROR\",\n            \"formatter\": \"standard\",\n            \"class\": \"logging.StreamHandler\",\n            \"stream\": \"ext://sys.stderr\",\n        },\n    },\n    \"loggers\": {\n        \"\": {\"handlers\": [\"console\"], \"level\": \"INFO\", \"propagate\": False},\n        LOGGER_NAME: {\n            \"handlers\": [\"console\", \"error_console\"],\n            \"level\": LOG_LEVEL,\n            \"propagate\": False,\n        },\n        \"sqlalchemy\": {\n            \"handlers\": [\"console\"],\n            \"level\": \"WARNING\",\n            \"propagate\": False,\n        },\n        \"s3\": {\n            \"handlers\": [\"console\"],\n            \"level\": \"WARNING\",\n            \"propagate\": False,\n        },\n        \"uvicorn.error\": {\"level\": \"INFO\", \"handlers\": [\"console\"], \"propagate\": False},\n        \"uvicorn.access\": {\n            \"level\": \"INFO\",\n            \"handlers\": [\"console\"],\n            \"propagate\": False,\n        },\n        \"uvicorn.asgi\": {\"level\": \"INFO\", \"handlers\": [\"console\"], \"propagate\": False},\n    },\n}\n\nif LOG_FILE:\n    LOGGING[\"handlers\"][\"file\"] = {\n        \"class\": \"logging.handlers.RotatingFileHandler\",\n        \"formatter\": \"standard\",\n        \"level\": \"DEBUG\",\n        \"filename\": LOG_FILE,\n        \"mode\": \"a\",\n        \"encoding\": \"utf-8\",\n        \"maxBytes\": 500000,\n        \"backupCount\": 4,\n    }\n\n    LOGGING[\"loggers\"][LOGGER_NAME][\"handlers\"].append(\"file\")\n    LOGGING[\"loggers\"][\"sqlalchemy\"][\"handlers\"].append(\"file\")\n    LOGGING[\"loggers\"][\"s3\"][\"handlers\"].append(\"file\")\n\ntry:\n    logging.config.dictConfig(LOGGING)\nexcept Exception as e:\n    logging.basicConfig(\n        level=LOG_LEVEL, format=LOG_FORMAT, handlers=[logging.StreamHandler()]\n    )\n    print(f\"Warning: Failed to configure logging: {e}\")\n\ndocflow_logger = logging.getLogger(LOGGER_NAME)\ns3_logger = logging.getLogger(\"s3\")\nsqlalchemy_logger = logging.getLogger(\"sqlalchemy\")\n\nif LOG_FILE:\n    docflow_logger.info(f\"File logging enabled: {LOG_FILE}\")\nelse:\n    docflow_logger.warning(\"File logging disabled - no writable location found\")\n"
  },
  {
    "path": "app/main.py",
    "content": "from contextlib import asynccontextmanager\n\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\n\nfrom app.api.router import router\nfrom app.core.config import settings\nfrom app.db.models import check_tables\nfrom app.logs.logger import docflow_logger\nfrom app.scripts.init_bucket import create_bucket_if_not_exists\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n    docflow_logger.info(\"Starting DocFlow...\")\n\n    try:\n        docflow_logger.info(\"Initializing Tables and Storage buckets...\")\n        await check_tables()\n        await create_bucket_if_not_exists()\n        docflow_logger.info(\"Tables and Storage buckets successfully created.\")\n    except Exception as e:\n        docflow_logger.error(f\"Error during startup: {e}\")\n        raise\n    yield\n\n\napp = FastAPI(\n    title=settings.title,\n    version=settings.version,\n    description=settings.description,\n    docs_url=settings.docs_url,\n    openapi_url=settings.openapi_url,\n    lifespan=lifespan,\n)\n\napp.include_router(router=router, prefix=settings.api_prefix)\n\n\nFAVICON_PATH = \"favicon.ico\"\n\n\n@app.get(FAVICON_PATH, include_in_schema=False, tags=[\"Default\"])\nasync def favicon():\n    return FileResponse(FAVICON_PATH)\n\n\n@app.get(\"/\", tags=[\"Default\"])\nasync def root():\n    return {\n        \"API\": \"DocFlow - Document Management API is running! 🚀\",\n        \"version\": settings.version,\n        \"docs\": f\"{settings.host_url}{settings.docs_url}\",\n        \"storage\": \"MinIO\" if settings.s3_endpoint_url else \"AWS S3\",\n    }\n\n\n@app.get(\"/health\", tags=[\"Default\"])\nasync def health_check():\n    \"\"\"Health check endpoint\"\"\"\n    return {\"status\": \"healthy\", \"service\": \"DocFlow API\", \"version\": settings.version}\n"
  },
  {
    "path": "app/schemas/__init__.py",
    "content": ""
  },
  {
    "path": "app/schemas/auth/__init__.py",
    "content": ""
  },
  {
    "path": "app/schemas/auth/auth.py",
    "content": "from app.schemas.auth.bands import UserOut\n\n\nclass SystemUser(UserOut):\n    password: str\n"
  },
  {
    "path": "app/schemas/auth/bands.py",
    "content": "from datetime import datetime\nfrom typing import Annotated, Optional\nfrom ulid import ULID\n\nfrom pydantic import BaseModel, EmailStr, Field\n\n\nPydanticULID = Annotated[str, ULID]\n\n\nclass UserAuth(BaseModel):\n    username: str = Field(...)\n    email: EmailStr = Field(..., description=\"Email ID\")\n    password: str = Field(..., min_length=5, max_length=14, description=\"Password\")\n\n\nclass UserOut(BaseModel):\n    id: PydanticULID\n    email: EmailStr\n    user_since: datetime\n\n    class Config:\n        from_attributes = True\n\n\nclass Token(BaseModel):\n    access_token: str\n    token_type: str\n\n\nclass TokenData(BaseModel):\n    id: Optional[str] = None\n    username: Optional[str] = None\n"
  },
  {
    "path": "app/schemas/documents/__init__.py",
    "content": ""
  },
  {
    "path": "app/schemas/documents/bands.py",
    "content": "from datetime import datetime\nfrom typing import Optional, List\nfrom uuid import UUID\n\nfrom pydantic import BaseModel\n\nfrom app.db.tables.base_class import StatusEnum, NotifyEnum\n\n\n# Document Metadata\nclass DocumentMetadataBase(BaseModel):\n    _id: UUID\n    owner_id: str\n    name: str\n    s3_url: str\n    created_at: datetime\n    size: Optional[int]\n    file_type: Optional[str]\n    tags: Optional[List[str]]\n    categories: Optional[List[str]]\n    status: StatusEnum\n    file_hash: Optional[str]\n    access_to: Optional[List[str]]\n\n\nclass DocumentMetadataPatch(BaseModel):\n    name: str = None\n    tags: Optional[List[str]] = None\n    categories: Optional[List[str]] = None\n    access_to: Optional[List[str]] = None\n\n\n# Document Sharing\nclass DocumentSharingBase(BaseModel):\n    url_id: str\n    owner_id: str\n    filename: str\n    url: str\n    expires_at: datetime\n    visits: int\n    share_to: Optional[List[str]] = None\n\n\nclass DocUserAccess(BaseModel):\n    id: str\n    doc_id: UUID\n    user_id: str\n\n    class Config:\n        from_attribute = True\n\n\nclass DocUserAccessCreate(BaseModel):\n    doc_id: str\n    user_id: str\n\n\n# Notifications\nclass Notification(BaseModel):\n    id: UUID\n    receiver_id: str\n    message: str\n    status: NotifyEnum\n    notified_at: datetime\n\n\nclass NotifyPatchStatus(BaseModel):\n    status: NotifyEnum = NotifyEnum.unread\n    mark_all: bool = False\n"
  },
  {
    "path": "app/schemas/documents/document_sharing.py",
    "content": "from typing import List, Optional\n\nfrom pydantic import BaseModel\n\nfrom app.schemas.documents.bands import DocumentSharingBase\n\n\nclass DocumentSharingCreate(DocumentSharingBase): ...\n\n\nclass DocumentSharingRead(DocumentSharingBase):\n    url_id: str\n    visits: int\n\n    class Config:\n        from_attributes = True\n\n\nclass SharingRequest(BaseModel):\n    visits: int = 1  # default value of visits (1)\n    share_to: Optional[List[str]] = None  # emails, or usernames of users to share.\n    message: Optional[str] = None  # message from sender if any\n"
  },
  {
    "path": "app/schemas/documents/documents_metadata.py",
    "content": "from typing import Optional, List\nfrom uuid import UUID\n\nfrom app.schemas.documents.bands import DocumentMetadataBase\n\n\nclass DocumentMetadataCreate(DocumentMetadataBase):\n    owner_id: Optional[str] = None\n    name: str\n    s3_url: str\n    access_to: Optional[List[str]] = None\n\n\nclass DocumentMetadataRead(DocumentMetadataBase):\n    id: UUID\n    name: str\n\n    class Config:\n        from_attributes = True\n"
  },
  {
    "path": "app/scripts/create_database.sql",
    "content": "-- Creating the DATABASE\nCREATE DATABASE document_db;\nCREATE DATABASE test_document_db;\n\nGRANT ALL PRIVILEGES ON DATABASE document_db to \"postgres\";\nGRANT ALL PRIVILEGES ON DATABASE test_document_db to \"postgres\";"
  },
  {
    "path": "app/scripts/init_bucket.py",
    "content": "import asyncio\n\nimport boto3\nfrom botocore.exceptions import ClientError\n\nfrom app.core.config import settings\nfrom app.logs.logger import s3_logger\n\n\nasync def create_bucket_if_not_exists():\n    \"\"\"Create S3/MinIO bucket if it doesn't exist\"\"\"\n    try:\n        boto3_config = {\n            \"aws_access_key_id\": settings.aws_access_key_id,\n            \"aws_secret_access_key\": settings.aws_secret_key,\n            \"region_name\": settings.aws_region,\n        }\n\n        if settings.s3_endpoint_url:\n            boto3_config[\"endpoint_url\"] = settings.s3_endpoint_url\n\n        client = boto3.client(\"s3\", **boto3_config)\n\n        try:\n            client.head_bucket(Bucket=settings.s3_bucket)\n            s3_logger.info(f\"✅ Bucket '{settings.s3_bucket}' already exists\")\n        except ClientError as e:\n            error_code = e.response[\"Error\"][\"Code\"]\n            if error_code == \"404\":\n                try:\n                    if settings.s3_endpoint_url:\n                        client.create_bucket(Bucket=settings.s3_bucket)\n                    else:\n                        if settings.aws_region == \"us-east-1\":\n                            client.create_bucket(Bucket=settings.s3_bucket)\n                        else:\n                            client.create_bucket(\n                                Bucket=settings.s3_bucket,\n                                CreateBucketConfiguration={\n                                    \"LocationConstraint\": settings.aws_region\n                                },\n                            )\n\n                    s3_logger.info(f\"✅ Created bucket '{settings.s3_bucket}'\")\n\n                    await asyncio.sleep(1)  # waiting for bucket to get created\n\n                    try:\n                        client.put_bucket_versioning(\n                            Bucket=settings.s3_bucket,\n                            VersioningConfiguration={\"Status\": \"Enabled\"},\n                        )\n                        s3_logger.info(\n                            f\"✅ Enabled versioning for bucket '{settings.s3_bucket}'\"\n                        )\n                    except Exception as ve:\n                        s3_logger.warning(f\"⚠️  Could not enable versioning: {ve}\")\n\n                except ClientError as ce:\n                    s3_logger.warning(\n                        f\"❌ Failed to create bucket '{settings.s3_bucket}': {ce}\"\n                    )\n                    raise\n            else:\n                s3_logger.warning(\n                    f\"❌ Error accessing bucket '{settings.s3_bucket}': {e}\"\n                )\n                raise\n\n        # Also create test bucket if specified and different from main bucket\n        if settings.s3_test_bucket and settings.s3_test_bucket != settings.s3_bucket:\n            try:\n                client.head_bucket(Bucket=settings.s3_test_bucket)\n                s3_logger.info(\n                    f\"✅ Test bucket '{settings.s3_test_bucket}' already exists\"\n                )\n            except ClientError as e:\n                if e.response[\"Error\"][\"Code\"] == \"404\":\n                    try:\n                        if settings.s3_endpoint_url:\n                            client.create_bucket(Bucket=settings.s3_test_bucket)\n                        else:\n                            if settings.aws_region == \"us-east-1\":\n                                client.create_bucket(Bucket=settings.s3_test_bucket)\n                            else:\n                                client.create_bucket(\n                                    Bucket=settings.s3_test_bucket,\n                                    CreateBucketConfiguration={\n                                        \"LocationConstraint\": settings.aws_region\n                                    },\n                                )\n                        s3_logger.info(\n                            f\"✅ Created test bucket '{settings.s3_test_bucket}'\"\n                        )\n                    except ClientError as ce:\n                        s3_logger.warning(\n                            f\"❌ Failed to create test bucket '{settings.s3_test_bucket}': {ce}\"\n                        )\n\n    except Exception as e:\n        s3_logger.warning(f\"❌ Error during bucket initialization: {e}\")\n"
  },
  {
    "path": "docker-compose.override.yml",
    "content": "services:\n  api:\n    build:\n        context: .\n        dockerfile: api.Dockerfile\n    # Bind mounts\n    volumes:\n      - ./:/usr/src/app:ro\n      - ./downloads:/app/downloads\n      - ./logs:/usr/src/app/logs\n    command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload\n  \n  minio:\n    image: minio/minio:RELEASE.2025-05-24T17-08-30Z-cpuv1\n    command: server /data --console-address \":9001\"\n    ports:\n      - \"9000:9000\"\n      - \"9001:9001\"\n    env_file:\n      - app/.env\n    healthcheck:\n      test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:9000/minio/health/live\"]\n      interval: 30s\n      timeout: 20s\n      retries: 3\n    volumes:\n      - minio-data:/data\n      \nvolumes:\n  minio-data:\n"
  },
  {
    "path": "docker-compose.prod.yml",
    "content": "services:\n  api:\n    image: jiisanda/docflow:1\n    command: uvicorn app.main:app --host 0.0.0.0 --port 8000\n  nginx:\n    image: nginx:1.25.3-alpine\n    ports:\n      - \"80:80\"\n    volumes:\n      - ./nginx:/etc/nginx/conf.d\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "services:\n  api:\n    depends_on:\n      - postgres\n    ports:\n      - \"8000:8000\"\n    env_file: app/.env\n\n  postgres:\n    image: postgres\n    env_file: app/.env\n    volumes:\n      - postgres-db:/var/lib/postgresql\n    ports:\n        - \"5432:5432\"\n\nvolumes:\n  postgres-db:\n"
  },
  {
    "path": "hello.txt",
    "content": ""
  },
  {
    "path": "migrations/__init__.py",
    "content": ""
  },
  {
    "path": "migrations/env.py",
    "content": "from logging.config import fileConfig\n\nfrom sqlalchemy import engine_from_config\nfrom sqlalchemy import pool\n\nfrom alembic import context\n\nfrom app.db.models import Base\n\nfrom app.core.config import settings\nfrom app.db.tables.documents.documents_metadata import DocumentMetadata\nfrom app.db.tables.auth.auth import User\nfrom app.db.tables.documents.document_sharing import DocumentSharing\nfrom app.db.tables.documents.notify import Notify\n\n# this is the Alembic Config object, which provides\n# access to the values within the .ini file in use.\nconfig = context.config\nconfig.set_main_option(\"sqlalchemy.url\", settings.sync_database_url)\n\n# Interpret the config file for Python logging.\n# This line sets up loggers basically.\nif config.config_file_name is not None:\n    fileConfig(config.config_file_name)\n\n# add your model's MetaData object here\n# for 'autogenerate' support\n\ntarget_metadata = Base.metadata\n\n# other values from the config, defined by the needs of env.py,\n# can be acquired:\n# my_important_option = config.get_main_option(\"my_important_option\")\n# ... etc.\n\n\ndef run_migrations_offline() -> None:\n    \"\"\"Run migrations in 'offline' mode.\n\n    This configures the context with just a URL\n    and not an Engine, though an Engine is acceptable\n    here as well.  By skipping the Engine creation\n    we don't even need a DBAPI to be available.\n\n    Calls to context.execute() here emit the given string to the\n    script output.\n\n    \"\"\"\n    url = config.get_main_option(\"sqlalchemy.url\")\n    context.configure(\n        url=url,\n        target_metadata=target_metadata,\n        literal_binds=True,\n        dialect_opts={\"paramstyle\": \"named\"},\n    )\n\n    with context.begin_transaction():\n        context.run_migrations()\n\n\ndef run_migrations_online() -> None:\n    \"\"\"Run migrations in 'online' mode.\n\n    In this scenario we need to create an Engine\n    and associate a connection with the context.\n\n    \"\"\"\n    connectable = engine_from_config(\n        config.get_section(config.config_ini_section, {}),\n        prefix=\"sqlalchemy.\",\n        poolclass=pool.NullPool,\n    )\n\n    with connectable.connect() as connection:\n        context.configure(connection=connection, target_metadata=target_metadata)\n\n        with context.begin_transaction():\n            context.run_migrations()\n\n\nif context.is_offline_mode():\n    run_migrations_offline()\nelse:\n    run_migrations_online()\n"
  },
  {
    "path": "migrations/script.py.mako",
    "content": "\"\"\"${message}\n\nRevision ID: ${up_revision}\nRevises: ${down_revision | comma,n}\nCreate Date: ${create_date}\n\n\"\"\"\nfrom typing import Sequence, Union\n\nfrom alembic import op\nimport sqlalchemy as sa\n${imports if imports else \"\"}\n\n# revision identifiers, used by Alembic.\nrevision: str = ${repr(up_revision)}\ndown_revision: Union[str, None] = ${repr(down_revision)}\nbranch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}\ndepends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}\n\n\ndef upgrade() -> None:\n    ${upgrades if upgrades else \"pass\"}\n\n\ndef downgrade() -> None:\n    ${downgrades if downgrades else \"pass\"}\n"
  },
  {
    "path": "migrations/versions/2a02384ab925_initial_almebic.py",
    "content": "\"\"\"Initial Almebic\n\nRevision ID: 2a02384ab925\nRevises: \nCreate Date: 2023-11-01 20:51:23.621851\n\n\"\"\"\n\nfrom typing import Sequence, Union\n\nfrom alembic import op\nimport sqlalchemy as sa\nfrom sqlalchemy.dialects import postgresql\n\n# revision identifiers, used by Alembic.\nrevision: str = \"2a02384ab925\"\ndown_revision: Union[str, None] = None\nbranch_labels: Union[str, Sequence[str], None] = None\ndepends_on: Union[str, Sequence[str], None] = None\n\n\ndef upgrade() -> None:\n    # ### commands auto generated by Alembic - please adjust! ###\n    op.create_table(\n        \"notify\",\n        sa.Column(\"id\", postgresql.UUID(as_uuid=True), nullable=False),\n        sa.Column(\"receiver_id\", sa.String(), nullable=False),\n        sa.Column(\"message\", sa.Text(), nullable=False),\n        sa.Column(\n            \"status\", sa.Enum(\"read\", \"unread\", name=\"notifyenum\"), nullable=True\n        ),\n        sa.Column(\n            \"notified_at\",\n            sa.DateTime(timezone=True),\n            server_default=sa.text(\"NOW()\"),\n            nullable=False,\n        ),\n        sa.PrimaryKeyConstraint(\"id\"),\n    )\n    op.create_index(op.f(\"ix_notify_id\"), \"notify\", [\"id\"], unique=False)\n    op.create_table(\n        \"users\",\n        sa.Column(\"id\", sa.String(length=26), nullable=False),\n        sa.Column(\"username\", sa.String(), nullable=False),\n        sa.Column(\"email\", sa.String(), nullable=False),\n        sa.Column(\"password\", sa.Text(), nullable=False),\n        sa.Column(\n            \"user_since\",\n            sa.TIMESTAMP(timezone=True),\n            server_default=sa.text(\"now()\"),\n            nullable=False,\n        ),\n        sa.PrimaryKeyConstraint(\"id\"),\n        sa.UniqueConstraint(\"email\"),\n        sa.UniqueConstraint(\"username\"),\n    )\n    op.create_index(op.f(\"ix_users_id\"), \"users\", [\"id\"], unique=True)\n    op.create_table(\n        \"document_metadata\",\n        sa.Column(\"id\", postgresql.UUID(as_uuid=True), nullable=False),\n        sa.Column(\"owner_id\", sa.String(), nullable=False),\n        sa.Column(\"name\", sa.String(), nullable=True),\n        sa.Column(\"s3_url\", sa.String(), nullable=True),\n        sa.Column(\n            \"created_at\",\n            sa.DateTime(timezone=True),\n            server_default=sa.text(\"NOW()\"),\n            nullable=False,\n        ),\n        sa.Column(\"size\", sa.Integer(), nullable=True),\n        sa.Column(\"file_type\", sa.String(), nullable=True),\n        sa.Column(\"tags\", sa.ARRAY(sa.String()), nullable=True),\n        sa.Column(\"categories\", sa.ARRAY(sa.String()), nullable=True),\n        sa.Column(\n            \"status\",\n            sa.Enum(\n                \"public\", \"private\", \"shared\", \"deleted\", \"archived\", name=\"statusenum\"\n            ),\n            nullable=True,\n        ),\n        sa.Column(\"file_hash\", sa.String(), nullable=True),\n        sa.Column(\"access_to\", sa.ARRAY(sa.String()), nullable=True),\n        sa.ForeignKeyConstraint(\n            [\"owner_id\"],\n            [\"users.id\"],\n        ),\n        sa.PrimaryKeyConstraint(\"id\"),\n        sa.UniqueConstraint(\"s3_url\"),\n    )\n    op.create_index(\n        op.f(\"ix_document_metadata_id\"), \"document_metadata\", [\"id\"], unique=False\n    )\n    op.create_table(\n        \"share_url\",\n        sa.Column(\"url_id\", sa.String(), nullable=False),\n        sa.Column(\"filename\", sa.String(), nullable=False),\n        sa.Column(\"owner_id\", sa.String(), nullable=False),\n        sa.Column(\"url\", sa.String(), nullable=True),\n        sa.Column(\"expires_at\", sa.DateTime(timezone=True), nullable=True),\n        sa.Column(\"visits\", sa.Integer(), nullable=True),\n        sa.Column(\"share_to\", sa.ARRAY(sa.String()), nullable=True),\n        sa.ForeignKeyConstraint(\n            [\"owner_id\"],\n            [\"users.id\"],\n        ),\n        sa.PrimaryKeyConstraint(\"url_id\"),\n        sa.UniqueConstraint(\"filename\"),\n        sa.UniqueConstraint(\"url\"),\n        sa.UniqueConstraint(\"url_id\"),\n    )\n    op.create_table(\n        \"doc_user_access\",\n        sa.Column(\"doc_id\", postgresql.UUID(as_uuid=True), nullable=True),\n        sa.Column(\"user_id\", sa.String(length=26), nullable=True),\n        sa.ForeignKeyConstraint(\n            [\"doc_id\"], [\"document_metadata.id\"], ondelete=\"CASCADE\"\n        ),\n        sa.ForeignKeyConstraint(\n            [\"user_id\"],\n            [\"users.id\"],\n        ),\n        sa.UniqueConstraint(\"doc_id\", \"user_id\", name=\"uq_doc_user_access_doc_user\"),\n    )\n    # ### end Alembic commands ###\n\n\ndef downgrade() -> None:\n    # ### commands auto generated by Alembic - please adjust! ###\n    op.drop_table(\"doc_user_access\")\n    op.drop_table(\"share_url\")\n    op.drop_index(op.f(\"ix_document_metadata_id\"), table_name=\"document_metadata\")\n    op.drop_table(\"document_metadata\")\n    op.drop_index(op.f(\"ix_users_id\"), table_name=\"users\")\n    op.drop_table(\"users\")\n    op.drop_index(op.f(\"ix_notify_id\"), table_name=\"notify\")\n    op.drop_table(\"notify\")\n    # ### end Alembic commands ###\n"
  },
  {
    "path": "migrations/versions/__init__.py",
    "content": ""
  },
  {
    "path": "nginx/nginx.conf",
    "content": "server {\n    listen 80;\n    server_name _;      # As we are using IP address or the public DNS of our EC2 instance\n\n    location / {\n        proxy_pass http://34.219.169.191:8000;\n    }\n}"
  },
  {
    "path": "requirements/api.txt",
    "content": "alembic>=1.12.1\nannotated-types>=0.6.0\nanyio>=4.2.0\nasyncpg==0.30.0\nboto3>=1.34.34\nbotocore>=1.34.34\ncertifi>=2024.7.4\nclick>=8.1.7\ncolorama>=0.4.6\ndnspython>=2.6.1\nemail-validator>=2.1.0\nfastapi>=0.109.2\ngreenlet==3.1.1\nh11>=0.14.0\nhttpcore>=0.17.3\nhttpx>=0.24.1\nidna>=3.7\niniconfig>=2.0.0\njmespath>=1.0.1\nMako>=1.3.0\nMarkupSafe>=2.1.3\npackaging>=23.2\npasslib~=1.7.4\npluggy>=1.3.0\npsycopg2-binary==2.9.10\npyasn1>=0.5.1\npydantic>=2.8.2\npydantic-settings>=2.4.0\npydantic_core==2.23.4\npytest>=7.4.4\npython-dateutil>=2.8.2\npython-dotenv>=1.0.0\npython-jose==3.3.0\npython-multipart>=0.0.18\npython-ulid>=2.2.0\nrsa>=4.9\ns3transfer>=0.10.0\nsix>=1.16.0\nsniffio>=1.3.0\nSQLAlchemy>=1.4.51\nstarlette>=0.40.0\ntyping_extensions>=4.9.0\nurllib3>=2.2.2\nuvicorn>=0.26.0\n"
  }
]