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>
43 lines
1.5 KiB
Python
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")
|