From 26a679268b3db4deb88049342a9f4e83d015bf98 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Thu, 25 Jun 2026 14:39:13 +0545 Subject: [PATCH] chore(root): remove project planning markdown and outdated configuration files Remove extensive PLAN.md, management scripts, and lock files that are no longer needed. --- PLAN.md | 538 ----------------------------------------------- Procfile | 20 -- README.md | 112 ---------- justfile | 229 -------------------- manage.py | 32 --- pyproject.toml | 40 ---- requirements.txt | 9 - runtime.txt | 1 - skills-lock.json | 17 -- uv.lock | 329 ----------------------------- 10 files changed, 1327 deletions(-) delete mode 100644 PLAN.md delete mode 100644 Procfile delete mode 100644 README.md delete mode 100644 justfile delete mode 100755 manage.py delete mode 100644 pyproject.toml delete mode 100644 requirements.txt delete mode 100644 runtime.txt delete mode 100644 skills-lock.json delete mode 100644 uv.lock diff --git a/PLAN.md b/PLAN.md deleted file mode 100644 index d71f59f..0000000 --- a/PLAN.md +++ /dev/null @@ -1,538 +0,0 @@ -# Django Project Architecture Plan - -## Overview - -This project is a modular Django-based project management and business operations platform with: - -- Role-based access control -- Project management -- Private kanban workflows -- Issue tracking -- Ticketing system -- Finance & payroll -- Activity tracking -- HTMX + Alpine.js frontend architecture - ---- - -# Project Structure - -````text -myproject/ -├── config/ # settings, urls, wsgi -├── apps/ -│ ├── accounts/ # CustomUser, role system -│ ├── projects/ # Project, Membership - │ ├── finance/ # Invoice, Payment, Expense, Payroll -│ ├── kanban/ # Board, Column, Card (private per user) - │ ├── issues/ # Issue, Comment, Label, Status - │ ├── tickets/ # Ticket, FeatureRequest - │ └── activity/ # ActivityLog, progress aggregation - ├── templates/ - │ ├── base.html - │ ├── partials/ # HTMX partial templates - │ └── components/ # Alpine.js UI components - └── static/ - ``` - - --- - -# Actors - -## Admin - - Full system access - - Manage users, projects, finance, tickets, and reports - - Read-only access to aggregated kanban progress - -## Client - - View own projects - - Create/view tickets - - View invoices and payments - - Comment on issues - -## Team Member - - Work on assigned issues - - Access own kanban board - - View assigned projects - - Access payroll information - - --- - -# Django Apps Breakdown - -## 1. accounts - -### Responsibilities - - Authentication - - Authorization - - Role management - - Project memberships - -### Main Models - - ```python - class CustomUser(AbstractUser): - ROLE_CHOICES = [ - ("admin", "Admin"), - ("client", "Client"), - ("member", "Team Member"), - ] - - role = models.CharField(max_length=20, choices=ROLE_CHOICES) - ``` - - ```python - class ProjectMembership(models.Model): - user = models.ForeignKey(CustomUser, on_delete=models.CASCADE) - project = models.ForeignKey("projects.Project", on_delete=models.CASCADE) - joined_at = models.DateTimeField(auto_now_add=True) - ``` - - --- - -## 2. projects - -### Responsibilities - - Core project management - - Team assignment - - Project lifecycle - -### Main Models - - ```python - class Project(models.Model): - - class Status(models.TextChoices): - PLANNING = "planning" - ACTIVE = "active" - REVIEW = "review" - DONE = "done" - - name = models.CharField(max_length=255) - client = models.ForeignKey( - "accounts.CustomUser", - on_delete=models.CASCADE, - related_name="client_projects" - ) - -status = models.CharField( - max_length=20, - choices=Status.choices, - default=Status.PLANNING - ) - - members = models.ManyToManyField( - "accounts.CustomUser", - through="accounts.ProjectMembership" - ) - ``` - - --- - -## 3. finance - -### Responsibilities - - Invoices - - Payments - - Expenses - - Payroll management - -### Main Models - -## Invoice - - ```python - class Invoice(models.Model): - - class Status(models.TextChoices): - PENDING = "pending" - PAID = "paid" - OVERDUE = "overdue" - - project = models.ForeignKey("projects.Project", on_delete=models.CASCADE) - client = models.ForeignKey("accounts.CustomUser", on_delete=models.CASCADE) - - amount = models.DecimalField(max_digits=10, decimal_places=2) - due_date = models.DateField() -status = models.CharField(max_length=20, choices=Status.choices) - ``` - -## Payment - - ```python - class Payment(models.Model): - invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE) - paid_at = models.DateTimeField() - method = models.CharField(max_length=100) - ``` - -## Expense - - ```python - class Expense(models.Model): - project = models.ForeignKey("projects.Project", on_delete=models.CASCADE) - raised_by = models.ForeignKey("accounts.CustomUser", on_delete=models.CASCADE) - - amount = models.DecimalField(max_digits=10, decimal_places=2) -category = models.CharField(max_length=100) - ``` - -## TeamPayment - - ```python - class TeamPayment(models.Model): - member = models.ForeignKey("accounts.CustomUser", on_delete=models.CASCADE) - period = models.DateField() - amount = models.DecimalField(max_digits=10, decimal_places=2) - ``` - - --- - -## 4. kanban - -### Responsibilities - - Personal task management - - Progress tracking - - Drag-and-drop workflow - -### Privacy Rules - - Each board belongs to one user - - Members cannot access others' boards - - Admin sees only aggregated progress - -### Main Models - -## Board - - ```python - class Board(models.Model): - owner = models.ForeignKey( - "accounts.CustomUser", - on_delete=models.CASCADE - ) - - project = models.ForeignKey( - "projects.Project", - null=True, - blank=True, - on_delete=models.CASCADE - ) - ``` - -## Column - - ```python - class Column(models.Model): - board = models.ForeignKey(Board, on_delete=models.CASCADE) - name = models.CharField(max_length=100) - order = models.PositiveIntegerField() - ``` - -## Card - - ```python - class Card(models.Model): - column = models.ForeignKey(Column, on_delete=models.CASCADE) - - title = models.CharField(max_length=255) -description = models.TextField(blank=True) - - due_date = models.DateField(null=True, blank=True) -order = models.PositiveIntegerField() - ``` - -### Secure QuerySet Pattern - - ```python - class BoardQuerySet(models.QuerySet): - - def for_user(self, user): - return self.filter(owner=user) - ``` - - --- - -## 5. issues - -### Responsibilities - - Bug tracking - - Feature tracking - - Task assignment - - Internal discussion - -### Main Models - -## Issue - - ```python - class Issue(models.Model): - - class Status(models.TextChoices): - OPEN = "open" - IN_PROGRESS = "in_progress" - RESOLVED = "resolved" - CLOSED = "closed" - - class Priority(models.TextChoices): - LOW = "low" - MEDIUM = "medium" - HIGH = "high" - - project = models.ForeignKey("projects.Project", on_delete=models.CASCADE) - - reporter = models.ForeignKey( - "accounts.CustomUser", - on_delete=models.CASCADE, - related_name="reported_issues" - ) - - assignee = models.ForeignKey( - "accounts.CustomUser", - null=True, - blank=True, - on_delete=models.SET_NULL, - related_name="assigned_issues" - ) - - status = models.CharField(max_length=20, choices=Status.choices) -priority = models.CharField(max_length=20, choices=Priority.choices) - ``` - -## IssueComment - - ```python - class IssueComment(models.Model): - issue = models.ForeignKey(Issue, on_delete=models.CASCADE) - author = models.ForeignKey("accounts.CustomUser", on_delete=models.CASCADE) - body = models.TextField() - ``` - - --- - -## 6. tickets - -### Responsibilities - - Client support - - Feature requests - - Bug reporting - -### Main Models - - ```python - class Ticket(models.Model): - - class TicketType(models.TextChoices): - BUG = "bug" - FEATURE = "feature_request" - SUPPORT = "support" - - class Status(models.TextChoices): - NEW = "new" - ACKNOWLEDGED = "acknowledged" - IN_PROGRESS = "in_progress" - DONE = "done" - REJECTED = "rejected" - - creator = models.ForeignKey( - "accounts.CustomUser", - on_delete=models.CASCADE - ) - - project = models.ForeignKey( - "projects.Project", - null=True, - blank=True, - on_delete=models.CASCADE - ) - - ticket_type = models.CharField(max_length=30, choices=TicketType.choices) -status = models.CharField(max_length=30, choices=Status.choices) - ``` - -### Access Rules - - Only admin and client can create tickets - - Team members can only view assigned tickets - - Tickets may be converted into issues - - --- - -## 7. activity - -### Responsibilities - - Audit logging - - Timeline tracking - - Progress aggregation - -### Main Models - - ```python - class ActivityLog(models.Model): - actor = models.ForeignKey( - "accounts.CustomUser", - on_delete=models.CASCADE - ) - - verb = models.CharField(max_length=255) - -content_type = models.ForeignKey( - ContentType, - on_delete=models.CASCADE - ) - -object_id = models.PositiveIntegerField() - -timestamp = models.DateTimeField(auto_now_add=True) - ``` - -### Rules - - Members cannot view other members' activity logs - - Admin dashboard uses aggregated activity metrics - - --- - -# Frontend Stack - -## HTMX - Use HTMX for: - - Kanban drag-and-drop persistence - - Ticket status updates - - Issue comments - - Live search - - Partial rendering - - Inline updates - -## Alpine.js - Use Alpine.js for: - - Modal state - - Dropdowns - - Tabs - - Confirm dialogs - - Inline edit toggles - -## Suggested Drag-and-Drop Pattern - - - Use Sortable.js for drag UI - - Trigger HTMX POST request on drag end - - Persist new ordering server-side - - --- - -# Permission Pattern - - Instead of Django object permissions, use reusable helper functions and view mixins. - -## Example - - ```python - class ProjectMemberRequired(LoginRequiredMixin): - - def dispatch(self, request, *args, **kwargs): - - project = get_object_or_404( - Project, - pk=kwargs["pk"] - ) - - if not project.members.filter( - pk=request.user.pk - ).exists(): - raise PermissionDenied - - return super().dispatch(request, *args, **kwargs) - ``` - - --- - -# Access Control Matrix - - | Module | Admin | Client | Team Member | - |------------------|----------------|----------------------|---------------------| - | Kanban Board | Progress only | No access | Own board only | - | Issues | Full | View + comment | Assigned only | - | Tickets/Features | Full | Create + view own | View assigned | - | Finance | Full | Own invoices | Own payroll | - | Projects | Full | View own project | Assigned project | - - --- - -# Suggested Folder Layout - - ```text - core/ - ├── accounts - ├── projects - ├── notifications - └── activity - - features/ - ├── kanban - ├── issues - └── tickets - - finance/ - ├── invoices - ├── payments - ├── expenses - └── payroll - - templates/ - ├── base - ├── components - ├── partials - └── pages - ``` - - --- - -# Recommended Tech Stack - -## Backend - - Django -- Django REST Framework (optional API layer) - - PostgreSQL - - Redis - - Celery - -## Frontend - - HTMX - - Alpine.js - - Tailwind CSS - - django-tailwind-cli - -## Infrastructure - - Nginx - - Gunicorn - - Docker - - GitHub Actions CI/CD - - --- - -# Future Improvements - - - Real-time notifications with Django Channels - - WebSocket activity feed - - Time tracking - - Project analytics dashboard - - File attachments - - Email automation - - AI-assisted issue summaries - - Multi-tenant architecture - - --- - -# Final Notes - - This architecture keeps: - - Apps modular - - Permissions predictable - - HTMX interactions clean - - Kanban privacy secure - - Finance isolated - - Features scalable - - The structure is optimized for: - - Long-term maintainability - - Team collaboration - - Incremental feature expansion - - Clear domain separation -```` diff --git a/Procfile b/Procfile deleted file mode 100644 index a36a146..0000000 --- a/Procfile +++ /dev/null @@ -1,20 +0,0 @@ -# Procfile for config -# Used for deploying to PaaS platforms like Heroku, Railway, Render, etc. - -# Web server process (using Gunicorn) -# Adjust workers based on your needs: (2 x CPU cores) + 1 -web: gunicorn config.wsgi:application --bind 0.0.0.0:$PORT --workers 2 --timeout 120 --access-logfile - --error-logfile - --log-level info - -# Alternative web server configurations (uncomment to use): -# web: gunicorn config.wsgi:application --bind 0.0.0.0:$PORT --workers 4 --threads 2 --timeout 120 -# web: gunicorn config.wsgi:application --bind 0.0.0.0:$PORT --workers 2 --worker-class gevent --worker-connections 1000 --timeout 120 - -# Release task (runs migrations before deployment) -release: python manage.py migrate --noinput && python manage.py collectstatic --noinput - -# Uncomment below to run scheduled tasks (if using Celery) -# worker: celery -A config worker --loglevel=info -# beat: celery -A config beat --loglevel=info - -# Development server (for local testing with Foreman/Overmind) -# web: python manage.py runserver 0.0.0.0:$PORT \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 002b126..0000000 --- a/README.md +++ /dev/null @@ -1,112 +0,0 @@ -# config - -A Django project folder structure is generated with [djinitx/djinit/dj](https://github.com/S4NKALP/djinit). - -## Features - -- Modern project structure with environment-specific settings -- Pre-configured REST API with JWT authentication -- Essential dependencies and utilities -- Production-ready configuration - -## Setup - -### Using Just (Recommended) - -1. Set environment variables in `.env` file - -2. Run setup (installs dependencies, runs migrations, creates superuser): - ```bash - just setup - ``` - -3. Start development server: - ```bash - just dev - ``` - -### Traditional Method - -1. Install dependencies: - ```bash - pip install -r requirements.txt - ``` - -2. Set environment variables in `.env` file - -3. Run migrations: - ```bash - python manage.py migrate - ``` - -4. Create superuser: - ```bash - python manage.py createsuperuser - ``` - -5. Start development server: - ```bash - python manage.py runserver - ``` - -## Available Commands - -Run `just` to see all available commands, including: - -- `just dev` - Run development server -- `just migrate` - Run migrations -- `just makemigrations` - Create migrations -- `just createsuperuser` - Create superuser -- `just test` - Run tests -- `just lint` - Lint code -- `just format` - Format code -- `just shell` - Django shell -- `just clean` - Clean cache files -- `just install ` - Install package -- `just remove ` - Remove package -- `just server` - Run production server -- `just ci` - Run all linting and checks -- `just test-coverage` - Run tests with coverage - -## Project Structure - -``` -config/ -├── config/ -│ ├── settings/ -│ │ ├── base.py -│ │ ├── development.py -│ │ └── production.py -│ ├── admin/ -│ ├── api/ # API endpoints organized by model -│ │ ├── user/ # Example: if you have a User model -│ │ │ ├── views.py -│ │ │ ├── serializers.py -│ │ │ └── urls.py -│ │ └── urls.py -│ ├── models/ # Django models -│ ├── tests/ -│ ├── urls.py -│ ├── wsgi.py -│ └── asgi.py -├── manage.py -├── requirements.txt -├── pyproject.toml -├── uv.lock -├── .env.sample -└── README.md - -**Note:** For the single folder layout, organize your API endpoints by model name under the `api/` directory. -For example, if you have a `User` model in `models/user.py`, create: -- `api/user/views.py` - API views for User -- `api/user/serializers.py` - Serializers for User -- `api/user/urls.py` - URL patterns for User endpoints - -See the README files in `api/` and `models/` directories for more details. -``` - -## API Documentation - -When running in development mode, API documentation is available at: -- Swagger UI: http://localhost:8000/docs/ -- Schema: http://localhost:8000/schema/ \ No newline at end of file diff --git a/justfile b/justfile deleted file mode 100644 index ab66d62..0000000 --- a/justfile +++ /dev/null @@ -1,229 +0,0 @@ -# Justfile for config -# Task runner for Django development -# Install just: https://github.com/casey/just - -# Default task: show available commands -default: - @just --list - -# Run development server -dev: - uv run python manage.py runserver - -# Run development server with custom host and port -dev-server HOST="0.0.0.0" PORT="8000": - uv run python manage.py runserver {{ HOST }}:{{ PORT }} - -# Create migrations for all apps -makemigrations: - uv run python manage.py makemigrations - -# Create migrations for specific app -makemigrations-app APP: - uv run python manage.py makemigrations {{ APP }} - -# Run all migrations -migrate: - uv run python manage.py migrate - -# Reset database (delete all migrations) -reset-db: - uv run python manage.py flush --noinput - uv run python manage.py migrate - -# Create superuser -createsuperuser: - uv run python manage.py createsuperuser - -# Collect static files -collectstatic: - uv run python manage.py collectstatic --noinput - -# Run Django shell -shell: - uv run python manage.py shell - -# Run Django shell plus (IPython) -shell-plus: - uv run python manage.py shell_plus - -# Run tests -test: - uv run python manage.py test - -# Run tests with coverage -test-coverage: - uv run pytest --cov=. --cov-report=html --cov-report=term - -# Lint code with ruff -lint: - uv run ruff check . - -# Format code with ruff -format: - uv run ruff format . - -# Lint and format code -style: - uv run ruff check . - uv run ruff format . - -# Check security issues -check: - uv run python manage.py check - -# Check security issues (production settings) -check-deploy: - uv run python manage.py check --deploy - -# Show all database migrations status -showmigrations: - uv run python manage.py showmigrations - -# Sync dependencies (uv equivalent of pip freeze) -requirements: - #!/usr/bin/env -S uv run python - import tomllib - from pathlib import Path - pyproject = Path("pyproject.toml") - if not pyproject.exists(): - print("pyproject.toml not found") - raise SystemExit(1) - data = tomllib.loads(pyproject.read_text()) - deps = data.get("project", {}).get("dependencies", []) - Path("requirements.txt").write_text("\n".join(deps) + "\n") - print("Generated requirements.txt from pyproject.toml") - -# Run all linting and checks -ci: - uv run ruff check . - uv run ruff format --check . - uv run python manage.py check - -# Start interactive shell -shell-ipython: - uv run python manage.py shell_plus - -# Clear all cache -clear-cache: - uv run python manage.py clear_cache - -# Show Django version -version: - uv run python manage.py version - -# Run database shell -dbshell: - uv run python manage.py dbshell - -# Start production server with gunicorn -server: - uv run gunicorn config.wsgi:application --bind 0.0.0.0:8000 - -# Start production server with gunicorn workers -server-prod WORKERS="4": - uv run gunicorn config.wsgi:application --bind 0.0.0.0:8000 --workers {{ WORKERS }} - -# Start production server with gunicorn and reload on file changes -server-watch: - uv run gunicorn config.wsgi:application --bind 0.0.0.0:8000 --reload - -# Clean Python cache files -clean: - find . -type d -name "__pycache__" -exec rm -rf {} + - find . -type f -name "*.pyc" -delete - find . -type f -name "*.pyo" -delete - find . -type f -name ".coverage" -delete - find . -type d -name "*.egg-info" -exec rm -rf {} + - rm -rf htmlcov/ - rm -rf .pytest_cache/ - -# Pin dependencies in pyproject.toml using versions from uv.lock, keeping >= and extras -pin-deps: - #!/usr/bin/env -S uv run python - import tomllib, re - from pathlib import Path - - lock = Path("uv.lock") - if not lock.exists(): - print("uv.lock not found — run `uv sync` first") - raise SystemExit(0) - - data = tomllib.loads(lock.read_text()) - packages = {p["name"].lower(): p["version"] for p in data.get("package", [])} - - py = Path("pyproject.toml") - lines = py.read_text().splitlines() - - pattern = re.compile(r'^(\s*)"([^"]+)"(,?)') - - out = [] - for line in lines: - m = pattern.match(line) - if not m: - out.append(line) - continue - - indent, dep, comma = m.groups() - - base = dep - extras = "" - operator = ">=" - version = None - - # extras: django[postgres] - if "[" in base and "]" in base: - before, after = base.split("[", 1) - extras = "[" + after.split("]")[0] + "]" - base = before - - # detect >= or == - if ">=" in dep: - operator = ">=" - base, version = dep.split(">=") - base = base.strip() - elif "==" in dep: - operator = "==" - base, version = dep.split("==") - base = base.strip() - else: - base = dep - - base_lower = base.lower() - new_version = packages.get(base_lower) - - if new_version: - new_dep = f'{base}{extras}{operator}{new_version}' - line = f'{indent}"{new_dep}"{comma}' - - out.append(line) - - py.write_text("\n".join(out) + "\n") - print("Pinned dependencies (>= preserved, extras preserved).") - - -# Setup project for development (using uv) -setup: - uv sync - just pin-deps - uv run python manage.py migrate - uv run python manage.py createsuperuser - -# Complete setup including static files -setup-complete: - uv sync - uv run python manage.py migrate - uv run python manage.py collectstatic --noinput - uv run python manage.py createsuperuser - -# Install a new package -install PACKAGE: - uv add {{ PACKAGE }} - -# Install a dev package -install-dev PACKAGE: - uv add --dev {{ PACKAGE }} - -# Remove a package -remove PACKAGE: - uv remove {{ PACKAGE }} \ No newline at end of file diff --git a/manage.py b/manage.py deleted file mode 100755 index acda5d2..0000000 --- a/manage.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python - -"""generated with djinit""" - -"""Django's command-line utility for administrative tasks.""" -import os -import sys - -import environ - - -def main(): - """Run administrative tasks.""" - os.environ.setdefault("DJANGO_SETTINGS_MODULE", os.getenv("DJANGO_SETTINGS_MODULE", "config.settings.production")) - - try: - from django.core.management import execute_from_command_line - except ImportError as exc: - raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" - ) from exc - execute_from_command_line(sys.argv) - - -if __name__ == "__main__": - env = environ.Env() - # Read .env file, if it exists - environ.Env.read_env() - - main() \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 94d2748..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,40 +0,0 @@ -[project] -name = "backend" -version = "0.1.0" -description = "" -readme = "README.md" -requires-python = ">=3.13" -license = { text = "MIT" } -dependencies = [ - "django>=6.0.5", - "django-environ>=0.13.0", - "django-jazzmin==3.0.1", - "whitenoise>=6.12.0", - "psycopg[binary]", - "dj-database-url>=3.1.2", - "gunicorn>=26.0.0", - "django-tailwind-cli>=4.6.2", - "django-htmx>=1.27.0" -] - -[tool.ruff] -line-length = 88 -target-version = "py313" - -[tool.ruff.lint] -select = [ - "E", # pycodestyle errors - "W", # pycodestyle warnings - "F", # pyflakes - "I", # isort - "B", # flake8-bugbear - "C4", # flake8-comprehensions - "UP", # pyupgrade -] -ignore = [ - "E501", # line too long, handled by formatter - "B008", # do not perform function calls in argument defaults -] - -[tool.ruff.lint.isort] -known-first-party = ["config"] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 2aecf60..0000000 --- a/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -django>=6.0.5 -django-environ>=0.13.0 -django-jazzmin==3.0.1 -whitenoise>=6.12.0 -psycopg[binary] -dj-database-url>=3.1.2 -gunicorn>=26.0.0 -django-tailwind-cli>=4.6.2 -django-htmx>=1.27.0 diff --git a/runtime.txt b/runtime.txt deleted file mode 100644 index 3bbfd95..0000000 --- a/runtime.txt +++ /dev/null @@ -1 +0,0 @@ -python-3.13 \ No newline at end of file diff --git a/skills-lock.json b/skills-lock.json deleted file mode 100644 index fd0d0b9..0000000 --- a/skills-lock.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": 1, - "skills": { - "frontend-design": { - "source": "anthropics/skills", - "sourceType": "github", - "skillPath": "skills/frontend-design/SKILL.md", - "computedHash": "063a0e6448123cd359ad0044cc46b0e490cc7964d45ef4bb9fd842bd2ffbca67" - }, - "interface-design": { - "source": "Dammyjay93/interface-design", - "sourceType": "github", - "skillPath": ".claude/skills/interface-design/SKILL.md", - "computedHash": "d004c5e5e2e7132e1d64e9c2a339db7f7aaa69053a5c19cddc210dd35dd6fff5" - } - } -} diff --git a/uv.lock b/uv.lock deleted file mode 100644 index 4f38678..0000000 --- a/uv.lock +++ /dev/null @@ -1,329 +0,0 @@ -version = 1 -revision = 3 -requires-python = ">=3.13" - -[[package]] -name = "annotated-doc" -version = "0.0.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, -] - -[[package]] -name = "asgiref" -version = "3.11.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/63/40/f03da1264ae8f7cfdbf9146542e5e7e8100a4c66ab48e791df9a03d3f6c0/asgiref-3.11.1.tar.gz", hash = "sha256:5f184dc43b7e763efe848065441eac62229c9f7b0475f41f80e207a114eda4ce", size = 38550, upload-time = "2026-02-03T13:30:14.33Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/0a/a72d10ed65068e115044937873362e6e32fab1b7dce0046aeb224682c989/asgiref-3.11.1-py3-none-any.whl", hash = "sha256:e8667a091e69529631969fd45dc268fa79b99c92c5fcdda727757e52146ec133", size = 24345, upload-time = "2026-02-03T13:30:13.039Z" }, -] - -[[package]] -name = "backend" -version = "0.1.0" -source = { virtual = "." } -dependencies = [ - { name = "dj-database-url" }, - { name = "django" }, - { name = "django-environ" }, - { name = "django-htmx" }, - { name = "django-jazzmin" }, - { name = "django-tailwind-cli" }, - { name = "gunicorn" }, - { name = "psycopg", extra = ["binary"] }, - { name = "whitenoise" }, -] - -[package.metadata] -requires-dist = [ - { name = "dj-database-url", specifier = ">=3.1.2" }, - { name = "django", specifier = ">=6.0.5" }, - { name = "django-environ", specifier = ">=0.13.0" }, - { name = "django-htmx", specifier = ">=1.27.0" }, - { name = "django-jazzmin", specifier = "==3.0.1" }, - { name = "django-tailwind-cli", specifier = ">=4.6.2" }, - { name = "gunicorn", specifier = ">=26.0.0" }, - { name = "psycopg", extras = ["binary"] }, - { name = "whitenoise", specifier = ">=6.12.0" }, -] - -[[package]] -name = "click" -version = "8.4.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/9b/98/518d8e5081007684232226f475082b30087d0f585e8457db087298259f49/click-8.4.1.tar.gz", hash = "sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96", size = 353007, upload-time = "2026-05-22T04:08:37.769Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl", hash = "sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2", size = 116639, upload-time = "2026-05-22T04:08:35.26Z" }, -] - -[[package]] -name = "colorama" -version = "0.4.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, -] - -[[package]] -name = "dj-database-url" -version = "3.1.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "django" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/03/f6/00b625e9d371b980aa261011d0dc906a16444cb688f94215e0dc86996eb5/dj_database_url-3.1.2.tar.gz", hash = "sha256:63c20e4bbaa51690dfd4c8d189521f6bf6bc9da9fcdb23d95d2ee8ee87f9ec62", size = 11490, upload-time = "2026-02-19T15:30:23.638Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/a9/57c66006373381f1d3e5bd94216f1d371228a89f443d3030e010f73dd198/dj_database_url-3.1.2-py3-none-any.whl", hash = "sha256:544e015fee3efa5127a1eb1cca465f4ace578265b3671fe61d0ed7dbafb5ec8a", size = 8953, upload-time = "2026-02-19T15:30:39.37Z" }, -] - -[[package]] -name = "django" -version = "6.0.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "asgiref" }, - { name = "sqlparse" }, - { name = "tzdata", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5e/f1/bf85f0d29ef76abf901f193fe8fef4769d3da7794197832bc30151c071d8/django-6.0.5.tar.gz", hash = "sha256:bc6d6872e98a2864c836e42edd644b362db311147dd5aa8d5b82ba7a032f5269", size = 10924131, upload-time = "2026-05-05T13:54:39.329Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/94/5b/1328f8b84fce040c404f76822bf8c57d254e368e8cbd8bd67ec2b26d75f5/django-6.0.5-py3-none-any.whl", hash = "sha256:9d58a7cb49244e74c8e161d5e403a46d6209f1009ba40f5a66d6aa0d0786a8f0", size = 8368680, upload-time = "2026-05-05T13:54:33.532Z" }, -] - -[[package]] -name = "django-environ" -version = "0.13.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/3c/60983e6ec9b24a8d8588eecebfd21123cba980bce0a905807a27692f0860/django_environ-0.13.0.tar.gz", hash = "sha256:6c401e4c219442c2c4588c2116d5292b5484a6f69163ed09cd41f3943bfb645f", size = 63529, upload-time = "2026-02-18T01:08:08.791Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/00/3767393ece946084e1c6830a33ffb8e39d68642e27ad5ac7d4c8bd5de866/django_environ-0.13.0-py3-none-any.whl", hash = "sha256:37799d14cd78222c6fd8298e48bfe17965ff8e586091ad66a463e52e0e7b799e", size = 20682, upload-time = "2026-02-18T01:08:07.359Z" }, -] - -[[package]] -name = "django-htmx" -version = "1.27.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "asgiref" }, - { name = "django" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/34/f2/8c3e28a5eed8e5226835c762892bfef74eda7e8629c65b49c186098eb303/django_htmx-1.27.0.tar.gz", hash = "sha256:036e5da801bfdf5f1ca815f21592cfb9f004a898f330c842f15e55c70e301a75", size = 65362, upload-time = "2025-11-28T23:18:55.049Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/23/ac/25d28489dc43224e260f4ebee7565f7ef1efe12af0f284a89500c19f75e2/django_htmx-1.27.0-py3-none-any.whl", hash = "sha256:13e1e13b87d39b57f95aae6e4987cb3df056d0b1373a41f4a94504a00298ffd8", size = 62126, upload-time = "2025-11-28T23:18:53.57Z" }, -] - -[[package]] -name = "django-jazzmin" -version = "3.0.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "django" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/84/96/21b6255e90d92a3eb4e93bea9376635d54258e0353ebb913a55e40ae9254/django_jazzmin-3.0.1.tar.gz", hash = "sha256:67ae148bade41267a09ca8e4352ddefa6121795ebbac238bb9a6564ff841eb1b", size = 2053550, upload-time = "2024-10-08T17:40:59.771Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ad/5b/2f8c4b168e6c41bf1e4b14d787deb23d80f618f0693db913bbe208a4a907/django_jazzmin-3.0.1-py3-none-any.whl", hash = "sha256:12a0a4c1d4fd09c2eef22acf6a1f03112b515ba695c59faa8ea80efc81c1f21b", size = 2125957, upload-time = "2024-10-08T17:40:57.359Z" }, -] - -[[package]] -name = "django-tailwind-cli" -version = "4.6.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "django" }, - { name = "django-typer" }, - { name = "semver" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/dd/4e/67143e297e6196f3a7661ab912f888493fb9b40c2f50dd04964a7f22f055/django_tailwind_cli-4.6.2.tar.gz", hash = "sha256:479b82096ed2656c8990f59ae2ee2d1ea2abace7d82ba6013a0861502a906004", size = 122664, upload-time = "2026-05-14T09:12:48.168Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/8b/ed7e4d5757341e7a7daba9d8daa7152c80613208693d1ebb180d579e1428/django_tailwind_cli-4.6.2-py3-none-any.whl", hash = "sha256:5fed9b26c56533fa7c41a92f369ebd41da50b2f520414d5f77b0f2bf9a3caebc", size = 38388, upload-time = "2026-05-14T09:12:46.968Z" }, -] - -[[package]] -name = "django-typer" -version = "3.7.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "django" }, - { name = "typer" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c7/de/8b38b5d7277e70a00adc6328532f174c632facdf99553b904f79e8aad026/django_typer-3.7.3.tar.gz", hash = "sha256:833059b0bddd5a0c68945c4963064ebb0662b54eec803f86b43904ba6038b777", size = 2977182, upload-time = "2026-05-24T14:33:55.391Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/ee/ff00e923a81de3ea95deac71667744079d1e2709249631a5484a57b7baf6/django_typer-3.7.3-py3-none-any.whl", hash = "sha256:2e6591e081117725ef036578ada407dd5882b0213a8aff821d50399854b2c6f1", size = 296863, upload-time = "2026-05-24T14:33:53.502Z" }, -] - -[[package]] -name = "gunicorn" -version = "26.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "packaging" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6d/b7/a4a3f632f823e432ce6bc65f62961b7980c898c77f075a2f7118cb3846fe/gunicorn-26.0.0.tar.gz", hash = "sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf", size = 727286, upload-time = "2026-05-05T06:38:25.529Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl", hash = "sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc", size = 212009, upload-time = "2026-05-05T06:38:23.007Z" }, -] - -[[package]] -name = "markdown-it-py" -version = "4.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mdurl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, -] - -[[package]] -name = "mdurl" -version = "0.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, -] - -[[package]] -name = "packaging" -version = "26.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, -] - -[[package]] -name = "psycopg" -version = "3.3.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "tzdata", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/db/2f/cb91e5502ec9de1de6f1b76cfbf69531932725361168bb06963620c77e2e/psycopg-3.3.4.tar.gz", hash = "sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc", size = 165799, upload-time = "2026-05-01T23:31:55.179Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/e0/7b3dee031daae7743609ce3c746565d4a3ed7c2c186479eb48e34e838c64/psycopg-3.3.4-py3-none-any.whl", hash = "sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a", size = 213001, upload-time = "2026-05-01T23:20:50.816Z" }, -] - -[package.optional-dependencies] -binary = [ - { name = "psycopg-binary", marker = "implementation_name != 'pypy'" }, -] - -[[package]] -name = "psycopg-binary" -version = "3.3.4" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/09/43/13e9c406fbbf354580476e248a16b64802a376873ebe6339e30bb655572d/psycopg_binary-3.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7", size = 4590377, upload-time = "2026-05-01T23:29:18.782Z" }, - { url = "https://files.pythonhosted.org/packages/22/be/2923cd7c3683e7afdecf4f10796a18de02f5c5ddc0969aa2ad0a8cdd3bbd/psycopg_binary-3.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:75a9067e236f9b9ae3535b66fe99bddb33d39c0de10112e49b9ab11eee53dc31", size = 4669023, upload-time = "2026-05-01T23:29:25.884Z" }, - { url = "https://files.pythonhosted.org/packages/96/a0/2c913d6fe13d6a8bd13597d36739bf47af063ad9399e402cfecab16f3c1e/psycopg_binary-3.3.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:b56b603ebcea8aa10b46228b8410ba7f13e7c2ee54389d4d9be0927fd8ce2a70", size = 5467423, upload-time = "2026-05-01T23:29:33.416Z" }, - { url = "https://files.pythonhosted.org/packages/e7/38/205d10bc1ad0df4a21c5c51659126bd3ea0ef98fcad1e852f78c249bb9c3/psycopg_binary-3.3.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c677c4ad433cb7150c8cd304a0769ae3bcfbe5ea0676eb53faa7b1443b16d0d3", size = 5151137, upload-time = "2026-05-01T23:29:42.013Z" }, - { url = "https://files.pythonhosted.org/packages/36/fc/f0381ddcd45eff3bb70dbca6823a996048d7f507b2ec3fc92c6fabc0fe87/psycopg_binary-3.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:26df2717e59c0473e4465a97dfb1b7afebaa479277870fd5784d1436470db47c", size = 6736671, upload-time = "2026-05-01T23:29:51.626Z" }, - { url = "https://files.pythonhosted.org/packages/95/40/fa545ae152c24327651e5624e4902121e808270be36c10b12e9939be09bc/psycopg_binary-3.3.4-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1dc1f79fd16bb1f3f4421417a514607539f17804d95c7ed617265369d1981cae", size = 4979601, upload-time = "2026-05-01T23:29:56.961Z" }, - { url = "https://files.pythonhosted.org/packages/86/e4/2f8a47ee97f90cd2b933d0463081d35631ff419de2b8c984a5f369857de0/psycopg_binary-3.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:136f199a407b5348b9b857c504aff60c77622a28482e7195839ce1b51238c4cc", size = 4510513, upload-time = "2026-05-01T23:30:07.243Z" }, - { url = "https://files.pythonhosted.org/packages/0e/0e/94e842ff4a7f98ed162580ca2e8b8864b28c1e0350f2443f8ee47f821167/psycopg_binary-3.3.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b6f5a29e9c775b9f12a1a717aa7a2c80f9e1db6f27ba44a5b59c80ac61d2ffcf", size = 4187243, upload-time = "2026-05-01T23:30:15.352Z" }, - { url = "https://files.pythonhosted.org/packages/d0/83/fc6c174b672e29b7de996ea77b6cbddf46c891751c3355f6974292baa6b4/psycopg_binary-3.3.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:ee17a2cf4943cde261adfad1bbc5bf38d6b3776d7afff74c7cabcbeaeb08c260", size = 3927347, upload-time = "2026-05-01T23:30:21.186Z" }, - { url = "https://files.pythonhosted.org/packages/e9/65/768364d4a97a15b1a7f47ba52688c1686f22941d8332a8398cefc468e25f/psycopg_binary-3.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5c4ab71be17bdca30cb34c34c4e1496e2f5d6f20c199c12bad226070b22ef9bf", size = 4236393, upload-time = "2026-05-01T23:30:26.211Z" }, - { url = "https://files.pythonhosted.org/packages/bd/3b/218efbc9e645becd80cdf651acda05f85cfe546b7a9c0458c7cbc8fe1f74/psycopg_binary-3.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:dbfdb9b6cc79f31104a7b162a2b921b765fcc62af6c00540a167a8de47e4ed38", size = 3564592, upload-time = "2026-05-01T23:30:31.764Z" }, - { url = "https://files.pythonhosted.org/packages/48/a6/828c9185701dab71b234c2a76c38a08b098ebfec5020716b4e93807492b5/psycopg_binary-3.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:28b7398fdd19db3232c884fb24550bdfe951221f510e195e233299e4c9b78f97", size = 4607292, upload-time = "2026-05-01T23:30:38.962Z" }, - { url = "https://files.pythonhosted.org/packages/92/58/5b40dbc9d839045c9dae956960e4fb6d20bcabe6c59a2aa34fc3a371913f/psycopg_binary-3.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1fbaa292a3c8bb61b45df1ad3da1908ccee7cb889db9425e3557d9e34e2a4829", size = 4687023, upload-time = "2026-05-01T23:30:47.227Z" }, - { url = "https://files.pythonhosted.org/packages/85/a9/793f0ac107a9003b48441d0d1f9f616d96e0f37458dd8dc12528ceff55fb/psycopg_binary-3.3.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94596f9e7633ee3f6440711d43bb70aa31cc0a46a900ab8b4201a366ace5c9e7", size = 5486985, upload-time = "2026-05-01T23:30:55.517Z" }, - { url = "https://files.pythonhosted.org/packages/8f/26/42e8533497e2592334f68ec529cf5f840f7fa4e99575a4bb61aa184dbfbf/psycopg_binary-3.3.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8c0056529e68dbe9184cd4019a1f3d8f3a4ead2f6fc7a5afcf27d3314edd1277", size = 5168745, upload-time = "2026-05-01T23:31:01.904Z" }, - { url = "https://files.pythonhosted.org/packages/15/af/b7151776cc08d5935d45c833ec818a9beb417cf7c08239af1aafbdae78ee/psycopg_binary-3.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c09aad7051326e7603c14e50636db9c01f78272dc54b3accff03d46370461e6", size = 6761486, upload-time = "2026-05-01T23:31:14.511Z" }, - { url = "https://files.pythonhosted.org/packages/d0/ed/c92533b9124712d592cbf1cd6c76da933a2e0acea81dfe1fbe7e735f0cff/psycopg_binary-3.3.4-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:514404ed543efd620c85602b747df2a23cf1241b4067199e1a66f2d2757aaa41", size = 4997427, upload-time = "2026-05-01T23:31:20.901Z" }, - { url = "https://files.pythonhosted.org/packages/a2/23/ccadfd0de416aa188356daa199453af24087b042e296088706d190ae0295/psycopg_binary-3.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:46893c26858be12cc49ca4226ed6a60b4bfccadd946b3bebb783a60b38788228", size = 4533549, upload-time = "2026-05-01T23:31:26.204Z" }, - { url = "https://files.pythonhosted.org/packages/fd/a0/c8f43cee36386f7bc891ab41a9d31ea07cf9826038e732da79f26b1e5f34/psycopg_binary-3.3.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:df1d567fc430f6df15c9fcf67d87685fc49bdb325adc0db5af1adfb2f44eb5c9", size = 4210256, upload-time = "2026-05-01T23:31:33.884Z" }, - { url = "https://files.pythonhosted.org/packages/4e/2c/c1547871be3790676e8868b38655496422f94f0978dfb66b74bdba2f1676/psycopg_binary-3.3.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:6b9016b1714da4dd5ecaaa75b82098aa5a0b87854ce9b092e21c27c4ae23e014", size = 3946204, upload-time = "2026-05-01T23:31:39.626Z" }, - { url = "https://files.pythonhosted.org/packages/c4/b1/f6670f00fa7ea601584623f6c11602ab92117d83eaff885e0210f6de7418/psycopg_binary-3.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:47c656a8a7ba6eb0cff1801a4caaa9c8bdc12d03080e273aff1c8ac39971a77e", size = 4255811, upload-time = "2026-05-01T23:31:44.986Z" }, - { url = "https://files.pythonhosted.org/packages/eb/e6/5fff07a70d1f945ed90ae131c3bd76cab32beff7c58c6db15ad5820b6d1f/psycopg_binary-3.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:c37e024c07308cd06cf3ec51bfd0e7f6157585a4d84d1bce4a7f5f7913719bf8", size = 3666849, upload-time = "2026-05-01T23:31:51.165Z" }, -] - -[[package]] -name = "pygments" -version = "2.20.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, -] - -[[package]] -name = "rich" -version = "15.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, -] - -[[package]] -name = "semver" -version = "3.0.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/d1/d3159231aec234a59dd7d601e9dd9fe96f3afff15efd33c1070019b26132/semver-3.0.4.tar.gz", hash = "sha256:afc7d8c584a5ed0a11033af086e8af226a9c0b206f313e0301f8dd7b6b589602", size = 269730, upload-time = "2025-01-24T13:19:27.617Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/24/4d91e05817e92e3a61c8a21e08fd0f390f5301f1c448b137c57c4bc6e543/semver-3.0.4-py3-none-any.whl", hash = "sha256:9c824d87ba7f7ab4a1890799cec8596f15c1241cb473404ea1cb0c55e4b04746", size = 17912, upload-time = "2025-01-24T13:19:24.949Z" }, -] - -[[package]] -name = "shellingham" -version = "1.5.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, -] - -[[package]] -name = "sqlparse" -version = "0.5.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/90/76/437d71068094df0726366574cf3432a4ed754217b436eb7429415cf2d480/sqlparse-0.5.5.tar.gz", hash = "sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e", size = 120815, upload-time = "2025-12-19T07:17:45.073Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/49/4b/359f28a903c13438ef59ebeee215fb25da53066db67b305c125f1c6d2a25/sqlparse-0.5.5-py3-none-any.whl", hash = "sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba", size = 46138, upload-time = "2025-12-19T07:17:46.573Z" }, -] - -[[package]] -name = "typer" -version = "0.25.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-doc" }, - { name = "click" }, - { name = "rich" }, - { name = "shellingham" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e4/51/9aed62104cea109b820bbd6c14245af756112017d309da813ef107d42e7e/typer-0.25.1.tar.gz", hash = "sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc", size = 122276, upload-time = "2026-04-30T19:32:16.964Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl", hash = "sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89", size = 58409, upload-time = "2026-04-30T19:32:18.271Z" }, -] - -[[package]] -name = "tzdata" -version = "2026.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35cb345486df41110984ea67ae69dddbc0e8a100999493/tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10", size = 198254, upload-time = "2026-04-24T15:22:08.651Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" }, -] - -[[package]] -name = "whitenoise" -version = "6.12.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cb/2a/55b3f3a4ec326cd077c1c3defeee656b9298372a69229134d930151acd01/whitenoise-6.12.0.tar.gz", hash = "sha256:f723ebb76a112e98816ff80fcea0a6c9b8ecde835f8ddda25df7a30a3c2db6ad", size = 26841, upload-time = "2026-02-27T00:05:42.028Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/eb/d5583a11486211f3ebd4b385545ae787f32363d453c19fffd81106c9c138/whitenoise-6.12.0-py3-none-any.whl", hash = "sha256:fc5e8c572e33ebf24795b47b6a7da8da3c00cff2349f5b04c02f28d0cc5a3cc2", size = 20302, upload-time = "2026-02-27T00:05:40.086Z" }, -]