refactor: [api] Remove the direction field from flashcards and word_bank_templates

This commit is contained in:
wilson 2026-04-17 07:18:40 +01:00
parent 91caf5d5ca
commit 517e2bf90e
12 changed files with 33 additions and 28 deletions

View file

@ -17,6 +17,9 @@ shell:
# Run pending migrations against the running db container
migrate:
docker compose build api --no-cache && docker compose up -d && docker compose exec api alembic upgrade head
migrate-no-build:
docker compose exec api alembic upgrade head
# Generate a new migration: make migration NAME="add foo table"

View file

@ -0,0 +1,26 @@
"""drop card_direction from flashcard and word_bank_pack_flashcard_template
Revision ID: 0014
Revises: 0013
Create Date: 2026-04-17
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
revision: str = "0014"
down_revision: Union[str, None] = "0013"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.drop_column("flashcard", "card_direction")
op.drop_column("word_bank_pack_flashcard_template", "card_direction")
def downgrade() -> None:
op.add_column("word_bank_pack_flashcard_template", sa.Column("card_direction", sa.Text(), nullable=False, server_default="both"))
op.add_column("flashcard", sa.Column("card_direction", sa.Text(), nullable=False, server_default="both"))

View file

@ -13,7 +13,6 @@ class Flashcard:
answer_text: str
prompt_context_text: str | None
answer_context_text: str | None
card_direction: str
prompt_modality: str
source_pack_flashcard_template_id: str | None
created_at: datetime

View file

@ -29,7 +29,6 @@ class WordBankPackEntry:
class WordBankPackFlashcardTemplate:
id: str
pack_entry_id: str
card_direction: str
prompt_text: str
answer_text: str
prompt_context_text: str | None

View file

@ -111,7 +111,6 @@ class FlashcardService:
target_lang=pair.target_lang,
prompt_text=prompt,
answer_text=answer,
card_direction=d,
)
flashcards.append(card)

View file

@ -107,7 +107,6 @@ class PackService:
async def add_flashcard_template_to_entry(
self,
pack_entry_id: uuid.UUID,
card_direction: str,
prompt_text: str,
answer_text: str,
prompt_context_text: str | None = None,
@ -115,7 +114,6 @@ class PackService:
) -> WordBankPackFlashcardTemplate:
return await self.pack_repo.add_flashcard_template(
pack_entry_id=pack_entry_id,
card_direction=card_direction,
prompt_text=prompt_text,
answer_text=answer_text,
prompt_context_text=prompt_context_text,
@ -184,7 +182,6 @@ class PackService:
target_lang=pair.target_lang,
prompt_text=template.prompt_text,
answer_text=template.answer_text,
card_direction=template.card_direction,
prompt_context_text=template.prompt_context_text,
answer_context_text=template.answer_context_text,
source_pack_flashcard_template_id=uuid.UUID(template.id),
@ -217,11 +214,10 @@ class PackService:
lemma = await self.dict_repo.get_lemma(uuid.UUID(sense.lemma_id))
if lemma is None:
return
for direction in ("target_to_source", "source_to_target"):
if direction == "target_to_source":
prompt, answer = lemma.headword, sense.gloss
else:
prompt, answer = sense.gloss, lemma.headword
for prompt, answer in [
(lemma.headword, sense.gloss),
(sense.gloss, lemma.headword),
]:
await self.flashcard_repo.create_flashcard(
user_id=user_id,
bank_entry_id=bank_entry_id,
@ -229,5 +225,4 @@ class PackService:
target_lang=target_lang,
prompt_text=prompt,
answer_text=answer,
card_direction=direction,
)

View file

@ -30,7 +30,6 @@ class FlashcardEntity(Base):
answer_text: Mapped[str] = mapped_column(Text, nullable=False)
prompt_context_text: Mapped[str | None] = mapped_column(Text, nullable=True)
answer_context_text: Mapped[str | None] = mapped_column(Text, nullable=True)
card_direction: Mapped[str] = mapped_column(Text, nullable=False)
prompt_modality: Mapped[str] = mapped_column(Text, nullable=False, default="text")
source_pack_flashcard_template_id: Mapped[uuid.UUID | None] = mapped_column(
UUID(as_uuid=True),

View file

@ -61,7 +61,6 @@ class WordBankPackFlashcardTemplateEntity(Base):
nullable=False,
index=True,
)
card_direction: Mapped[str] = mapped_column(Text, nullable=False)
prompt_text: Mapped[str] = mapped_column(Text, nullable=False)
answer_text: Mapped[str] = mapped_column(Text, nullable=False)
prompt_context_text: Mapped[str | None] = mapped_column(Text, nullable=True)

View file

@ -18,7 +18,6 @@ class FlashcardRepository(Protocol):
target_lang: str,
prompt_text: str,
answer_text: str,
card_direction: str,
prompt_modality: str = "text",
prompt_context_text: str | None = None,
answer_context_text: str | None = None,
@ -49,7 +48,6 @@ def _flashcard_to_model(entity: FlashcardEntity) -> Flashcard:
answer_text=entity.answer_text,
prompt_context_text=entity.prompt_context_text,
answer_context_text=entity.answer_context_text,
card_direction=entity.card_direction,
prompt_modality=entity.prompt_modality,
source_pack_flashcard_template_id=(
str(entity.source_pack_flashcard_template_id)
@ -83,7 +81,6 @@ class PostgresFlashcardRepository:
target_lang: str,
prompt_text: str,
answer_text: str,
card_direction: str,
prompt_modality: str = "text",
prompt_context_text: str | None = None,
answer_context_text: str | None = None,
@ -98,7 +95,6 @@ class PostgresFlashcardRepository:
answer_text=answer_text,
prompt_context_text=prompt_context_text,
answer_context_text=answer_context_text,
card_direction=card_direction,
prompt_modality=prompt_modality,
source_pack_flashcard_template_id=source_pack_flashcard_template_id,
created_at=datetime.now(timezone.utc),

View file

@ -61,7 +61,6 @@ class PackRepository(Protocol):
async def add_flashcard_template(
self,
pack_entry_id: uuid.UUID,
card_direction: str,
prompt_text: str,
answer_text: str,
prompt_context_text: str | None = None,
@ -114,7 +113,6 @@ def _template_to_model(entity: WordBankPackFlashcardTemplateEntity) -> WordBankP
return WordBankPackFlashcardTemplate(
id=str(entity.id),
pack_entry_id=str(entity.pack_entry_id),
card_direction=entity.card_direction,
prompt_text=entity.prompt_text,
answer_text=entity.answer_text,
prompt_context_text=entity.prompt_context_text,
@ -250,7 +248,6 @@ class PostgresPackRepository:
async def add_flashcard_template(
self,
pack_entry_id: uuid.UUID,
card_direction: str,
prompt_text: str,
answer_text: str,
prompt_context_text: str | None = None,
@ -258,7 +255,6 @@ class PostgresPackRepository:
) -> WordBankPackFlashcardTemplate:
entity = WordBankPackFlashcardTemplateEntity(
pack_entry_id=pack_entry_id,
card_direction=card_direction,
prompt_text=prompt_text,
answer_text=answer_text,
prompt_context_text=prompt_context_text,

View file

@ -41,7 +41,6 @@ class AddEntryRequest(BaseModel):
class AddFlashcardTemplateRequest(BaseModel):
card_direction: str
prompt_text: str
answer_text: str
prompt_context_text: str | None = None
@ -51,7 +50,6 @@ class AddFlashcardTemplateRequest(BaseModel):
class FlashcardTemplateResponse(BaseModel):
id: str
pack_entry_id: str
card_direction: str
prompt_text: str
answer_text: str
prompt_context_text: str | None
@ -246,7 +244,6 @@ async def add_flashcard_template(
) -> FlashcardTemplateResponse:
template = await _service(db).add_flashcard_template_to_entry(
pack_entry_id=_parse_uuid(entry_id),
card_direction=request.card_direction,
prompt_text=request.prompt_text,
answer_text=request.answer_text,
prompt_context_text=request.prompt_context_text,
@ -294,7 +291,6 @@ def _to_template_response(template) -> FlashcardTemplateResponse:
return FlashcardTemplateResponse(
id=template.id,
pack_entry_id=template.pack_entry_id,
card_direction=template.card_direction,
prompt_text=template.prompt_text,
answer_text=template.answer_text,
prompt_context_text=template.prompt_context_text,

View file

@ -24,7 +24,6 @@ class FlashcardResponse(BaseModel):
answer_text: str
prompt_context_text: str | None
answer_context_text: str | None
card_direction: str
prompt_modality: str
created_at: str
@ -137,7 +136,6 @@ def _flashcard_response(card) -> FlashcardResponse:
answer_text=card.answer_text,
prompt_context_text=card.prompt_context_text,
answer_context_text=card.answer_context_text,
card_direction=card.card_direction,
prompt_modality=card.prompt_modality,
created_at=card.created_at.isoformat(),
)