eivo-rails-api 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/Gemfile +5 -0
  4. data/LICENSE +19 -0
  5. data/README.md +36 -0
  6. data/Rakefile +1 -0
  7. data/app/controllers/eivo/application_controller.rb +33 -0
  8. data/app/controllers/eivo/concerns/exception.rb +23 -0
  9. data/app/controllers/eivo/concerns/pagination.rb +34 -0
  10. data/app/controllers/eivo/concerns/rendering.rb +73 -0
  11. data/app/controllers/eivo/concerns/resource.rb +77 -0
  12. data/app/controllers/eivo/concerns/resources.rb +93 -0
  13. data/app/controllers/eivo/status_controller.rb +11 -0
  14. data/bin/eivo +5 -0
  15. data/config/initializers/sentry.rb +8 -0
  16. data/config/routes.rb +7 -0
  17. data/eivo-rails-api.gemspec +32 -0
  18. data/lib/eivo-rails-api/cli.rb +12 -0
  19. data/lib/eivo-rails-api/engine.rb +9 -0
  20. data/lib/eivo-rails-api/environments/development.rb +54 -0
  21. data/lib/eivo-rails-api/environments/production.rb +79 -0
  22. data/lib/eivo-rails-api/environments/staging.rb +11 -0
  23. data/lib/eivo-rails-api/environments/test.rb +44 -0
  24. data/lib/eivo-rails-api.rb +29 -0
  25. data/lib/generators/eivo/USAGE +3 -0
  26. data/lib/generators/eivo/install_generator.rb +101 -0
  27. data/lib/generators/eivo/templates/.env.example +5 -0
  28. data/lib/generators/eivo/templates/.ruby-version +1 -0
  29. data/lib/generators/eivo/templates/Gemfile +40 -0
  30. data/lib/generators/eivo/templates/Procfile +1 -0
  31. data/lib/generators/eivo/templates/app/controllers/application_controller.rb +2 -0
  32. data/lib/generators/eivo/templates/config/application.rb +16 -0
  33. data/lib/generators/eivo/templates/config/database.example.yml +24 -0
  34. data/lib/generators/eivo/templates/config/puma.rb +30 -0
  35. data/lib/generators/eivo/templates/db/migrate/enable_btree_gin_extension.rb +7 -0
  36. data/lib/generators/eivo/templates/db/migrate/enable_pg_stat_statements_extension.rb +7 -0
  37. data/lib/generators/eivo/templates/db/migrate/enable_pgcrypto_extension.rb +7 -0
  38. data/lib/generators/eivo/templates/db/migrate/enable_unaccent_extension.rb +7 -0
  39. metadata +194 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b7ca7376988bf2e7bd7449c8a267b327f228fcb3
4
+ data.tar.gz: f06a2a177096ce3a994a57d9705c98d3b7670e58
5
+ SHA512:
6
+ metadata.gz: 0949512009b53d64a9d76933fe023b223be8a2e1feeea589f720ed64cb2b1aa721253bfd1d1e5a1a5efec2889587c9c7bd4cddd759cc2f53cb1cc6fde984cb3f
7
+ data.tar.gz: 4675524835f20b9d248ddf31d442fb9dcc13b002afb31177605d68c75db50bd381fd856affacc88980d6d0b5826b970d9ddd808ddbd213f5ea8abc4be7de5b5e
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .DS_Store
2
+ /.bundle/
3
+ /pkg/
4
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2019 Jonathan VUKOVICH-TRIBOUHARET
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # EIVO Rails API
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'eivo-rails-api'
9
+ ```
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install eivo-rails-api -N
18
+
19
+ ## Usage
20
+
21
+ If you don't have a Ruby On Rails project:
22
+
23
+ $ rails new ../example/ -d postgresql --skip-yarn --skip-active-storage --skip-action-cable --skip-sprockets --skip-spring --skip-coffee --skip-javascript --skip-turbolinks --skip-test --skip-system-test --skip-bootsnap --skip-action-mailer --api
24
+
25
+ Then:
26
+
27
+ $ rails g eivo:install
28
+
29
+ Add missing credentials:
30
+
31
+ $ rails credentials:edit
32
+
33
+ ```
34
+ sentry:
35
+ dsn: ""
36
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EIVO
4
+ class ApplicationController < ::ActionController::API
5
+
6
+ include EIVO::Concerns::Exception
7
+ include EIVO::Concerns::Rendering
8
+ include EIVO::Concerns::Pagination
9
+
10
+ # doesn't work
11
+ # rescue_from ::ActiveRecord::RecordNotFound, with: :render_not_found
12
+ # rescue_from ::ActionController::ParameterMissing, with: :render_parameter_missing
13
+ # rescue_from ::StandardError, with: :render_internal_server_error
14
+
15
+ def process_action(*args)
16
+ begin
17
+ super
18
+ rescue ::ActiveRecord::RecordNotFound => e
19
+ render_not_found(e)
20
+ rescue ::ActionController::ParameterMissing => e
21
+ render_parameter_missing(e)
22
+ rescue ::StandardError => e
23
+ if Rails.env.development?
24
+ raise e
25
+ else
26
+ ::Raven.capture_exception(exception)
27
+ end
28
+ render_internal_server_error(e)
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EIVO
4
+ module Concerns
5
+ module Exception
6
+
7
+ extend ::ActiveSupport::Concern
8
+
9
+ included do
10
+ before_action :set_exception_context
11
+ end
12
+
13
+ def set_exception_context
14
+ ::Raven.extra_context(
15
+ params: params.to_unsafe_h,
16
+ url: request.url,
17
+ request_id: request.request_id
18
+ )
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EIVO
4
+ module Concerns
5
+ module Pagination
6
+ extend ::ActiveSupport::Concern
7
+
8
+ def pagination_options(collection)
9
+ options = {
10
+ is_collection: true,
11
+ meta: {
12
+ total: collection.total_count,
13
+ pages: collection.total_pages
14
+ },
15
+ links: {
16
+ self: url_for(params.to_unsafe_h.merge({ page: collection.current_page })),
17
+ first: url_for(params.to_unsafe_h.merge({ page: 1 })),
18
+ last: url_for(params.to_unsafe_h.merge({ page: collection.total_pages })),
19
+ }
20
+ }
21
+
22
+ if !collection.out_of_range? && !collection.first_page?
23
+ options[:links][:prev] = url_for(params.to_unsafe_h.merge({ page: collection.prev_page }))
24
+ end
25
+ if !collection.out_of_range? && !collection.last_page?
26
+ options[:links][:next] = url_for(params.to_unsafe_h.merge({ page: collection.next_page }))
27
+ end
28
+
29
+ options
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EIVO
4
+ module Concerns
5
+ module Rendering
6
+
7
+ extend ::ActiveSupport::Concern
8
+
9
+ def render_success(serializer = nil)
10
+ if serializer
11
+ render json: serializer.serialized_json
12
+ else
13
+ data = {
14
+ data: nil
15
+ }
16
+ render json: ::MultiJson.dump(data)
17
+ end
18
+ end
19
+
20
+ def render_unauthorized(exception = nil)
21
+ render_error 'unauthorized', status: :unauthorized
22
+ end
23
+
24
+ def render_forbidden(exception = nil)
25
+ render_error 'forbidden', status: :forbidden
26
+ end
27
+
28
+ def render_not_found(exception = nil)
29
+ render_error 'not_found', status: :not_found
30
+ end
31
+
32
+ def render_internal_server_error(exception)
33
+ render_error 'internal_server_error', status: :internal_server_error
34
+ end
35
+
36
+ def render_parameter_missing(exception)
37
+ render_error 'parameter_missing', source: { parameter: exception.param }
38
+ end
39
+
40
+ def render_model_errors(errors)
41
+ json_errors = errors.details.map do |attribute, errors|
42
+ errors.map do |error|
43
+ {
44
+ code: error[:error],
45
+ source: {
46
+ parameter: attribute
47
+ },
48
+ status: ::Rack::Utils::SYMBOL_TO_STATUS_CODE[:bad_request].to_s
49
+ }
50
+ end
51
+ end
52
+
53
+ render_errors json_errors.flatten
54
+ end
55
+
56
+ def render_error(code, status: :bad_request, source: nil)
57
+ render_errors([{
58
+ code: code,
59
+ source: source,
60
+ status: ::Rack::Utils::SYMBOL_TO_STATUS_CODE[status].to_s
61
+ }.compact], status: status)
62
+ end
63
+
64
+ def render_errors(errors, status: :bad_request)
65
+ data = {
66
+ errors: errors
67
+ }
68
+ render json: ::MultiJson.dump(data), status: status
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EIVO
4
+ module Concerns
5
+ module Resource
6
+ extend ::ActiveSupport::Concern
7
+
8
+ included do
9
+ before_action :set_default_serializer_options
10
+ end
11
+
12
+ def show
13
+ @object ||= collection
14
+ render_success serializer.new(@object, @serializer_options)
15
+ end
16
+
17
+ def create
18
+ @object ||= collection.new(object_params_create)
19
+ if @object.save
20
+ render_success serializer.new(@object, @serializer_options)
21
+ else
22
+ render_model_errors @object.errors
23
+ end
24
+ end
25
+
26
+ def update
27
+ @object ||= collection
28
+ if @object.update(object_params_update)
29
+ render_success serializer.new(@object, @serializer_options)
30
+ else
31
+ render_model_errors @object.errors
32
+ end
33
+ end
34
+
35
+ def destroy
36
+ @object ||= collection
37
+
38
+ if @object.destroy
39
+ render_success
40
+ else
41
+ render_model_errors @object.errors
42
+ end
43
+ end
44
+
45
+ protected
46
+
47
+ def collection
48
+ raise NotImplementedError
49
+ end
50
+
51
+ def collection_index
52
+ collection
53
+ end
54
+
55
+ def serializer
56
+ raise NotImplementedError
57
+ end
58
+
59
+ def object_params
60
+ raise NotImplementedError
61
+ end
62
+
63
+ def object_params_create
64
+ object_params
65
+ end
66
+
67
+ def object_params_update
68
+ object_params
69
+ end
70
+
71
+ def set_default_serializer_options
72
+ @serializer_options ||= {}
73
+ end
74
+
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EIVO
4
+ module Concerns
5
+ module Resources
6
+ extend ::ActiveSupport::Concern
7
+
8
+ included do
9
+ before_action :set_default_serializer_options
10
+ end
11
+
12
+ def index
13
+ @objects ||= collection_index
14
+
15
+ unless ::ActiveModel::Type::Boolean.new.cast(params[:pagination]) == false
16
+ limit = 50
17
+ if params[:limit]
18
+ limit = [[params[:limit].to_i, 1].max, 500].min
19
+ end
20
+
21
+ @objects = @objects.page(params[:page]).per(limit)
22
+ @serializer_options.merge!(pagination_options(@objects))
23
+ end
24
+
25
+ render_success serializer.new(@objects, @serializer_options)
26
+ end
27
+
28
+ def show
29
+ @object ||= collection.find(params[:id])
30
+ render_success serializer.new(@object, @serializer_options)
31
+ end
32
+
33
+ def create
34
+ @object ||= collection.new(object_params_create)
35
+ if @object.save
36
+ render_success serializer.new(@object, @serializer_options)
37
+ else
38
+ render_model_errors @object.errors
39
+ end
40
+ end
41
+
42
+ def update
43
+ @object ||= collection.find(params[:id])
44
+ if @object.update(object_params_update)
45
+ render_success serializer.new(@object, @serializer_options)
46
+ else
47
+ render_model_errors @object.errors
48
+ end
49
+ end
50
+
51
+ def destroy
52
+ @object ||= collection.find(params[:id])
53
+
54
+ if @object.destroy
55
+ render_success
56
+ else
57
+ render_model_errors @object.errors
58
+ end
59
+ end
60
+
61
+ protected
62
+
63
+ def collection
64
+ raise NotImplementedError
65
+ end
66
+
67
+ def collection_index
68
+ collection
69
+ end
70
+
71
+ def serializer
72
+ raise NotImplementedError
73
+ end
74
+
75
+ def object_params
76
+ raise NotImplementedError
77
+ end
78
+
79
+ def object_params_create
80
+ object_params
81
+ end
82
+
83
+ def object_params_update
84
+ object_params
85
+ end
86
+
87
+ def set_default_serializer_options
88
+ @serializer_options ||= {}
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EIVO
4
+ class StatusController < ApplicationController
5
+
6
+ def index
7
+ render_success
8
+ end
9
+
10
+ end
11
+ end
data/bin/eivo ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'eivo-rails-api/cli'
4
+
5
+ EIVO::CLI.start
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'raven'
4
+
5
+ Raven.configure do |config|
6
+ config.environments = %w[ staging production ]
7
+ config.dsn = Rails.application.credentials.dig(:sentry, :dsn)
8
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ EIVO::Engine.routes.draw do
4
+ scope module: 'eivo' do
5
+ get :status, to: 'status#index'
6
+ end
7
+ end
@@ -0,0 +1,32 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'eivo-rails-api'
5
+ spec.version = '0.0.1'
6
+ spec.authors = ['Jonathan VUKOVICH-TRIBOUHARET']
7
+ spec.email = ['jonathan@eivo.co']
8
+
9
+ spec.summary = 'EIVO Rails API'
10
+ spec.description = 'EIVO Rails API'
11
+ spec.homepage = 'https://www.eivo.co'
12
+ spec.license = 'MIT'
13
+
14
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
15
+ `git ls-files -z`.split("\x0")
16
+ end
17
+ spec.executables << 'eivo'
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_dependency 'thor'
21
+
22
+ spec.add_dependency 'oj'
23
+ spec.add_dependency 'multi_json'
24
+ spec.add_dependency 'fast_jsonapi'
25
+
26
+ spec.add_dependency 'kaminari'
27
+
28
+ spec.add_dependency 'sentry-raven'
29
+
30
+ spec.add_development_dependency 'bundler'
31
+ spec.add_development_dependency 'rake'
32
+ end
@@ -0,0 +1,12 @@
1
+ require 'thor'
2
+
3
+ module EIVO
4
+ class CLI < Thor
5
+
6
+ desc 'install', 'Initialize default files'
7
+ def install(args = nil)
8
+ system("rails g eivo:install #{args}")
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EIVO
4
+ class Engine < ::Rails::Engine
5
+ ActiveSupport::Inflector.inflections(:en) do |inflect|
6
+ inflect.acronym 'EIVO'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EIVO
4
+ class Environment
5
+ def self.development
6
+ Rails.application.configure do
7
+ # Settings specified here will take precedence over those in config/application.rb.
8
+
9
+ # In the development environment your application's code is reloaded on
10
+ # every request. This slows down response time but is perfect for development
11
+ # since you don't have to restart the web server when you make code changes.
12
+ config.cache_classes = false
13
+
14
+ # Do not eager load code on boot.
15
+ config.eager_load = false
16
+
17
+ # Show full error reports.
18
+ config.consider_all_requests_local = true
19
+
20
+ # Enable/disable caching. By default caching is disabled.
21
+ # Run rails dev:cache to toggle caching.
22
+ if Rails.root.join('tmp', 'caching-dev.txt').exist?
23
+ config.action_controller.perform_caching = true
24
+
25
+ config.cache_store = :memory_store
26
+ config.public_file_server.headers = {
27
+ 'Cache-Control' => "public, max-age=#{2.days.to_i}"
28
+ }
29
+ else
30
+ config.action_controller.perform_caching = false
31
+
32
+ config.cache_store = :null_store
33
+ end
34
+
35
+ # Print deprecation notices to the Rails logger.
36
+ config.active_support.deprecation = :log
37
+
38
+ # Raise an error on page load if there are pending migrations.
39
+ config.active_record.migration_error = :page_load
40
+
41
+ # Highlight code that triggered database queries in logs.
42
+ config.active_record.verbose_query_logs = true
43
+
44
+
45
+ # Raises error for missing translations
46
+ # config.action_view.raise_on_missing_translations = true
47
+
48
+ # Use an evented file watcher to asynchronously detect changes in source code,
49
+ # routes, locales, etc. This feature depends on the listen gem.
50
+ config.file_watcher = ActiveSupport::EventedFileUpdateChecker
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EIVO
4
+ class Environment
5
+ def self.production
6
+ Rails.application.configure do
7
+ # Settings specified here will take precedence over those in config/application.rb.
8
+
9
+ # Code is not reloaded between requests.
10
+ config.cache_classes = true
11
+
12
+ # Eager load code on boot. This eager loads most of Rails and
13
+ # your application in memory, allowing both threaded web servers
14
+ # and those relying on copy on write to perform better.
15
+ # Rake tasks automatically ignore this option for performance.
16
+ config.eager_load = true
17
+
18
+ # Full error reports are disabled and caching is turned on.
19
+ config.consider_all_requests_local = false
20
+ config.action_controller.perform_caching = true
21
+
22
+ # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
23
+ # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
24
+ # config.require_master_key = true
25
+
26
+ # Disable serving static files from the `/public` folder by default since
27
+ # Apache or NGINX already handles this.
28
+ config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
29
+
30
+ # Enable serving of images, stylesheets, and JavaScripts from an asset server.
31
+ # config.action_controller.asset_host = 'http://assets.example.com'
32
+
33
+ # Specifies the header that your server uses for sending files.
34
+ # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
35
+ config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
36
+
37
+ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
38
+ config.force_ssl = true
39
+
40
+ # Use the lowest log level to ensure availability of diagnostic information
41
+ # when problems arise.
42
+ config.log_level = :debug
43
+
44
+ # Prepend all log lines with the following tags.
45
+ config.log_tags = [ :request_id ]
46
+
47
+ # Use a different cache store in production.
48
+ # config.cache_store = :mem_cache_store
49
+
50
+ # Use a real queuing backend for Active Job (and separate queues per environment)
51
+ # config.active_job.queue_adapter = :resque
52
+ # config.active_job.queue_name_prefix = "example_#{Rails.env}"
53
+
54
+ # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
55
+ # the I18n.default_locale when a translation cannot be found).
56
+ config.i18n.fallbacks = true
57
+
58
+ # Send deprecation notices to registered listeners.
59
+ config.active_support.deprecation = :notify
60
+
61
+ # Use default logging formatter so that PID and timestamp are not suppressed.
62
+ config.log_formatter = ::Logger::Formatter.new
63
+
64
+ # Use a different logger for distributed setups.
65
+ # require 'syslog/logger'
66
+ # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
67
+
68
+ if ENV["RAILS_LOG_TO_STDOUT"].present?
69
+ logger = ActiveSupport::Logger.new(STDOUT)
70
+ logger.formatter = config.log_formatter
71
+ config.logger = ActiveSupport::TaggedLogging.new(logger)
72
+ end
73
+
74
+ # Do not dump schema after migrations.
75
+ config.active_record.dump_schema_after_migration = false
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'production'
4
+
5
+ module EIVO
6
+ class Environment
7
+ def self.staging
8
+ production
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EIVO
4
+ class Environment
5
+ def self.test
6
+ Rails.application.configure do
7
+ # Settings specified here will take precedence over those in config/application.rb.
8
+
9
+ # The test environment is used exclusively to run your application's
10
+ # test suite. You never need to work with it otherwise. Remember that
11
+ # your test database is "scratch space" for the test suite and is wiped
12
+ # and recreated between test runs. Don't rely on the data there!
13
+ config.cache_classes = true
14
+
15
+ # Do not eager load code on boot. This avoids loading your whole application
16
+ # just for the purpose of running a single test. If you are using a tool that
17
+ # preloads Rails for running tests, you may have to set it to true.
18
+ config.eager_load = false
19
+
20
+ # Configure public file server for tests with Cache-Control for performance.
21
+ config.public_file_server.enabled = true
22
+ config.public_file_server.headers = {
23
+ 'Cache-Control' => "public, max-age=#{1.hour.to_i}"
24
+ }
25
+
26
+ # Show full error reports and disable caching.
27
+ config.consider_all_requests_local = true
28
+ config.action_controller.perform_caching = false
29
+
30
+ # Raise exceptions instead of rendering exception templates.
31
+ config.action_dispatch.show_exceptions = false
32
+
33
+ # Disable request forgery protection in test environment.
34
+ config.action_controller.allow_forgery_protection = false
35
+
36
+ # Print deprecation notices to the stderr.
37
+ config.active_support.deprecation = :stderr
38
+
39
+ # Raises error for missing translations
40
+ # config.action_view.raise_on_missing_translations = true
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'raven'
4
+
5
+ require 'oj'
6
+ require 'multi_json'
7
+ require 'fast_jsonapi'
8
+
9
+ require 'kaminari'
10
+
11
+ require_relative 'eivo-rails-api/engine'
12
+
13
+ module EIVO
14
+ class << self
15
+ def configure(application)
16
+ application.config.load_defaults 5.2
17
+ application.config.api_only = true
18
+
19
+ application.config.require_master_key = true
20
+
21
+ application.config.generators do |g|
22
+ g.orm :active_record, primary_key_type: :uuid
23
+ end
24
+
25
+ require_relative "eivo-rails-api/environments/#{Rails.env}"
26
+ EIVO::Environment.send(Rails.env)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ Initialize default files
2
+
3
+ rails g eivo:install
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+
5
+ module EIVO
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+
9
+ source_root File.expand_path('../templates', __FILE__)
10
+
11
+ def self.namespace(name = nil)
12
+ @namespace ||= super.sub('e_i_v_o', 'eivo')
13
+ end
14
+
15
+ # Implement the required interface for Rails::Generators::Migration.
16
+ def self.next_migration_number(dirname)
17
+ next_migration_number = current_migration_number(dirname) + 1
18
+ ActiveRecord::Migration.next_migration_number(next_migration_number)
19
+ end
20
+
21
+ def create_initializer_file
22
+ @application = Rails.application.class.parent_name
23
+
24
+ remove_dir 'config/environments'
25
+
26
+ copy_file 'Gemfile'
27
+ copy_file 'Procfile'
28
+ copy_file '.env.example'
29
+ copy_file '.ruby-version'
30
+
31
+ create_restart_files
32
+
33
+ template 'config/application.rb'
34
+ copy_file 'config/puma.rb'
35
+ template 'config/database.example.yml'
36
+ template 'config/database.example.yml', 'config/database.yml', skip: true
37
+
38
+ copy_file 'app/controllers/application_controller.rb'
39
+
40
+ migration_template 'db/migrate/enable_pgcrypto_extension.rb', 'db/migrate/enable_pgcrypto_extension.rb', skip: true
41
+ migration_template 'db/migrate/enable_pg_stat_statements_extension.rb', 'db/migrate/enable_pg_stat_statements_extension.rb', skip: true
42
+ migration_template 'db/migrate/enable_btree_gin_extension.rb', 'db/migrate/enable_btree_gin_extension.rb', skip: true
43
+ migration_template 'db/migrate/enable_unaccent_extension.rb', 'db/migrate/enable_unaccent_extension.rb', skip: true
44
+
45
+ route "mount EIVO::Engine => '/'"
46
+ end
47
+
48
+ def create_restart_files
49
+ restart_code = <<-'EOF'
50
+ ### EIVO begin ###
51
+
52
+ bundle exec pumactl -F config/puma.rb restart
53
+
54
+ ### EIVO end ###
55
+ EOF
56
+
57
+ stop_code = <<-'EOF'
58
+ ### EIVO begin ###
59
+
60
+ bundle exec pumactl -F config/puma.rb stop
61
+
62
+ ### EIVO end ###
63
+ EOF
64
+
65
+ header_production = <<-'EOF'
66
+ #!/usr/bin/env bash
67
+ export RAILS_ENV="production"
68
+
69
+ EOF
70
+ header_staging = <<-'EOF'
71
+ #!/usr/bin/env bash
72
+ export RAILS_ENV="staging"
73
+
74
+ EOF
75
+
76
+ create_file 'restart_production.sh', header_production, skip: true
77
+ create_file 'stop_production.sh', header_production, skip: true
78
+ create_file 'restart_staging.sh', header_staging, skip: true
79
+ create_file 'stop_staging.sh', header_staging, skip: true
80
+
81
+ # Remove old code if present
82
+ regexp = /\n### EIVO begin ###.*### EIVO end ###/m
83
+ gsub_file 'restart_production.sh', regexp, ''
84
+ gsub_file 'restart_staging.sh', regexp, ''
85
+ gsub_file 'stop_production.sh', regexp, ''
86
+ gsub_file 'stop_staging.sh', regexp, ''
87
+
88
+ # Inject new code
89
+ inject_into_file 'restart_production.sh', restart_code, after: header_production
90
+ inject_into_file 'stop_production.sh', stop_code, after: header_production
91
+ inject_into_file 'restart_staging.sh', restart_code, after: header_staging
92
+ inject_into_file 'stop_staging.sh', stop_code, after: header_staging
93
+
94
+ chmod 'restart_production.sh', 0755
95
+ chmod 'stop_production.sh', 0755
96
+ chmod 'restart_staging.sh', 0755
97
+ chmod 'stop_staging.sh', 0755
98
+ end
99
+
100
+ end
101
+ end
@@ -0,0 +1,5 @@
1
+ WEB_CONCURRENCY="0"
2
+ RAILS_MAX_THREADS="5"
3
+ DB_POOL="5" # RAILS_MAX_THREADS
4
+ DB_STATEMENT_TIMEOUT="10000"
5
+ REDIS_URL="redis://localhost:6379/0"
@@ -0,0 +1 @@
1
+ ruby-2.6.3
@@ -0,0 +1,40 @@
1
+ source 'https://rubygems.org'
2
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
+
4
+ ruby '2.6.3'
5
+
6
+ gem 'rails', '~> 5.2.3'
7
+ gem 'pg', '>= 0.18', '< 2.0'
8
+ gem 'puma', '~> 3.11'
9
+
10
+ group :development, :test do
11
+ gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
12
+ end
13
+
14
+ group :development do
15
+ gem 'listen', '>= 3.0.5', '< 3.2'
16
+ end
17
+
18
+ gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
19
+
20
+ group :development, :test do
21
+ gem 'derailed_benchmarks'
22
+ gem 'factory_bot_rails'
23
+ gem 'faker'
24
+ gem 'rspec-rails'
25
+ gem 'brakeman'
26
+ gem 'rubocop'
27
+ gem 'rubocop-rspec'
28
+ gem 'webmock'
29
+ end
30
+
31
+ gem 'eivo-rails-api'
32
+
33
+ gem 'rack-cors'
34
+ gem 'jwt'
35
+
36
+ gem 'validates_email_format_of'
37
+ gem 'validates_phone_format_of'
38
+ gem 'validates_timeliness'
39
+
40
+ ### EIVO ###
@@ -0,0 +1 @@
1
+ web: bundle exec puma -C config/puma.rb
@@ -0,0 +1,2 @@
1
+ class ApplicationController < EIVO::ApplicationController
2
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'boot'
4
+
5
+ require 'rails'
6
+ require 'active_model/railtie'
7
+ require 'active_record/railtie'
8
+ require 'action_controller/railtie'
9
+
10
+ Bundler.require(*Rails.groups)
11
+
12
+ module <%= @application %>
13
+ class Application < Rails::Application
14
+ EIVO.configure(self)
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ default: &default
2
+ adapter: postgresql
3
+ encoding: unicode
4
+ pool: <%%= ENV.fetch('DB_POOL') { 5 } %>
5
+ host: db
6
+ username: postgres
7
+ variables:
8
+ statement_timeout: <%%= ENV.fetch('DB_STATEMENT_TIMEOUT') { 10000 } %>
9
+
10
+ development:
11
+ <<: *default
12
+ database: <%= @application.parameterize %>_development
13
+
14
+ test:
15
+ <<: *default
16
+ database: <%= @application.parameterize %>_test
17
+
18
+ staging:
19
+ <<: *default
20
+ database: <%= @application.parameterize %>_staging
21
+
22
+ production:
23
+ <<: *default
24
+ database: <%= @application.parameterize %>
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ workers ENV.fetch('WEB_CONCURRENCY') { 0 }
4
+ threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }
5
+ threads threads_count, threads_count
6
+
7
+ environment ENV.fetch('RAILS_ENV') { "development" }
8
+
9
+ if ['production', 'staging'].include?(ENV['RAILS_ENV'])
10
+ bind 'unix://tmp/sockets/puma.sock'
11
+ pidfile 'tmp/pids/puma.pid'
12
+ state_path 'tmp/pids/puma.state'
13
+ daemonize true
14
+ else
15
+ port ENV.fetch('PORT') { 3000 }
16
+ end
17
+
18
+ before_fork do
19
+ ActiveRecord::Base.connection.disconnect!
20
+ end
21
+
22
+ on_worker_boot do
23
+ ActiveSupport.on_load(:active_record) do
24
+ ActiveRecord::Base.establish_connection
25
+ end
26
+ end
27
+
28
+ preload_app!
29
+
30
+ plugin :tmp_restart
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EnableBtreeGinExtension < ActiveRecord::Migration[5.2]
4
+ def change
5
+ enable_extension 'btree_gin'
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EnablePgStatStatementsExtension < ActiveRecord::Migration[5.2]
4
+ def change
5
+ enable_extension 'pg_stat_statements'
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EnablePgcryptoExtension < ActiveRecord::Migration[5.2]
4
+ def change
5
+ enable_extension 'pgcrypto'
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EnableUnaccentExtension < ActiveRecord::Migration[5.2]
4
+ def change
5
+ enable_extension 'unaccent'
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,194 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eivo-rails-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jonathan VUKOVICH-TRIBOUHARET
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-06-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oj
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: multi_json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: fast_jsonapi
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: kaminari
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: sentry-raven
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: EIVO Rails API
126
+ email:
127
+ - jonathan@eivo.co
128
+ executables:
129
+ - eivo
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - Gemfile
135
+ - LICENSE
136
+ - README.md
137
+ - Rakefile
138
+ - app/controllers/eivo/application_controller.rb
139
+ - app/controllers/eivo/concerns/exception.rb
140
+ - app/controllers/eivo/concerns/pagination.rb
141
+ - app/controllers/eivo/concerns/rendering.rb
142
+ - app/controllers/eivo/concerns/resource.rb
143
+ - app/controllers/eivo/concerns/resources.rb
144
+ - app/controllers/eivo/status_controller.rb
145
+ - bin/eivo
146
+ - config/initializers/sentry.rb
147
+ - config/routes.rb
148
+ - eivo-rails-api.gemspec
149
+ - lib/eivo-rails-api.rb
150
+ - lib/eivo-rails-api/cli.rb
151
+ - lib/eivo-rails-api/engine.rb
152
+ - lib/eivo-rails-api/environments/development.rb
153
+ - lib/eivo-rails-api/environments/production.rb
154
+ - lib/eivo-rails-api/environments/staging.rb
155
+ - lib/eivo-rails-api/environments/test.rb
156
+ - lib/generators/eivo/USAGE
157
+ - lib/generators/eivo/install_generator.rb
158
+ - lib/generators/eivo/templates/.env.example
159
+ - lib/generators/eivo/templates/.ruby-version
160
+ - lib/generators/eivo/templates/Gemfile
161
+ - lib/generators/eivo/templates/Procfile
162
+ - lib/generators/eivo/templates/app/controllers/application_controller.rb
163
+ - lib/generators/eivo/templates/config/application.rb
164
+ - lib/generators/eivo/templates/config/database.example.yml
165
+ - lib/generators/eivo/templates/config/puma.rb
166
+ - lib/generators/eivo/templates/db/migrate/enable_btree_gin_extension.rb
167
+ - lib/generators/eivo/templates/db/migrate/enable_pg_stat_statements_extension.rb
168
+ - lib/generators/eivo/templates/db/migrate/enable_pgcrypto_extension.rb
169
+ - lib/generators/eivo/templates/db/migrate/enable_unaccent_extension.rb
170
+ homepage: https://www.eivo.co
171
+ licenses:
172
+ - MIT
173
+ metadata: {}
174
+ post_install_message:
175
+ rdoc_options: []
176
+ require_paths:
177
+ - lib
178
+ required_ruby_version: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ required_rubygems_version: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ requirements: []
189
+ rubyforge_project:
190
+ rubygems_version: 2.4.5
191
+ signing_key:
192
+ specification_version: 4
193
+ summary: EIVO Rails API
194
+ test_files: []