add journaling feature: categories, tags, attachments, calendar, and multi-select emotions
Adds an 8th development stage that lets users keep a free-form journal alongside habit tracking, reusing the existing Google OAuth/DB/PWA infrastructure instead of a separate project. Users organize entries into custom categories, filter by a month calendar with day-detail drill-down, attach photos/videos (served via an authenticated route, never /static), tag entries, and pick multiple emotions per entry from a curated 9-option set. Includes a global journal prompt bank for lightweight guided journaling. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
"""allow journal entries to have multiple moods, and expand the mood vocabulary
|
||||
|
||||
Revision ID: 0011_journal_entry_multi_mood
|
||||
Revises: 0010_add_journal_tables
|
||||
Create Date: 2026-08-04
|
||||
|
||||
기분을 하나만 고를 수 있던 journal_entry.mood(단일 컬럼)를, 태그처럼 여러 개를 붙일 수 있는
|
||||
journal_entry_mood 연결 테이블로 바꾼다. mood 자체가 고정된 값 집합(enum)이라 journal_tag처럼
|
||||
별도 이름 엔티티를 둘 필요 없이 값 자체를 PK로 쓴다. 동시에 기존 5종(만족도 스케일)에
|
||||
구체적인 감정 9종을 추가한다.
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
revision: str = "0011_journal_entry_multi_mood"
|
||||
down_revision: Union[str, None] = "0010_add_journal_tables"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
MOOD_VALUES = (
|
||||
"great", "good", "neutral", "bad", "awful",
|
||||
"pain", "achievement", "anger", "excited", "calm", "happy", "worry", "tired", "sad",
|
||||
)
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.drop_constraint("ck_journal_entry_mood", "journal_entry", type_="check")
|
||||
op.drop_column("journal_entry", "mood")
|
||||
|
||||
op.create_table(
|
||||
"journal_entry_mood",
|
||||
sa.Column(
|
||||
"entry_id", sa.Integer(), sa.ForeignKey("journal_entry.id", ondelete="CASCADE"), primary_key=True
|
||||
),
|
||||
sa.Column("mood", sa.String(length=20), primary_key=True),
|
||||
sa.CheckConstraint(
|
||||
"mood in (" + ",".join(f"'{v}'" for v in MOOD_VALUES) + ")", name="ck_journal_entry_mood_mood"
|
||||
),
|
||||
mysql_engine="InnoDB",
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table("journal_entry_mood")
|
||||
op.add_column("journal_entry", sa.Column("mood", sa.String(length=20), nullable=True))
|
||||
op.create_check_constraint(
|
||||
"ck_journal_entry_mood", "journal_entry", "mood in ('great','good','neutral','bad','awful')"
|
||||
)
|
||||
Reference in New Issue
Block a user