develop #3
@@ -1,3 +1,3 @@
|
|||||||
// Entry point for the build script in your package.json
|
// Entry point for the build script in your package.json
|
||||||
import "@hotwired/turbo-rails"
|
import "@hotwired/turbo-rails";
|
||||||
import "./controllers"
|
import "./controllers";
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
import { Application } from "@hotwired/stimulus"
|
import { Application } from "@hotwired/stimulus";
|
||||||
|
import Alpine from "alpinejs";
|
||||||
|
|
||||||
const application = Application.start()
|
const application = Application.start();
|
||||||
|
|
||||||
// Configure Stimulus development experience
|
// Configure Stimulus development experience
|
||||||
application.debug = false
|
application.debug = false;
|
||||||
window.Stimulus = application
|
window.Stimulus = application;
|
||||||
|
|
||||||
export { application }
|
// Configure and load Alpine
|
||||||
|
window.Alpine = Alpine;
|
||||||
|
Alpine.start();
|
||||||
|
|
||||||
|
export { application };
|
||||||
|
|||||||
8
app/models/ticket.rb
Normal file
8
app/models/ticket.rb
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
class Ticket < ApplicationRecord
|
||||||
|
# Validations
|
||||||
|
validates :qr_code, presence: true, uniqueness: true
|
||||||
|
validates :party_id, presence: true
|
||||||
|
validates :user_id, presence: true
|
||||||
|
validates :price_cents, presence: true, numericality: { greater_than: 0 }
|
||||||
|
validates :status, presence: true, inclusion: { in: %w[active used expired refunded] }
|
||||||
|
end
|
||||||
24
app/models/ticket_type.rb
Normal file
24
app/models/ticket_type.rb
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
class TicketType < ApplicationRecord
|
||||||
|
# Associations
|
||||||
|
belongs_to :party
|
||||||
|
has_many :tickets
|
||||||
|
|
||||||
|
# Validations
|
||||||
|
validates :name, presence: true, length: { minimum: 3, maximum: 50 }
|
||||||
|
validates :description, presence: true, length: { minimum: 10, maximum: 500 }
|
||||||
|
validates :price_cents, presence: true, numericality: { greater_than: 0 }
|
||||||
|
validates :quantity, presence: true, numericality: { only_integer: true, greater_than: 0 }
|
||||||
|
validates :party_id, presence: true
|
||||||
|
validates :sale_start_at, presence: true
|
||||||
|
validates :sale_end_at, presence: true
|
||||||
|
validate :sale_end_after_start
|
||||||
|
validates :requires_id, inclusion: { in: [true, false] }
|
||||||
|
validates :minimum_age, numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: 120 }, allow_nil: true
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def sale_end_after_start
|
||||||
|
return unless sale_start_at && sale_end_at
|
||||||
|
errors.add(:sale_end_at, "must be after sale start") if sale_end_at <= sale_start_at
|
||||||
|
end
|
||||||
|
end
|
||||||
17
db/migrate/20250823170408_create_ticket_types.rb
Normal file
17
db/migrate/20250823170408_create_ticket_types.rb
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
class CreateTicketTypes < ActiveRecord::Migration[8.0]
|
||||||
|
def change
|
||||||
|
create_table :ticket_types do |t|
|
||||||
|
t.references :party, null: false, foreign_key: true
|
||||||
|
t.string :name
|
||||||
|
t.text :description
|
||||||
|
t.integer :price_cents
|
||||||
|
t.integer :quantity
|
||||||
|
t.datetime :sale_start_at
|
||||||
|
t.datetime :sale_end_at
|
||||||
|
t.boolean :requires_id
|
||||||
|
t.integer :minimum_age
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
9
db/migrate/20250823171354_create_tickets.rb
Normal file
9
db/migrate/20250823171354_create_tickets.rb
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
class CreateTickets < ActiveRecord::Migration[8.0]
|
||||||
|
def change
|
||||||
|
create_table :tickets do |t|
|
||||||
|
t.string :qr_code
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
25
db/schema.rb
generated
25
db/schema.rb
generated
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[8.0].define(version: 2025_08_23_145902) do
|
ActiveRecord::Schema[8.0].define(version: 2025_08_23_171354) do
|
||||||
create_table "parties", charset: "utf8mb4", collation: "utf8mb4_uca1400_ai_ci", force: :cascade do |t|
|
create_table "parties", charset: "utf8mb4", collation: "utf8mb4_uca1400_ai_ci", force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.text "description", null: false
|
t.text "description", null: false
|
||||||
@@ -27,6 +27,27 @@ ActiveRecord::Schema[8.0].define(version: 2025_08_23_145902) do
|
|||||||
t.index ["state"], name: "index_parties_on_state"
|
t.index ["state"], name: "index_parties_on_state"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "ticket_types", charset: "utf8mb4", collation: "utf8mb4_uca1400_ai_ci", force: :cascade do |t|
|
||||||
|
t.bigint "party_id", null: false
|
||||||
|
t.string "name"
|
||||||
|
t.text "description"
|
||||||
|
t.integer "price_cents"
|
||||||
|
t.integer "quantity"
|
||||||
|
t.datetime "sale_start_at"
|
||||||
|
t.datetime "sale_end_at"
|
||||||
|
t.boolean "requires_id"
|
||||||
|
t.integer "minimum_age"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.index ["party_id"], name: "index_ticket_types_on_party_id"
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "tickets", charset: "utf8mb4", collation: "utf8mb4_uca1400_ai_ci", force: :cascade do |t|
|
||||||
|
t.string "qr_code"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
end
|
||||||
|
|
||||||
create_table "users", charset: "utf8mb4", collation: "utf8mb4_uca1400_ai_ci", force: :cascade do |t|
|
create_table "users", charset: "utf8mb4", collation: "utf8mb4_uca1400_ai_ci", force: :cascade do |t|
|
||||||
t.string "email", default: "", null: false
|
t.string "email", default: "", null: false
|
||||||
t.string "encrypted_password", default: "", null: false
|
t.string "encrypted_password", default: "", null: false
|
||||||
@@ -38,4 +59,6 @@ ActiveRecord::Schema[8.0].define(version: 2025_08_23_145902) do
|
|||||||
t.index ["email"], name: "index_users_on_email", unique: true
|
t.index ["email"], name: "index_users_on_email", unique: true
|
||||||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_foreign_key "ticket_types", "parties"
|
||||||
end
|
end
|
||||||
|
|||||||
21
opencode.json
Normal file
21
opencode.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://opencode.ai/config.json",
|
||||||
|
"provider": {
|
||||||
|
"myprovider": {
|
||||||
|
"npm": "@ai-sdk/openai-compatible",
|
||||||
|
"name": "Scaleway",
|
||||||
|
"options": {
|
||||||
|
"baseURL": "https://api.scaleway.ai/v1",
|
||||||
|
"apiKey": "928c8440-604b-423a-983b-00afd5a1164e"
|
||||||
|
},
|
||||||
|
"models": {
|
||||||
|
"devstral-small-2505": {
|
||||||
|
"name": "Devstral 2505"
|
||||||
|
},
|
||||||
|
"qwen3-coder-30b-a3b-instruct": {
|
||||||
|
"name": "Qwen3 Coder 30b a3b instruct"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
test/fixtures/tickets.yml
vendored
Normal file
7
test/fixtures/tickets.yml
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||||
|
|
||||||
|
one:
|
||||||
|
qr_code: MyString
|
||||||
|
|
||||||
|
two:
|
||||||
|
qr_code: MyString
|
||||||
7
test/models/ticket_test.rb
Normal file
7
test/models/ticket_test.rb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class TicketTest < ActiveSupport::TestCase
|
||||||
|
# test "the truth" do
|
||||||
|
# assert true
|
||||||
|
# end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user