1+ """create core user tables
2+
3+ Revision ID: 0001_create_core_user_tables
4+ Revises:
5+ Create Date: 2026-06-01 00:00:00.000000
6+ """
7+
8+ from alembic import op
9+ import sqlalchemy as sa
10+
11+
12+ # revision identifiers, used by Alembic.
13+ revision = "0001_create_core_user_tables"
14+ down_revision = None
15+ branch_labels = None
16+ depends_on = None
17+
18+
19+ def upgrade () -> None :
20+ op .create_table (
21+ "users" ,
22+ sa .Column ("id" , sa .Integer (), primary_key = True ),
23+ sa .Column ("email" , sa .String (), nullable = False ),
24+ sa .Column ("password_hash" , sa .String (), nullable = False ),
25+ sa .Column ("first_name" , sa .String (), nullable = False ),
26+ sa .Column ("last_name" , sa .String (), nullable = False ),
27+ sa .Column ("display_name" , sa .String (), nullable = True ),
28+ sa .Column ("is_active" , sa .Boolean (), nullable = False , server_default = sa .text ("true" )),
29+ sa .Column ("created_at" , sa .DateTime (timezone = True ), server_default = sa .func .now (), nullable = False ),
30+ sa .Column ("updated_at" , sa .DateTime (timezone = True ), server_default = sa .func .now (), nullable = False ),
31+ )
32+ op .create_index (op .f ("ix_users_email" ), "users" , ["email" ], unique = True )
33+ op .create_index (op .f ("ix_users_id" ), "users" , ["id" ], unique = False )
34+
35+ op .create_table (
36+ "user_preferred_genres" ,
37+ sa .Column ("id" , sa .Integer (), primary_key = True ),
38+ sa .Column ("user_id" , sa .Integer (), sa .ForeignKey ("users.id" ), nullable = False ),
39+ sa .Column ("genre_id" , sa .Integer (), nullable = False ),
40+ sa .Column ("created_at" , sa .DateTime (timezone = True ), server_default = sa .func .now (), nullable = False ),
41+ sa .UniqueConstraint ("user_id" , "genre_id" ),
42+ )
43+ op .create_index (op .f ("ix_user_preferred_genres_id" ), "user_preferred_genres" , ["id" ], unique = False )
44+ op .create_index (op .f ("ix_user_preferred_genres_user_id" ), "user_preferred_genres" , ["user_id" ], unique = False )
45+ op .create_index (op .f ("ix_user_preferred_genres_genre_id" ), "user_preferred_genres" , ["genre_id" ], unique = False )
46+
47+ op .create_table (
48+ "refresh_tokens" ,
49+ sa .Column ("id" , sa .Integer (), primary_key = True ),
50+ sa .Column ("user_id" , sa .Integer (), sa .ForeignKey ("users.id" ), nullable = False ),
51+ sa .Column ("jti" , sa .String (), nullable = False ),
52+ sa .Column ("expires_at" , sa .DateTime (timezone = True ), nullable = False ),
53+ sa .Column ("revoked_at" , sa .DateTime (timezone = True ), nullable = True ),
54+ sa .Column ("created_at" , sa .DateTime (timezone = True ), server_default = sa .func .now (), nullable = False ),
55+ )
56+ op .create_index (op .f ("ix_refresh_tokens_id" ), "refresh_tokens" , ["id" ], unique = False )
57+ op .create_index (op .f ("ix_refresh_tokens_user_id" ), "refresh_tokens" , ["user_id" ], unique = False )
58+ op .create_index (op .f ("ix_refresh_tokens_jti" ), "refresh_tokens" , ["jti" ], unique = True )
59+
60+ op .create_table (
61+ "user_saved_movies" ,
62+ sa .Column ("id" , sa .Integer (), primary_key = True ),
63+ sa .Column ("user_id" , sa .Integer (), sa .ForeignKey ("users.id" ), nullable = False ),
64+ sa .Column ("movie_id" , sa .Integer (), nullable = False ),
65+ sa .Column ("saved_at" , sa .DateTime (timezone = True ), server_default = sa .func .now (), nullable = False ),
66+ sa .UniqueConstraint ("user_id" , "movie_id" ),
67+ )
68+ op .create_index (op .f ("ix_user_saved_movies_id" ), "user_saved_movies" , ["id" ], unique = False )
69+ op .create_index (op .f ("ix_user_saved_movies_user_id" ), "user_saved_movies" , ["user_id" ], unique = False )
70+ op .create_index (op .f ("ix_user_saved_movies_movie_id" ), "user_saved_movies" , ["movie_id" ], unique = False )
71+
72+ op .create_table (
73+ "user_watched_movies" ,
74+ sa .Column ("id" , sa .Integer (), primary_key = True ),
75+ sa .Column ("user_id" , sa .Integer (), sa .ForeignKey ("users.id" ), nullable = False ),
76+ sa .Column ("movie_id" , sa .Integer (), nullable = False ),
77+ sa .Column ("watched_at" , sa .DateTime (timezone = True ), server_default = sa .func .now (), nullable = False ),
78+ sa .UniqueConstraint ("user_id" , "movie_id" ),
79+ )
80+ op .create_index (op .f ("ix_user_watched_movies_id" ), "user_watched_movies" , ["id" ], unique = False )
81+ op .create_index (op .f ("ix_user_watched_movies_user_id" ), "user_watched_movies" , ["user_id" ], unique = False )
82+ op .create_index (op .f ("ix_user_watched_movies_movie_id" ), "user_watched_movies" , ["movie_id" ], unique = False )
83+
84+ op .create_table (
85+ "user_movie_notes" ,
86+ sa .Column ("id" , sa .Integer (), primary_key = True ),
87+ sa .Column ("user_id" , sa .Integer (), sa .ForeignKey ("users.id" ), nullable = False ),
88+ sa .Column ("movie_id" , sa .Integer (), nullable = False ),
89+ sa .Column ("note_text" , sa .Text (), nullable = False , server_default = "" ),
90+ sa .Column ("updated_at" , sa .DateTime (timezone = True ), server_default = sa .func .now (), nullable = False ),
91+ sa .UniqueConstraint ("user_id" , "movie_id" ),
92+ )
93+ op .create_index (op .f ("ix_user_movie_notes_id" ), "user_movie_notes" , ["id" ], unique = False )
94+ op .create_index (op .f ("ix_user_movie_notes_user_id" ), "user_movie_notes" , ["user_id" ], unique = False )
95+ op .create_index (op .f ("ix_user_movie_notes_movie_id" ), "user_movie_notes" , ["movie_id" ], unique = False )
96+
97+
98+ def downgrade () -> None :
99+ op .drop_index (op .f ("ix_user_movie_notes_movie_id" ), table_name = "user_movie_notes" )
100+ op .drop_index (op .f ("ix_user_movie_notes_user_id" ), table_name = "user_movie_notes" )
101+ op .drop_index (op .f ("ix_user_movie_notes_id" ), table_name = "user_movie_notes" )
102+ op .drop_table ("user_movie_notes" )
103+
104+ op .drop_index (op .f ("ix_user_watched_movies_movie_id" ), table_name = "user_watched_movies" )
105+ op .drop_index (op .f ("ix_user_watched_movies_user_id" ), table_name = "user_watched_movies" )
106+ op .drop_index (op .f ("ix_user_watched_movies_id" ), table_name = "user_watched_movies" )
107+ op .drop_table ("user_watched_movies" )
108+
109+ op .drop_index (op .f ("ix_user_saved_movies_movie_id" ), table_name = "user_saved_movies" )
110+ op .drop_index (op .f ("ix_user_saved_movies_user_id" ), table_name = "user_saved_movies" )
111+ op .drop_index (op .f ("ix_user_saved_movies_id" ), table_name = "user_saved_movies" )
112+ op .drop_table ("user_saved_movies" )
113+
114+ op .drop_index (op .f ("ix_refresh_tokens_jti" ), table_name = "refresh_tokens" )
115+ op .drop_index (op .f ("ix_refresh_tokens_user_id" ), table_name = "refresh_tokens" )
116+ op .drop_index (op .f ("ix_refresh_tokens_id" ), table_name = "refresh_tokens" )
117+ op .drop_table ("refresh_tokens" )
118+
119+ op .drop_index (op .f ("ix_user_preferred_genres_genre_id" ), table_name = "user_preferred_genres" )
120+ op .drop_index (op .f ("ix_user_preferred_genres_user_id" ), table_name = "user_preferred_genres" )
121+ op .drop_index (op .f ("ix_user_preferred_genres_id" ), table_name = "user_preferred_genres" )
122+ op .drop_table ("user_preferred_genres" )
123+
124+ op .drop_index (op .f ("ix_users_id" ), table_name = "users" )
125+ op .drop_index (op .f ("ix_users_email" ), table_name = "users" )
126+ op .drop_table ("users" )
0 commit comments