Skip to content

Commit 1c24935

Browse files
committed
feat: implement docs and status page
1 parent 8e0bbca commit 1c24935

10 files changed

Lines changed: 1448 additions & 1 deletion

File tree

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# frozen_string_literal: true
2+
3+
class StatusController < ActionController::API
4+
skip_before_action :verify_authenticity_token, raise: false
5+
6+
def index
7+
components = build_component_statuses
8+
overall_indicator, overall_description = overall_status(components)
9+
10+
render json: {
11+
page: {
12+
id: 'prostaff',
13+
name: 'ProStaff',
14+
url: 'https://status.prostaff.gg',
15+
time_zone: 'UTC',
16+
updated_at: Time.current.iso8601
17+
},
18+
status: {
19+
indicator: overall_indicator,
20+
description: overall_description
21+
},
22+
components: components,
23+
incidents: []
24+
}, status: :ok
25+
end
26+
27+
private
28+
29+
def build_component_statuses
30+
[
31+
api_component,
32+
database_component,
33+
redis_component,
34+
websocket_component,
35+
riot_api_component
36+
]
37+
end
38+
39+
def api_component
40+
{
41+
id: 'api',
42+
name: 'API',
43+
status: 'operational',
44+
description: 'Core REST API services',
45+
updated_at: Time.current.iso8601
46+
}
47+
end
48+
49+
def database_component
50+
begin
51+
ActiveRecord::Base.connection.execute('SELECT 1')
52+
status = 'operational'
53+
rescue StandardError => e
54+
Rails.logger.error "Status check DB error: #{e.message}"
55+
status = 'major_outage'
56+
end
57+
58+
{
59+
id: 'database',
60+
name: 'Database',
61+
status: status,
62+
description: 'PostgreSQL primary database',
63+
updated_at: Time.current.iso8601
64+
}
65+
end
66+
67+
def redis_component
68+
begin
69+
redis = Redis.new(url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0'))
70+
redis.ping
71+
status = 'operational'
72+
rescue StandardError => e
73+
Rails.logger.error "Status check Redis error: #{e.message}"
74+
status = 'major_outage'
75+
end
76+
77+
{
78+
id: 'redis',
79+
name: 'Cache & Background Jobs',
80+
status: status,
81+
description: 'Redis cache and Sidekiq queue processor',
82+
updated_at: Time.current.iso8601
83+
}
84+
end
85+
86+
def websocket_component
87+
{
88+
id: 'websocket',
89+
name: 'Real-time (WebSocket)',
90+
status: 'operational',
91+
description: 'ActionCable WebSocket connections',
92+
updated_at: Time.current.iso8601
93+
}
94+
end
95+
96+
def riot_api_component
97+
{
98+
id: 'riot_api',
99+
name: 'Riot API Integration',
100+
status: 'operational',
101+
description: 'Riot Games data synchronization',
102+
updated_at: Time.current.iso8601
103+
}
104+
end
105+
106+
def overall_status(components)
107+
statuses = components.map { |c| c[:status] }
108+
109+
if statuses.any? { |s| s == 'major_outage' }
110+
['major', 'Major System Outage']
111+
elsif statuses.any? { |s| s == 'partial_outage' }
112+
['critical', 'Partial System Outage']
113+
elsif statuses.any? { |s| s == 'degraded_performance' }
114+
['minor', 'Partially Degraded Service']
115+
else
116+
['none', 'All Systems Operational']
117+
end
118+
end
119+
end

config/initializers/cors.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Rails.application.config.middleware.insert_before 0, Rack::Cors do
44
allow do
55
# The fallback (second argument) must be a single string separated by commas
6-
origins ENV.fetch('CORS_ORIGINS', 'http://localhost:5173,http://localhost:8888,https://prostaff.vercel.app,https://prostaff.gg,https://www.prostaff.gg,https://api.prostaff.gg').split(',')
6+
origins ENV.fetch('CORS_ORIGINS', 'http://localhost:5173,http://localhost:8888,https://prostaff.vercel.app,https://prostaff.gg,https://www.prostaff.gg,https://api.prostaff.gg,https://status.prostaff.gg,https://docs.prostaff.gg').split(',')
77

88
resource '*',
99
headers: :any,

config/routes.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
get 'health' => proc { [200, { 'Content-Type' => 'application/json' }, ['{"status":"ok","service":"ProStaff API"}']] }
1919
get 'health/detailed' => 'health#show' # Detailed health with DB check
2020

21+
# Public status page API (used by status.prostaff.gg)
22+
get 'status' => 'status#index'
23+
2124
# SEO - Sitemap
2225
get 'sitemap.xml', to: 'sitemap#index', defaults: { format: 'xml' }
2326

docs-page/Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM nginx:1.25-alpine
2+
3+
# Copy Swagger UI docs page
4+
COPY index.html /usr/share/nginx/html/index.html
5+
6+
# Copy nginx configuration
7+
COPY nginx.conf /etc/nginx/conf.d/default.conf
8+
9+
EXPOSE 80
10+
11+
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
12+
CMD wget -qO- http://localhost/health || exit 1

0 commit comments

Comments
 (0)