chore(root): remove project planning markdown and outdated configuration files

Remove extensive PLAN.md, management scripts, and lock files that are no longer needed.
This commit is contained in:
sankalp committed 2026-06-25 14:39:13 +05:45
1 parent d8557415d9
commit 26a679268b
10 files changed
-1327

No files matched your search

-538
View File
@@ -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
````
-20
View File
@@ -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
-112
View File
@@ -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 <package>` - Install package
- `just remove <package>` - 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/
-229
View File
@@ -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 }}
-32
View File
@@ -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()
-40
View File
@@ -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"]
-9
View File
@@ -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
-1
View File
@@ -1 +0,0 @@
python-3.13
-17
View File
@@ -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"
}
}
}
Generated
-329
View File
@@ -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" },
]