- backend: tabela survey_responses (0055), GET /survey/current z bramka po obejrzanych
scenach, POST /survey/{id} (upsert per urzadzenie), GET /survey/{id}/summary
- apka: SurveyModal po tutorialu i po "What's new" (popupBus), raz na urzadzenie,
pomijalna, flaga w SecureStore; wpis w changelogu
37 lines
1.6 KiB
Python
37 lines
1.6 KiB
Python
"""Odpowiedzi na jednorazowa ankiete in-app (pytania sa w apce, patrz app/api/survey.py).
|
|
|
|
Jedna odpowiedz na urzadzenie i ankiete (UNIQUE survey_id + device_id, ponowne wyslanie
|
|
nadpisuje). `answers` to JSON {klucz_pytania: wartosc | [wartosci]}, bez danych osobowych.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
from datetime import datetime
|
|
from typing import Any
|
|
|
|
from sqlalchemy import DateTime, Index, String, Text, UniqueConstraint, func
|
|
from sqlalchemy.dialects.postgresql import JSONB, UUID
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.models.base import Base
|
|
|
|
|
|
class SurveyResponse(Base):
|
|
__tablename__ = "survey_responses"
|
|
__table_args__ = (
|
|
UniqueConstraint("survey_id", "device_id", name="uq_survey_responses_survey_device"),
|
|
Index("ix_survey_responses_survey_created", "survey_id", "created_at"),
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
survey_id: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
device_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
answers: Mapped[dict[str, Any]] = mapped_column(JSONB, nullable=False)
|
|
free_text: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
app_version: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), server_default=func.now(), nullable=False
|
|
)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False
|
|
)
|