Much base work started
This commit is contained in:
17
db/migrate/20251029113808_create_works.rb
Normal file
17
db/migrate/20251029113808_create_works.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
class CreateWorks < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :works do |t|
|
||||
t.string :title
|
||||
t.integer :year
|
||||
t.string :director
|
||||
t.text :description
|
||||
t.decimal :rating
|
||||
t.boolean :organized
|
||||
t.string :poster_path
|
||||
t.string :backdrop_path
|
||||
t.text :metadata
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
11
db/migrate/20251029113830_create_external_ids.rb
Normal file
11
db/migrate/20251029113830_create_external_ids.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class CreateExternalIds < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :external_ids do |t|
|
||||
t.references :work, null: false, foreign_key: true
|
||||
t.integer :source
|
||||
t.string :value
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
17
db/migrate/20251029113850_create_storage_locations.rb
Normal file
17
db/migrate/20251029113850_create_storage_locations.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
class CreateStorageLocations < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :storage_locations do |t|
|
||||
t.string :name
|
||||
t.string :path
|
||||
t.integer :location_type
|
||||
t.boolean :writable
|
||||
t.boolean :enabled
|
||||
t.boolean :scan_subdirectories
|
||||
t.integer :priority
|
||||
t.text :settings
|
||||
t.datetime :last_scanned_at
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
31
db/migrate/20251029113911_create_videos.rb
Normal file
31
db/migrate/20251029113911_create_videos.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
class CreateVideos < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :videos do |t|
|
||||
t.references :work, null: false, foreign_key: true
|
||||
t.references :storage_location, null: false, foreign_key: true
|
||||
t.string :title
|
||||
t.string :file_path
|
||||
t.string :file_hash
|
||||
t.integer :file_size
|
||||
t.float :duration
|
||||
t.integer :width
|
||||
t.integer :height
|
||||
t.string :resolution_label
|
||||
t.string :video_codec
|
||||
t.string :audio_codec
|
||||
t.integer :bit_rate
|
||||
t.float :frame_rate
|
||||
t.string :format
|
||||
t.boolean :has_subtitles
|
||||
t.string :version_type
|
||||
t.integer :source_type
|
||||
t.string :source_url
|
||||
t.boolean :imported
|
||||
t.boolean :processing_failed
|
||||
t.text :error_message
|
||||
t.text :metadata
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
11
db/migrate/20251029113919_create_video_assets.rb
Normal file
11
db/migrate/20251029113919_create_video_assets.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class CreateVideoAssets < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :video_assets do |t|
|
||||
t.references :video, null: false, foreign_key: true
|
||||
t.integer :asset_type
|
||||
t.text :metadata
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
15
db/migrate/20251029113957_create_playback_sessions.rb
Normal file
15
db/migrate/20251029113957_create_playback_sessions.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
class CreatePlaybackSessions < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :playback_sessions do |t|
|
||||
t.references :video, null: false, foreign_key: true
|
||||
t.references :user, null: false, foreign_key: true
|
||||
t.float :position
|
||||
t.float :duration_watched
|
||||
t.datetime :last_watched_at
|
||||
t.boolean :completed
|
||||
t.integer :play_count
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
11
db/migrate/20251029120242_create_users.rb
Normal file
11
db/migrate/20251029120242_create_users.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class CreateUsers < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :users do |t|
|
||||
t.string :email_address, null: false
|
||||
t.string :password_digest, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
add_index :users, :email_address, unique: true
|
||||
end
|
||||
end
|
||||
11
db/migrate/20251029120243_create_sessions.rb
Normal file
11
db/migrate/20251029120243_create_sessions.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class CreateSessions < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :sessions do |t|
|
||||
t.references :user, null: false, foreign_key: true
|
||||
t.string :ip_address
|
||||
t.string :user_agent
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
29
db/migrate/20251029120404_update_videos_from_architecture.rb
Normal file
29
db/migrate/20251029120404_update_videos_from_architecture.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
class UpdateVideosFromArchitecture < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
change_table :videos do |t|
|
||||
# Make work reference optional (videos can exist without works initially)
|
||||
t.change_null :work_id, true
|
||||
|
||||
# Add defaults for boolean fields
|
||||
t.change_default :imported, false
|
||||
t.change_default :processing_failed, false
|
||||
t.change_default :has_subtitles, false
|
||||
|
||||
# Note: file_size is already integer, SQLite compatible with bigint
|
||||
|
||||
# Add source_type default and make required fields not null
|
||||
t.change_default :source_type, 0
|
||||
t.change_null :source_type, false
|
||||
|
||||
# Make file_path required
|
||||
t.change_null :file_path, false
|
||||
end
|
||||
|
||||
# Add indexes as specified in architecture
|
||||
add_index :videos, [:storage_location_id, :file_path], unique: true
|
||||
add_index :videos, :source_type
|
||||
add_index :videos, :file_hash
|
||||
add_index :videos, :imported
|
||||
add_index :videos, [:work_id, :resolution_label]
|
||||
end
|
||||
end
|
||||
16
db/migrate/20251029120428_update_works_from_architecture.rb
Normal file
16
db/migrate/20251029120428_update_works_from_architecture.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
class UpdateWorksFromArchitecture < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
change_table :works do |t|
|
||||
# Add defaults for boolean fields
|
||||
t.change_default :organized, false
|
||||
|
||||
# Make title required
|
||||
t.change_null :title, false
|
||||
end
|
||||
|
||||
# Add indexes as specified in architecture
|
||||
add_index :works, :title
|
||||
add_index :works, [:title, :year], unique: true
|
||||
add_index :works, :organized
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,24 @@
|
||||
class UpdateStorageLocationsFromArchitecture < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
change_table :storage_locations do |t|
|
||||
# Add defaults for boolean fields
|
||||
t.change_default :writable, false
|
||||
t.change_default :enabled, true
|
||||
t.change_default :scan_subdirectories, true
|
||||
t.change_default :priority, 0
|
||||
|
||||
# Add location_type default and make required fields not null
|
||||
t.change_default :location_type, 0
|
||||
t.change_null :location_type, false
|
||||
|
||||
# Make name required
|
||||
t.change_null :name, false
|
||||
end
|
||||
|
||||
# Add indexes as specified in architecture
|
||||
add_index :storage_locations, :name, unique: true
|
||||
add_index :storage_locations, :location_type
|
||||
add_index :storage_locations, :enabled
|
||||
add_index :storage_locations, :priority
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
class UpdateVideoAssetsFromArchitecture < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
change_table :video_assets do |t|
|
||||
# Make asset_type required
|
||||
t.change_null :asset_type, false
|
||||
end
|
||||
|
||||
# Add indexes as specified in architecture
|
||||
add_index :video_assets, [:video_id, :asset_type], unique: true
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
class UpdatePlaybackSessionsFromArchitecture < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
change_table :playback_sessions do |t|
|
||||
# Add defaults for fields
|
||||
t.change_default :position, 0.0
|
||||
t.change_default :duration_watched, 0.0
|
||||
t.change_default :completed, false
|
||||
t.change_default :play_count, 0
|
||||
end
|
||||
|
||||
# Add indexes as specified in architecture
|
||||
add_index :playback_sessions, [:video_id, :user_id], unique: true
|
||||
add_index :playback_sessions, :last_watched_at
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
class UpdateExternalIdsFromArchitecture < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
change_table :external_ids do |t|
|
||||
# Make source and value required
|
||||
t.change_null :source, false
|
||||
t.change_null :value, false
|
||||
end
|
||||
|
||||
# Add indexes as specified in architecture
|
||||
# Ensure each source only appears once per work
|
||||
add_index :external_ids, [:work_id, :source], unique: true
|
||||
|
||||
# Fast lookup by external ID (for "find work by IMDB ID" queries)
|
||||
add_index :external_ids, [:source, :value], unique: true
|
||||
end
|
||||
end
|
||||
7
db/migrate/20251029204614_add_json_stores_to_video.rb
Normal file
7
db/migrate/20251029204614_add_json_stores_to_video.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
class AddJsonStoresToVideo < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :videos, :fingerprints, :text
|
||||
add_column :videos, :video_metadata, :text
|
||||
add_column :videos, :processing_info, :text
|
||||
end
|
||||
end
|
||||
7
db/migrate/20251029204641_add_json_stores_to_work.rb
Normal file
7
db/migrate/20251029204641_add_json_stores_to_work.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
class AddJsonStoresToWork < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :works, :tmdb_data, :text
|
||||
add_column :works, :imdb_data, :text
|
||||
add_column :works, :custom_fields, :text
|
||||
end
|
||||
end
|
||||
8
db/migrate/20251029215501_add_phase1_fields_to_videos.rb
Normal file
8
db/migrate/20251029215501_add_phase1_fields_to_videos.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class AddPhase1FieldsToVideos < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :videos, :filename, :string
|
||||
add_column :videos, :transcoded_path, :string
|
||||
add_column :videos, :transcoded_permanently, :boolean
|
||||
add_column :videos, :web_compatible, :boolean
|
||||
end
|
||||
end
|
||||
5
db/migrate/20251029215811_add_processed_to_videos.rb
Normal file
5
db/migrate/20251029215811_add_processed_to_videos.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddProcessedToVideos < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :videos, :processed, :boolean
|
||||
end
|
||||
end
|
||||
6
db/migrate/20251031022926_add_type_to_videos.rb
Normal file
6
db/migrate/20251031022926_add_type_to_videos.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class AddTypeToVideos < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :videos, :type, :string, default: 'Video', null: false
|
||||
add_index :videos, :type
|
||||
end
|
||||
end
|
||||
146
db/schema.rb
generated
146
db/schema.rb
generated
@@ -10,5 +10,149 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.1].define(version: 0) do
|
||||
ActiveRecord::Schema[8.1].define(version: 2025_10_31_022926) do
|
||||
create_table "external_ids", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "source", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "value", null: false
|
||||
t.integer "work_id", null: false
|
||||
t.index ["source", "value"], name: "index_external_ids_on_source_and_value", unique: true
|
||||
t.index ["work_id", "source"], name: "index_external_ids_on_work_id_and_source", unique: true
|
||||
t.index ["work_id"], name: "index_external_ids_on_work_id"
|
||||
end
|
||||
|
||||
create_table "playback_sessions", force: :cascade do |t|
|
||||
t.boolean "completed", default: false
|
||||
t.datetime "created_at", null: false
|
||||
t.float "duration_watched", default: 0.0
|
||||
t.datetime "last_watched_at"
|
||||
t.integer "play_count", default: 0
|
||||
t.float "position", default: 0.0
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id", null: false
|
||||
t.integer "video_id", null: false
|
||||
t.index ["last_watched_at"], name: "index_playback_sessions_on_last_watched_at"
|
||||
t.index ["user_id"], name: "index_playback_sessions_on_user_id"
|
||||
t.index ["video_id", "user_id"], name: "index_playback_sessions_on_video_id_and_user_id", unique: true
|
||||
t.index ["video_id"], name: "index_playback_sessions_on_video_id"
|
||||
end
|
||||
|
||||
create_table "sessions", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.string "ip_address"
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "user_agent"
|
||||
t.integer "user_id", null: false
|
||||
t.index ["user_id"], name: "index_sessions_on_user_id"
|
||||
end
|
||||
|
||||
create_table "storage_locations", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.boolean "enabled", default: true
|
||||
t.datetime "last_scanned_at"
|
||||
t.integer "location_type", default: 0, null: false
|
||||
t.string "name", null: false
|
||||
t.string "path"
|
||||
t.integer "priority", default: 0
|
||||
t.boolean "scan_subdirectories", default: true
|
||||
t.text "settings"
|
||||
t.datetime "updated_at", null: false
|
||||
t.boolean "writable", default: false
|
||||
t.index ["enabled"], name: "index_storage_locations_on_enabled"
|
||||
t.index ["location_type"], name: "index_storage_locations_on_location_type"
|
||||
t.index ["name"], name: "index_storage_locations_on_name", unique: true
|
||||
t.index ["priority"], name: "index_storage_locations_on_priority"
|
||||
end
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.string "email_address", null: false
|
||||
t.string "password_digest", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["email_address"], name: "index_users_on_email_address", unique: true
|
||||
end
|
||||
|
||||
create_table "video_assets", force: :cascade do |t|
|
||||
t.integer "asset_type", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.text "metadata"
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "video_id", null: false
|
||||
t.index ["video_id", "asset_type"], name: "index_video_assets_on_video_id_and_asset_type", unique: true
|
||||
t.index ["video_id"], name: "index_video_assets_on_video_id"
|
||||
end
|
||||
|
||||
create_table "videos", force: :cascade do |t|
|
||||
t.string "audio_codec"
|
||||
t.integer "bit_rate"
|
||||
t.datetime "created_at", null: false
|
||||
t.float "duration"
|
||||
t.text "error_message"
|
||||
t.string "file_hash"
|
||||
t.string "file_path", null: false
|
||||
t.integer "file_size"
|
||||
t.string "filename"
|
||||
t.text "fingerprints"
|
||||
t.string "format"
|
||||
t.float "frame_rate"
|
||||
t.boolean "has_subtitles", default: false
|
||||
t.integer "height"
|
||||
t.boolean "imported", default: false
|
||||
t.text "metadata"
|
||||
t.boolean "processed"
|
||||
t.boolean "processing_failed", default: false
|
||||
t.text "processing_info"
|
||||
t.string "resolution_label"
|
||||
t.integer "source_type", default: 0, null: false
|
||||
t.string "source_url"
|
||||
t.integer "storage_location_id", null: false
|
||||
t.string "title"
|
||||
t.string "transcoded_path"
|
||||
t.boolean "transcoded_permanently"
|
||||
t.string "type", default: "Video", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "version_type"
|
||||
t.string "video_codec"
|
||||
t.text "video_metadata"
|
||||
t.boolean "web_compatible"
|
||||
t.integer "width"
|
||||
t.integer "work_id"
|
||||
t.index ["file_hash"], name: "index_videos_on_file_hash"
|
||||
t.index ["imported"], name: "index_videos_on_imported"
|
||||
t.index ["source_type"], name: "index_videos_on_source_type"
|
||||
t.index ["storage_location_id", "file_path"], name: "index_videos_on_storage_location_id_and_file_path", unique: true
|
||||
t.index ["storage_location_id"], name: "index_videos_on_storage_location_id"
|
||||
t.index ["type"], name: "index_videos_on_type"
|
||||
t.index ["work_id", "resolution_label"], name: "index_videos_on_work_id_and_resolution_label"
|
||||
t.index ["work_id"], name: "index_videos_on_work_id"
|
||||
end
|
||||
|
||||
create_table "works", force: :cascade do |t|
|
||||
t.string "backdrop_path"
|
||||
t.datetime "created_at", null: false
|
||||
t.text "custom_fields"
|
||||
t.text "description"
|
||||
t.string "director"
|
||||
t.text "imdb_data"
|
||||
t.text "metadata"
|
||||
t.boolean "organized", default: false
|
||||
t.string "poster_path"
|
||||
t.decimal "rating"
|
||||
t.string "title", null: false
|
||||
t.text "tmdb_data"
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "year"
|
||||
t.index ["organized"], name: "index_works_on_organized"
|
||||
t.index ["title", "year"], name: "index_works_on_title_and_year", unique: true
|
||||
t.index ["title"], name: "index_works_on_title"
|
||||
end
|
||||
|
||||
add_foreign_key "external_ids", "works"
|
||||
add_foreign_key "playback_sessions", "users"
|
||||
add_foreign_key "playback_sessions", "videos"
|
||||
add_foreign_key "sessions", "users"
|
||||
add_foreign_key "video_assets", "videos"
|
||||
add_foreign_key "videos", "storage_locations"
|
||||
add_foreign_key "videos", "works"
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user