- Event ORM model with status/level enums, domain categories, review tracking - Alembic migration e7f3a9b1c5d0 for events table - Event crawler service with placeholder data (12 sample events) - GET /api/v1/events with status/domain/search filtering and overdue_days - EventArchivePage with filter toolbar (status, domain, search) and adaptive card grid - Status badges, level badges, domain tags, overdue markers on event cards - Loading/error/empty states, hover-to-honey card interaction Co-Authored-By: Claude <noreply@anthropic.com>
47 lines
1.6 KiB
Python
47 lines
1.6 KiB
Python
"""create events table
|
|
|
|
Revision ID: e7f3a9b1c5d0
|
|
Revises: ab0c56ae4242
|
|
Create Date: 2026-07-22 17:30:00.000000
|
|
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = 'e7f3a9b1c5d0'
|
|
down_revision: Union[str, Sequence[str], None] = 'ab0c56ae4242'
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.create_table(
|
|
'events',
|
|
sa.Column('id', sa.String(36), primary_key=True),
|
|
sa.Column('title', sa.String(255), nullable=False),
|
|
sa.Column('level', sa.Enum('A', 'B', 'C', name='eventlevel'), nullable=False),
|
|
sa.Column('domain', sa.String(50), nullable=False, index=True),
|
|
sa.Column(
|
|
'status',
|
|
sa.Enum('active', 'fading', 'dissipating', 'closed', name='eventstatus'),
|
|
nullable=False,
|
|
server_default='active',
|
|
),
|
|
sa.Column('occurred_date', sa.Date, nullable=False),
|
|
sa.Column('last_reviewed', sa.DateTime, nullable=True),
|
|
sa.Column('no_new_info_count', sa.Integer, nullable=False, server_default='0'),
|
|
sa.Column('next_review', sa.DateTime, nullable=True),
|
|
sa.Column('created_at', sa.DateTime, nullable=False, server_default=sa.func.now()),
|
|
sa.Column('updated_at', sa.DateTime, nullable=False, server_default=sa.func.now()),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_table('events')
|
|
op.execute('DROP TYPE IF EXISTS eventlevel')
|
|
op.execute('DROP TYPE IF EXISTS eventstatus')
|