This commit is contained in:
2026-10-23 12:19:40 -04:00
parent 6cf0f0525f
commit faf6c5f2b3
19 changed files with 785 additions and 12 deletions
+25
View File
@@ -14,6 +14,7 @@ class Account(models.Model):
checkout_id = models.CharField(max_length=128, blank=True)
checkout_key = models.UUIDField(default=uuid.uuid4)
last_billing_sync = models.DateTimeField(null=True)
last_shkeeper_sync = models.DateTimeField(null=True)
last_ldap_sync = models.DateTimeField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
@@ -50,6 +51,30 @@ class ManagedGroup(models.Model):
constraints = [models.UniqueConstraint(fields=["account", "dn"], name="unique_account_group")]
class CryptoInvoice(models.Model):
"""Immutable prepaid order; one canonical invoice can grant one month only."""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
account = models.ForeignKey(Account, on_delete=models.PROTECT)
tier = models.CharField(max_length=48)
usd_amount = models.DecimalField(max_digits=12, decimal_places=2)
crypto = models.CharField(max_length=32)
provider_id = models.CharField(max_length=128, blank=True)
wallet = models.CharField(max_length=512, blank=True)
crypto_amount = models.CharField(max_length=128, blank=True)
# SHKeeper invoices do not expire. Keep incomplete orders available for late
# payments; never silently discard a deposit address with money on the way.
status = models.CharField(max_length=24, default="creating")
credited_at = models.DateTimeField(null=True)
access_start = models.DateTimeField(null=True)
access_end = models.DateTimeField(null=True, db_index=True)
last_checked_at = models.DateTimeField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
constraints = [models.UniqueConstraint(fields=["account"], condition=models.Q(credited_at__isnull=True), name="one_uncredited_crypto_invoice")]
class WebhookEvent(models.Model):
stripe_id = models.CharField(max_length=128, primary_key=True)
account = models.ForeignKey(Account, on_delete=models.CASCADE, null=True)