develop #3
51
CRUSH.md
Normal file
51
CRUSH.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Aperonight - CRUSH Development Guidelines
|
||||
|
||||
## Build Commands
|
||||
- `bin/rails server` - Start development server
|
||||
- `bin/rails assets:precompile` - Compile assets
|
||||
- `npm run build` - Build JavaScript bundle (production)
|
||||
- `npm run build:dev` - Build JavaScript bundle (development)
|
||||
- `npm run build:css` - Compile CSS with PostCSS/Tailwind
|
||||
|
||||
## Test Commands
|
||||
- `bin/rails test` - Run all tests
|
||||
- `bin/rails test test/models/user_test.rb` - Run specific test file
|
||||
- `bin/rails test test/models/user_test.rb:15` - Run specific test method
|
||||
- `bin/rails test:system` - Run system tests
|
||||
|
||||
## Lint Commands
|
||||
- `bin/rubocop` - Run Ruby linter
|
||||
- `bin/rubocop -a` - Run Ruby linter with auto-fix
|
||||
- Check JS/JSX files manually (no configured linter)
|
||||
|
||||
## Development Workflow
|
||||
1. Branch naming: `type/descriptive-name` (e.g., `feature/user-profile`)
|
||||
2. Follow Git Flow with `main` and `develop` branches
|
||||
3. Run tests and linters before committing
|
||||
4. Keep PRs focused on single features/fixes
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
### Ruby
|
||||
- Follow Rubocop Rails Omakase defaults
|
||||
- Standard Rails MVC conventions
|
||||
- Use descriptive method and variable names
|
||||
- Prefer single quotes for strings without interpolation
|
||||
|
||||
### JavaScript/React
|
||||
- Use Stimulus controllers for DOM interactions
|
||||
- React components in PascalCase (`UserProfile.jsx`)
|
||||
- Shadcn components in kebab-case (`button.jsx`) but exported as PascalCase
|
||||
- Functional components with hooks over class components
|
||||
|
||||
### CSS/Tailwind
|
||||
- Mobile-first responsive design
|
||||
- Use Tailwind utility classes over custom CSS
|
||||
- Primary color palette: indigo → purple → pink gradients
|
||||
- Consistent spacing with Tailwind's spacing scale
|
||||
|
||||
### General
|
||||
- Keep functions small and focused
|
||||
- Comment complex logic
|
||||
- Use descriptive commit messages
|
||||
- Maintain consistency with existing code patterns
|
||||
82
app/controllers/api/v1/parties_controller.rb
Normal file
82
app/controllers/api/v1/parties_controller.rb
Normal file
@@ -0,0 +1,82 @@
|
||||
# API controller for managing party resources
|
||||
# Provides RESTful endpoints for CRUD operations on Party model
|
||||
module Api
|
||||
module V1
|
||||
class PartiesController < ApiController
|
||||
# Load party before specific actions to reduce duplication
|
||||
before_action :set_party, only: [:show, :update, :destroy]
|
||||
|
||||
# GET /api/v1/parties
|
||||
# Returns all parties sorted by creation date (newest first)
|
||||
def index
|
||||
@parties = Party.all.order(created_at: :desc)
|
||||
render json: @parties, status: :ok
|
||||
end
|
||||
|
||||
# GET /api/v1/parties/:id
|
||||
# Returns a single party by ID
|
||||
# Returns 404 if party is not found
|
||||
def show
|
||||
render json: @party, status: :ok
|
||||
end
|
||||
|
||||
# POST /api/v1/parties
|
||||
# Creates a new party with provided attributes
|
||||
# Returns 201 Created on success with party data
|
||||
# Returns 422 Unprocessable Entity with validation errors on failure
|
||||
def create
|
||||
@party = Party.new(party_params)
|
||||
if @party.save
|
||||
render json: @party, status: :created
|
||||
else
|
||||
render json: { errors: @party.errors.full_messages }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /api/v1/parties/:id
|
||||
# Updates an existing party with provided attributes
|
||||
# Returns 200 OK with updated party data on success
|
||||
# Returns 422 Unprocessable Entity with validation errors on failure
|
||||
def update
|
||||
if @party.update(party_params)
|
||||
render json: @party, status: :ok
|
||||
else
|
||||
render json: { errors: @party.errors.full_messages }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /api/v1/parties/:id
|
||||
# Permanently deletes a party
|
||||
# Returns 204 No Content on success
|
||||
def destroy
|
||||
@party.destroy
|
||||
head :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Finds a party by ID or returns 404 Not Found
|
||||
# Used as before_action for show, update, and destroy actions
|
||||
def set_party
|
||||
@party = Party.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render json: { error: "Party not found" }, status: :not_found
|
||||
end
|
||||
|
||||
# Strong parameters for party creation and updates
|
||||
# Whitelists permitted attributes to prevent mass assignment vulnerabilities
|
||||
def party_params
|
||||
params.require(:party).permit(
|
||||
:name,
|
||||
:description,
|
||||
:state,
|
||||
:venue_name,
|
||||
:venue_address,
|
||||
:latitude,
|
||||
:longitude,
|
||||
:featured
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
app/controllers/api_controller.rb
Normal file
24
app/controllers/api_controller.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
# Base controller for API endpoints
|
||||
# Provides authentication and common functionality for API controllers
|
||||
class ApiController < ApplicationController
|
||||
# Disable CSRF protection for API requests (token-based authentication instead)
|
||||
protect_from_forgery with: :null_session
|
||||
|
||||
# Authenticate all API requests using API key
|
||||
# Must be called before any API action
|
||||
before_action :authenticate_api_key
|
||||
|
||||
private
|
||||
|
||||
# Authenticates API requests using X-API-Key header or api_key parameter
|
||||
# Returns 401 Unauthorized if key is invalid or missing
|
||||
def authenticate_api_key
|
||||
# Extract API key from header or query parameter
|
||||
api_key = request.headers["X-API-Key"] || params[:api_key]
|
||||
|
||||
# Validate against hardcoded key (in production, use environment variable)
|
||||
unless api_key == "aperonight-api-key-2025"
|
||||
render json: { error: "Unauthorized" }, status: :unauthorized
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,16 @@
|
||||
# Base controller for the application
|
||||
# Provides common functionality and security configurations for all controllers
|
||||
class ApplicationController < ActionController::Base
|
||||
# Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
|
||||
# Protect against Cross-Site Request Forgery (CSRF) attacks
|
||||
# Ensures that all non-GET requests include a valid authenticity token
|
||||
protect_from_forgery with: :exception
|
||||
|
||||
# Restrict access to modern browsers only
|
||||
# Requires browsers to support modern web standards:
|
||||
# - WebP images for better compression
|
||||
# - Web Push notifications
|
||||
# - Badge API for notifications
|
||||
# - Import maps for JavaScript modules
|
||||
# - CSS nesting and :has() pseudo-class
|
||||
allow_browser versions: :modern
|
||||
end
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
# Controller for static pages and user dashboard
|
||||
# Handles basic page rendering and user-specific content
|
||||
class PagesController < ApplicationController
|
||||
# Display homepage
|
||||
def home
|
||||
end
|
||||
# Require user authentication for dashboard access
|
||||
# Redirects to login page if user is not signed in
|
||||
before_action :authenticate_user!, only: [:dashboard]
|
||||
|
||||
# Display legal page
|
||||
def legals
|
||||
# User dashboard showing personalized content
|
||||
# Accessible only to authenticated users
|
||||
def dashboard
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Base class for all ActiveRecord models in the application
|
||||
# Provides common functionality and configuration for all models
|
||||
class ApplicationRecord < ActiveRecord::Base
|
||||
# Mark this as the primary abstract class to establish inheritance hierarchy
|
||||
primary_abstract_class
|
||||
end
|
||||
|
||||
40
app/models/party.rb
Normal file
40
app/models/party.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
# Party model representing nightlife events and parties
|
||||
# Manages event details, location data, and publication state
|
||||
class Party < ApplicationRecord
|
||||
# Define states for party lifecycle management
|
||||
# draft: Initial state when party is being created
|
||||
# published: Party is visible to public and can be discovered
|
||||
# canceled: Party has been canceled by organizer
|
||||
# sold_out: Party has reached capacity and tickets are no longer available
|
||||
enum state: {
|
||||
draft: 0,
|
||||
published: 1,
|
||||
canceled: 2,
|
||||
sold_out: 3
|
||||
}, default: :draft
|
||||
|
||||
# Validations for party attributes
|
||||
# Basic information
|
||||
validates :name, presence: true, length: { minimum: 3, maximum: 100 }
|
||||
validates :description, presence: true, length: { minimum: 10, maximum: 1000 }
|
||||
validates :state, presence: true, inclusion: { in: states.keys }
|
||||
|
||||
# Venue information
|
||||
validates :venue_name, presence: true, length: { maximum: 100 }
|
||||
validates :venue_address, presence: true, length: { maximum: 200 }
|
||||
|
||||
# Geographic coordinates for map display
|
||||
validates :latitude, presence: true, numericality: {
|
||||
greater_than_or_equal_to: -90,
|
||||
less_than_or_equal_to: 90
|
||||
}
|
||||
validates :longitude, presence: true, numericality: {
|
||||
greater_than_or_equal_to: -180,
|
||||
less_than_or_equal_to: 180
|
||||
}
|
||||
|
||||
# Scopes for querying parties with common filters
|
||||
scope :featured, -> { where(featured: true) } # Get featured parties for homepage
|
||||
scope :published, -> { where(state: :published) } # Get publicly visible parties
|
||||
scope :search_by_name, ->(query) { where("name ILIKE ?", "%#{query}%") } # Search by name (case-insensitive)
|
||||
end
|
||||
@@ -1,6 +1,21 @@
|
||||
# User model for authentication and user management
|
||||
# Handles user accounts, authentication, and authorization using Devise
|
||||
class User < ApplicationRecord
|
||||
# Include default devise modules. Others available are:
|
||||
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
||||
#
|
||||
# Include default devise modules for authentication
|
||||
# :database_authenticatable - encrypts and stores password in database
|
||||
# :registerable - allows users to sign up and edit their accounts
|
||||
# :recoverable - handles password reset functionality
|
||||
# :rememberable - manages token-based user remembering
|
||||
# :validatable - provides email and password validation
|
||||
# Other available modules are:
|
||||
# :confirmable - requires email confirmation
|
||||
# :lockable - locks account after failed login attempts
|
||||
# :timeoutable - expires sessions after inactivity
|
||||
# :trackable - tracks sign-in count, timestamps, and IP
|
||||
# :omniauthable - allows authentication via OAuth providers
|
||||
devise :database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :validatable
|
||||
end
|
||||
|
||||
@@ -31,4 +31,15 @@ Rails.application.routes.draw do
|
||||
confirmation: "authentications/confirmations" # Custom controller for confirmations
|
||||
}
|
||||
|
||||
# API routes versioning
|
||||
namespace :api do
|
||||
namespace :v1 do
|
||||
# RESTful routes for party management
|
||||
resources :parties, only: [ :index, :show, :create, :update, :destroy ]
|
||||
|
||||
# Additional API endpoints can be added here as needed
|
||||
# Example: search, filtering, user-specific endpoints
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
19
db/migrate/20250823145902_create_parties.rb
Normal file
19
db/migrate/20250823145902_create_parties.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
class CreateParties < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :parties do |t|
|
||||
t.string :name, null: false
|
||||
t.text :description, null: false
|
||||
t.integer :state, default: 0, null: false
|
||||
t.string :venue_name, null: false
|
||||
t.string :venue_address, null: false
|
||||
t.decimal :latitude, precision: 10, scale: 6, null: false
|
||||
t.decimal :longitude, precision: 10, scale: 6, null: false
|
||||
t.boolean :featured, default: false, null: false
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :parties, :state
|
||||
add_index :parties, :featured
|
||||
add_index :parties, [:latitude, :longitude]
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user