goated projects api

This commit is contained in:
Echo
2025-07-14 11:07:21 -04:00
parent 633eb4a5ce
commit 3742942f0e
2 changed files with 75 additions and 12 deletions

View File

@@ -1,6 +1,6 @@
class Api::V1::StatsController < ApplicationController
before_action :ensure_authenticated!, only: [ :show ], unless: -> { Rails.env.development? }
before_action :set_user, only: [ :user_stats, :user_spans, :trust_factor, :user_projects, :user_project ]
before_action :set_user, only: [ :user_stats, :user_spans, :trust_factor, :user_projects, :user_project, :user_projects_details ]
def show
# take either user_id with a start date & end date
@@ -127,19 +127,33 @@ class Api::V1::StatsController < ApplicationController
project_name = params[:project_name]
return render json: { error: "whats the name?" }, status: :bad_request unless project_name.present?
heartbeats = @user.heartbeats.where(project: project_name)
return render json: { error: "found nuthin" }, status: :not_found if heartbeats.empty?
project_data = get_project([ project_name ]).first
return render json: { error: "found nuthin" }, status: :not_found unless project_data
repo_url = nil
last_commit = nil
languages = heartbeats.where.not(language: [ nil, "" ]).distinct.pluck(:language)
render json: project_data
end
render json: {
project: project_name,
repo_url: repo_url,
last_commit: last_commit,
languages: languages
}
def user_projects_details
return render json: { error: "User not found" }, status: :not_found unless @user
names = if params[:projects].present?
params[:projects].split(",").map(&:strip)
else
since = params[:since]&.to_datetime || 30.days.ago.beginning_of_day
until_date = params[:until]&.to_datetime || Time.current
@user.heartbeats
.where(time: since..until_date)
.where.not(project: [ nil, "" ])
.select(:project)
.distinct
.pluck(:project)
end
return render json: { projects: [] } if names.empty?
data = get_project(names)
render json: { projects: data }
end
private
@@ -183,4 +197,52 @@ class Api::V1::StatsController < ApplicationController
slack_id
end
def get_project(names)
start_date = params[:start_date]&.to_datetime || 1.year.ago
end_date = params[:end_date]&.to_datetime || Time.current
query = @user.heartbeats
.where(time: start_date..end_date)
.where(project: names)
return [] if query.empty?
stats = query
.group(:project)
.select("project,
COUNT(*) as heartbeat_count,
MIN(time) as first_heartbeat,
MAX(time) as last_heartbeat")
data = []
names.each do |name|
heartbeats = query.where(project: name)
next if heartbeats.empty?
seconds = heartbeats.duration_seconds || 0
stat = stats.find { |p| p.project == name }
languages = heartbeats
.where.not(language: [ nil, "" ])
.select(:language)
.distinct
.pluck(:language)
repo = @user.project_repo_mappings.find_by(project_name: name)
data << {
name: name,
total_seconds: seconds,
languages: languages,
repo_url: repo&.repo_url,
total_heartbeats: stat&.heartbeat_count || 0,
first_heartbeat: stat&.first_heartbeat ? Time.at(stat.first_heartbeat).strftime("%Y-%m-%dT%H:%M:%SZ") : nil,
last_heartbeat: stat&.last_heartbeat ? Time.at(stat.last_heartbeat).strftime("%Y-%m-%dT%H:%M:%SZ") : nil
}
end
data.sort_by { |project| -project[:total_seconds] }
end
end

View File

@@ -131,6 +131,7 @@ Rails.application.routes.draw do
get "users/:username/trust_factor", to: "stats#trust_factor"
get "users/:username/projects", to: "stats#user_projects"
get "users/:username/project/:project_name", to: "stats#user_project"
get "users/:username/projects/details", to: "stats#user_projects_details"
get "users/lookup_email/:email", to: "users#lookup_email", constraints: { email: /[^\/]+/ }
get "users/lookup_slack_uid/:slack_uid", to: "users#lookup_slack_uid"