Skip to content

Commit

Permalink
integrate panko serializers, change APi for using panko serializers
Browse files Browse the repository at this point in the history
  • Loading branch information
kortirso committed Jul 10, 2024
1 parent c974318 commit 004a1a3
Show file tree
Hide file tree
Showing 22 changed files with 175 additions and 204 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ gem 'emailbutler'

# api serializer
gem 'jsonapi-serializer', '2.2.0'
gem 'oj'
gem 'panko_serializer'

# notification layer
gem 'active_delivery'
Expand Down
7 changes: 7 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,12 @@ GEM
racc (~> 1.4)
nokogiri (1.16.6-x86_64-linux)
racc (~> 1.4)
oj (3.16.4)
bigdecimal (>= 3.0)
pagy (8.6.3)
panko_serializer (0.8.1)
activesupport
oj (> 3.11.0, < 4.0.0)
parallel (1.25.1)
parser (3.3.3.0)
ast (~> 2.4.1)
Expand Down Expand Up @@ -527,7 +532,9 @@ DEPENDENCIES
jwt (~> 2.5)
kudos
letter_opener
oj
pagy (~> 8.0)
panko_serializer
pg (~> 1.4)
pghero
prawn
Expand Down
33 changes: 17 additions & 16 deletions app/controllers/api/frontend/insights_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class InsightsController < Api::Frontend::BaseController

def index
respond_to do |format|
format.json { render json: json_response, status: :ok }
format.json { render json: Panko::Response.new(json_response), status: :ok }
format.pdf { send_data pdf_response, type: 'application/pdf', filename: 'insights.pdf' }
end
end
Expand All @@ -16,33 +16,34 @@ def index

def json_response
{
insights: insights_json,
insights: insights,
insight_fields: insight_fields,
ratio_type: ratio_enabled? ? ratio_type : nil
}.compact
}
end

def pdf_response
Reports::Insights::Pdf.new(
page_size: Reports::Insights::Pdf::PAGE_SIZE,
page_layout: Reports::Insights::Pdf::PAGE_LAYOUT
).to_pdf(
insights: insights_json,
insights: JSON.parse(insights.to_json),
insight_fields: insight_fields
)
end

def insights_json
InsightSerializer.new(
actual_insights,
{
params: {
previous_insights: previous_insights,
insight_fields: insight_fields,
ratio_enabled: ratio_enabled?,
ratio_type: ratio_type
}
}
).serializable_hash
def insights
Panko::ArraySerializer.new(
actual_insights,
each_serializer: InsightSerializer,
only: %i[id values entity],
context: {
previous_insights: previous_insights,
insight_fields: insight_fields,
ratio_enabled: ratio_enabled?,
ratio_type: ratio_type
}
)
end

def find_insightable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,29 @@ class RepositoryInsightsController < Api::Frontend::BaseController
before_action :find_repository

def index
render json: {
insights: InsightSerializer.new(
actual_insights,
{
params: {
previous_insights: previous_insights,
insight_fields: ::Repositories::Insight::DEFAULT_ATTRIBUTES,
ratio_enabled: ratio_enabled?,
ratio_type: ratio_type,
no_entity: true
}
}
).serializable_hash,
ratio_type: ratio_enabled? ? ratio_type : nil
}.compact, status: :ok
render json: Panko::Response.create { |response| json_response(response) }, status: :ok
end

private

def json_response(response)
{
insight: response.serializer(
actual_insight,
InsightSerializer,
only: %i[id values entity],
context: {
previous_insights: previous_insights,
insight_fields: ::Repositories::Insight::DEFAULT_ATTRIBUTES,
ratio_enabled: ratio_enabled?,
ratio_type: ratio_type,
no_entity: true
}
),
ratio_type: ratio_enabled? ? ratio_type : nil
}
end

def find_repository
@repository = authorized_scope(Repository.order(id: :desc)).find_by!(uuid: params[:repository_id])
end
Expand All @@ -34,7 +38,7 @@ def visible_insights
@visible_insights ||= @repository.repository_insights.to_a
end

def actual_insights
def actual_insight
visible_insights.find(&:actual?)
end

Expand Down
13 changes: 8 additions & 5 deletions app/controllers/api/v1/companies_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ class CompaniesController < Api::V1Controller
SERIALIZER_FIELDS = %w[title repositories_count accessable].freeze

def index
render json: { companies: companies }, status: :ok
render json: Panko::Response.new(
companies: Panko::ArraySerializer.new(
companies,
each_serializer: CompanySerializer,
**serializer_fields(CompanySerializer, SERIALIZER_FIELDS)
)
)
end

private

def companies
CompanySerializer.new(
current_user.available_companies.order(id: :desc),
params: serializer_fields(CompanySerializer, SERIALIZER_FIELDS)
).serializable_hash
current_user.available_companies.order(id: :desc)
end
end
end
Expand Down
30 changes: 17 additions & 13 deletions app/controllers/api/v1/insights_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,28 @@ class InsightsController < Api::V1Controller
before_action :find_insightable

def index
render json: {
insights: InsightSerializer.new(
render json: Panko::Response.new(json_response), status: :ok
end

private

def json_response
{
insights: Panko::ArraySerializer.new(
actual_insights,
{
params: {
previous_insights: previous_insights,
insight_fields: insight_fields,
ratio_enabled: ratio_enabled?,
ratio_type: ratio_type
}
each_serializer: InsightSerializer,
only: %i[id values entity],
context: {
previous_insights: previous_insights,
insight_fields: insight_fields,
ratio_enabled: ratio_enabled?,
ratio_type: ratio_type
}
).serializable_hash,
),
ratio_type: ratio_enabled? ? ratio_type : nil
}.compact, status: :ok
}
end

private

def find_insightable
find_company if params[:company_id]
find_repository if params[:repository_id]
Expand Down
18 changes: 9 additions & 9 deletions app/controllers/api/v1_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@ def set_current_user
end

def serializer_fields(serializer_class, default_include_fields=[], forbidden_fields=[])
@serializer_attributes = serializer_class.attributes_to_serialize.keys.map(&:to_s)
return {} if response_include_fields.any? && response_exclude_fields.any?
return { include_fields: response_include_fields - forbidden_fields } if response_include_fields.any?
return { exclude_fields: response_exclude_fields + forbidden_fields } if response_exclude_fields.any?
@serializer_attributes = serializer_class::ATTRIBUTES
return {} if response_only_fields.any? && response_except_fields.any?
return { only: (response_only_fields - forbidden_fields).map(&:to_sym) } if response_only_fields.any?
return { except: (response_except_fields + forbidden_fields).map(&:to_sym) } if response_except_fields.any?

{ include_fields: default_include_fields }
{ only: default_include_fields.map(&:to_sym) }
end

def response_include_fields
@response_include_fields ||= params[:response_include_fields]&.split(',').to_a & @serializer_attributes
def response_only_fields
@response_only_fields ||= params[:response_only_fields]&.split(',').to_a & @serializer_attributes
end

def response_exclude_fields
@response_exclude_fields ||= params[:response_exclude_fields]&.split(',').to_a & @serializer_attributes
def response_except_fields
@response_except_fields ||= params[:response_except_fields]&.split(',').to_a & @serializer_attributes
end

def authentication_error
Expand Down
8 changes: 3 additions & 5 deletions app/javascript/components/Company/Company.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,11 @@ export const Company = ({
const fetchInsights = async () => await insightsRequest(uuid);

Promise.all([fetchInsights()]).then(([insightsData]) => {
const insightTypes = insightsData.data.length > 0 ? Object.keys(insightsData.data[0].values) : [];
const ratioType = insightsData.ratioType || null;
setPageState({
...pageState,
entities: insightsData.data,
insightTypes: insightTypes,
ratioType: ratioType,
entities: insightsData.insights,
insightTypes: insightsData.insight_fields,
ratioType: insightsData.ratio_type,
});
});
}, [pageState, uuid]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,5 @@ export const insightsRequest = async (companyUuid) => {
const result = await apiRequest({
url: `/api/frontend/companies/${companyUuid}/insights.json`,
});
return {
data: result.insights.data.map((element) => element.attributes),
ratioType: result.insights.ratio_type
};
return result;
};
11 changes: 4 additions & 7 deletions app/javascript/components/Repository/Repository.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,12 @@ export const Repository = ({

Promise.all([fetchInsights(), fetchRepositoryInsights()]).then(
([insightsData, repositoryInsightsData]) => {
const insightTypes = insightsData.data.length > 0 ? Object.keys(insightsData.data[0].values) : [];
const ratioType = insightsData.ratioType || null;
setPageState({
...pageState,
entities: insightsData.data,
insights:
Object.keys(repositoryInsightsData).length === 0 ? undefined : repositoryInsightsData,
insightTypes: insightTypes,
ratioType: ratioType,
entities: insightsData.insights,
insights: repositoryInsightsData.insight.values,
insightTypes: insightsData.insight_fields,
ratioType: insightsData.ratio_type,
});
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,5 @@ export const insightsRequest = async (repositoryUuid) => {
const result = await apiRequest({
url: `/api/frontend/repositories/${repositoryUuid}/insights.json`,
});
return {
data: result.insights.data.map((element) => element.attributes),
ratioType: result.insights.ratio_type
};
return result;
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export const repositoryInsightsRequest = async (repositoryUuid) => {
const result = await apiRequest({
url: `/api/frontend/repositories/${repositoryUuid}/repository_insights.json`,
});
return result.insights.data?.attributes?.values || {};
return result;
};
11 changes: 3 additions & 8 deletions app/serializers/company_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
# frozen_string_literal: true

class CompanySerializer < ApplicationSerializer
set_id :uuid
class CompanySerializer < PankoApplicationSerializer
ATTRIBUTES = %w[uuid title repositories_count accessable].freeze

attribute :uuid, if: proc { |_, params| required_field?(params, 'uuid') }, &:uuid
attribute :title, if: proc { |_, params| required_field?(params, 'title') }, &:title
# rubocop: disable Layout/LineLength
attribute :repositories_count, if: proc { |_, params| required_field?(params, 'repositories_count') }, &:repositories_count
# rubocop: enable Layout/LineLength
attribute :accessable, if: proc { |_, params| required_field?(params, 'accessable') }, &:accessable
attributes :uuid, :title, :repositories_count, :accessable
end
4 changes: 2 additions & 2 deletions app/serializers/helpers/insight.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ def ratio_value(insight, previous_insight, attribute)

def change_value(insight, previous_insight, insight_field)
method_name = ::Insight::DECIMAL_ATTRIBUTES.include?(insight_field) ? :to_f : :to_i
return insight[attribute].send(method_name) if previous_insight.nil?
return insight[insight_field].send(method_name) if previous_insight.nil?

insight[attribute].send(method_name) - previous_insight[insight_field].send(method_name)
insight[insight_field].send(method_name) - previous_insight[insight_field].send(method_name)
end
end
end
18 changes: 11 additions & 7 deletions app/serializers/insight_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
# frozen_string_literal: true

class InsightSerializer < ApplicationSerializer
extend Helpers::Insight
class InsightSerializer < PankoApplicationSerializer
include Helpers::Insight

attribute :values do |object, params|
params[:insight_fields].index_with do |insight_field|
attributes :id, :values, :entity

def id = SecureRandom.hex

def values
context[:insight_fields].index_with do |insight_field|
value = object[insight_field]
{
value: Insight::DECIMAL_ATTRIBUTES.include?(insight_field.to_sym) ? value.to_f : value,
ratio_value: params[:ratio_enabled] ? compare_with_previous_period(object, insight_field, params) : nil
ratio_value: context[:ratio_enabled] ? compare_with_previous_period(object, insight_field, context) : nil
}.compact
end
end

attribute :entity do |object, params|
params[:no_entity] ? nil : (Rails.cache.read("entity_payload_#{object.entity_id}_v1") || Entity::EMPTY_PAYLOAD)
def entity
context[:no_entity] ? nil : (Rails.cache.read("entity_payload_#{object.entity_id}_v1") || Entity::EMPTY_PAYLOAD)
end
end
4 changes: 4 additions & 0 deletions app/serializers/panko_application_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

class PankoApplicationSerializer < Panko::Serializer
end
Loading

0 comments on commit 004a1a3

Please sign in to comment.