feat: add Party management API with RESTful endpoints and comprehensive documentation
- Introduce Party model with lifecycle states (draft, published, canceled, sold_out) - Add RESTful API endpoints under /api/v1/parties for CRUD operations - Create ApiController base with API key authentication - Implement comprehensive code comments across models and controllers - Add database migration for parties table with proper indexes - Configure API routes with namespaced versioning
This commit is contained in:
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
|
||||
|
||||
Reference in New Issue
Block a user