mumuki-domain 7.8.0 → 7.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/assignment.rb +15 -1
  3. data/app/models/avatar.rb +7 -1
  4. data/app/models/concerns/contextualization.rb +1 -0
  5. data/app/models/concerns/gamified.rb +15 -0
  6. data/app/models/concerns/with_reminders.rb +1 -1
  7. data/app/models/concerns/with_target_audience.rb +13 -0
  8. data/app/models/organization.rb +6 -0
  9. data/app/models/user.rb +38 -6
  10. data/app/models/user_stats.rb +16 -0
  11. data/db/migrate/20200616160640_create_user_stats.rb +10 -0
  12. data/db/migrate/20200617142217_add_top_submission_status_to_assignments.rb +5 -0
  13. data/db/migrate/20200717143830_add_target_audience_to_organizations_and_avatars.rb +6 -0
  14. data/lib/mumuki/domain/extensions.rb +1 -0
  15. data/lib/mumuki/domain/extensions/time.rb +5 -0
  16. data/lib/mumuki/domain/factories.rb +2 -1
  17. data/lib/mumuki/domain/factories/avatar_factory.rb +6 -0
  18. data/lib/mumuki/domain/factories/user_factory.rb +0 -1
  19. data/lib/mumuki/domain/helpers/organization.rb +4 -0
  20. data/lib/mumuki/domain/helpers/user.rb +6 -10
  21. data/lib/mumuki/domain/incognito.rb +12 -1
  22. data/lib/mumuki/domain/locales/activerecord/es-CL.yml +59 -0
  23. data/lib/mumuki/domain/locales/console_submission/es-CL.yml +3 -0
  24. data/lib/mumuki/domain/organization/profile.rb +2 -1
  25. data/lib/mumuki/domain/organization/settings.rb +12 -3
  26. data/lib/mumuki/domain/status/submission/passed.rb +4 -0
  27. data/lib/mumuki/domain/status/submission/passed_with_warnings.rb +4 -0
  28. data/lib/mumuki/domain/status/submission/skipped.rb +4 -0
  29. data/lib/mumuki/domain/status/submission/submission.rb +8 -0
  30. data/lib/mumuki/domain/version.rb +1 -1
  31. metadata +14 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14a6d0b035451e69ddc77479e3f32854ecae51ca0a3c6bc3031f8d68a4b7fcdd
4
- data.tar.gz: a1dbea618e7a152e55417174cecf35a0338a464cd199b02114d524c65c7c23c5
3
+ metadata.gz: 1182f3c80cde421e92bb67ae1a57313bd3a52bbafbb8d0e8cf0a5696dd067ebc
4
+ data.tar.gz: 6a6ba4ecaf5f0c7d2dd8b10a9900141ae7cccc527c32e6b55484636ac7c1e117
5
5
  SHA512:
6
- metadata.gz: d3e2039abf83cd21c0ef3d6b33bcfcef54db1dc7df1eb91fb771ab218076b484b34a4a7c034a1e945d5ab3f84e739fdffbdba05999e2bb1878430af4698e4678
7
- data.tar.gz: 1cc3cb4565b4999bfac4f351fffb0d937c28db74c93e26a94267332b9c15ca8812f0bce4c19e2298169a957d008546bde95442a2ca7d798f9912b2bd3c9c39e8
6
+ metadata.gz: 6e0ab0481ab8cd37417f7d94d18cd73e7f4fb270ff28db3a7ef29f089dde509b34191bf235c1a3945af411c886a3629f3957424a840ff8b6cdbcf71e7fa7d819
7
+ data.tar.gz: fa2f135124d5d4159e9766e28a71b4fee6ee1a3290c22d37f2230153382e9256e3d15663d6d55af22f7aa9ac65750360b3da10056f0e17f565ca78a8064978a3
@@ -1,6 +1,7 @@
1
1
  class Assignment < Progress
2
2
  include Contextualization
3
3
  include WithMessages
4
+ include Gamified
4
5
 
5
6
  markdown_on :extra_preview
6
7
 
@@ -41,6 +42,8 @@ class Assignment < Progress
41
42
  alias_method :parent_content, :guide
42
43
  alias_method :user, :submitter
43
44
 
45
+ after_initialize :set_default_top_submission_status
46
+ before_save :award_experience_points!, :update_top_submission!, if: :submission_status_changed?
44
47
  after_save :dirty_parent_by_submission!, if: :completion_changed?
45
48
  before_validation :set_current_organization!, unless: :organization
46
49
 
@@ -49,6 +52,10 @@ class Assignment < Progress
49
52
  self.organization = Organization.current
50
53
  end
51
54
 
55
+ def set_default_top_submission_status
56
+ self.top_submission_status ||= 0
57
+ end
58
+
52
59
  def completion_changed?
53
60
  completed_before_last_save? != completed?
54
61
  end
@@ -161,7 +168,10 @@ class Assignment < Progress
161
168
  end
162
169
 
163
170
  def to_resource_h
164
- as_json(except: %i(exercise_id submission_id organization_id id submitter_id solution created_at updated_at submission_status submitted_at parent_id),
171
+ excluded_fields = %i(created_at exercise_id id organization_id parent_id solution submission_id
172
+ submission_status submitted_at submitter_id top_submission_status updated_at)
173
+
174
+ as_json(except: excluded_fields,
165
175
  include: {
166
176
  guide: {
167
177
  only: [:slug, :name],
@@ -224,6 +234,10 @@ class Assignment < Progress
224
234
  exercise.files_for(current_content)
225
235
  end
226
236
 
237
+ def update_top_submission!
238
+ self.top_submission_status = submission_status unless submission_status.improved_by?(top_submission_status)
239
+ end
240
+
227
241
  private
228
242
 
229
243
  def update_submissions_count!
@@ -1,5 +1,11 @@
1
1
  class Avatar < ApplicationRecord
2
+ include WithTargetAudience
3
+
4
+ def self.sample_for(user)
5
+ with_current_audience_for(user).sample
6
+ end
7
+
2
8
  def self.sample
3
- Avatar.order('RANDOM()').first
9
+ order('RANDOM()').first
4
10
  end
5
11
  end
@@ -16,6 +16,7 @@ module Contextualization
16
16
  end
17
17
 
18
18
  included do
19
+ serialize :top_submission_status, Mumuki::Domain::Status::Submission
19
20
  serialize :submission_status, Mumuki::Domain::Status::Submission
20
21
  validates_presence_of :submission_status
21
22
 
@@ -0,0 +1,15 @@
1
+ module Gamified
2
+ def award_experience_points!
3
+ points = net_experience
4
+
5
+ if points > 0
6
+ stats = UserStats.stats_for(submitter)
7
+ stats.add_exp!(points)
8
+ stats.save!
9
+ end
10
+ end
11
+
12
+ def net_experience
13
+ submission_status.exp_given - top_submission_status.exp_given
14
+ end
15
+ end
@@ -9,7 +9,7 @@ module WithReminders
9
9
  end
10
10
 
11
11
  def remind!
12
- build_reminder.deliver
12
+ build_reminder.deliver_now
13
13
  update! last_reminded_date: Time.now
14
14
  end
15
15
 
@@ -0,0 +1,13 @@
1
+ module WithTargetAudience
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ enum target_audience: [:grown_ups, :kids]
6
+ end
7
+
8
+ class_methods do
9
+ def with_current_audience_for(user)
10
+ where(target_audience: user.current_audience)
11
+ end
12
+ end
13
+ end
@@ -5,6 +5,8 @@ class Organization < ApplicationRecord
5
5
 
6
6
  include Mumukit::Login::OrganizationHelpers
7
7
 
8
+ include WithTargetAudience
9
+
8
10
  serialize :profile, Mumuki::Domain::Organization::Profile
9
11
  serialize :settings, Mumuki::Domain::Organization::Settings
10
12
  serialize :theme, Mumuki::Domain::Organization::Theme
@@ -128,6 +130,10 @@ class Organization < ApplicationRecord
128
130
  update! progressive_display_lookahead: lookahead
129
131
  end
130
132
 
133
+ def display_name
134
+ name.gsub(/\W/, ' ').titleize
135
+ end
136
+
131
137
  private
132
138
 
133
139
  def ensure_consistent_public_login
@@ -30,16 +30,15 @@ class User < ApplicationRecord
30
30
 
31
31
  has_many :exams, through: :exam_authorizations
32
32
 
33
- after_initialize :init
34
-
35
33
  enum gender: %i(female male other unspecified)
36
-
37
34
  belongs_to :avatar, optional: true
38
35
 
39
36
  before_validation :set_uid!
40
37
  validates :uid, presence: true
41
38
 
42
39
  after_save :welcome_to_new_organizations!, if: :gained_access_to_new_orga?
40
+ after_initialize :init
41
+ PLACEHOLDER_IMAGE_URL = 'user_shape.png'.freeze
43
42
 
44
43
  resource_fields :uid, :social_id, :email, :permissions, :verified_first_name, :verified_last_name, *profile_fields
45
44
 
@@ -147,10 +146,14 @@ class User < ApplicationRecord
147
146
  exams.any? { |e| e.in_progress_for? self }
148
147
  end
149
148
 
150
- def profile_picture
149
+ def custom_profile_picture
151
150
  avatar&.image_url || image_url
152
151
  end
153
152
 
153
+ def profile_picture
154
+ custom_profile_picture || placeholder_image_url
155
+ end
156
+
154
157
  def bury!
155
158
  # TODO change avatar
156
159
  update! self.class.buried_profile.merge(accepts_reminders: false, gender: nil, birthdate: nil)
@@ -187,6 +190,10 @@ class User < ApplicationRecord
187
190
  can_discuss_in? Organization.current
188
191
  end
189
192
 
193
+ def can_access_teacher_info_in?(organization)
194
+ teacher_of?(organization) || organization.teacher_training?
195
+ end
196
+
190
197
  def name_initials
191
198
  name.split.map(&:first).map(&:capitalize).join(' ')
192
199
  end
@@ -215,11 +222,25 @@ class User < ApplicationRecord
215
222
  false
216
223
  end
217
224
 
225
+ def current_audience
226
+ current_organic_context&.target_audience
227
+ end
228
+
229
+ def placeholder_image_url
230
+ PLACEHOLDER_IMAGE_URL
231
+ end
232
+
233
+ def age
234
+ if birthdate.present?
235
+ @age ||= Time.now.round_years_since(birthdate.to_time)
236
+ end
237
+ end
238
+
218
239
  private
219
240
 
220
241
  def welcome_to_new_organizations!
221
242
  new_accessible_organizations.each do |organization|
222
- UserMailer.welcome_email(self, organization).deliver_later if organization.greet_new_users?
243
+ UserMailer.welcome_email(self, organization).deliver_now rescue nil if organization.greet_new_users?
223
244
  end
224
245
  end
225
246
 
@@ -240,7 +261,10 @@ class User < ApplicationRecord
240
261
  end
241
262
 
242
263
  def init
243
- self.avatar = Avatar.sample unless profile_picture.present?
264
+ if custom_profile_picture.blank?
265
+ self.avatar = Avatar.sample_for(self)
266
+ save if persisted?
267
+ end
244
268
  end
245
269
 
246
270
  def self.sync_key_id_field
@@ -265,4 +289,12 @@ class User < ApplicationRecord
265
289
  def self.buried_profile
266
290
  (@buried_profile || {}).slice(:first_name, :last_name, :email)
267
291
  end
292
+
293
+ def current_organic_context
294
+ if Organization.current?
295
+ Organization.current
296
+ else
297
+ main_organization
298
+ end
299
+ end
268
300
  end
@@ -0,0 +1,16 @@
1
+ class UserStats < ApplicationRecord
2
+ belongs_to :organization
3
+ belongs_to :user
4
+
5
+ def self.stats_for(user)
6
+ UserStats.find_or_initialize_by(user: user, organization: Organization.current)
7
+ end
8
+
9
+ def self.exp_for(user)
10
+ self.stats_for(user).exp
11
+ end
12
+
13
+ def add_exp!(points)
14
+ self.exp += points
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ class CreateUserStats < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :user_stats do |t|
4
+ t.integer :exp, default: 0
5
+
6
+ t.references :user, index: true
7
+ t.references :organization, index: true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ class AddTopSubmissionStatusToAssignments < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :assignments, :top_submission_status, :integer
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class AddTargetAudienceToOrganizationsAndAvatars < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :organizations, :target_audience, :integer, default: 0
4
+ add_column :avatars, :target_audience, :integer, default: 0
5
+ end
6
+ end
@@ -2,3 +2,4 @@ require_relative './extensions/string'
2
2
  require_relative './extensions/array'
3
3
  require_relative './extensions/module'
4
4
  require_relative './extensions/hash'
5
+ require_relative './extensions/time'
@@ -0,0 +1,5 @@
1
+ class Time
2
+ def round_years_since(another_time)
3
+ (self.to_s(:number).to_i - another_time.to_s(:number).to_i) / 10e9.to_i
4
+ end
5
+ end
@@ -1,5 +1,6 @@
1
1
  require_relative './factories/api_client_factory'
2
2
  require_relative './factories/assignments_factory'
3
+ require_relative './factories/avatar_factory'
3
4
  require_relative './factories/book_factory'
4
5
  require_relative './factories/chapter_factory'
5
6
  require_relative './factories/complement_factory'
@@ -15,4 +16,4 @@ require_relative './factories/message_factory'
15
16
  require_relative './factories/organization_factory'
16
17
  require_relative './factories/topic_factory'
17
18
  require_relative './factories/user_factory'
18
- require_relative './factories/usage_factory'
19
+ require_relative './factories/usage_factory'
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ factory :avatar do
3
+ image_url { Faker::Internet.url }
4
+ target_audience { :grown_ups }
5
+ end
6
+ end
@@ -6,6 +6,5 @@ FactoryBot.define do
6
6
  last_name { Faker::Name.last_name }
7
7
  gender { 1 }
8
8
  birthdate { Date.today }
9
- avatar { Avatar.new image_url: 'user_shape.png' }
10
9
  end
11
10
  end
@@ -66,6 +66,10 @@ module Mumuki::Domain::Helpers::Organization
66
66
  Mumukit::Platform::Organization.current
67
67
  end
68
68
 
69
+ def current?
70
+ Mumukit::Platform::Organization.current?
71
+ end
72
+
69
73
  def parse(json)
70
74
  json
71
75
  .slice(:name)
@@ -13,6 +13,8 @@ module Mumuki::Domain::Helpers::User
13
13
  :protect!,
14
14
  :protect_delegation!,
15
15
  :protect_permissions_assignment!,
16
+ :student_granted_organizations,
17
+ :any_granted_organizations,
16
18
  to: :permissions
17
19
 
18
20
  def platform_class_name
@@ -71,12 +73,10 @@ module Mumuki::Domain::Helpers::User
71
73
  "#{full_name} <#{email}> [#{uid}]"
72
74
  end
73
75
 
74
- ## Accesible organizations
76
+ ## Accessible organizations
75
77
 
76
- def student_granted_organizations
77
- permissions.student_granted_organizations.map do |org|
78
- Mumukit::Platform::Organization.find_by_name!(org) rescue nil
79
- end.compact
78
+ revamp_accessor :any_granted_organizations, :student_granted_organizations do |_, _, result|
79
+ result.map { |org| Mumukit::Platform::Organization.find_by_name!(org) rescue nil }.compact
80
80
  end
81
81
 
82
82
  def has_student_granted_organizations?
@@ -84,11 +84,7 @@ module Mumuki::Domain::Helpers::User
84
84
  end
85
85
 
86
86
  def main_organization
87
- student_granted_organizations.first
88
- end
89
-
90
- def has_main_organization?
91
- student_granted_organizations.length == 1
87
+ student_granted_organizations.first || any_granted_organizations.first
92
88
  end
93
89
 
94
90
  def has_immersive_main_organization?
@@ -40,6 +40,14 @@ module Mumuki::Domain
40
40
  false
41
41
  end
42
42
 
43
+ def can_discuss_in?(*)
44
+ false
45
+ end
46
+
47
+ def can_access_teacher_info_in?(*)
48
+ false
49
+ end
50
+
43
51
  # ========
44
52
  # Visiting
45
53
  # ========
@@ -88,6 +96,10 @@ module Mumuki::Domain
88
96
  raise "unknown attribute #{key}"
89
97
  end
90
98
 
99
+ def new_record?
100
+ false
101
+ end
102
+
91
103
  def self.primary_key
92
104
  'id'
93
105
  end
@@ -105,7 +117,6 @@ module Mumuki::Domain
105
117
  assignment.assign_attributes results
106
118
  results
107
119
  end
108
-
109
120
  end
110
121
 
111
122
  Incognito = IncognitoClass.new
@@ -0,0 +1,59 @@
1
+ ---
2
+ es-CL:
3
+ activerecord:
4
+ attributes:
5
+ exercise:
6
+ description: Descripción
7
+ extra: Biblioteca
8
+ hint: Ayudas
9
+ language: Lenguaje
10
+ locale: Idioma
11
+ tag_list: Etiquetas
12
+ title: Título
13
+ guide:
14
+ description: Descripción
15
+ github_repository: Repositorio Github
16
+ language: Lenguaje
17
+ locale: Idioma
18
+ name: Nombre
19
+ submission:
20
+ content: Contenido
21
+ errors:
22
+ models:
23
+ guide:
24
+ attributes:
25
+ base:
26
+ in_use: 'La guía aún está siendo utilizada en la organización %{organization}'
27
+ topic:
28
+ attributes:
29
+ base:
30
+ in_use: 'El tema aún está siendo utilizado en la organización %{organization}'
31
+ exercise:
32
+ attributes:
33
+ randomizations:
34
+ invalid_format: 'formato inválido'
35
+ own_expectations:
36
+ invalid_format: 'formato inválido'
37
+ assistance_rules:
38
+ invalid_format: 'formato inválido'
39
+ name:
40
+ invalid_format: 'no debe contener /'
41
+ base:
42
+ evaluation_criteria_required: 'Tienes que proveer tests y/o expectativas'
43
+ organization:
44
+ attributes:
45
+ base:
46
+ consistent_public_login: 'Una organización pública no puede restringir los métodos de login'
47
+ invalid_activity_range: 'La fecha de inhabilitación no puede ser anterior a la de inicio del recorrido'
48
+ models:
49
+ exercise:
50
+ one: Ejercicio
51
+ other: Ejercicios
52
+ chapter:
53
+ one: Capítulo
54
+ other: Capítulos
55
+ guide: Guía
56
+ language: Lenguaje
57
+ submission:
58
+ one: Solución
59
+ other: Soluciones
@@ -0,0 +1,3 @@
1
+ es-CL:
2
+ console_submission:
3
+ try_again: ¡Ups! Algo salió mal en mumuki. Reinicia el ejercicio, espera unos segundos y vuelve a intentar.
@@ -12,7 +12,8 @@ class Mumuki::Domain::Organization::Profile < Mumukit::Platform::Model
12
12
  :terms_of_service,
13
13
  :community_link,
14
14
  :errors_explanations,
15
- :welcome_email_template
15
+ :welcome_email_template,
16
+ :welcome_email_sender
16
17
 
17
18
  def locale_json
18
19
  locale_h.to_json
@@ -8,6 +8,7 @@ class Mumuki::Domain::Organization::Settings < Mumukit::Platform::Model
8
8
  :forum_enabled?,
9
9
  :forum_only_for_trusted?,
10
10
  :gamification_enabled?,
11
+ :greet_new_users?,
11
12
  :immersive?,
12
13
  :in_preparation_until,
13
14
  :login_methods,
@@ -16,7 +17,7 @@ class Mumuki::Domain::Organization::Settings < Mumukit::Platform::Model
16
17
  :public?,
17
18
  :raise_hand_enabled?,
18
19
  :report_issue_enabled?,
19
- :greet_new_users?
20
+ :teacher_training?
20
21
 
21
22
  def private?
22
23
  !public?
@@ -30,11 +31,19 @@ class Mumuki::Domain::Organization::Settings < Mumukit::Platform::Model
30
31
  (@forum_discussions_minimal_role || 'student').to_sym
31
32
  end
32
33
 
34
+ def disabled_from=(disabled_from)
35
+ @disabled_from = disabled_from&.to_time
36
+ end
37
+
38
+ def in_preparation_until=(in_preparation_until)
39
+ @in_preparation_until = in_preparation_until&.to_time
40
+ end
41
+
33
42
  def disabled?
34
- disabled_from.present? && disabled_from.to_datetime < DateTime.now
43
+ disabled_from.present? && disabled_from < Time.now
35
44
  end
36
45
 
37
46
  def in_preparation?
38
- in_preparation_until.present? && in_preparation_until.to_datetime > DateTime.now
47
+ in_preparation_until.present? && in_preparation_until > Time.now
39
48
  end
40
49
  end
@@ -8,4 +8,8 @@ module Mumuki::Domain::Status::Submission::Passed
8
8
  def self.iconize
9
9
  {class: :success, type: 'check-circle'}
10
10
  end
11
+
12
+ def self.exp_given
13
+ 100
14
+ end
11
15
  end
@@ -12,4 +12,8 @@ module Mumuki::Domain::Status::Submission::PassedWithWarnings
12
12
  def self.iconize
13
13
  {class: :warning, type: 'exclamation-circle'}
14
14
  end
15
+
16
+ def self.exp_given
17
+ 50
18
+ end
15
19
  end
@@ -8,4 +8,8 @@ module Mumuki::Domain::Status::Submission::Skipped
8
8
  def self.iconize
9
9
  {class: :success, type: 'check-circle'}
10
10
  end
11
+
12
+ def self.exp_given
13
+ 100
14
+ end
11
15
  end
@@ -42,4 +42,12 @@ module Mumuki::Domain::Status::Submission
42
42
  def solved?
43
43
  passed? || skipped?
44
44
  end
45
+
46
+ def improved_by?(status)
47
+ self.exp_given < status.exp_given
48
+ end
49
+
50
+ def exp_given
51
+ 0
52
+ end
45
53
  end
@@ -1,5 +1,5 @@
1
1
  module Mumuki
2
2
  module Domain
3
- VERSION = '7.8.0'
3
+ VERSION = '7.10.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mumuki-domain
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.8.0
4
+ version: 7.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franco Leonardo Bulgarelli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-28 00:00:00.000000000 Z
11
+ date: 2020-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '5.1'
131
+ version: '5.2'
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '5.1'
138
+ version: '5.2'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: mumukit-sync
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -256,6 +256,7 @@ files:
256
256
  - app/models/concerns/contextualization.rb
257
257
  - app/models/concerns/disabling.rb
258
258
  - app/models/concerns/friendly_name.rb
259
+ - app/models/concerns/gamified.rb
259
260
  - app/models/concerns/guide_container.rb
260
261
  - app/models/concerns/navigation/parent_navigation.rb
261
262
  - app/models/concerns/navigation/siblings_navigation.rb
@@ -292,6 +293,7 @@ files:
292
293
  - app/models/concerns/with_scoped_queries/page.rb
293
294
  - app/models/concerns/with_scoped_queries/sort.rb
294
295
  - app/models/concerns/with_slug.rb
296
+ - app/models/concerns/with_target_audience.rb
295
297
  - app/models/concerns/with_usages.rb
296
298
  - app/models/concerns/with_user_navigation.rb
297
299
  - app/models/content.rb
@@ -322,6 +324,7 @@ files:
322
324
  - app/models/upvote.rb
323
325
  - app/models/usage.rb
324
326
  - app/models/user.rb
327
+ - app/models/user_stats.rb
325
328
  - app/models/with_stats.rb
326
329
  - db/migrate/20141120231135_create_exercises.rb
327
330
  - db/migrate/20141120231735_create_submissions.rb
@@ -608,7 +611,10 @@ files:
608
611
  - db/migrate/20200601203033_add_course_to_exam.rb
609
612
  - db/migrate/20200605161350_add_passing_criterions_to_exam.rb
610
613
  - db/migrate/20200608132959_add_progressive_display_lookahead_to_organizations.rb
614
+ - db/migrate/20200616160640_create_user_stats.rb
615
+ - db/migrate/20200617142217_add_top_submission_status_to_assignments.rb
611
616
  - db/migrate/20200702165503_add_messages_count_to_discussion.rb
617
+ - db/migrate/20200717143830_add_target_audience_to_organizations_and_avatars.rb
612
618
  - db/migrate/20200728162727_add_not_actually_a_question_field_to_messages.rb
613
619
  - db/migrate/20200728163038_add_requires_moderator_response_to_discussions.rb
614
620
  - db/migrate/20200730221001_add_trusted_for_forum_to_user.rb
@@ -634,9 +640,11 @@ files:
634
640
  - lib/mumuki/domain/extensions/hash.rb
635
641
  - lib/mumuki/domain/extensions/module.rb
636
642
  - lib/mumuki/domain/extensions/string.rb
643
+ - lib/mumuki/domain/extensions/time.rb
637
644
  - lib/mumuki/domain/factories.rb
638
645
  - lib/mumuki/domain/factories/api_client_factory.rb
639
646
  - lib/mumuki/domain/factories/assignments_factory.rb
647
+ - lib/mumuki/domain/factories/avatar_factory.rb
640
648
  - lib/mumuki/domain/factories/book_factory.rb
641
649
  - lib/mumuki/domain/factories/chapter_factory.rb
642
650
  - lib/mumuki/domain/factories/complement_factory.rb
@@ -660,9 +668,11 @@ files:
660
668
  - lib/mumuki/domain/helpers/user.rb
661
669
  - lib/mumuki/domain/incognito.rb
662
670
  - lib/mumuki/domain/locales/activerecord/en.yml
671
+ - lib/mumuki/domain/locales/activerecord/es-CL.yml
663
672
  - lib/mumuki/domain/locales/activerecord/es.yml
664
673
  - lib/mumuki/domain/locales/activerecord/pt.yml
665
674
  - lib/mumuki/domain/locales/console_submission/en.yml
675
+ - lib/mumuki/domain/locales/console_submission/es-CL.yml
666
676
  - lib/mumuki/domain/locales/console_submission/es.yml
667
677
  - lib/mumuki/domain/locales/console_submission/pt.yml
668
678
  - lib/mumuki/domain/organization.rb