Webapp Mobilità articolare semplificata
Quest’app fa parte del workflow utente dell’igiene posturale:
Piattaforma online
Workflow: utente_online
- Brand: igiene posturale
- Landing Page
- Profilazione
- Patologie
- Stato Salute
- Funzionamento dei sistemi
- Valutazione Mobilità articolare semplificata
- Igiene posturale
- Programma 4 settimane
- In autonomia
- Con un professionista
- In gruppo
- Singolo
- Feedback
- Prosecuzione programma
- Programma 4 settimane
1. Genera l’app
rails new evaluemobility –database=postgresql –css=tailwind –javascript=importmap
Development
ruby# config/environments/development.rb config.cache_store = :memory_store config.active_job.queue_adapter = :solid_queue config.action_cable.adapter = :solid_cable ?
Production
ruby# config/environments/production.rb config.cache_store = :solid_cache_store config.active_job.queue_adapter = :solid_queue config.action_cable.adapter = :solid_cable ?
2. Modifica il Gemfile (rimuovi redis, tieni solid_*)
cd evaluemobility
3. Bundle install
bundle install
4. Installa Solid gems
rails generate solid_cache:install rails generate solid_queue:install
rails generate solid_cable:install
5. Migra il database
rails db:migrate
config/routes.rb
Rails.application.routes.draw do root “assessments#new”
resources :assessments, only: [:new, :create, :show] do member do get :result end end
get “up” => “rails/health#show”, as: :rails_health_check end
Genera il controller per le valutazioni con le azioni necessarie
rails generate controller Assessments new create show result
rails generate controller Home index about contact
rails generate controller Pages privacy terms contact
. Genera model per Assessment
rails generate model Assessment name:string age:integer email:string phone:string privacy_consent:boolean marketing_consent:boolean notes:text flexion_extension:integer arms_overhead:integer spine_rotation_right:integer spine_rotation_left:integer deep_squat:integer hands_behind_back_right:integer hands_behind_back_left:integer straight_leg_raise_right:integer straight_leg_raise_left:integer
db/migrate/001_create_assessments.rb
class CreateAssessments < ActiveRecord::Migration[8.0] def change create_table :assessments do |t| t.string :name, null: false t.integer :age, null: false t.string :email t.string :phone t.boolean :privacy_consent, default: false t.boolean :marketing_consent, default: false t.text :notes
# Exercise scores (0-3)
t.integer :flexion_extension, null: false, default: 0
t.integer :arms_overhead, null: false, default: 0
t.integer :spine_rotation_right, null: false, default: 0
t.integer :spine_rotation_left, null: false, default: 0
t.integer :deep_squat, null: false, default: 0
t.integer :hands_behind_back_right, null: false, default: 0
t.integer :hands_behind_back_left, null: false, default: 0
t.integer :straight_leg_raise_right, null: false, default: 0
t.integer :straight_leg_raise_left, null: false, default: 0
t.timestamps
end
add_index :assessments, :created_at end end
app/models/assessment.rb
class Assessment < ApplicationRecord validates :name, presence: true validates :age, presence: true, numericality: { greater_than: 0 } validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }, allow_blank: true validates :phone, format: { with: /\A[+]?[\d\s-()]{8,15}\z/ }, allow_blank: true validates :privacy_consent, acceptance: true
# Scores for each exercise (0-3) validates :flexion_extension, presence: true, inclusion: { in: 0..3 } validates :arms_overhead, presence: true, inclusion: { in: 0..3 } validates :spine_rotation_right, presence: true, inclusion: { in: 0..3 } validates :spine_rotation_left, presence: true, inclusion: { in: 0..3 } validates :deep_squat, presence: true, inclusion: { in: 0..3 } validates :hands_behind_back_right, presence: true, inclusion: { in: 0..3 } validates :hands_behind_back_left, presence: true, inclusion: { in: 0..3 } validates :straight_leg_raise_right, presence: true, inclusion: { in: 0..3 } validates :straight_leg_raise_left, presence: true, inclusion: { in: 0..3 }
def total_score flexion_extension + arms_overhead + spine_rotation_right + spine_rotation_left + deep_squat + hands_behind_back_right + hands_behind_back_left + straight_leg_raise_right + straight_leg_raise_left end
def mobility_level case total_score when 0..9 { level: “Limitata”, color: “red”, description: “Mobilità limitata → consigliata valutazione individuale” } when 10..18 { level: “Media”, color: “yellow”, description: “Mobilità media → percorso di gruppo consigliato” } when 19..27 { level: “Buona”, color: “green”, description: “Buona mobilità → accedi a percorsi avanzati o di mantenimento” } end end
def color_class case mobility_level[:color] when “red” “bg-red-100 border-red-500 text-red-800” when “yellow” “bg-yellow-100 border-yellow-500 text-yellow-800” when “green” “bg-green-100 border-green-500 text-green-800” end end end
app/controllers/assessments_controller.rb
class AssessmentsController < ApplicationController before_action :set_assessment, only: [:show, :result]
def new @assessment = Assessment.new end
def create @assessment = Assessment.new(assessment_params)
if @assessment.save
redirect_to result_assessment_path(@assessment)
else
render :new, status: :unprocessable_entity
end end
def show redirect_to result_assessment_path(@assessment) end
def result @mobility_data = @assessment.mobility_level end
private
def set_assessment @assessment = Assessment.find(params[:id]) end
def assessment_params params.require(:assessment).permit( :name, :age, :email, :phone, :privacy_consent, :marketing_consent, :notes, :flexion_extension, :arms_overhead, :spine_rotation_right, :spine_rotation_left, :deep_squat, :hands_behind_back_right, :hands_behind_back_left, :straight_leg_raise_right, :straight_leg_raise_left ) end end
application.html.erb
🧘♂️ Valutazione Mobilità Articolare
Metodo PosturaCorretta - Scheda di valutazione semplificata
app/views/assessments/new.html.erb
Test di Autovalutazione
Questo test ti aiuta a valutare la tua mobilità articolare generale in modo semplice e autonomo. Per ogni movimento, assegna un punteggio da 0 a 3 secondo i criteri riportati.
⚠️ Importante: Esegui ogni movimento lentamente, senza forzare. Se avverti dolore, interrompi il test.
Per ricevere i risultati e promemoria re-test
Per eventuali follow-up o chiarimenti
1. Flesso-estensione in avanti (da in piedi)
2. Braccia sopra la testa (in piedi)
3A. Rotazione globale del rachide (collo + tronco) - Destra
3B. Rotazione globale del rachide (collo + tronco) - Sinistra
4. Squat profondo (a corpo libero)
5A. Mani dietro la schiena (destra sopra)
5B. Mani dietro la schiena (sinistra sopra)
6A. Sollevamento gamba tesa (supino) - Destra
6B. Sollevamento gamba tesa (supino) - Sinistra
app/views/assessments/result.html.erb
Risultati del Test
Valutazione per: <%= @assessment.name %> (<%= @assessment.age %> anni)
<% if @assessment.email.present? %>📧 <%= @assessment.email %>
<% end %> <% if @assessment.phone.present? %>📱 <%= @assessment.phone %>
<% end %>Test completato il <%= @assessment.created_at.strftime("%d/%m/%Y alle %H:%M") %>
<%= @mobility_data[:description] %>
Dettaglio Punteggi
📌 Raccomandazioni
• Ripeti il test ogni 4 settimane per monitorare i tuoi miglioramenti
• Se avverti dolore durante gli esercizi, consulta un professionista
<% case @mobility_data[:color] %> <% when "red" %>Consiglio: Ti consigliamo una valutazione individuale con un professionista qualificato per sviluppare un piano di miglioramento personalizzato.
Consiglio: Un percorso di gruppo potrebbe aiutarti a migliorare la tua mobilità articolare. Considera di partecipare a corsi di ginnastica posturale o stretching.
Complimenti! Hai una buona mobilità articolare. Puoi accedere a percorsi avanzati o di mantenimento per preservare questo livello.
config/application.rb
require_relative “boot”
require “rails/all”
Bundler.require(*Rails.groups)
module MobilityAssessment class Application < Rails::Application config.load_defaults 8.0 config.autoload_lib(ignore: %w[assets tasks])
# Time zone
config.time_zone = 'Rome'
# Locale
config.i18n.default_locale = :it end end
app/assets/stylesheets/application.tailwind.css
@tailwind base; @tailwind components; @tailwind utilities;
@layer base { body { font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; } }
@layer components { .btn-primary { @apply bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition duration-200; }
.card { @apply bg-white rounded-lg shadow-lg p-6; }
.form-input { @apply w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500; } }
@media print { .no-print { display: none; }
body { background: white; }
.shadow-lg { box-shadow: none; border: 1px solid #e5e7eb; } }
prossimi miglioramenti
config/environments/production.rb
require “active_support/core_ext/integer/time”
Rails.application.configure do config.enable_reloading = false config.eager_load = true config.consider_all_requests_local = false config.action_controller.perform_caching = true
config.public_file_server.enabled = true config.public_file_server.headers = { “cache-control” => “public, max-age=#{1.year.to_i}” }
config.cache_store = :solid_cache_store config.active_job.queue_adapter = :solid_queue config.action_cable.adapter = :solid_cable
config.force_ssl = true config.ssl_options = { redirect: { exclude: ->(request) { request.path.start_with?(“/up”) } } }
config.assume_ssl = true config.log_level = ENV.fetch(“RAILS_LOG_LEVEL”, “info”) config.log_tags = [:request_id]
config.action_mailer.perform_caching = false config.action_mailer.default_url_options = { host: ENV.fetch(“APP_HOST”) { “valutazione.igieneposturale.it” }, protocol: “https” }
config.i18n.fallbacks = true config.active_support.report_deprecations = false config.active_record.dump_schema_after_migration = false end
config/database.yml
production: primary: «: *default database: <%= ENV.fetch(“DB_PRIMARY”) %> username: <%= ENV.fetch(“DB_PRIMARY_USER”) %> password: <%= ENV.fetch(“DB_PRIMARY_PASS”) %> host: <%= ENV.fetch(“DB_PRIMARY_HOST”) %>
queue: «: *default database: <%= ENV.fetch(“DB_QUEUE”) %> username: <%= ENV.fetch(“DB_QUEUE_USER”) %> password: <%= ENV.fetch(“DB_QUEUE_PASS”) %> host: <%= ENV.fetch(“DB_QUEUE_HOST”) %>
cache: «: *default database: <%= ENV.fetch(“DB_CACHE”) %> username: <%= ENV.fetch(“DB_CACHE_USER”) %> password: <%= ENV.fetch(“DB_CACHE_PASS”) %> host: <%= ENV.fetch(“DB_CACHE_HOST”) %>
cable: «: *default database: <%= ENV.fetch(“DB_CABLE”) %> username: <%= ENV.fetch(“DB_CABLE_USER”) %> password: <%= ENV.fetch(“DB_CABLE_PASS”) %> host: <%= ENV.fetch(“DB_CABLE_HOST”) %> Poi nei initializer generati dai generator (o che puoi creare tu) indichi quale connessione usare:
ruby Copia Modifica
config/initializers/solid_queue.rb
SolidQueue.configure do |c| c.database = :queue # usa la chiave ‘queue’ di database.yml per l’env corrente end
config/initializers/solid_cache.rb
SolidCache.configure do |c| c.database = :cache end
config/initializers/solid_cable.rb
SolidCable.configure do |c| c.database = :cable end
rails generate controller Admin::Dashboard index assessments users
# Setup per produzione
RAILS_ENV=production rails db:create
RAILS_ENV=production rails db:migrate
RAILS_ENV=production rails assets:precompile
# Variabili ambiente richieste:
export DATABASE_NAME=mobility_assessment_production
export DATABASE_USERNAME=your_db_user
export DATABASE_PASSWORD=your_db_password
export DATABASE_HOST=your_db_host
export APP_HOST=valutazione.igieneposturale.it
export RAILS_MASTER_KEY=your_master_key
Struttura del Test
Esercizi Valutati
- Flesso-estensione in avanti (da in piedi)
- Braccia sopra la testa (in piedi)
- Rotazione globale del rachide (destra e sinistra)
- Squat profondo (a corpo libero)
- Mani dietro la schiena (destra e sinistra sopra)
- Sollevamento gamba tesa (supino, destra e sinistra)
Sistema di Punteggio
- Ogni esercizio: 0-3 punti
- Totale massimo: 27 punti
- Classificazione:
- 🔴 0-9 punti: Mobilità limitata
- 🟡 10-18 punti: Mobilità media
- 🟢 19-27 punti: Buona mobilità
Tecnologie Utilizzate
- Rails 8.0: Framework principale
- TailwindCSS: Styling e responsive design
- PostgreSQL: Database
- Turbo & Stimulus: Interattività frontend
- Solid Cache/Queue/Cable: Performance e background jobs
TODO per Miglioramenti Futuri
- Upload e gestione immagini per ogni esercizio
- Sistema di autenticazione utenti
- Storico progressi e grafici
- Export PDF dei risultati
- API per integrazione con altre app
- Sistema di promemoria per test periodici
- Integrazione video esplicativi per ogni esercizio
Licenza
Sviluppato per IgienePosturale.it - 2024