pénzügyi modul továbbfejlesztése (csomagkezelés)

This commit is contained in:
Roo
2026-07-29 09:46:10 +00:00
parent 6f28d3e70d
commit 75904cd2f8
50 changed files with 5851 additions and 312 deletions

View File

@@ -164,12 +164,60 @@ class OrganizationSubscription(Base):
# Példa: {"extra_vehicles": 1, "extra_garages": 1, "extra_credits": 100}
extra_allowances: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"), default=dict)
# ── P0 AUTO-RENEWAL FIELDS ──
auto_renew: Mapped[bool] = mapped_column(
Boolean, nullable=False, default=False, server_default=text("false"),
comment="Whether this subscription auto-renews at expiry"
)
provider_subscription_id: Mapped[Optional[str]] = mapped_column(
String(255), nullable=True,
comment="External payment gateway subscription ID (e.g., Stripe sub_xxx)"
)
wallet_auto_deduct: Mapped[bool] = mapped_column(
Boolean, nullable=False, default=False, server_default=text("false"),
comment="Auto-deduct from wallet at renewal time"
)
renewal_failure_count: Mapped[int] = mapped_column(
Integer, nullable=False, default=0, server_default=text("0"),
comment="Consecutive failed renewal attempts"
)
last_renewal_attempt: Mapped[Optional[datetime]] = mapped_column(
DateTime(timezone=True), nullable=True,
comment="Timestamp of the most recent renewal attempt"
)
next_renewal_date: Mapped[Optional[datetime]] = mapped_column(
DateTime(timezone=True), nullable=True,
comment="Pre-calculated next auto-renewal date (denormalized from valid_until for fast cron queries)"
)
# ── P0 PENDING DOWNGRADE FIELDS (Issue #429) ──
# When a user switches to a cheaper/free tier, the change takes effect
# only after the current, already-paid subscription period expires.
# pending_tier_id stores the target tier for the delayed activation.
pending_tier_id: Mapped[Optional[int]] = mapped_column(
Integer, ForeignKey("system.subscription_tiers.id"), nullable=True,
default=None, server_default=text("NULL"),
comment="If set, this is a pending downgrade that activates after current period expires (FK → system.subscription_tiers.id)"
)
pending_activated_at: Mapped[Optional[datetime]] = mapped_column(
DateTime(timezone=True), nullable=True,
default=None, server_default=text("NULL"),
comment="When the pending downgrade was requested (audit trail)"
)
# ── P0 FEATURE FLAG: relationship a SubscriptionTier-hez ──
tier: Mapped[Optional["SubscriptionTier"]] = relationship(
"SubscriptionTier",
foreign_keys=[tier_id],
lazy="selectin",
)
# ── P0 PENDING DOWNGRADE: kapcsolat a pending tier-hez ──
pending_tier: Mapped[Optional["SubscriptionTier"]] = relationship(
"SubscriptionTier",
foreign_keys=[pending_tier_id],
lazy="selectin",
)
class UserSubscription(Base):
"""
@@ -193,12 +241,60 @@ class UserSubscription(Base):
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
# ── P0 AUTO-RENEWAL FIELDS ──
auto_renew: Mapped[bool] = mapped_column(
Boolean, nullable=False, default=False, server_default=text("false"),
comment="Whether this subscription auto-renews at expiry"
)
provider_subscription_id: Mapped[Optional[str]] = mapped_column(
String(255), nullable=True,
comment="External payment gateway subscription ID (e.g., Stripe sub_xxx)"
)
wallet_auto_deduct: Mapped[bool] = mapped_column(
Boolean, nullable=False, default=False, server_default=text("false"),
comment="Auto-deduct from wallet at renewal time"
)
renewal_failure_count: Mapped[int] = mapped_column(
Integer, nullable=False, default=0, server_default=text("0"),
comment="Consecutive failed renewal attempts"
)
last_renewal_attempt: Mapped[Optional[datetime]] = mapped_column(
DateTime(timezone=True), nullable=True,
comment="Timestamp of the most recent renewal attempt"
)
next_renewal_date: Mapped[Optional[datetime]] = mapped_column(
DateTime(timezone=True), nullable=True,
comment="Pre-calculated next auto-renewal date (denormalized from valid_until for fast cron queries)"
)
# ── P0 PENDING DOWNGRADE FIELDS (Issue #429) ──
# When a user switches to a cheaper/free tier, the change takes effect
# only after the current, already-paid subscription period expires.
# pending_tier_id stores the target tier for the delayed activation.
pending_tier_id: Mapped[Optional[int]] = mapped_column(
Integer, ForeignKey("system.subscription_tiers.id"), nullable=True,
default=None, server_default=text("NULL"),
comment="If set, this is a pending downgrade that activates after current period expires (FK → system.subscription_tiers.id)"
)
pending_activated_at: Mapped[Optional[datetime]] = mapped_column(
DateTime(timezone=True), nullable=True,
default=None, server_default=text("NULL"),
comment="When the pending downgrade was requested (audit trail)"
)
# ── P0 FEATURE FLAG: relationship a SubscriptionTier-hez ──
tier: Mapped[Optional["SubscriptionTier"]] = relationship(
"SubscriptionTier",
foreign_keys=[tier_id],
lazy="selectin",
)
# ── P0 PENDING DOWNGRADE: kapcsolat a pending tier-hez ──
pending_tier: Mapped[Optional["SubscriptionTier"]] = relationship(
"SubscriptionTier",
foreign_keys=[pending_tier_id],
lazy="selectin",
)
class CreditTransaction(Base):