mirror of
https://github.com/ryankazokas/turbovault-app.git
synced 2026-04-16 22:12:53 +00:00
Moving to github
This commit is contained in:
11
db/cable_schema.rb
Normal file
11
db/cable_schema.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
ActiveRecord::Schema[7.1].define(version: 1) do
|
||||
create_table "solid_cable_messages", force: :cascade do |t|
|
||||
t.binary "channel", limit: 1024, null: false
|
||||
t.binary "payload", limit: 536870912, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "channel_hash", limit: 8, null: false
|
||||
t.index ["channel"], name: "index_solid_cable_messages_on_channel"
|
||||
t.index ["channel_hash"], name: "index_solid_cable_messages_on_channel_hash"
|
||||
t.index ["created_at"], name: "index_solid_cable_messages_on_created_at"
|
||||
end
|
||||
end
|
||||
12
db/cache_schema.rb
Normal file
12
db/cache_schema.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
ActiveRecord::Schema[7.2].define(version: 1) do
|
||||
create_table "solid_cache_entries", force: :cascade do |t|
|
||||
t.binary "key", limit: 1024, null: false
|
||||
t.binary "value", limit: 536870912, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "key_hash", limit: 8, null: false
|
||||
t.integer "byte_size", limit: 4, null: false
|
||||
t.index ["byte_size"], name: "index_solid_cache_entries_on_byte_size"
|
||||
t.index ["key_hash", "byte_size"], name: "index_solid_cache_entries_on_key_hash_and_byte_size"
|
||||
t.index ["key_hash"], name: "index_solid_cache_entries_on_key_hash", unique: true
|
||||
end
|
||||
end
|
||||
29
db/migrate/20260328183428_create_users.rb
Normal file
29
db/migrate/20260328183428_create_users.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
class CreateUsers < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :users do |t|
|
||||
t.string :email, null: false
|
||||
t.string :username, null: false
|
||||
t.string :password_digest, null: false
|
||||
t.text :bio
|
||||
t.boolean :profile_public, default: false, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
add_index :users, :email, unique: true
|
||||
add_index :users, :username, unique: true
|
||||
|
||||
# Enable Row Level Security
|
||||
enable_rls_on :users
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def enable_rls_on(table_name)
|
||||
execute <<-SQL
|
||||
ALTER TABLE #{table_name} ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY #{table_name}_isolation_policy ON #{table_name}
|
||||
USING (id = current_setting('app.current_user_id', true)::bigint);
|
||||
SQL
|
||||
end
|
||||
end
|
||||
12
db/migrate/20260328183431_create_platforms.rb
Normal file
12
db/migrate/20260328183431_create_platforms.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class CreatePlatforms < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :platforms do |t|
|
||||
t.string :name, null: false
|
||||
t.string :abbreviation
|
||||
t.string :manufacturer
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
add_index :platforms, :name, unique: true
|
||||
end
|
||||
end
|
||||
10
db/migrate/20260328183435_create_genres.rb
Normal file
10
db/migrate/20260328183435_create_genres.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class CreateGenres < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :genres do |t|
|
||||
t.string :name, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
add_index :genres, :name, unique: true
|
||||
end
|
||||
end
|
||||
22
db/migrate/20260328183438_create_api_tokens.rb
Normal file
22
db/migrate/20260328183438_create_api_tokens.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
class CreateApiTokens < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :api_tokens do |t|
|
||||
t.references :user, null: false, foreign_key: true, index: true
|
||||
t.string :token, null: false
|
||||
t.string :name
|
||||
t.datetime :last_used_at
|
||||
t.datetime :expires_at
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
add_index :api_tokens, :token, unique: true
|
||||
|
||||
# Enable Row Level Security
|
||||
execute <<-SQL
|
||||
ALTER TABLE api_tokens ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY api_tokens_isolation_policy ON api_tokens
|
||||
USING (user_id = current_setting('app.current_user_id', true)::bigint);
|
||||
SQL
|
||||
end
|
||||
end
|
||||
33
db/migrate/20260328183444_create_games.rb
Normal file
33
db/migrate/20260328183444_create_games.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
class CreateGames < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :games do |t|
|
||||
t.references :user, null: false, foreign_key: true, index: true
|
||||
t.references :platform, null: false, foreign_key: true, index: true
|
||||
t.string :title, null: false
|
||||
t.string :format, null: false
|
||||
t.date :date_added, null: false
|
||||
t.string :completion_status
|
||||
t.integer :user_rating
|
||||
t.text :notes
|
||||
t.string :condition
|
||||
t.decimal :price_paid, precision: 10, scale: 2
|
||||
t.string :location
|
||||
t.string :digital_store
|
||||
t.boolean :custom_entry, default: false, null: false
|
||||
t.integer :igdb_id
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :games, :title
|
||||
add_index :games, :igdb_id
|
||||
|
||||
# Enable Row Level Security
|
||||
execute <<-SQL
|
||||
ALTER TABLE games ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY games_isolation_policy ON games
|
||||
USING (user_id = current_setting('app.current_user_id', true)::bigint);
|
||||
SQL
|
||||
end
|
||||
end
|
||||
12
db/migrate/20260328183447_create_game_genres.rb
Normal file
12
db/migrate/20260328183447_create_game_genres.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class CreateGameGenres < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :game_genres do |t|
|
||||
t.references :game, null: false, foreign_key: true, index: true
|
||||
t.references :genre, null: false, foreign_key: true, index: true
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :game_genres, [ :game_id, :genre_id ], unique: true
|
||||
end
|
||||
end
|
||||
23
db/migrate/20260328183451_create_collections.rb
Normal file
23
db/migrate/20260328183451_create_collections.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
class CreateCollections < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :collections do |t|
|
||||
t.references :user, null: false, foreign_key: true, index: true
|
||||
t.string :name, null: false
|
||||
t.text :description
|
||||
t.integer :parent_collection_id
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :collections, :parent_collection_id
|
||||
add_foreign_key :collections, :collections, column: :parent_collection_id
|
||||
|
||||
# Enable Row Level Security
|
||||
execute <<-SQL
|
||||
ALTER TABLE collections ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY collections_isolation_policy ON collections
|
||||
USING (user_id = current_setting('app.current_user_id', true)::bigint);
|
||||
SQL
|
||||
end
|
||||
end
|
||||
13
db/migrate/20260328183456_create_collection_games.rb
Normal file
13
db/migrate/20260328183456_create_collection_games.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class CreateCollectionGames < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :collection_games do |t|
|
||||
t.references :collection, null: false, foreign_key: true, index: true
|
||||
t.references :game, null: false, foreign_key: true, index: true
|
||||
t.integer :position
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :collection_games, [ :collection_id, :game_id ], unique: true
|
||||
end
|
||||
end
|
||||
28
db/migrate/20260328183500_create_items.rb
Normal file
28
db/migrate/20260328183500_create_items.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
class CreateItems < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :items do |t|
|
||||
t.references :user, null: false, foreign_key: true, index: true
|
||||
t.string :name, null: false
|
||||
t.string :item_type, null: false
|
||||
t.references :platform, foreign_key: true, index: true
|
||||
t.string :condition
|
||||
t.decimal :price_paid, precision: 10, scale: 2
|
||||
t.string :location
|
||||
t.date :date_added, null: false
|
||||
t.text :notes
|
||||
t.integer :igdb_id
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :items, :igdb_id
|
||||
|
||||
# Enable Row Level Security
|
||||
execute <<-SQL
|
||||
ALTER TABLE items ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY items_isolation_policy ON items
|
||||
USING (user_id = current_setting('app.current_user_id', true)::bigint);
|
||||
SQL
|
||||
end
|
||||
end
|
||||
6
db/migrate/20260328183634_add_password_reset_to_users.rb
Normal file
6
db/migrate/20260328183634_add_password_reset_to_users.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class AddPasswordResetToUsers < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :users, :password_reset_token, :string
|
||||
add_column :users, :password_reset_sent_at, :datetime
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class RenameEncryptedPasswordToPasswordDigest < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
rename_column :users, :encrypted_password, :password_digest
|
||||
end
|
||||
end
|
||||
20
db/migrate/20260328200226_create_igdb_games.rb
Normal file
20
db/migrate/20260328200226_create_igdb_games.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
class CreateIgdbGames < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :igdb_games do |t|
|
||||
t.bigint :igdb_id, null: false
|
||||
t.string :name, null: false
|
||||
t.string :slug
|
||||
t.string :cover_url
|
||||
t.text :summary
|
||||
t.date :first_release_date
|
||||
t.integer :match_count, default: 0, null: false
|
||||
t.datetime :last_synced_at
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :igdb_games, :igdb_id, unique: true
|
||||
add_index :igdb_games, :name
|
||||
add_index :igdb_games, :slug
|
||||
end
|
||||
end
|
||||
14
db/migrate/20260328200237_create_igdb_platform_mappings.rb
Normal file
14
db/migrate/20260328200237_create_igdb_platform_mappings.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class CreateIgdbPlatformMappings < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :igdb_platform_mappings do |t|
|
||||
t.references :platform, null: false, foreign_key: true, index: true
|
||||
t.integer :igdb_platform_id, null: false
|
||||
t.string :igdb_platform_name
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :igdb_platform_mappings, :igdb_platform_id
|
||||
add_index :igdb_platform_mappings, [ :platform_id, :igdb_platform_id ], unique: true, name: 'index_platform_mappings_unique'
|
||||
end
|
||||
end
|
||||
8
db/migrate/20260328200248_add_igdb_sync_to_users.rb
Normal file
8
db/migrate/20260328200248_add_igdb_sync_to_users.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class AddIgdbSyncToUsers < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :users, :igdb_sync_enabled, :boolean, default: false, null: false
|
||||
add_column :users, :igdb_last_synced_at, :datetime
|
||||
|
||||
add_index :users, :igdb_sync_enabled
|
||||
end
|
||||
end
|
||||
9
db/migrate/20260328200256_add_igdb_matching_to_games.rb
Normal file
9
db/migrate/20260328200256_add_igdb_matching_to_games.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class AddIgdbMatchingToGames < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :games, :igdb_matched_at, :datetime
|
||||
add_column :games, :igdb_match_status, :string
|
||||
add_column :games, :igdb_match_confidence, :decimal, precision: 5, scale: 2
|
||||
|
||||
add_index :games, :igdb_match_status
|
||||
end
|
||||
end
|
||||
22
db/migrate/20260328200307_create_igdb_match_suggestions.rb
Normal file
22
db/migrate/20260328200307_create_igdb_match_suggestions.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
class CreateIgdbMatchSuggestions < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :igdb_match_suggestions do |t|
|
||||
t.references :game, null: false, foreign_key: true, index: true
|
||||
t.references :igdb_game, foreign_key: true, index: true
|
||||
t.bigint :igdb_id, null: false
|
||||
t.string :igdb_name, null: false
|
||||
t.string :igdb_slug
|
||||
t.string :igdb_cover_url
|
||||
t.date :igdb_release_date
|
||||
t.string :igdb_platform_name
|
||||
t.decimal :confidence_score, precision: 5, scale: 2
|
||||
t.string :status, default: 'pending', null: false # pending, approved, rejected
|
||||
t.datetime :reviewed_at
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :igdb_match_suggestions, :status
|
||||
add_index :igdb_match_suggestions, [ :game_id, :igdb_id ], unique: true
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddSummaryToIgdbMatchSuggestions < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :igdb_match_suggestions, :igdb_summary, :text
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddGenresToIgdbMatchSuggestions < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :igdb_match_suggestions, :igdb_genres, :text, array: true, default: []
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class ChangeIgdbSyncEnabledDefaultToTrue < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
change_column_default :users, :igdb_sync_enabled, from: false, to: true
|
||||
end
|
||||
end
|
||||
6
db/migrate/20260328222034_add_theme_to_users.rb
Normal file
6
db/migrate/20260328222034_add_theme_to_users.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class AddThemeToUsers < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :users, :theme, :string, default: "light", null: false
|
||||
add_index :users, :theme
|
||||
end
|
||||
end
|
||||
129
db/queue_schema.rb
Normal file
129
db/queue_schema.rb
Normal file
@@ -0,0 +1,129 @@
|
||||
ActiveRecord::Schema[7.1].define(version: 1) do
|
||||
create_table "solid_queue_blocked_executions", force: :cascade do |t|
|
||||
t.bigint "job_id", null: false
|
||||
t.string "queue_name", null: false
|
||||
t.integer "priority", default: 0, null: false
|
||||
t.string "concurrency_key", null: false
|
||||
t.datetime "expires_at", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.index [ "concurrency_key", "priority", "job_id" ], name: "index_solid_queue_blocked_executions_for_release"
|
||||
t.index [ "expires_at", "concurrency_key" ], name: "index_solid_queue_blocked_executions_for_maintenance"
|
||||
t.index [ "job_id" ], name: "index_solid_queue_blocked_executions_on_job_id", unique: true
|
||||
end
|
||||
|
||||
create_table "solid_queue_claimed_executions", force: :cascade do |t|
|
||||
t.bigint "job_id", null: false
|
||||
t.bigint "process_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.index [ "job_id" ], name: "index_solid_queue_claimed_executions_on_job_id", unique: true
|
||||
t.index [ "process_id", "job_id" ], name: "index_solid_queue_claimed_executions_on_process_id_and_job_id"
|
||||
end
|
||||
|
||||
create_table "solid_queue_failed_executions", force: :cascade do |t|
|
||||
t.bigint "job_id", null: false
|
||||
t.text "error"
|
||||
t.datetime "created_at", null: false
|
||||
t.index [ "job_id" ], name: "index_solid_queue_failed_executions_on_job_id", unique: true
|
||||
end
|
||||
|
||||
create_table "solid_queue_jobs", force: :cascade do |t|
|
||||
t.string "queue_name", null: false
|
||||
t.string "class_name", null: false
|
||||
t.text "arguments"
|
||||
t.integer "priority", default: 0, null: false
|
||||
t.string "active_job_id"
|
||||
t.datetime "scheduled_at"
|
||||
t.datetime "finished_at"
|
||||
t.string "concurrency_key"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index [ "active_job_id" ], name: "index_solid_queue_jobs_on_active_job_id"
|
||||
t.index [ "class_name" ], name: "index_solid_queue_jobs_on_class_name"
|
||||
t.index [ "finished_at" ], name: "index_solid_queue_jobs_on_finished_at"
|
||||
t.index [ "queue_name", "finished_at" ], name: "index_solid_queue_jobs_for_filtering"
|
||||
t.index [ "scheduled_at", "finished_at" ], name: "index_solid_queue_jobs_for_alerting"
|
||||
end
|
||||
|
||||
create_table "solid_queue_pauses", force: :cascade do |t|
|
||||
t.string "queue_name", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.index [ "queue_name" ], name: "index_solid_queue_pauses_on_queue_name", unique: true
|
||||
end
|
||||
|
||||
create_table "solid_queue_processes", force: :cascade do |t|
|
||||
t.string "kind", null: false
|
||||
t.datetime "last_heartbeat_at", null: false
|
||||
t.bigint "supervisor_id"
|
||||
t.integer "pid", null: false
|
||||
t.string "hostname"
|
||||
t.text "metadata"
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name", null: false
|
||||
t.index [ "last_heartbeat_at" ], name: "index_solid_queue_processes_on_last_heartbeat_at"
|
||||
t.index [ "name", "supervisor_id" ], name: "index_solid_queue_processes_on_name_and_supervisor_id", unique: true
|
||||
t.index [ "supervisor_id" ], name: "index_solid_queue_processes_on_supervisor_id"
|
||||
end
|
||||
|
||||
create_table "solid_queue_ready_executions", force: :cascade do |t|
|
||||
t.bigint "job_id", null: false
|
||||
t.string "queue_name", null: false
|
||||
t.integer "priority", default: 0, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.index [ "job_id" ], name: "index_solid_queue_ready_executions_on_job_id", unique: true
|
||||
t.index [ "priority", "job_id" ], name: "index_solid_queue_poll_all"
|
||||
t.index [ "queue_name", "priority", "job_id" ], name: "index_solid_queue_poll_by_queue"
|
||||
end
|
||||
|
||||
create_table "solid_queue_recurring_executions", force: :cascade do |t|
|
||||
t.bigint "job_id", null: false
|
||||
t.string "task_key", null: false
|
||||
t.datetime "run_at", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.index [ "job_id" ], name: "index_solid_queue_recurring_executions_on_job_id", unique: true
|
||||
t.index [ "task_key", "run_at" ], name: "index_solid_queue_recurring_executions_on_task_key_and_run_at", unique: true
|
||||
end
|
||||
|
||||
create_table "solid_queue_recurring_tasks", force: :cascade do |t|
|
||||
t.string "key", null: false
|
||||
t.string "schedule", null: false
|
||||
t.string "command", limit: 2048
|
||||
t.string "class_name"
|
||||
t.text "arguments"
|
||||
t.string "queue_name"
|
||||
t.integer "priority", default: 0
|
||||
t.boolean "static", default: true, null: false
|
||||
t.text "description"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index [ "key" ], name: "index_solid_queue_recurring_tasks_on_key", unique: true
|
||||
t.index [ "static" ], name: "index_solid_queue_recurring_tasks_on_static"
|
||||
end
|
||||
|
||||
create_table "solid_queue_scheduled_executions", force: :cascade do |t|
|
||||
t.bigint "job_id", null: false
|
||||
t.string "queue_name", null: false
|
||||
t.integer "priority", default: 0, null: false
|
||||
t.datetime "scheduled_at", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.index [ "job_id" ], name: "index_solid_queue_scheduled_executions_on_job_id", unique: true
|
||||
t.index [ "scheduled_at", "priority", "job_id" ], name: "index_solid_queue_dispatch_all"
|
||||
end
|
||||
|
||||
create_table "solid_queue_semaphores", force: :cascade do |t|
|
||||
t.string "key", null: false
|
||||
t.integer "value", default: 1, null: false
|
||||
t.datetime "expires_at", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index [ "expires_at" ], name: "index_solid_queue_semaphores_on_expires_at"
|
||||
t.index [ "key", "value" ], name: "index_solid_queue_semaphores_on_key_and_value"
|
||||
t.index [ "key" ], name: "index_solid_queue_semaphores_on_key", unique: true
|
||||
end
|
||||
|
||||
add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
add_foreign_key "solid_queue_claimed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
add_foreign_key "solid_queue_failed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
end
|
||||
331
db/schema.rb
generated
Normal file
331
db/schema.rb
generated
Normal file
@@ -0,0 +1,331 @@
|
||||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
#
|
||||
# This file is the source Rails uses to define your schema when running `bin/rails
|
||||
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
|
||||
# be faster and is potentially less error prone than running all of your
|
||||
# migrations from scratch. Old migrations may fail to apply correctly if those
|
||||
# migrations use external dependencies or application code.
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.1].define(version: 2026_03_28_222034) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pg_catalog.plpgsql"
|
||||
|
||||
create_table "api_tokens", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "expires_at"
|
||||
t.datetime "last_used_at"
|
||||
t.string "name"
|
||||
t.string "token", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["token"], name: "index_api_tokens_on_token", unique: true
|
||||
t.index ["user_id"], name: "index_api_tokens_on_user_id"
|
||||
end
|
||||
|
||||
create_table "collection_games", force: :cascade do |t|
|
||||
t.bigint "collection_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "game_id", null: false
|
||||
t.integer "position"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["collection_id", "game_id"], name: "index_collection_games_on_collection_id_and_game_id", unique: true
|
||||
t.index ["collection_id"], name: "index_collection_games_on_collection_id"
|
||||
t.index ["game_id"], name: "index_collection_games_on_game_id"
|
||||
end
|
||||
|
||||
create_table "collections", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.text "description"
|
||||
t.string "name", null: false
|
||||
t.integer "parent_collection_id"
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["parent_collection_id"], name: "index_collections_on_parent_collection_id"
|
||||
t.index ["user_id"], name: "index_collections_on_user_id"
|
||||
end
|
||||
|
||||
create_table "game_genres", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "game_id", null: false
|
||||
t.bigint "genre_id", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["game_id", "genre_id"], name: "index_game_genres_on_game_id_and_genre_id", unique: true
|
||||
t.index ["game_id"], name: "index_game_genres_on_game_id"
|
||||
t.index ["genre_id"], name: "index_game_genres_on_genre_id"
|
||||
end
|
||||
|
||||
create_table "games", force: :cascade do |t|
|
||||
t.string "completion_status"
|
||||
t.string "condition"
|
||||
t.datetime "created_at", null: false
|
||||
t.boolean "custom_entry", default: false, null: false
|
||||
t.date "date_added", null: false
|
||||
t.string "digital_store"
|
||||
t.string "format", null: false
|
||||
t.integer "igdb_id"
|
||||
t.decimal "igdb_match_confidence", precision: 5, scale: 2
|
||||
t.string "igdb_match_status"
|
||||
t.datetime "igdb_matched_at"
|
||||
t.string "location"
|
||||
t.text "notes"
|
||||
t.bigint "platform_id", null: false
|
||||
t.decimal "price_paid", precision: 10, scale: 2
|
||||
t.string "title", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.integer "user_rating"
|
||||
t.index ["igdb_id"], name: "index_games_on_igdb_id"
|
||||
t.index ["igdb_match_status"], name: "index_games_on_igdb_match_status"
|
||||
t.index ["platform_id"], name: "index_games_on_platform_id"
|
||||
t.index ["title"], name: "index_games_on_title"
|
||||
t.index ["user_id"], name: "index_games_on_user_id"
|
||||
end
|
||||
|
||||
create_table "genres", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["name"], name: "index_genres_on_name", unique: true
|
||||
end
|
||||
|
||||
create_table "igdb_games", force: :cascade do |t|
|
||||
t.string "cover_url"
|
||||
t.datetime "created_at", null: false
|
||||
t.date "first_release_date"
|
||||
t.bigint "igdb_id", null: false
|
||||
t.datetime "last_synced_at"
|
||||
t.integer "match_count", default: 0, null: false
|
||||
t.string "name", null: false
|
||||
t.string "slug"
|
||||
t.text "summary"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["igdb_id"], name: "index_igdb_games_on_igdb_id", unique: true
|
||||
t.index ["name"], name: "index_igdb_games_on_name"
|
||||
t.index ["slug"], name: "index_igdb_games_on_slug"
|
||||
end
|
||||
|
||||
create_table "igdb_match_suggestions", force: :cascade do |t|
|
||||
t.decimal "confidence_score", precision: 5, scale: 2
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "game_id", null: false
|
||||
t.string "igdb_cover_url"
|
||||
t.bigint "igdb_game_id"
|
||||
t.text "igdb_genres", default: [], array: true
|
||||
t.bigint "igdb_id", null: false
|
||||
t.string "igdb_name", null: false
|
||||
t.string "igdb_platform_name"
|
||||
t.date "igdb_release_date"
|
||||
t.string "igdb_slug"
|
||||
t.text "igdb_summary"
|
||||
t.datetime "reviewed_at"
|
||||
t.string "status", default: "pending", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["game_id", "igdb_id"], name: "index_igdb_match_suggestions_on_game_id_and_igdb_id", unique: true
|
||||
t.index ["game_id"], name: "index_igdb_match_suggestions_on_game_id"
|
||||
t.index ["igdb_game_id"], name: "index_igdb_match_suggestions_on_igdb_game_id"
|
||||
t.index ["status"], name: "index_igdb_match_suggestions_on_status"
|
||||
end
|
||||
|
||||
create_table "igdb_platform_mappings", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "igdb_platform_id", null: false
|
||||
t.string "igdb_platform_name"
|
||||
t.bigint "platform_id", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["igdb_platform_id"], name: "index_igdb_platform_mappings_on_igdb_platform_id"
|
||||
t.index ["platform_id", "igdb_platform_id"], name: "index_platform_mappings_unique", unique: true
|
||||
t.index ["platform_id"], name: "index_igdb_platform_mappings_on_platform_id"
|
||||
end
|
||||
|
||||
create_table "items", force: :cascade do |t|
|
||||
t.string "condition"
|
||||
t.datetime "created_at", null: false
|
||||
t.date "date_added", null: false
|
||||
t.integer "igdb_id"
|
||||
t.string "item_type", null: false
|
||||
t.string "location"
|
||||
t.string "name", null: false
|
||||
t.text "notes"
|
||||
t.bigint "platform_id"
|
||||
t.decimal "price_paid", precision: 10, scale: 2
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["igdb_id"], name: "index_items_on_igdb_id"
|
||||
t.index ["platform_id"], name: "index_items_on_platform_id"
|
||||
t.index ["user_id"], name: "index_items_on_user_id"
|
||||
end
|
||||
|
||||
create_table "platforms", force: :cascade do |t|
|
||||
t.string "abbreviation"
|
||||
t.datetime "created_at", null: false
|
||||
t.string "manufacturer"
|
||||
t.string "name", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["name"], name: "index_platforms_on_name", unique: true
|
||||
end
|
||||
|
||||
create_table "solid_queue_blocked_executions", force: :cascade do |t|
|
||||
t.string "concurrency_key", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "expires_at", null: false
|
||||
t.bigint "job_id", null: false
|
||||
t.integer "priority", default: 0, null: false
|
||||
t.string "queue_name", null: false
|
||||
t.index ["concurrency_key", "priority", "job_id"], name: "index_solid_queue_blocked_executions_for_release"
|
||||
t.index ["expires_at", "concurrency_key"], name: "index_solid_queue_blocked_executions_for_maintenance"
|
||||
t.index ["job_id"], name: "index_solid_queue_blocked_executions_on_job_id", unique: true
|
||||
end
|
||||
|
||||
create_table "solid_queue_claimed_executions", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "job_id", null: false
|
||||
t.bigint "process_id"
|
||||
t.index ["job_id"], name: "index_solid_queue_claimed_executions_on_job_id", unique: true
|
||||
t.index ["process_id", "job_id"], name: "index_solid_queue_claimed_executions_on_process_id_and_job_id"
|
||||
end
|
||||
|
||||
create_table "solid_queue_failed_executions", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.text "error"
|
||||
t.bigint "job_id", null: false
|
||||
t.index ["job_id"], name: "index_solid_queue_failed_executions_on_job_id", unique: true
|
||||
end
|
||||
|
||||
create_table "solid_queue_jobs", force: :cascade do |t|
|
||||
t.string "active_job_id"
|
||||
t.text "arguments"
|
||||
t.string "class_name", null: false
|
||||
t.string "concurrency_key"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "finished_at"
|
||||
t.integer "priority", default: 0, null: false
|
||||
t.string "queue_name", null: false
|
||||
t.datetime "scheduled_at"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["active_job_id"], name: "index_solid_queue_jobs_on_active_job_id"
|
||||
t.index ["class_name"], name: "index_solid_queue_jobs_on_class_name"
|
||||
t.index ["finished_at"], name: "index_solid_queue_jobs_on_finished_at"
|
||||
t.index ["queue_name", "finished_at"], name: "index_solid_queue_jobs_for_filtering"
|
||||
t.index ["scheduled_at", "finished_at"], name: "index_solid_queue_jobs_for_alerting"
|
||||
end
|
||||
|
||||
create_table "solid_queue_pauses", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.string "queue_name", null: false
|
||||
t.index ["queue_name"], name: "index_solid_queue_pauses_on_queue_name", unique: true
|
||||
end
|
||||
|
||||
create_table "solid_queue_processes", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.string "hostname"
|
||||
t.string "kind", null: false
|
||||
t.datetime "last_heartbeat_at", null: false
|
||||
t.text "metadata"
|
||||
t.string "name", null: false
|
||||
t.integer "pid", null: false
|
||||
t.bigint "supervisor_id"
|
||||
t.index ["last_heartbeat_at"], name: "index_solid_queue_processes_on_last_heartbeat_at"
|
||||
t.index ["name", "supervisor_id"], name: "index_solid_queue_processes_on_name_and_supervisor_id", unique: true
|
||||
t.index ["supervisor_id"], name: "index_solid_queue_processes_on_supervisor_id"
|
||||
end
|
||||
|
||||
create_table "solid_queue_ready_executions", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "job_id", null: false
|
||||
t.integer "priority", default: 0, null: false
|
||||
t.string "queue_name", null: false
|
||||
t.index ["job_id"], name: "index_solid_queue_ready_executions_on_job_id", unique: true
|
||||
t.index ["priority", "job_id"], name: "index_solid_queue_poll_all"
|
||||
t.index ["queue_name", "priority", "job_id"], name: "index_solid_queue_poll_by_queue"
|
||||
end
|
||||
|
||||
create_table "solid_queue_recurring_executions", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "job_id", null: false
|
||||
t.datetime "run_at", null: false
|
||||
t.string "task_key", null: false
|
||||
t.index ["job_id"], name: "index_solid_queue_recurring_executions_on_job_id", unique: true
|
||||
t.index ["task_key", "run_at"], name: "index_solid_queue_recurring_executions_on_task_key_and_run_at", unique: true
|
||||
end
|
||||
|
||||
create_table "solid_queue_recurring_tasks", force: :cascade do |t|
|
||||
t.text "arguments"
|
||||
t.string "class_name"
|
||||
t.string "command", limit: 2048
|
||||
t.datetime "created_at", null: false
|
||||
t.text "description"
|
||||
t.string "key", null: false
|
||||
t.integer "priority", default: 0
|
||||
t.string "queue_name"
|
||||
t.string "schedule", null: false
|
||||
t.boolean "static", default: true, null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["key"], name: "index_solid_queue_recurring_tasks_on_key", unique: true
|
||||
t.index ["static"], name: "index_solid_queue_recurring_tasks_on_static"
|
||||
end
|
||||
|
||||
create_table "solid_queue_scheduled_executions", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "job_id", null: false
|
||||
t.integer "priority", default: 0, null: false
|
||||
t.string "queue_name", null: false
|
||||
t.datetime "scheduled_at", null: false
|
||||
t.index ["job_id"], name: "index_solid_queue_scheduled_executions_on_job_id", unique: true
|
||||
t.index ["scheduled_at", "priority", "job_id"], name: "index_solid_queue_dispatch_all"
|
||||
end
|
||||
|
||||
create_table "solid_queue_semaphores", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "expires_at", null: false
|
||||
t.string "key", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "value", default: 1, null: false
|
||||
t.index ["expires_at"], name: "index_solid_queue_semaphores_on_expires_at"
|
||||
t.index ["key", "value"], name: "index_solid_queue_semaphores_on_key_and_value"
|
||||
t.index ["key"], name: "index_solid_queue_semaphores_on_key", unique: true
|
||||
end
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.text "bio"
|
||||
t.datetime "created_at", null: false
|
||||
t.string "email", null: false
|
||||
t.datetime "igdb_last_synced_at"
|
||||
t.boolean "igdb_sync_enabled", default: true, null: false
|
||||
t.string "password_digest", null: false
|
||||
t.datetime "password_reset_sent_at"
|
||||
t.string "password_reset_token"
|
||||
t.boolean "profile_public", default: false, null: false
|
||||
t.string "theme", default: "light", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "username", null: false
|
||||
t.index ["email"], name: "index_users_on_email", unique: true
|
||||
t.index ["igdb_sync_enabled"], name: "index_users_on_igdb_sync_enabled"
|
||||
t.index ["theme"], name: "index_users_on_theme"
|
||||
t.index ["username"], name: "index_users_on_username", unique: true
|
||||
end
|
||||
|
||||
add_foreign_key "api_tokens", "users"
|
||||
add_foreign_key "collection_games", "collections"
|
||||
add_foreign_key "collection_games", "games"
|
||||
add_foreign_key "collections", "collections", column: "parent_collection_id"
|
||||
add_foreign_key "collections", "users"
|
||||
add_foreign_key "game_genres", "games"
|
||||
add_foreign_key "game_genres", "genres"
|
||||
add_foreign_key "games", "platforms"
|
||||
add_foreign_key "games", "users"
|
||||
add_foreign_key "igdb_match_suggestions", "games"
|
||||
add_foreign_key "igdb_match_suggestions", "igdb_games"
|
||||
add_foreign_key "igdb_platform_mappings", "platforms"
|
||||
add_foreign_key "items", "platforms"
|
||||
add_foreign_key "items", "users"
|
||||
add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
add_foreign_key "solid_queue_claimed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
add_foreign_key "solid_queue_failed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||
end
|
||||
345
db/seeds.rb
Normal file
345
db/seeds.rb
Normal file
@@ -0,0 +1,345 @@
|
||||
puts "Seeding database..."
|
||||
|
||||
# Create Platforms
|
||||
puts "Creating platforms..."
|
||||
platforms_data = [
|
||||
# Nintendo
|
||||
{ name: "Nintendo Entertainment System", abbreviation: "NES", manufacturer: "Nintendo" },
|
||||
{ name: "Super Nintendo Entertainment System", abbreviation: "SNES", manufacturer: "Nintendo" },
|
||||
{ name: "Nintendo 64", abbreviation: "N64", manufacturer: "Nintendo" },
|
||||
{ name: "GameCube", abbreviation: "GCN", manufacturer: "Nintendo" },
|
||||
{ name: "Wii", abbreviation: "Wii", manufacturer: "Nintendo" },
|
||||
{ name: "Wii U", abbreviation: "Wii U", manufacturer: "Nintendo" },
|
||||
{ name: "Nintendo Switch", abbreviation: "Switch", manufacturer: "Nintendo" },
|
||||
{ name: "Game Boy", abbreviation: "GB", manufacturer: "Nintendo" },
|
||||
{ name: "Game Boy Color", abbreviation: "GBC", manufacturer: "Nintendo" },
|
||||
{ name: "Game Boy Advance", abbreviation: "GBA", manufacturer: "Nintendo" },
|
||||
{ name: "Nintendo DS", abbreviation: "DS", manufacturer: "Nintendo" },
|
||||
{ name: "Nintendo 3DS", abbreviation: "3DS", manufacturer: "Nintendo" },
|
||||
|
||||
# Sony
|
||||
{ name: "PlayStation", abbreviation: "PS1", manufacturer: "Sony" },
|
||||
{ name: "PlayStation 2", abbreviation: "PS2", manufacturer: "Sony" },
|
||||
{ name: "PlayStation 3", abbreviation: "PS3", manufacturer: "Sony" },
|
||||
{ name: "PlayStation 4", abbreviation: "PS4", manufacturer: "Sony" },
|
||||
{ name: "PlayStation 5", abbreviation: "PS5", manufacturer: "Sony" },
|
||||
{ name: "PlayStation Portable", abbreviation: "PSP", manufacturer: "Sony" },
|
||||
{ name: "PlayStation Vita", abbreviation: "PS Vita", manufacturer: "Sony" },
|
||||
|
||||
# Microsoft
|
||||
{ name: "Xbox", abbreviation: "Xbox", manufacturer: "Microsoft" },
|
||||
{ name: "Xbox 360", abbreviation: "X360", manufacturer: "Microsoft" },
|
||||
{ name: "Xbox One", abbreviation: "XB1", manufacturer: "Microsoft" },
|
||||
{ name: "Xbox Series X/S", abbreviation: "Series X/S", manufacturer: "Microsoft" },
|
||||
|
||||
# Sega
|
||||
{ name: "Sega Genesis", abbreviation: "Genesis", manufacturer: "Sega" },
|
||||
{ name: "Sega Saturn", abbreviation: "Saturn", manufacturer: "Sega" },
|
||||
{ name: "Sega Dreamcast", abbreviation: "Dreamcast", manufacturer: "Sega" },
|
||||
{ name: "Sega Game Gear", abbreviation: "Game Gear", manufacturer: "Sega" },
|
||||
|
||||
# Other
|
||||
{ name: "PC", abbreviation: "PC", manufacturer: nil },
|
||||
{ name: "Mobile (iOS)", abbreviation: "iOS", manufacturer: "Apple" },
|
||||
{ name: "Mobile (Android)", abbreviation: "Android", manufacturer: "Google" },
|
||||
{ name: "Arcade", abbreviation: "Arcade", manufacturer: nil }
|
||||
]
|
||||
|
||||
platforms_data.each do |platform_data|
|
||||
Platform.find_or_create_by!(name: platform_data[:name]) do |platform|
|
||||
platform.abbreviation = platform_data[:abbreviation]
|
||||
platform.manufacturer = platform_data[:manufacturer]
|
||||
end
|
||||
end
|
||||
|
||||
puts "Created #{Platform.count} platforms"
|
||||
|
||||
# Create Genres
|
||||
puts "Creating genres..."
|
||||
genres = [
|
||||
"Action", "Adventure", "RPG", "JRPG", "Strategy", "Simulation",
|
||||
"Platformer", "Fighting", "Racing", "Sports", "Puzzle", "Horror",
|
||||
"Stealth", "Shooter", "FPS", "TPS", "Rhythm", "Visual Novel",
|
||||
"Roguelike", "Metroidvania", "Sandbox", "MMO", "Turn-Based",
|
||||
"Real-Time Strategy", "Tower Defense", "Card Game", "Party Game",
|
||||
"Educational", "Survival", "Battle Royale"
|
||||
]
|
||||
|
||||
genres.each do |genre_name|
|
||||
Genre.find_or_create_by!(name: genre_name)
|
||||
end
|
||||
|
||||
puts "Created #{Genre.count} genres"
|
||||
|
||||
# Create demo user and sample games for development
|
||||
if Rails.env.development?
|
||||
puts "Creating demo user..."
|
||||
|
||||
demo_user = User.find_or_create_by!(email: "demo@turbovault.com") do |user|
|
||||
user.username = "demo"
|
||||
user.password = "password123"
|
||||
user.password_confirmation = "password123"
|
||||
user.bio = "Demo user for TurboVault development"
|
||||
user.profile_public = true
|
||||
puts " ✓ Created demo user"
|
||||
puts " Email: demo@turbovault.com"
|
||||
puts " Password: password123"
|
||||
end
|
||||
|
||||
if demo_user.persisted? && !demo_user.previously_new_record?
|
||||
puts " ✓ Demo user already exists"
|
||||
puts " Email: demo@turbovault.com"
|
||||
puts " Password: password123"
|
||||
end
|
||||
|
||||
# Create sample collections
|
||||
puts "Creating sample collections for demo user..."
|
||||
|
||||
nintendo_collection = demo_user.collections.find_or_create_by!(name: "Nintendo Games") do |collection|
|
||||
collection.description = "All my Nintendo platform games"
|
||||
end
|
||||
|
||||
n64_collection = demo_user.collections.find_or_create_by!(name: "N64 Classics") do |collection|
|
||||
collection.description = "Best games from the Nintendo 64 era"
|
||||
collection.parent_collection = nintendo_collection
|
||||
end
|
||||
|
||||
favorites_collection = demo_user.collections.find_or_create_by!(name: "All-Time Favorites") do |collection|
|
||||
collection.description = "My absolute favorite games across all platforms"
|
||||
end
|
||||
|
||||
backlog_collection = demo_user.collections.find_or_create_by!(name: "To Play") do |collection|
|
||||
collection.description = "Games I still need to complete"
|
||||
end
|
||||
|
||||
puts " ✓ Created #{demo_user.collections.count} collections"
|
||||
|
||||
# Only create games if demo user has none
|
||||
if demo_user.games.empty?
|
||||
puts "Creating sample games for demo user..."
|
||||
|
||||
# Find platforms
|
||||
n64 = Platform.find_by(abbreviation: "N64")
|
||||
ps5 = Platform.find_by(abbreviation: "PS5")
|
||||
switch = Platform.find_by(abbreviation: "Switch")
|
||||
snes = Platform.find_by(abbreviation: "SNES")
|
||||
ps2 = Platform.find_by(abbreviation: "PS2")
|
||||
pc = Platform.find_by(name: "PC")
|
||||
|
||||
# Find genres
|
||||
action = Genre.find_by(name: "Action")
|
||||
adventure = Genre.find_by(name: "Adventure")
|
||||
rpg = Genre.find_by(name: "RPG")
|
||||
jrpg = Genre.find_by(name: "JRPG")
|
||||
platformer = Genre.find_by(name: "Platformer")
|
||||
puzzle = Genre.find_by(name: "Puzzle")
|
||||
shooter = Genre.find_by(name: "Shooter")
|
||||
fps = Genre.find_by(name: "FPS")
|
||||
simulation = Genre.find_by(name: "Simulation")
|
||||
|
||||
sample_games = [
|
||||
{
|
||||
title: "The Legend of Zelda: Ocarina of Time",
|
||||
platform: n64,
|
||||
genres: [ action, adventure ],
|
||||
collections: [ nintendo_collection, n64_collection, favorites_collection ],
|
||||
format: "physical",
|
||||
condition: "cib",
|
||||
completion_status: "completed",
|
||||
user_rating: 5,
|
||||
price_paid: 45.00,
|
||||
location: "Shelf A - Row 2",
|
||||
notes: "One of the best games ever made. Perfect condition with manual and box.",
|
||||
date_added: 30.days.ago
|
||||
},
|
||||
{
|
||||
title: "Super Mario 64",
|
||||
platform: n64,
|
||||
genres: [ platformer, adventure ],
|
||||
collections: [ nintendo_collection, n64_collection, favorites_collection ],
|
||||
format: "physical",
|
||||
condition: "loose",
|
||||
completion_status: "completed",
|
||||
user_rating: 5,
|
||||
price_paid: 30.00,
|
||||
location: "Shelf A - Row 2",
|
||||
date_added: 45.days.ago
|
||||
},
|
||||
{
|
||||
title: "Elden Ring",
|
||||
platform: ps5,
|
||||
genres: [ action, rpg ],
|
||||
collections: [ favorites_collection ],
|
||||
format: "digital",
|
||||
digital_store: "PlayStation Store",
|
||||
completion_status: "currently_playing",
|
||||
user_rating: 5,
|
||||
price_paid: 59.99,
|
||||
notes: "Amazing open world. Currently at 80 hours playtime.",
|
||||
date_added: 10.days.ago
|
||||
},
|
||||
{
|
||||
title: "The Legend of Zelda: Breath of the Wild",
|
||||
platform: switch,
|
||||
genres: [ action, adventure ],
|
||||
collections: [ nintendo_collection, favorites_collection ],
|
||||
format: "physical",
|
||||
condition: "cib",
|
||||
completion_status: "completed",
|
||||
user_rating: 5,
|
||||
price_paid: 60.00,
|
||||
location: "Shelf B - Row 1",
|
||||
date_added: 20.days.ago
|
||||
},
|
||||
{
|
||||
title: "Super Metroid",
|
||||
platform: snes,
|
||||
genres: [ action, adventure, platformer ],
|
||||
collections: [ nintendo_collection, favorites_collection ],
|
||||
format: "physical",
|
||||
condition: "loose",
|
||||
completion_status: "completed",
|
||||
user_rating: 5,
|
||||
price_paid: 85.00,
|
||||
location: "Shelf A - Row 1",
|
||||
notes: "Classic Metroidvania. Still holds up today!",
|
||||
date_added: 60.days.ago
|
||||
},
|
||||
{
|
||||
title: "Final Fantasy VII",
|
||||
platform: ps2,
|
||||
genres: [ jrpg, rpg ],
|
||||
collections: [ backlog_collection ],
|
||||
format: "physical",
|
||||
condition: "cib",
|
||||
completion_status: "backlog",
|
||||
user_rating: nil,
|
||||
price_paid: 20.00,
|
||||
location: "Shelf B - Row 3",
|
||||
notes: "Need to replay this classic.",
|
||||
date_added: 15.days.ago
|
||||
},
|
||||
{
|
||||
title: "Hollow Knight",
|
||||
platform: pc,
|
||||
genres: [ action, platformer, adventure ],
|
||||
collections: [ favorites_collection ],
|
||||
format: "digital",
|
||||
digital_store: "Steam",
|
||||
completion_status: "on_hold",
|
||||
user_rating: 5,
|
||||
price_paid: 15.00,
|
||||
notes: "Incredible art style and gameplay. Taking a break but will return.",
|
||||
date_added: 25.days.ago
|
||||
},
|
||||
{
|
||||
title: "Portal 2",
|
||||
platform: pc,
|
||||
genres: [ puzzle, fps ],
|
||||
collections: [ favorites_collection ],
|
||||
format: "digital",
|
||||
digital_store: "Steam",
|
||||
completion_status: "completed",
|
||||
user_rating: 5,
|
||||
price_paid: 9.99,
|
||||
notes: "Perfect puzzle game. Co-op is fantastic.",
|
||||
date_added: 50.days.ago
|
||||
},
|
||||
{
|
||||
title: "Hades",
|
||||
platform: switch,
|
||||
genres: [ action, rpg ],
|
||||
collections: [ nintendo_collection, favorites_collection ],
|
||||
format: "digital",
|
||||
digital_store: "Nintendo eShop",
|
||||
completion_status: "completed",
|
||||
user_rating: 5,
|
||||
price_paid: 24.99,
|
||||
notes: "Best roguelike I've ever played. Fantastic story and gameplay loop.",
|
||||
date_added: 35.days.ago
|
||||
},
|
||||
{
|
||||
title: "Cyberpunk 2077",
|
||||
platform: ps5,
|
||||
genres: [ action, rpg, shooter ],
|
||||
collections: [ backlog_collection ],
|
||||
format: "digital",
|
||||
digital_store: "PlayStation Store",
|
||||
completion_status: "backlog",
|
||||
user_rating: nil,
|
||||
price_paid: 29.99,
|
||||
notes: "Heard it's much better now after patches. Need to start this.",
|
||||
date_added: 5.days.ago
|
||||
},
|
||||
{
|
||||
title: "GoldenEye 007",
|
||||
platform: n64,
|
||||
genres: [ fps, action ],
|
||||
collections: [ nintendo_collection, n64_collection ],
|
||||
format: "physical",
|
||||
condition: "loose",
|
||||
completion_status: "completed",
|
||||
user_rating: 4,
|
||||
price_paid: 35.00,
|
||||
location: "Shelf A - Row 2",
|
||||
notes: "Classic multiplayer. Still fun with friends.",
|
||||
date_added: 40.days.ago
|
||||
},
|
||||
{
|
||||
title: "Stardew Valley",
|
||||
platform: switch,
|
||||
genres: [ simulation ],
|
||||
collections: [ nintendo_collection ],
|
||||
format: "digital",
|
||||
digital_store: "Nintendo eShop",
|
||||
completion_status: "currently_playing",
|
||||
user_rating: 5,
|
||||
price_paid: 14.99,
|
||||
notes: "Perfect game for relaxing. Over 100 hours in!",
|
||||
date_added: 55.days.ago
|
||||
}
|
||||
]
|
||||
|
||||
sample_games.each do |game_data|
|
||||
game = demo_user.games.create!(
|
||||
title: game_data[:title],
|
||||
platform: game_data[:platform],
|
||||
format: game_data[:format],
|
||||
condition: game_data[:condition],
|
||||
completion_status: game_data[:completion_status],
|
||||
user_rating: game_data[:user_rating],
|
||||
price_paid: game_data[:price_paid],
|
||||
location: game_data[:location],
|
||||
digital_store: game_data[:digital_store],
|
||||
notes: game_data[:notes],
|
||||
date_added: game_data[:date_added] || Date.current
|
||||
)
|
||||
|
||||
game.genres = game_data[:genres] if game_data[:genres]
|
||||
game.collections = game_data[:collections] if game_data[:collections]
|
||||
end
|
||||
|
||||
puts " ✓ Created #{demo_user.games.count} sample games"
|
||||
puts " ✓ Games organized into collections"
|
||||
else
|
||||
puts " ✓ Demo user already has #{demo_user.games.count} games"
|
||||
end
|
||||
|
||||
puts "\n" + "="*60
|
||||
puts "Demo Account Ready!"
|
||||
puts "="*60
|
||||
puts "Email: demo@turbovault.com"
|
||||
puts "Password: password123"
|
||||
puts ""
|
||||
puts "Quick Login: http://localhost:3000/login"
|
||||
puts "="*60
|
||||
end
|
||||
|
||||
puts "Seeding completed!"
|
||||
puts "- #{Platform.count} platforms"
|
||||
puts "- #{Genre.count} genres"
|
||||
|
||||
# Seed IGDB Platform Mappings
|
||||
puts "\nSeeding IGDB platform mappings..."
|
||||
IgdbPlatformMapping.seed_common_mappings!
|
||||
puts " ✓ Created #{IgdbPlatformMapping.count} platform mappings"
|
||||
Reference in New Issue
Block a user