goon/alembic/versions/20260612_0023_bug_report_replies.py
jtrzupek d1f2f035b0 feat(bug-reports): two-way replies (device-scoped) + admin reply endpoint
Reports were anonymous and one-way. Tie each report to the submitting device
(X-Device-Id), add an admin response back-channel, and let the app fetch replies for
its own device:
- migration 0023: bug_reports gains device_id, response, responded_at, response_seen.
- create_bug_report captures device_id.
- GET /bug-reports/mine (device-scoped) returns this device's reports + unseen count.
- POST /bug-reports/mine/seen clears the unseen flag.
- POST /bug-reports/{id}/reply sets the admin response (authored during triage).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 11:35:44 +02:00

43 lines
1.5 KiB
Python

"""bug report replies: device_id + admin response back-channel
Revision ID: 0023_bug_report_replies
Revises: 0022_device_scoped_user_state
Create Date: 2026-06-12
Dwukierunkowy kanał na zgłoszenia: `device_id` wiąże zgłoszenie z urządzeniem (z
X-Device-Id), `response`/`responded_at` to odpowiedź admina, `response_seen` steruje
kropką na FAB (false = nieprzeczytana). Wszystko nullable/default — legacy reports OK.
"""
from collections.abc import Sequence
import sqlalchemy as sa
from alembic import op
revision: str = "0023_bug_report_replies"
down_revision: str | None = "0022_device_scoped_user_state"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
op.add_column("bug_reports", sa.Column("device_id", sa.String(length=64), nullable=True))
op.add_column("bug_reports", sa.Column("response", sa.Text(), nullable=True))
op.add_column(
"bug_reports",
sa.Column("responded_at", sa.DateTime(timezone=True), nullable=True),
)
op.add_column(
"bug_reports",
sa.Column(
"response_seen", sa.Boolean(), nullable=False, server_default=sa.false()
),
)
op.create_index("ix_bug_reports_device_id", "bug_reports", ["device_id"])
def downgrade() -> None:
op.drop_index("ix_bug_reports_device_id", table_name="bug_reports")
op.drop_column("bug_reports", "response_seen")
op.drop_column("bug_reports", "responded_at")
op.drop_column("bug_reports", "response")
op.drop_column("bug_reports", "device_id")