feat: add calendar subscription token functionality and ICS generation

- Introduced a new database model for calendar subscription tokens, allowing users to generate unique tokens for accessing their personal calendar.
- Implemented API endpoint to return ICS files containing only the subscribing user's duties, enhancing user experience with personalized calendar access.
- Added utility functions for generating ICS files from user duties, ensuring proper formatting and timezone handling.
- Updated command handlers to support the new calendar link feature, providing users with easy access to their personal calendar subscriptions.
- Included unit tests for the new functionality, ensuring reliability and correctness of token generation and ICS file creation.
This commit is contained in:
2026-02-19 17:04:22 +03:00
parent 4afd0ca5cc
commit dc116270b7
14 changed files with 501 additions and 12 deletions

View File

@@ -0,0 +1,46 @@
"""Calendar subscription tokens table
Revision ID: 005
Revises: 004
Create Date: 2025-02-19
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
revision: str = "005"
down_revision: Union[str, None] = "004"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.create_table(
"calendar_subscription_tokens",
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.Column("user_id", sa.Integer(), nullable=False),
sa.Column("token_hash", sa.Text(), nullable=False),
sa.Column("created_at", sa.Text(), nullable=False),
sa.ForeignKeyConstraint(["user_id"], ["users.id"]),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint(
"token_hash", name="uq_calendar_subscription_tokens_token_hash"
),
)
op.create_index(
"ix_calendar_subscription_tokens_token_hash",
"calendar_subscription_tokens",
["token_hash"],
unique=True,
)
def downgrade() -> None:
op.drop_index(
"ix_calendar_subscription_tokens_token_hash",
table_name="calendar_subscription_tokens",
)
op.drop_table("calendar_subscription_tokens")