feat: add AirShelf core implementation
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
from django.db import models
|
||||
|
||||
from apps.common.models import TimeStampedModel
|
||||
|
||||
|
||||
class CreditAccount(TimeStampedModel):
|
||||
team = models.OneToOneField("accounts.Team", on_delete=models.CASCADE, related_name="credit_account")
|
||||
balance = models.DecimalField(max_digits=14, decimal_places=4, default=0)
|
||||
reserved_balance = models.DecimalField(max_digits=14, decimal_places=4, default=0)
|
||||
currency = models.CharField(max_length=16, default="CNY")
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.team} / {self.balance}"
|
||||
|
||||
|
||||
class CreditLedger(TimeStampedModel):
|
||||
class Type(models.TextChoices):
|
||||
RECHARGE = "recharge", "Recharge"
|
||||
RESERVE = "reserve", "Reserve"
|
||||
RELEASE = "release", "Release"
|
||||
CHARGE = "charge", "Charge"
|
||||
ADJUSTMENT = "adjustment", "Adjustment"
|
||||
REFUND = "refund", "Refund"
|
||||
|
||||
team = models.ForeignKey("accounts.Team", on_delete=models.CASCADE, related_name="credit_ledgers")
|
||||
user = models.ForeignKey("accounts.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="credit_ledgers")
|
||||
project = models.ForeignKey(
|
||||
"projects.Project",
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="credit_ledgers",
|
||||
)
|
||||
task = models.ForeignKey("ai.AITask", on_delete=models.SET_NULL, null=True, blank=True, related_name="credit_ledgers")
|
||||
ledger_type = models.CharField(max_length=32, choices=Type.choices)
|
||||
amount = models.DecimalField(max_digits=14, decimal_places=4)
|
||||
balance_after = models.DecimalField(max_digits=14, decimal_places=4)
|
||||
reason = models.CharField(max_length=255, blank=True)
|
||||
metadata = models.JSONField(default=dict, blank=True)
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
models.Index(fields=["team", "ledger_type"]),
|
||||
models.Index(fields=["project", "task"]),
|
||||
]
|
||||
|
||||
|
||||
class CreditReservation(TimeStampedModel):
|
||||
class Status(models.TextChoices):
|
||||
ACTIVE = "active", "Active"
|
||||
RELEASED = "released", "Released"
|
||||
CHARGED = "charged", "Charged"
|
||||
CANCELLED = "cancelled", "Cancelled"
|
||||
|
||||
team = models.ForeignKey("accounts.Team", on_delete=models.CASCADE, related_name="credit_reservations")
|
||||
user = models.ForeignKey("accounts.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="credit_reservations")
|
||||
project = models.ForeignKey(
|
||||
"projects.Project",
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="credit_reservations",
|
||||
)
|
||||
task = models.OneToOneField("ai.AITask", on_delete=models.CASCADE, related_name="credit_reservation")
|
||||
amount = models.DecimalField(max_digits=14, decimal_places=4)
|
||||
status = models.CharField(max_length=32, choices=Status.choices, default=Status.ACTIVE)
|
||||
expires_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
|
||||
class QuotaPolicy(TimeStampedModel):
|
||||
team = models.ForeignKey("accounts.Team", on_delete=models.CASCADE, related_name="quota_policies")
|
||||
user = models.ForeignKey("accounts.User", on_delete=models.CASCADE, null=True, blank=True, related_name="quota_policies")
|
||||
project = models.ForeignKey(
|
||||
"projects.Project",
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="quota_policies",
|
||||
)
|
||||
monthly_limit = models.DecimalField(max_digits=14, decimal_places=4, null=True, blank=True)
|
||||
project_limit = models.DecimalField(max_digits=14, decimal_places=4, null=True, blank=True)
|
||||
per_task_limit = models.DecimalField(max_digits=14, decimal_places=4, null=True, blank=True)
|
||||
is_active = models.BooleanField(default=True)
|
||||
|
||||
Reference in New Issue
Block a user