Files
aperonight/AGENTS.md
2025-09-29 01:17:26 +02:00

10 KiB
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

-- 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)

# 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
# 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)

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

# 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

# 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

# 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

-- 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

# Creates test users, events, and ticket types
users = User.create!([...])
events = Event.create!([...])
ticket_types = TicketType.create!([...])

🛠️ Available Development Tools

AST-Grep for Mass Code Replacement

The system has ast-grep installed for structural code search and replacement. This tool is particularly useful for:

  • Mass refactoring: Rename methods, classes, or variables across the codebase
  • Pattern-based replacements: Update code patterns using AST matching
  • Language-aware transformations: Safer than regex for code modifications

Usage Examples:

# Find all method calls to a specific method
ast-grep --pattern 'find_by_$FIELD($VALUE)' --lang ruby

# Replace method calls with new syntax
ast-grep --pattern 'find_by_$FIELD($VALUE)' --rewrite 'find_by($FIELD: $VALUE)' --lang ruby

# Search for specific Rails patterns
ast-grep --pattern 'validates :$FIELD, presence: true' --lang ruby

# Mass rename across multiple files
ast-grep --pattern 'old_method_name($$$ARGS)' --rewrite 'new_method_name($$$ARGS)' --lang ruby --update-all

Best Practices:

  • Always run with --dry-run first to preview changes
  • Use --lang ruby for Ruby files to ensure proper AST parsing
  • Test changes in a branch before applying to main codebase
  • Particularly useful for Rails conventions and ActiveRecord pattern updates

📝 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
  • Mass Changes: Use ast-grep for structural code replacements instead of simple find/replace

This architecture provides a solid foundation for a scalable ticket selling platform with proper separation of concerns, security, and user experience.