Prepare ERP source for Gitea deployment
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
"""Phase 7S.1E email queue and retry metadata
|
||||
|
||||
Revision ID: 20260610_phase_7s1e_email_queue
|
||||
Revises: 20260609_phase_7s1c_email_preferences
|
||||
Create Date: 2026-06-10
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision = "20260610_phase_7s1e_email_queue"
|
||||
down_revision = "20260609_phase_7s1c_email_preferences"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def _existing_columns(table_name: str) -> set[str]:
|
||||
bind = op.get_bind()
|
||||
inspector = sa.inspect(bind)
|
||||
try:
|
||||
return {col["name"] for col in inspector.get_columns(table_name)}
|
||||
except Exception:
|
||||
return set()
|
||||
|
||||
|
||||
def _add_column_if_missing(table_name: str, column: sa.Column) -> None:
|
||||
if column.name not in _existing_columns(table_name):
|
||||
op.add_column(table_name, column)
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
_add_column_if_missing("email_logs", sa.Column("attempt_count", sa.Integer(), nullable=False, server_default="0"))
|
||||
_add_column_if_missing("email_logs", sa.Column("max_attempts", sa.Integer(), nullable=False, server_default="3"))
|
||||
_add_column_if_missing("email_logs", sa.Column("queue_priority", sa.Integer(), nullable=False, server_default="100"))
|
||||
_add_column_if_missing("email_logs", sa.Column("is_retryable", sa.Boolean(), nullable=False, server_default=sa.true()))
|
||||
_add_column_if_missing("email_logs", sa.Column("queued_at", sa.DateTime(timezone=True), nullable=True))
|
||||
_add_column_if_missing("email_logs", sa.Column("next_retry_at", sa.DateTime(timezone=True), nullable=True))
|
||||
_add_column_if_missing("email_logs", sa.Column("last_attempt_at", sa.DateTime(timezone=True), nullable=True))
|
||||
_add_column_if_missing("email_logs", sa.Column("processing_started_at", sa.DateTime(timezone=True), nullable=True))
|
||||
|
||||
existing_indexes = {idx["name"] for idx in sa.inspect(op.get_bind()).get_indexes("email_logs")}
|
||||
for name, cols in {
|
||||
"ix_email_logs_queue_priority": ["queue_priority"],
|
||||
"ix_email_logs_is_retryable": ["is_retryable"],
|
||||
"ix_email_logs_queued_at": ["queued_at"],
|
||||
"ix_email_logs_next_retry_at": ["next_retry_at"],
|
||||
"ix_email_logs_last_attempt_at": ["last_attempt_at"],
|
||||
"ix_email_logs_processing_started_at": ["processing_started_at"],
|
||||
}.items():
|
||||
if name not in existing_indexes:
|
||||
op.create_index(name, "email_logs", cols)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# Safe downgrade for development only. SQLite may not support all drop-column
|
||||
# operations depending on version, so production rollback should use backups.
|
||||
for name in [
|
||||
"ix_email_logs_processing_started_at",
|
||||
"ix_email_logs_last_attempt_at",
|
||||
"ix_email_logs_next_retry_at",
|
||||
"ix_email_logs_queued_at",
|
||||
"ix_email_logs_is_retryable",
|
||||
"ix_email_logs_queue_priority",
|
||||
]:
|
||||
try:
|
||||
op.drop_index(name, table_name="email_logs")
|
||||
except Exception:
|
||||
pass
|
||||
for col in [
|
||||
"processing_started_at",
|
||||
"last_attempt_at",
|
||||
"next_retry_at",
|
||||
"queued_at",
|
||||
"is_retryable",
|
||||
"queue_priority",
|
||||
"max_attempts",
|
||||
"attempt_count",
|
||||
]:
|
||||
try:
|
||||
op.drop_column("email_logs", col)
|
||||
except Exception:
|
||||
pass
|
||||
Reference in New Issue
Block a user