Files
aperonight/AGENT.md
kbe 4e2445198f feat: Implement complete event ticketing system with Stripe integration and email confirmations
- Enhanced events index page with improved visual design and better information display
- Completely redesigned event show page with modern layout, ticket selection, and checkout functionality
- Implemented Stripe payment processing for ticket purchases
- Created ticket generation system with PDF tickets and QR codes
- Added email confirmation system with ticket attachments
- Updated database configuration to use SQLite for easier development setup
- Fixed gem dependencies and resolved conflicts
- Improved error handling throughout the checkout process
- Enhanced Stimulus controller for ticket cart management
- Added proper redirect handling for successful and cancelled payments
2025-08-28 18:08:05 +02:00

267 lines
8.8 KiB
Markdown
Executable File

# Aperonight - Technical Documentation for AI Agents
## 🤖 Agent Implementation Guide
This document provides technical details for AI agents working on the Aperonight ticket selling system.
## 🏗️ System Architecture
### Core Components
#### 1. User Management (`app/models/user.rb`)
- **Devise Integration**: Complete authentication system with registration, login, password reset
- **Relationships**: Users can create events and purchase tickets
- **Validations**: Email format, password strength, optional name fields
#### 2. Event System (`app/models/event.rb`)
- **States**: `draft`, `published`, `canceled`, `sold_out` with enum management
- **Geographic Data**: Latitude/longitude for venue mapping
- **Relationships**: Belongs to user, has many ticket types and tickets through ticket types
- **Scopes**: Featured events, published events, upcoming events with proper ordering
#### 3. Ticket Management
- **TicketType** (`app/models/ticket_type.rb`): Defines ticket categories with pricing, quantity, sale periods
- **Ticket** (`app/models/ticket.rb`): Individual tickets with unique QR codes, status tracking, price storage
#### 4. Payment Processing (`app/controllers/events_controller.rb`)
- **Stripe Integration**: Complete checkout session creation and payment confirmation
- **Session Management**: Proper handling of payment success/failure with ticket generation
- **Security**: Authentication required, cart validation, availability checking
### Database Schema Key Points
```sql
-- Users table (managed by Devise)
CREATE TABLE users (
id bigint PRIMARY KEY,
email varchar(255) UNIQUE NOT NULL,
encrypted_password varchar(255) NOT NULL,
first_name varchar(255),
last_name varchar(255),
-- Devise fields: confirmation, reset tokens, etc.
);
-- Events table
CREATE TABLE events (
id bigint PRIMARY KEY,
user_id bigint REFERENCES users(id),
name varchar(100) NOT NULL,
slug varchar(100) NOT NULL,
description text(1000) NOT NULL,
venue_name varchar(100) NOT NULL,
venue_address varchar(200) NOT NULL,
latitude decimal(10,8) NOT NULL,
longitude decimal(11,8) NOT NULL,
start_time datetime NOT NULL,
end_time datetime,
state integer DEFAULT 0, -- enum: draft=0, published=1, canceled=2, sold_out=3
featured boolean DEFAULT false,
image varchar(500)
);
-- Ticket types define pricing and availability
CREATE TABLE ticket_types (
id bigint PRIMARY KEY,
event_id bigint REFERENCES events(id),
name varchar(255) NOT NULL,
description text,
price_cents integer NOT NULL,
quantity integer NOT NULL,
sale_start_at datetime,
sale_end_at datetime,
requires_id boolean DEFAULT false,
minimum_age integer
);
-- Individual tickets with QR codes
CREATE TABLE tickets (
id bigint PRIMARY KEY,
user_id bigint REFERENCES users(id),
ticket_type_id bigint REFERENCES ticket_types(id),
qr_code varchar(255) UNIQUE NOT NULL,
price_cents integer NOT NULL,
status varchar(255) DEFAULT 'active' -- active, used, expired, refunded
);
```
## 🎯 Key Implementation Details
### 1. Dashboard Metrics (`app/controllers/pages_controller.rb`)
```ruby
# User-specific metrics with optimized queries
@booked_events = current_user.tickets
.joins(:ticket_type, :event)
.where(events: { state: :published })
.count
# Event counts for different timeframes
@events_today = Event.published
.where("DATE(start_time) = ?", Date.current)
.count
# User's actual booked events (not just count)
@user_booked_events = Event.joins(ticket_types: :tickets)
.where(tickets: { user: current_user, status: 'active' })
.distinct
.limit(5)
```
### 2. Stripe Payment Flow
#### Checkout Initiation (`events#checkout`)
1. **Cart Validation**: Parse JSON cart data, validate ticket types and quantities
2. **Availability Check**: Ensure sufficient tickets available before payment
3. **Stripe Session**: Create checkout session with line items, success/cancel URLs
4. **Metadata Storage**: Store order details in Stripe session metadata for later retrieval
```ruby
# Key Stripe configuration
session = Stripe::Checkout::Session.create({
payment_method_types: ['card'],
line_items: line_items,
mode: 'payment',
success_url: payment_success_url(event_id: @event.id, session_id: '{CHECKOUT_SESSION_ID}'),
cancel_url: event_url(@event.slug, @event),
customer_email: current_user.email,
metadata: {
event_id: @event.id,
user_id: current_user.id,
order_items: order_items.to_json
}
})
```
#### Payment Confirmation (`events#payment_success`)
1. **Session Retrieval**: Get Stripe session with payment status
2. **Ticket Creation**: Generate tickets based on order items from metadata
3. **QR Code Generation**: Automatic unique QR code creation via model callbacks
4. **Success Page**: Display tickets with download links
### 3. PDF Ticket Generation (`app/services/ticket_pdf_generator.rb`)
```ruby
class TicketPdfGenerator
def generate
Prawn::Document.new(page_size: [350, 600], margin: 20) do |pdf|
# Header with branding
pdf.fill_color "2D1B69"
pdf.font "Helvetica", style: :bold, size: 24
pdf.text "ApéroNight", align: :center
# Event details
pdf.text ticket.event.name, align: :center
# QR Code generation
qr_code_data = {
ticket_id: ticket.id,
qr_code: ticket.qr_code,
event_id: ticket.event.id,
user_id: ticket.user.id
}.to_json
qrcode = RQRCode::QRCode.new(qr_code_data)
pdf.print_qr_code(qrcode, extent: 120, align: :center)
end.render
end
end
```
### 4. Frontend Cart Management (`app/javascript/controllers/ticket_cart_controller.js`)
- **Stimulus Controller**: Manages cart state and interactions
- **Authentication Check**: Validates user login before checkout
- **Session Storage**: Preserves cart when redirecting to login
- **Dynamic Updates**: Real-time cart total and ticket count updates
## 🔧 Development Patterns
### Model Validations
```ruby
# Event validations
validates :name, presence: true, length: { minimum: 3, maximum: 100 }
validates :latitude, numericality: {
greater_than_or_equal_to: -90,
less_than_or_equal_to: 90
}
# Ticket QR code generation
before_validation :generate_qr_code, on: :create
def generate_qr_code
loop do
self.qr_code = SecureRandom.uuid
break unless Ticket.exists?(qr_code: qr_code)
end
end
```
### Controller Patterns
```ruby
# Authentication for sensitive actions
before_action :authenticate_user!, only: [:checkout, :payment_success, :download_ticket]
# Strong parameters
private
def event_params
params.require(:event).permit(:name, :description, :venue_name, :venue_address,
:latitude, :longitude, :start_time, :image)
end
```
### View Helpers and Partials
- **Metric Cards**: Reusable component for dashboard statistics
- **Event Items**: Consistent event display across pages
- **Flash Messages**: Centralized notification system
## 🚀 Deployment Considerations
### Environment Variables
```bash
# Required for production
STRIPE_PUBLISHABLE_KEY=pk_live_...
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
DATABASE_URL=mysql2://user:pass@host/db
RAILS_MASTER_KEY=...
```
### Database Indexes
```sql
-- Performance indexes for common queries
CREATE INDEX idx_events_published_start_time ON events (state, start_time);
CREATE INDEX idx_tickets_user_status ON tickets (user_id, status);
CREATE INDEX idx_ticket_types_event ON ticket_types (event_id);
```
### Security Considerations
- **CSRF Protection**: Rails default protection enabled
- **Strong Parameters**: All user inputs filtered
- **Authentication**: Devise handles session security
- **Payment Security**: Stripe handles sensitive payment data
## 🧪 Testing Strategy
### Key Test Cases
1. **User Authentication**: Registration, login, logout flows
2. **Event Creation**: Validation, state management, relationships
3. **Booking Process**: Cart validation, payment processing, ticket generation
4. **PDF Generation**: QR code uniqueness, ticket format
5. **Dashboard Metrics**: Query accuracy, performance
### Seed Data Structure
```ruby
# Creates test users, events, and ticket types
users = User.create!([...])
events = Event.create!([...])
ticket_types = TicketType.create!([...])
```
## 📝 Code Style & Conventions
- **Ruby Style**: Follow Rails conventions and Rubocop rules
- **Database**: Use Rails migrations for all schema changes
- **JavaScript**: Stimulus controllers for interactive behavior
- **CSS**: Tailwind utility classes with custom components
- **Documentation**: Inline comments for complex business logic
This architecture provides a solid foundation for a scalable ticket selling platform with proper separation of concerns, security, and user experience.