Commit iniziale di eminuxCRM: CRM Rails con pipeline, campagne email e Docker.
CI / scan_ruby (push) Failing after 11m20s
CI / scan_js (push) Successful in 10m35s
CI / lint (push) Has been cancelled

Include autenticazione, progetti isolati, mail marketing HTML con SMTP, test A/B e editor WYSIWYG.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-17 23:01:48 +02:00
co-authored by Cursor
commit c4e5f289cf
258 changed files with 11293 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
require_relative "boot"
require "rails"
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "action_cable/engine"
require "action_text/trix"
require "rails/test_unit/railtie"
Bundler.require(*Rails.groups)
module Simplecrm
class Application < Rails::Application
config.load_defaults 8.1
config.autoload_lib(ignore: %w[assets tasks])
config.time_zone = "Europe/Rome"
config.i18n.default_locale = :it
config.i18n.available_locales = %i[it en]
config.generators.system_tests = nil
config.x.app_name = "eminuxCRM"
end
end
+4
View File
@@ -0,0 +1,4 @@
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
require "bundler/setup" # Set up gems listed in the Gemfile.
require "bootsnap/setup" # Speed up boot time by caching expensive operations.
+5
View File
@@ -0,0 +1,5 @@
# Audit all gems listed in the Gemfile for known security problems by running bin/bundler-audit.
# CVEs that are not relevant to the application can be enumerated on the ignore list below.
ignore:
- CVE-THAT-DOES-NOT-APPLY
+10
View File
@@ -0,0 +1,10 @@
development:
adapter: async
test:
adapter: test
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: app_production
+20
View File
@@ -0,0 +1,20 @@
# Run using bin/ci
CI.run do
step "Setup", "bin/setup --skip-server"
step "Style: Ruby", "bin/rubocop"
step "Security: Gem audit", "bin/bundler-audit"
step "Security: Importmap vulnerability audit", "bin/importmap audit"
step "Security: Brakeman code analysis", "bin/brakeman --quiet --no-pager --exit-on-warn --exit-on-error"
# Optional: set a green GitHub commit status to unblock PR merge.
# Requires the `gh` CLI and `gh extension install basecamp/gh-signoff`.
# if success?
# step "Signoff: All systems go. Ready for merge and deploy.", "gh signoff"
# else
# failure "Signoff: CI failed. Do not merge or deploy.", "Fix the issues and try again."
# end
end
+1
View File
@@ -0,0 +1 @@
5NspSSxWg4jYdRx5haY2znA/ik7gtI/quqyi/kkr+ilHOgwKhRyzQR2dS3ibSktDADY0BQh8V8Wd5aDH2sIRwo4hDKpT5ptmVNfEVUMjS8bpONxHxz1CchuyynpLp4COvu1Osnfbn4XZn9djx3rVJucq1/11ImlmthmieZP7oPCyMLOaB73EtIkgSqlwKGEaq8X1BleZzl6DvwA8/airYLjACIgycBeG2r8zdcTI/SKTI82BYxIFRXOccf+YPE3fNCefTi9ymNTne9eaQhBNXf4knaShXCokqawPLgZDc3rqSKaaIm15HdLC25OQBX57GbBAXj2PbC8wl1BbYh10ajXXFXaW8JiboA0cJdbBlMY8RTkUFsrgjgXg6MNnf/hbw6svVAdQYUueC8MRZXM/z99aRiSEdAzz4MqlQL/Hlh9s2VHHmy270PfVc/q+kVyJBZBRJbkwqlr3XLHyk1tWhofsYUNKt5vvZhzcnuXYCM5dnhorBQ5P34nH--nFSjTb/kdgiBtBhY--FI3OFfoWUpmlQu9RsHGqUQ==
+22
View File
@@ -0,0 +1,22 @@
# PostgreSQL
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: <%= ENV.fetch("DATABASE_HOST", "localhost") %>
port: <%= ENV.fetch("DATABASE_PORT", 5432) %>
username: <%= ENV.fetch("POSTGRES_USER", "simplecrm") %>
password: <%= ENV.fetch("POSTGRES_PASSWORD", "simplecrm_dev") %>
development:
<<: *default
database: <%= ENV.fetch("POSTGRES_DB", "simplecrm_development") %>
test:
<<: *default
database: simplecrm_test
production:
<<: *default
database: <%= ENV.fetch("POSTGRES_DB", "simplecrm_production") %>
url: <%= ENV["DATABASE_URL"] %>
+5
View File
@@ -0,0 +1,5 @@
# Load the Rails application.
require_relative "application"
# Initialize the Rails application.
Rails.application.initialize!
+84
View File
@@ -0,0 +1,84 @@
require "active_support/core_ext/integer/time"
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Make code changes take effect immediately without server restart.
config.enable_reloading = true
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports.
config.consider_all_requests_local = true
# Enable server timing.
config.server_timing = true
# Enable/disable Action Controller caching. By default Action Controller caching is disabled.
# Run rails dev:cache to toggle Action Controller caching.
if Rails.root.join("tmp/caching-dev.txt").exist?
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true
config.public_file_server.headers = { "cache-control" => "public, max-age=#{2.days.to_i}" }
else
config.action_controller.perform_caching = false
end
# Change to :null_store to avoid any caching.
config.cache_store = :memory_store
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
# Make template changes take effect immediately.
config.action_mailer.perform_caching = false
# Set localhost to be used by links generated in mailer templates.
config.action_mailer.default_url_options = {
host: ENV.fetch("APP_HOST", "localhost"),
port: ENV.fetch("APP_PORT", 3000)
}
config.active_job.queue_adapter = :async
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
# Highlight code that triggered database queries in logs.
config.active_record.verbose_query_logs = true
# Append comments with runtime information tags to SQL queries in logs.
config.active_record.query_log_tags_enabled = true
# Highlight code that enqueued background job in logs.
config.active_job.verbose_enqueue_logs = true
# Highlight code that triggered redirect in logs.
config.action_dispatch.verbose_redirect_logs = true
# Suppress logger output for asset requests.
config.assets.quiet = true
# Raises error for missing translations.
# config.i18n.raise_on_missing_translations = true
# Annotate rendered view with file names.
config.action_view.annotate_rendered_view_with_filenames = true
# Uncomment if you wish to allow Action Cable access from any origin.
# config.action_cable.disable_request_forgery_protection = true
# Raise error when a before_action's only/except options reference missing actions.
config.action_controller.raise_on_missing_callback_actions = true
# Apply autocorrection by RuboCop to files generated by `bin/rails generate`.
# config.generators.apply_rubocop_autocorrect_after_generate!
end
+106
View File
@@ -0,0 +1,106 @@
require "active_support/core_ext/integer/time"
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
config.enable_reloading = false
# Eager load code on boot for better performance and memory savings (ignored by Rake tasks).
config.eager_load = true
# Full error reports are disabled.
config.consider_all_requests_local = false
# Turn on fragment caching in view templates.
config.action_controller.perform_caching = true
# Cache assets for far-future expiry since they are all digest stamped.
config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" }
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.asset_host = "http://assets.example.com"
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
# Assume SSL quando il TLS termina sul reverse proxy (NPM) e inoltra X-Forwarded-Proto.
# Separato da force_ssl per non rompere healthcheck HTTP su :3000.
config.assume_ssl = ENV["ASSUME_SSL"] == "true" || ENV["FORCE_SSL"] == "true"
# Force SSL only when FORCE_SSL=true (LAN/HTTP o TLS su NPM: lasciare disabilitato).
config.force_ssl = ENV["FORCE_SSL"] == "true"
# Skip http-to-https redirect for the default health check endpoint.
# config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } }
# Log to STDOUT with the current request id as a default log tag.
config.log_tags = [ :request_id ]
config.logger = ActiveSupport::TaggedLogging.logger(STDOUT)
# Change to "debug" to log everything (including potentially personally-identifiable information!).
config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
# Prevent health checks from clogging up the logs.
config.silence_healthcheck_path = "/up"
# Don't log any deprecations.
config.active_support.report_deprecations = false
# Replace the default in-process memory cache store with a durable alternative.
# config.cache_store = :mem_cache_store
# Replace the default in-process and non-durable queuing backend for Active Job.
# config.active_job.queue_adapter = :resque
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
# Set host to be used by links generated in mailer templates.
config.action_mailer.default_url_options = {
host: ENV.fetch("APP_HOST", "localhost"),
port: ENV["APP_PORT"].presence&.to_i
}.compact
# Host authorization: allow configured hosts (comma-separated) or clear for LAN.
if ENV["RAILS_ALLOWED_HOSTS"].present?
config.hosts.clear
ENV["RAILS_ALLOWED_HOSTS"].split(",").map(&:strip).each { |h| config.hosts << h }
else
config.hosts.clear
end
# Healthcheck Docker e reverse proxy interni
config.hosts << "localhost"
config.hosts << "127.0.0.1"
config.hosts << "web"
config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
# Specify outgoing SMTP server. Remember to add smtp/* credentials via bin/rails credentials:edit.
# config.action_mailer.smtp_settings = {
# user_name: Rails.application.credentials.dig(:smtp, :user_name),
# password: Rails.application.credentials.dig(:smtp, :password),
# address: "smtp.example.com",
# port: 587,
# authentication: :plain
# }
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
# Only use :id for inspections in production.
config.active_record.attributes_for_inspect = [ :id ]
# Enable DNS rebinding protection and other `Host` header attacks.
# config.hosts = [
# "example.com", # Allow requests from example.com
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
# ]
#
# Skip DNS rebinding protection for the default health check endpoint.
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
end
+53
View File
@@ -0,0 +1,53 @@
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# While tests run files are not watched, reloading is not necessary.
config.enable_reloading = false
# Eager loading loads your entire application. When running a single test locally,
# this is usually not necessary, and can slow down your test suite. However, it's
# recommended that you enable it in continuous integration systems to ensure eager
# loading is working properly before deploying your code.
config.eager_load = ENV["CI"].present?
# Configure public file server for tests with cache-control for performance.
config.public_file_server.headers = { "cache-control" => "public, max-age=3600" }
# Show full error reports.
config.consider_all_requests_local = true
config.cache_store = :null_store
# Render exception templates for rescuable exceptions and raise for other exceptions.
config.action_dispatch.show_exceptions = :rescuable
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false
# Store uploaded files on the local file system in a temporary directory.
config.active_storage.service = :test
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Set host to be used by links generated in mailer templates.
config.action_mailer.default_url_options = { host: "example.com" }
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
# Raises error for missing translations.
# config.i18n.raise_on_missing_translations = true
# Annotate rendered view with file names.
# config.action_view.annotate_rendered_view_with_filenames = true
# Raise error when a before_action's only/except options reference missing actions.
config.action_controller.raise_on_missing_callback_actions = true
end
+8
View File
@@ -0,0 +1,8 @@
# Pin npm packages by running ./bin/importmap
pin "application"
pin "trix"
pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
pin_all_from "app/javascript/controllers", under: "controllers"
@@ -0,0 +1,25 @@
# Chiavi derivate da SECRET_KEY_BASE così le password SMTP restano cifrate
# anche senza rails credentials:edit (Docker / deploy).
#
# In Rails 8 il getter di ActiveRecord::Encryption.config.primary_key solleva
# se la chiave manca: non usare ||= su quell'oggetto.
require "digest"
secret = Rails.application.secret_key_base.to_s
keys = {
primary_key: Digest::SHA256.hexdigest("#{secret}/ar-enc-primary"),
deterministic_key: Digest::SHA256.hexdigest("#{secret}/ar-enc-deterministic"),
key_derivation_salt: Digest::SHA256.hexdigest("#{secret}/ar-enc-salt")
}
cfg = Rails.application.config.active_record.encryption
keys.each { |name, value| cfg[name] = value }
cfg.support_unencrypted_data = true
Rails.application.config.after_initialize do
enc = ActiveRecord::Encryption.config
enc.primary_key = keys[:primary_key]
enc.deterministic_key = keys[:deterministic_key]
enc.key_derivation_salt = keys[:key_derivation_salt]
enc.support_unencrypted_data = true
end
+7
View File
@@ -0,0 +1,7 @@
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = "1.0"
# Add additional assets to the asset load path.
# Rails.application.config.assets.paths << Emoji.images_path
@@ -0,0 +1,29 @@
# Be sure to restart your server when you modify this file.
# Define an application-wide content security policy.
# See the Securing Rails Applications Guide for more information:
# https://guides.rubyonrails.org/security.html#content-security-policy-header
# Rails.application.configure do
# config.content_security_policy do |policy|
# policy.default_src :self, :https
# policy.font_src :self, :https, :data
# policy.img_src :self, :https, :data
# policy.object_src :none
# policy.script_src :self, :https
# policy.style_src :self, :https
# # Specify URI for violation reports
# # policy.report_uri "/csp-violation-report-endpoint"
# end
#
# # Generate session nonces for permitted importmap, inline scripts, and inline styles.
# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
# config.content_security_policy_nonce_directives = %w(script-src style-src)
#
# # Automatically add `nonce` to `javascript_tag`, `javascript_include_tag`, and `stylesheet_link_tag`
# # if the corresponding directives are specified in `content_security_policy_nonce_directives`.
# # config.content_security_policy_nonce_auto = true
#
# # Report violations without enforcing the policy.
# # config.content_security_policy_report_only = true
# end
@@ -0,0 +1,8 @@
# Be sure to restart your server when you modify this file.
# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
# Use this to limit dissemination of sensitive information.
# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
Rails.application.config.filter_parameters += [
:passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc
]
+16
View File
@@ -0,0 +1,16 @@
# Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format. Inflections
# are locale specific, and you may define rules for as many different
# locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, "\\1en"
# inflect.singular /^(ox)en/i, "\\1"
# inflect.irregular "person", "people"
# inflect.uncountable %w( fish sheep )
# end
# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.acronym "RESTful"
# end
+5
View File
@@ -0,0 +1,5 @@
require "pagy"
require "pagy/extras/overflow"
Pagy::DEFAULT[:limit] = 25
Pagy::DEFAULT[:overflow] = :empty_page
+12
View File
@@ -0,0 +1,12 @@
# Be sure to restart your server when you modify this file.
#
# Cookie Secure solo con FORCE_SSL/SESSION_COOKIE_SECURE.
# Dietro NPM→Caddy→Rails (HTTP interno) request.ssl? è false: con secure:true
# Rails non emette _simplecrm_session → CSRF 422 al login su HTTPS.
secure_cookie = ENV["FORCE_SSL"] == "true" || ENV["SESSION_COOKIE_SECURE"] == "true"
Rails.application.config.session_store :cookie_store,
key: "_simplecrm_session",
secure: secure_cookie,
httponly: true,
same_site: :lax
+31
View File
@@ -0,0 +1,31 @@
# Files in the config/locales directory are used for internationalization and
# are automatically loaded by Rails. If you want to use locales other than
# English, add the necessary files in this directory.
#
# To use the locales, use `I18n.t`:
#
# I18n.t "hello"
#
# In views, this is aliased to just `t`:
#
# <%= t("hello") %>
#
# To use a different locale, set it with `I18n.locale`:
#
# I18n.locale = :es
#
# This would use the information in config/locales/es.yml.
#
# To learn more about the API, please read the Rails Internationalization guide
# at https://guides.rubyonrails.org/i18n.html.
#
# Be aware that YAML interprets the following case-insensitive strings as
# booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings
# must be quoted to be interpreted as strings. For example:
#
# en:
# "yes": yup
# enabled: "ON"
en:
hello: "Hello world"
+143
View File
@@ -0,0 +1,143 @@
it:
date:
formats:
default: "%d/%m/%Y"
long: "%d %B %Y"
short: "%d/%m/%Y"
day_names: [domenica, lunedì, martedì, mercoledì, giovedì, venerdì, sabato]
abbr_day_names: [dom, lun, mar, mer, gio, ven, sab]
month_names: [~, gennaio, febbraio, marzo, aprile, maggio, giugno, luglio, agosto, settembre, ottobre, novembre, dicembre]
abbr_month_names: [~, gen, feb, mar, apr, mag, giu, lug, ago, set, ott, nov, dic]
time:
formats:
default: "%d/%m/%Y %H:%M"
short: "%d/%m/%Y %H:%M"
long: "%d %B %Y %H:%M"
am: "am"
pm: "pm"
number:
currency:
format:
unit: "€"
separator: ","
delimiter: "."
format: "%n %u"
activerecord:
models:
organization: Organizzazione
contact: Contatto
opportunity: Opportunità
task: Task
activity: Attività
user: Utente
sales_goal: Obiettivo
mail_identity: Account email
mail_template: Template email
mailing: Invio email
mailing_recipient: Destinatario
attributes:
organization:
name: Nome
legal_name: Ragione sociale
organization_type: Tipologia
sport: Sport
country: Paese
region: Regione
province: Provincia
city: Città
address: Indirizzo
website: Sito / profilo
phone: Telefono
email: Email verificata
vat_number: P. IVA
notes: Note follow-up
status: Stato
lead_source: Fonte
assigned_user_id: Owner
list_position: N.
team_gender: M/F
streaming_status: Streaming rilevato
commercial_fit: Evidenza / fit commerciale
source_url: Fonte contatto / ricerca
verified_at: Data verifica
contact:
first_name: Nome
last_name: Cognome
role: Ruolo
email: Email
phone: Telefono
mobile: Cellulare
preferred_contact_method: Contatto preferito
primary_contact: Contatto principale
notes: Note
opportunity:
name: Nome
pipeline_stage: Stage
estimated_value: Valore stimato
probability: Probabilità
expected_close_date: Chiusura prevista
product: Piano
lost_reason: Motivo perdita
notes: Note
ab_variant: Test A/B
send_status: Stato invio
sent_on: Data invio
outcome: Esito
demo_trial: Demo / Trial
converted: Conversione
task:
title: Titolo
description: Descrizione
due_at: Scadenza
priority: Priorità
task_type: Tipo
status: Stato
user:
email: Email
first_name: Nome
last_name: Cognome
password: Password
password_confirmation: Conferma password
role: Ruolo
mail_identity:
name: Nome account
from_name: Nome mittente
from_email: Email mittente
reply_to: Reply-To
smtp_host: Host SMTP
smtp_port: Porta
smtp_username: Utente SMTP
smtp_password: Password SMTP
smtp_authentication: Autenticazione
encryption: Crittografia
verify_ssl: Verifica certificato SSL
active: Attivo
mail_template:
name: Nome
subject: Oggetto
body_html: Corpo HTML
mailing:
name: Nome invio
subject: Oggetto variante A
body_html: Corpo HTML variante A
subject_b: Oggetto variante B
body_html_b: Corpo HTML variante B
audience: Destinatari
ab_test: Test A/B
ab_assignment: Come assegnare A e B
interval_seconds: Pausa tra un invio e l'altro (secondi)
mail_identity: Account mittente
mail_template: Template A
mail_template_b: Template B
errors:
format: "%{attribute} %{message}"
messages:
blank: non può essere vuoto
taken: è già in uso
invalid: non è valido
confirmation: non coincide
too_short: è troppo corto (minimo %{count} caratteri)
helpers:
submit:
create: Crea
update: Salva
+39
View File
@@ -0,0 +1,39 @@
# This configuration file will be evaluated by Puma. The top-level methods that
# are invoked here are part of Puma's configuration DSL. For more information
# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.
#
# Puma starts a configurable number of processes (workers) and each process
# serves each request in a thread from an internal thread pool.
#
# You can control the number of workers using ENV["WEB_CONCURRENCY"]. You
# should only set this value when you want to run 2 or more workers. The
# default is already 1. You can set it to `auto` to automatically start a worker
# for each available processor.
#
# The ideal number of threads per worker depends both on how much time the
# application spends waiting for IO operations and on how much you wish to
# prioritize throughput over latency.
#
# As a rule of thumb, increasing the number of threads will increase how much
# traffic a given process can handle (throughput), but due to CRuby's
# Global VM Lock (GVL) it has diminishing returns and will degrade the
# response time (latency) of the application.
#
# The default is set to 3 threads as it's deemed a decent compromise between
# throughput and latency for the average Rails application.
#
# Any libraries that use a connection pool or another resource pool should
# be configured to provide at least as many connections as the number of
# threads. This includes Active Record's `pool` parameter in `database.yml`.
threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
threads threads_count, threads_count
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
port ENV.fetch("PORT", 3000)
# Allow puma to be restarted by `bin/rails restart` command.
plugin :tmp_restart
# Specify the PID file. Defaults to tmp/pids/server.pid in development.
# In other environments, only set the PID file if requested.
pidfile ENV["PIDFILE"] if ENV["PIDFILE"]
+62
View File
@@ -0,0 +1,62 @@
Rails.application.routes.draw do
get "up" => "rails/health#show", as: :rails_health_check
get "login", to: "sessions#new"
post "login", to: "sessions#create"
delete "logout", to: "sessions#destroy"
resource :password, only: %i[edit update]
resources :password_resets, only: %i[new create], path: "password_reset" do
collection do
get ":token/edit", action: :edit, as: :edit
patch ":token", action: :update, as: :update
end
end
# Launcher: scegli il progetto (istanza CRM)
root "home#index"
get "impostazioni", to: "admin#show", as: :admin
# CRUD progetti anche fuori da un'istanza (bootstrap admin)
resources :projects, only: %i[create edit update destroy]
resources :users, except: %i[show]
resources :mail_identities, except: %i[show]
# Ogni progetto = istanza CRM dedicata
scope "/p/:project_code" do
get "/", to: "dashboard#show", as: :project_root
get "/today", to: "today#show", as: :today
get "/pipeline", to: "pipeline#show", as: :pipeline
get "/search", to: "search#show", as: :search
get "/reports", to: "reports#index", as: :reports
get "/settings", to: "settings#show", as: :settings
patch "/settings/goal(/:id)", to: "settings#update_goal", as: :update_goal_settings
resources :organizations do
resources :activities, only: %i[create]
end
resources :contacts
resources :opportunities do
member do
patch :update_stage
end
end
resources :tasks do
member do
patch :complete
end
end
resources :imports, only: %i[new create]
resources :mail_templates, except: %i[show]
resources :mail_images, only: %i[create]
resources :mailings do
member do
post :queue
post :test_send
post :refresh_recipients
patch :update_recipients
get :preview
end
end
end
end
+27
View File
@@ -0,0 +1,27 @@
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>
# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
# amazon:
# service: S3
# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
# region: us-east-1
# bucket: your_own_bucket-<%= Rails.env %>
# Remember not to checkin your GCS keyfile to a repository
# google:
# service: GCS
# project: your_project
# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
# bucket: your_own_bucket-<%= Rails.env %>
# mirror:
# service: Mirror
# primary: local
# mirrors: [ amazon, google, microsoft ]