feat: complete promoter payout system implementation
- Add comprehensive payout styling with custom CSS classes for status indicators - Implement payout index and show views with French translations - Add payout migration with proper indexes and defaults - Update database schema with payout-related tables and fields - Add comprehensive seed data for testing payout functionality - Include payout CSS in application stylesheet - Document payout system implementation in AGENT.md - Add payout feature to BACKLOG.md This completes the full promoter payout system allowing event organizers to request and track revenue payouts for completed events. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
117
AGENT.md
117
AGENT.md
@@ -12,22 +12,30 @@ This document provides technical details for AI agents working on the Aperonight
|
||||
- **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
|
||||
- **Promoter System**: Professional accounts can create and manage events with Stripe integration
|
||||
|
||||
#### 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
|
||||
- **Payout Management**: Event-level payout tracking and status management
|
||||
|
||||
#### 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
|
||||
- **Order System** (`app/models/order.rb`): Groups tickets into orders with payment status tracking
|
||||
|
||||
#### 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
|
||||
|
||||
#### 5. Financial System
|
||||
- **Earnings** (`app/models/earning.rb`): Tracks revenue from paid orders, excluding refunded tickets
|
||||
- **Payouts** (`app/models/payout.rb`): Manages promoter payout requests and processing
|
||||
- **Platform Fees**: €0.50 fixed fee + 1.5% of ticket price, per ticket
|
||||
|
||||
### Database Schema Key Points
|
||||
|
||||
```sql
|
||||
@@ -38,6 +46,8 @@ CREATE TABLE users (
|
||||
encrypted_password varchar(255) NOT NULL,
|
||||
first_name varchar(255),
|
||||
last_name varchar(255),
|
||||
is_professionnal boolean DEFAULT false, -- Professional account flag
|
||||
stripe_connected_account_id varchar(255), -- Stripe Connect account for payouts
|
||||
-- Devise fields: confirmation, reset tokens, etc.
|
||||
);
|
||||
|
||||
@@ -55,6 +65,8 @@ CREATE TABLE events (
|
||||
start_time datetime NOT NULL,
|
||||
end_time datetime,
|
||||
state integer DEFAULT 0, -- enum: draft=0, published=1, canceled=2, sold_out=3
|
||||
payout_status integer, -- enum: not_requested=0, requested=1, processing=2, completed=3, failed=4
|
||||
payout_requested_at datetime,
|
||||
featured boolean DEFAULT false,
|
||||
image varchar(500)
|
||||
);
|
||||
@@ -73,14 +85,53 @@ CREATE TABLE ticket_types (
|
||||
minimum_age integer
|
||||
);
|
||||
|
||||
-- Orders group tickets and track payment status
|
||||
CREATE TABLE orders (
|
||||
id bigint PRIMARY KEY,
|
||||
user_id bigint REFERENCES users(id),
|
||||
event_id bigint REFERENCES events(id),
|
||||
status varchar(255) DEFAULT 'draft', -- draft, pending_payment, paid, completed, cancelled, expired
|
||||
total_amount_cents integer DEFAULT 0,
|
||||
payment_attempts integer DEFAULT 0,
|
||||
expires_at datetime,
|
||||
last_payment_attempt_at datetime
|
||||
);
|
||||
|
||||
-- Individual tickets with QR codes
|
||||
CREATE TABLE tickets (
|
||||
id bigint PRIMARY KEY,
|
||||
user_id bigint REFERENCES users(id),
|
||||
order_id bigint REFERENCES orders(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
|
||||
status varchar(255) DEFAULT 'active', -- draft, active, used, expired, refunded
|
||||
first_name varchar(255),
|
||||
last_name varchar(255)
|
||||
);
|
||||
|
||||
-- Earnings track revenue from paid orders
|
||||
CREATE TABLE earnings (
|
||||
id bigint PRIMARY KEY,
|
||||
event_id bigint REFERENCES events(id),
|
||||
user_id bigint REFERENCES users(id),
|
||||
order_id bigint REFERENCES orders(id),
|
||||
amount_cents integer, -- Promoter payout amount (after fees)
|
||||
fee_cents integer, -- Platform fees
|
||||
status integer DEFAULT 0, -- enum: pending=0, paid=1
|
||||
stripe_payout_id varchar(255)
|
||||
);
|
||||
|
||||
-- Payouts track promoter payout requests
|
||||
CREATE TABLE payouts (
|
||||
id bigint PRIMARY KEY,
|
||||
user_id bigint REFERENCES users(id),
|
||||
event_id bigint REFERENCES events(id),
|
||||
amount_cents integer NOT NULL, -- Gross amount
|
||||
fee_cents integer NOT NULL DEFAULT 0, -- Platform fees
|
||||
status integer DEFAULT 0, -- enum: pending=0, processing=1, completed=2, failed=3
|
||||
stripe_payout_id varchar(255),
|
||||
total_orders_count integer DEFAULT 0,
|
||||
refunded_orders_count integer DEFAULT 0
|
||||
);
|
||||
```
|
||||
|
||||
@@ -137,6 +188,7 @@ session = Stripe::Checkout::Session.create({
|
||||
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
|
||||
5. **Earnings Creation**: Automatically creates earnings records for promoter payout tracking
|
||||
|
||||
### 3. PDF Ticket Generation (`app/services/ticket_pdf_generator.rb`)
|
||||
|
||||
@@ -174,6 +226,61 @@ end
|
||||
- **Session Storage**: Preserves cart when redirecting to login
|
||||
- **Dynamic Updates**: Real-time cart total and ticket count updates
|
||||
|
||||
## 🔄 Application Workflows
|
||||
|
||||
### 1. User Registration & Onboarding
|
||||
1. User registers with email/password
|
||||
2. Completes onboarding process to set up profile
|
||||
3. Can browse and purchase tickets as a customer
|
||||
|
||||
### 2. Promoter Account Setup
|
||||
1. User requests professional account status
|
||||
2. Connects Stripe account for payment processing
|
||||
3. Can create and manage events
|
||||
|
||||
### 3. Event Creation & Management
|
||||
1. Promoter creates event in draft state
|
||||
2. Adds ticket types with pricing and quantities
|
||||
3. Publishes event to make it publicly available
|
||||
4. Manages event status (publish/unpublish/cancel)
|
||||
|
||||
### 4. Ticket Purchase Flow
|
||||
1. User adds tickets to cart
|
||||
2. Proceeds to checkout with Stripe
|
||||
3. Payment processing through Stripe
|
||||
4. Order and ticket creation upon successful payment
|
||||
5. Email confirmation sent to user
|
||||
6. Automatic earnings record creation for promoter
|
||||
|
||||
### 5. Financial Workflows
|
||||
|
||||
#### Platform Fee Structure
|
||||
- **Fixed Fee**: €0.50 per ticket
|
||||
- **Percentage Fee**: 1.5% of ticket price per ticket
|
||||
- **Calculation Example**:
|
||||
- 1 ticket at €20.00: €0.50 + (€20.00 × 1.5%) = €0.50 + €0.30 = €0.80 total fees
|
||||
- 3 tickets at €25.00 each: (3 × €0.50) + (3 × €25.00 × 1.5%) = €1.50 + €1.13 = €2.63 total fees
|
||||
|
||||
#### Earnings Tracking
|
||||
1. When order is marked as paid, earnings record is automatically created
|
||||
2. Earnings amount = Total ticket sales - Platform fees
|
||||
3. Only non-refunded tickets are counted in earnings
|
||||
4. Earnings remain in "pending" status until payout is requested
|
||||
|
||||
#### Payout Request Process
|
||||
1. Event ends (current time >= event end_time)
|
||||
2. Promoter requests payout through event management interface
|
||||
3. System calculates total earnings for the event (excluding refunded tickets)
|
||||
4. Creates payout record with gross amount, fees, and net amount
|
||||
5. Updates event payout status to "requested"
|
||||
6. Admin processes payout through Stripe
|
||||
7. Payout status updated to "processing" then "completed" or "failed"
|
||||
|
||||
### 6. Refund Management
|
||||
1. Tickets can be marked as refunded
|
||||
2. Refunded tickets are excluded from earnings calculations
|
||||
3. Promoters do not receive payouts for refunded tickets
|
||||
|
||||
## 🔧 Development Patterns
|
||||
|
||||
### Model Validations
|
||||
@@ -231,6 +338,8 @@ RAILS_MASTER_KEY=...
|
||||
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);
|
||||
CREATE INDEX idx_orders_event_status ON orders (event_id, status);
|
||||
CREATE INDEX idx_earnings_event_status ON earnings (event_id, status);
|
||||
```
|
||||
|
||||
### Security Considerations
|
||||
@@ -238,6 +347,7 @@ CREATE INDEX idx_ticket_types_event ON ticket_types (event_id);
|
||||
- **Strong Parameters**: All user inputs filtered
|
||||
- **Authentication**: Devise handles session security
|
||||
- **Payment Security**: Stripe handles sensitive payment data
|
||||
- **Authorization**: Proper access controls for promoter vs customer actions
|
||||
|
||||
## 🧪 Testing Strategy
|
||||
|
||||
@@ -247,6 +357,7 @@ CREATE INDEX idx_ticket_types_event ON ticket_types (event_id);
|
||||
3. **Booking Process**: Cart validation, payment processing, ticket generation
|
||||
4. **PDF Generation**: QR code uniqueness, ticket format
|
||||
5. **Dashboard Metrics**: Query accuracy, performance
|
||||
6. **Financial Workflows**: Fee calculations, payout processing, refund handling
|
||||
|
||||
### Seed Data Structure
|
||||
```ruby
|
||||
@@ -279,7 +390,7 @@ ast-grep --pattern 'find_by_$FIELD($VALUE)' --rewrite 'find_by($FIELD: $VALUE)'
|
||||
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
|
||||
ast-grep --pattern 'old_method_name($$ARGS)' --rewrite 'new_method_name($$ARGS)' --lang ruby --update-all
|
||||
```
|
||||
|
||||
#### Best Practices:
|
||||
|
||||
Reference in New Issue
Block a user