Compare commits

...

65 Commits

Author SHA1 Message Date
Renovate Bot
f550b8d92c Update dependency rubocop-rspec to v3.4.0
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m55s
Add copyright notice / copyright_notice (pull_request) Successful in 2m55s
Run unit tests / unit_tests (pull_request) Successful in 5m3s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 13m25s
Check usage of free licenses / check-licenses (push) Successful in 47s
Run unit tests / unit_tests (push) Successful in 1m50s
Build Nginx-based docker image / build-static-assets (push) Successful in 11m57s
2025-01-21 03:03:34 +00:00
7c968f555f Merge pull request 'Use group affinities in discomfort calculator' (#215) from discomfort-calculation-revamp into main
All checks were successful
Check usage of free licenses / check-licenses (push) Successful in 34s
Run unit tests / unit_tests (push) Successful in 1m40s
Build Nginx-based docker image / build-static-assets (push) Successful in 17m44s
Reviewed-on: #215
2025-01-19 20:19:10 +00:00
1f0c6c2aac Use group affinities in discomfort calculator
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 50s
Add copyright notice / copyright_notice (pull_request) Successful in 1m11s
Run unit tests / unit_tests (pull_request) Successful in 1m58s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 19m18s
2025-01-19 20:58:42 +01:00
390899524b Fix rubocop ofenses
All checks were successful
Add copyright notice / copyright_notice (pull_request) Successful in 1m5s
Run unit tests / unit_tests (pull_request) Successful in 2m49s
Check usage of free licenses / check-licenses (pull_request) Successful in 1m7s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 22m13s
Check usage of free licenses / check-licenses (push) Successful in 42s
Run unit tests / unit_tests (push) Successful in 1m32s
Build Nginx-based docker image / build-static-assets (push) Successful in 26m19s
2025-01-19 19:44:22 +01:00
Renovate Bot
59e7653064 Update dependency rubocop-rails to v2.29.0
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Successful in 49s
Run unit tests / unit_tests (pull_request) Failing after 48s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 24m24s
Add copyright notice / copyright_notice (pull_request) Successful in 1m51s
2025-01-19 03:18:52 +00:00
d6fd72a45c Merge pull request 'Fix duplicate row index on upsert statement' (#213) from fix-upsert-index into main
All checks were successful
Check usage of free licenses / check-licenses (push) Successful in 51s
Run unit tests / unit_tests (push) Successful in 1m48s
Build Nginx-based docker image / build-static-assets (push) Successful in 12m11s
Reviewed-on: #213
2025-01-14 22:11:43 +00:00
889485eaab Merge branch 'main' into fix-upsert-index
All checks were successful
Add copyright notice / copyright_notice (pull_request) Successful in 1m51s
Check usage of free licenses / check-licenses (pull_request) Successful in 1m9s
Run unit tests / unit_tests (pull_request) Successful in 3m18s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 15m7s
2025-01-14 21:08:36 +00:00
105a0ad30c Merge pull request 'Upgrade to ruby 3.4' (#196) from ruby-3-4 into main
Some checks failed
Run unit tests / unit_tests (push) Failing after 17s
Check usage of free licenses / check-licenses (push) Successful in 39s
Build Nginx-based docker image / build-static-assets (push) Successful in 25m52s
Reviewed-on: #196
2025-01-14 20:39:46 +00:00
d03ef173e6 Merge branch 'main' into ruby-3-4
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 58s
Add copyright notice / copyright_notice (pull_request) Successful in 1m31s
Run unit tests / unit_tests (pull_request) Successful in 3m1s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 29m24s
2025-01-14 20:10:18 +00:00
b86d537cdc Install missing libyaml dependencies
All checks were successful
Run unit tests / unit_tests (pull_request) Successful in 2m10s
Check usage of free licenses / check-licenses (pull_request) Successful in 48s
Add copyright notice / copyright_notice (pull_request) Successful in 1m22s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 30m20s
2025-01-14 20:59:30 +01:00
c1774a1c6c Upgrade Nokogiri to the latest version
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Successful in 41s
Run unit tests / unit_tests (pull_request) Successful in 2m9s
Build Nginx-based docker image / build-static-assets (pull_request) Failing after 10m38s
Add copyright notice / copyright_notice (pull_request) Successful in 1m15s
2025-01-14 20:16:02 +01:00
23d09df543 Fix version of GH action
Some checks failed
Build Nginx-based docker image / build-static-assets (pull_request) Failing after 11m42s
Check usage of free licenses / check-licenses (pull_request) Successful in 1m0s
Add copyright notice / copyright_notice (pull_request) Successful in 1m13s
Run unit tests / unit_tests (pull_request) Successful in 1m54s
2025-01-14 20:11:59 +01:00
44dbb7e005 Run bundle lock --normalize-platforms 2025-01-14 20:11:34 +01:00
8a9d0bfdb8 Use the lateste version of ruby/setup-ruby
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Failing after 47s
Add copyright notice / copyright_notice (pull_request) Successful in 1m16s
Run unit tests / unit_tests (pull_request) Successful in 4m34s
Build Nginx-based docker image / build-static-assets (pull_request) Failing after 11m25s
2025-01-14 19:51:29 +01:00
c6c5a87d8b Fix duplicate row index on upsert statement
Some checks failed
Add copyright notice / copyright_notice (pull_request) Successful in 1m22s
Run unit tests / unit_tests (pull_request) Successful in 2m59s
Build Nginx-based docker image / build-static-assets (pull_request) Failing after 8m46s
Check usage of free licenses / check-licenses (pull_request) Successful in 1m49s
2025-01-14 19:13:40 +01:00
acf3b7b82a Merge pull request 'Update copyright assignment to cover 2025 and include all contributors' (#212) from copyright-2025 into main
All checks were successful
Check usage of free licenses / check-licenses (push) Successful in 42s
Run unit tests / unit_tests (push) Successful in 2m3s
Build Nginx-based docker image / build-static-assets (push) Successful in 12m11s
Reviewed-on: #212
2025-01-13 21:04:10 +00:00
0ade367fb5 Merge pull request 'Define an endpoint to reset the discomfort between all groups' (#211) from full-affinity-reset into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 1m0s
Run unit tests / unit_tests (push) Successful in 1m35s
Build Nginx-based docker image / build-static-assets (push) Has been cancelled
Reviewed-on: #211
2025-01-13 20:57:43 +00:00
91bbae1c63 Add copyright notice
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 59s
Add copyright notice / copyright_notice (pull_request) Successful in 2m21s
Run unit tests / unit_tests (pull_request) Successful in 3m2s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 25m17s
2025-01-13 20:38:47 +00:00
e20a366410 Update copyright assignment to cover 2025 and include all contributors
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 56s
Add copyright notice / copyright_notice (pull_request) Successful in 1m36s
Run unit tests / unit_tests (pull_request) Successful in 3m56s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 28m26s
2025-01-13 21:37:02 +01:00
a154e92b6c Define an endpoint to reset the discomfort between all groups
All checks were successful
Add copyright notice / copyright_notice (pull_request) Successful in 1m15s
Run unit tests / unit_tests (pull_request) Successful in 2m2s
Check usage of free licenses / check-licenses (pull_request) Successful in 1m13s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 26m4s
2025-01-13 21:16:22 +01:00
65a265b900 Merge pull request 'Define an endpoint to return the default affinities of a group' (#209) from affinity-reset into main
All checks were successful
Check usage of free licenses / check-licenses (push) Successful in 36s
Run unit tests / unit_tests (push) Successful in 1m15s
Build Nginx-based docker image / build-static-assets (push) Successful in 12m1s
Reviewed-on: #209
2025-01-12 21:34:04 +00:00
f997657cd3 Define an endpoint to return the default affinities of a group
All checks were successful
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 16m44s
Add copyright notice / copyright_notice (pull_request) Successful in 1m45s
Check usage of free licenses / check-licenses (pull_request) Successful in 1m10s
Run unit tests / unit_tests (pull_request) Successful in 9m16s
2025-01-12 20:41:01 +01:00
37bbc1e4f1 Merge pull request 'Update dependency factory_bot_rails to v6.4.4' (#206) from renovate/factory_bot_rails-6.x-lockfile into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 42s
Run unit tests / unit_tests (push) Successful in 1m59s
Build Nginx-based docker image / build-static-assets (push) Failing after 1h53m59s
Reviewed-on: #206
2025-01-12 18:31:51 +00:00
Renovate Bot
088c609a44 Update dependency rubytree to v2.1.1
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m47s
Add copyright notice / copyright_notice (pull_request) Successful in 2m10s
Run unit tests / unit_tests (pull_request) Successful in 3m54s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 20m51s
Check usage of free licenses / check-licenses (push) Successful in 41s
Run unit tests / unit_tests (push) Successful in 1m31s
Build Nginx-based docker image / build-static-assets (push) Successful in 20m4s
2025-01-12 03:06:30 +00:00
Renovate Bot
fd40fb61b5 Update dependency factory_bot_rails to v6.4.4
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m44s
Add copyright notice / copyright_notice (pull_request) Successful in 2m17s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 14m23s
Run unit tests / unit_tests (pull_request) Successful in 3m32s
2025-01-12 03:06:19 +00:00
Renovate Bot
5db5281d9f Update dependency rubocop to v1.70.0
All checks were successful
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 39m41s
Check usage of free licenses / check-licenses (push) Successful in 1m9s
Run unit tests / unit_tests (push) Successful in 2m38s
Build Nginx-based docker image / build-static-assets (push) Successful in 20m11s
Add copyright notice / copyright_notice (pull_request) Successful in 2m28s
Check usage of free licenses / check-licenses (pull_request) Successful in 2m44s
Run unit tests / unit_tests (pull_request) Successful in 5m52s
2025-01-11 03:10:32 +00:00
492c8e362a Upgrade to ruby 3.4.1
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Failing after 30s
Run unit tests / unit_tests (pull_request) Failing after 1m20s
Add copyright notice / copyright_notice (pull_request) Successful in 1m21s
Build Nginx-based docker image / build-static-assets (pull_request) Failing after 8m9s
2024-12-30 08:15:56 +00:00
c5c7ea6d54 WIP: Upgrade to ruby 3.4 2024-12-30 08:15:56 +00:00
e175a3dd34 Merge pull request 'Build image on PR instead of on push' (#204) from build-image-on-pr into main
All checks were successful
Check usage of free licenses / check-licenses (push) Successful in 28s
Run unit tests / unit_tests (push) Successful in 1m32s
Build Nginx-based docker image / build-static-assets (push) Successful in 14m58s
Reviewed-on: #204
2024-12-30 07:37:28 +00:00
a8f0302bb9 Build image on PR instead of on push
All checks were successful
Add copyright notice / copyright_notice (pull_request) Successful in 1m2s
Check usage of free licenses / check-licenses (pull_request) Successful in 1m10s
Run unit tests / unit_tests (pull_request) Successful in 1m52s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 11m15s
2024-12-29 16:23:52 +01:00
1e533702fd Merge pull request 'Configure build and cache for intermediate layers' (#203) from optimize-docker-build into main
All checks were successful
Check usage of free licenses / check-licenses (push) Successful in 36s
Run unit tests / unit_tests (push) Successful in 1m46s
Build Nginx-based docker image / build-static-assets (push) Successful in 1m50s
Check usage of free licenses / check-licenses (pull_request) Successful in 1m0s
Add copyright notice / copyright_notice (pull_request) Successful in 1m34s
Run unit tests / unit_tests (pull_request) Successful in 2m5s
Reviewed-on: #203
2024-12-29 12:42:40 +00:00
9c3c766175 Configure build and cache for intermediate layers
All checks were successful
Add copyright notice / copyright_notice (pull_request) Successful in 1m5s
Check usage of free licenses / check-licenses (pull_request) Successful in 2m12s
Run unit tests / unit_tests (pull_request) Successful in 4m59s
Build Nginx-based docker image / build-static-assets (push) Successful in 17m31s
2024-12-29 13:25:02 +01:00
Renovate Bot
d2841a449e Update dependency solid_queue to v1.1.2
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Successful in 3m37s
Add copyright notice / copyright_notice (pull_request) Successful in 5m8s
Run unit tests / unit_tests (pull_request) Successful in 8m7s
Run unit tests / unit_tests (push) Failing after 1m18s
Check usage of free licenses / check-licenses (push) Successful in 1m22s
Build Nginx-based docker image / build-static-assets (push) Successful in 25m50s
2024-12-29 01:08:54 +00:00
802ec2761c Merge pull request 'rubocop-autocorrect' (#202) from rubocop-autocorrect into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 45s
Build Nginx-based docker image / build-static-assets (push) Failing after 1m30s
Run unit tests / unit_tests (push) Successful in 2m3s
Reviewed-on: #202
2024-12-28 18:26:28 +00:00
eded3946de Restore source in gemfile
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 2m45s
Add copyright notice / copyright_notice (pull_request) Successful in 2m57s
Run unit tests / unit_tests (pull_request) Successful in 3m59s
2024-12-28 18:39:25 +01:00
55e6cfcd36 Fix order of Ruby's magic string comment and Copyright assignment
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Failing after 1m53s
Run unit tests / unit_tests (pull_request) Failing after 3m11s
Add copyright notice / copyright_notice (pull_request) Successful in 3m16s
2024-12-28 18:37:47 +01:00
5f2778c97a Restore original name
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Failing after 1m24s
Run unit tests / unit_tests (pull_request) Failing after 2m11s
Add copyright notice / copyright_notice (pull_request) Successful in 2m12s
2024-12-28 18:35:42 +01:00
20cca87cdd Run rubocop checks as part of CI
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Failing after 40s
Run unit tests and Rubocop / unit_tests (pull_request) Failing after 1m28s
Add copyright notice / copyright_notice (pull_request) Failing after 1m39s
2024-12-28 18:35:04 +01:00
cb10d50d9e Rename .github -> .gitea 2024-12-28 18:32:46 +01:00
b16ef1e237 Run Rubocop autocorrect on the rest of the project 2024-12-28 18:30:54 +01:00
0c7c69ee5e Run Rubocop autocorrect on app/controllers 2024-12-28 18:28:38 +01:00
4fc95185fb Run Rubocop autocorrect on app/helpers 2024-12-28 18:21:16 +01:00
02fcd03b0e Run Rubocop autocorrect on app/services 2024-12-28 18:20:09 +01:00
fbc6926402 Run Rubocop autocorrect on app/queries 2024-12-28 18:16:36 +01:00
19dcb551fa Run Rubocop autocorrect on app/models 2024-12-28 18:13:57 +01:00
2fc8a6340b Run Rubocop autocorrect on spec/ 2024-12-28 18:07:40 +01:00
c15d0806a8 Add exception to some Rubocop offenses 2024-12-28 17:49:00 +01:00
27c7feebee Run Rubocop autocorrect on spec/queries 2024-12-28 17:37:49 +01:00
b85e2ef932 Run Rubocop autocorrect on spec/extensions 2024-12-28 17:37:49 +01:00
c7b9c83f37 Add copyright notice
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Failing after 47s
Add copyright notice / copyright_notice (pull_request) Successful in 1m21s
Run unit tests / unit_tests (pull_request) Failing after 1m25s
2024-12-28 16:31:27 +00:00
82f17056be Run rubocop autocorrect on factory files
Some checks failed
Check usage of free licenses / check-licenses (pull_request) Failing after 46s
Run unit tests / unit_tests (pull_request) Failing after 1m29s
Add copyright notice / copyright_notice (pull_request) Successful in 1m37s
2024-12-28 17:28:16 +01:00
4d69863974 Run Rubocop autocorrect on spec/models 2024-12-28 17:27:45 +01:00
5fcac34a52 Install Rubocop extensions 2024-12-28 17:08:57 +01:00
ad88fb0909 Merge pull request 'Define model and endpoints to store affinity between group pairs' (#200) from affinities-controller into main
Some checks failed
Check usage of free licenses / check-licenses (push) Successful in 40s
Run unit tests / unit_tests (push) Successful in 2m17s
Build Nginx-based docker image / build-static-assets (push) Failing after 2m43s
Reviewed-on: #200
2024-12-28 15:47:57 +00:00
9fe649f8b8 Update swagger documentation
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 37s
Add copyright notice / copyright_notice (pull_request) Successful in 55s
Run unit tests / unit_tests (pull_request) Successful in 1m42s
2024-12-28 16:43:58 +01:00
5784c89b79 Refine endpoint to receive an affinity value and transform it into a discomfort equivalent
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 49s
Add copyright notice / copyright_notice (pull_request) Successful in 1m14s
Run unit tests / unit_tests (pull_request) Successful in 3m25s
2024-12-28 14:19:06 +01:00
0780b17f4b Add copyright notice
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m20s
Add copyright notice / copyright_notice (pull_request) Successful in 41s
Run unit tests / unit_tests (pull_request) Successful in 2m11s
2024-12-26 19:30:32 +00:00
6c6ae62e5a Define model and endpoints to store affinity between group pairs
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m7s
Add copyright notice / copyright_notice (pull_request) Successful in 1m18s
Run unit tests / unit_tests (pull_request) Successful in 2m16s
2024-12-26 20:29:06 +01:00
3b2f52da9b Update dependency pry to v0.15.2 (#195)
All checks were successful
Check usage of free licenses / check-licenses (push) Successful in 38s
Run unit tests / unit_tests (push) Successful in 1m45s
Build Nginx-based docker image / build-static-assets (push) Successful in 24m14s
2024-12-25 07:18:03 +00:00
Renovate Bot
9ac8b9b783 Update dependency pry to v0.15.2
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m33s
Add copyright notice / copyright_notice (pull_request) Successful in 2m19s
Run unit tests / unit_tests (pull_request) Successful in 3m42s
2024-12-25 01:05:11 +00:00
Renovate Bot
1318f34cec Update dependency csv to v3.3.2
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 1m27s
Add copyright notice / copyright_notice (pull_request) Successful in 3m2s
Run unit tests / unit_tests (pull_request) Successful in 4m57s
Check usage of free licenses / check-licenses (push) Successful in 1m2s
Run unit tests / unit_tests (push) Successful in 2m16s
Build Nginx-based docker image / build-static-assets (push) Successful in 21m38s
2024-12-24 01:04:34 +00:00
bd4e0a0135 Merge pull request 'Update dependency factory_bot_rails to v6.4.4' (#189) from renovate/factory_bot_rails-6.x-lockfile into main
All checks were successful
Check usage of free licenses / check-licenses (push) Successful in 51s
Run unit tests / unit_tests (push) Successful in 3m46s
Build Nginx-based docker image / build-static-assets (push) Successful in 26m1s
Reviewed-on: #189
2024-12-23 18:21:20 +00:00
Renovate Bot
4f2c3ee1a6 Update dependency importmap-rails to v2.1.0
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 2m20s
Add copyright notice / copyright_notice (pull_request) Successful in 4m57s
Run unit tests / unit_tests (pull_request) Successful in 6m11s
Check usage of free licenses / check-licenses (push) Successful in 1m47s
Run unit tests / unit_tests (push) Successful in 3m44s
Build Nginx-based docker image / build-static-assets (push) Successful in 22m45s
2024-12-23 01:05:11 +00:00
Renovate Bot
a7e40f3d63 Update dependency factory_bot_rails to v6.4.4
All checks were successful
Check usage of free licenses / check-licenses (pull_request) Successful in 2m23s
Add copyright notice / copyright_notice (pull_request) Successful in 3m35s
Run unit tests / unit_tests (pull_request) Successful in 4m52s
2024-12-23 01:05:04 +00:00
43f4143df3 Merge pull request 'Upgrade bundler version and include gem checksums' (#191) from bundler-update into main
All checks were successful
Check usage of free licenses / check-licenses (push) Successful in 48s
Run unit tests / unit_tests (push) Successful in 2m3s
Build Nginx-based docker image / build-static-assets (push) Successful in 21m31s
Reviewed-on: #191
2024-12-21 08:34:09 +00:00
155 changed files with 1297 additions and 563 deletions

View File

@ -3,6 +3,7 @@ on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
@ -24,13 +25,22 @@ jobs:
registry: ${{ secrets.PRIVATE_REGISTRY_HOST }}
username: ${{ secrets.PRIVATE_REGISTRY_USERNAME }}
password: ${{ secrets.PRIVATE_REGISTRY_TOKEN }}
- name: Build and push
- name: Build and push intermediate stages (build)
uses: docker/build-push-action@v6
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: |
${{ secrets.PRIVATE_REGISTRY_HOST }}/${{ env.GITHUB_REPOSITORY }}:latest
cache-from: type=registry,ref=user/app:latest
target: build
push: ${{ github.ref == 'refs/heads/main' }}
tags: ${{ secrets.PRIVATE_REGISTRY_HOST }}/${{ env.GITHUB_REPOSITORY }}:build
cache-from: type=registry,ref=${{ secrets.PRIVATE_REGISTRY_HOST }}/${{ env.GITHUB_REPOSITORY }}:build
cache-to: type=inline
- name: Build and push (final)
uses: docker/build-push-action@v6
with:
context: .
push: ${{ github.ref == 'refs/heads/main' }}
tags: ${{ secrets.PRIVATE_REGISTRY_HOST }}/${{ env.GITHUB_REPOSITORY }}:latest
cache-from: type=registry,ref=${{ secrets.PRIVATE_REGISTRY_HOST }}/${{ env.GITHUB_REPOSITORY }}:latest
cache-to: type=inline

View File

@ -14,9 +14,7 @@ jobs:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- uses: ruby/setup-ruby@v1.202.0
with:
ruby-version: '3.3.6'
- uses: ruby/setup-ruby@v1.207.0
- name: Install project dependencies
run: bundle install --jobs `getconf _NPROCESSORS_ONLN`
- name: Run license finder

View File

@ -22,8 +22,9 @@ jobs:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- uses: ruby/setup-ruby@v1.202.0
- uses: ruby/setup-ruby@v1.207.0
- run: bundle install
- run: bundle exec rubocop --force-exclusion --parallel
- name: Wait until Postgres is ready to accept connections
run: |
apt-get update && apt-get install -f -y postgresql-client

29
.rubocop.yml Normal file
View File

@ -0,0 +1,29 @@
require:
- rubocop-rails
- rubocop-factory_bot
- rubocop-rspec
- rubocop-rspec_rails
AllCops:
NewCops: enable
Exclude:
- 'db/**/*'
- 'config/**/*'
- 'script/**/*'
- 'bin/*'
- '*.yml'
Layout/LineLength:
Max: 120
RSpec/ExampleLength:
Enabled: false
Metrics/ModuleLength:
Enabled: false
RSpec/MultipleMemoizedHelpers:
Enabled: false
Style/Documentation:
Enabled: false
Metrics/MethodLength:
Max: 20
Rails/SkipsModelValidations:
Enabled: false
Metrics/AbcSize:
Enabled: false

View File

@ -1 +1 @@
ruby-3.3.6
ruby-3.4.1

View File

@ -1,8 +1,8 @@
# syntax = docker/dockerfile:1
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.3.6
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
ARG RUBY_VERSION=3.4.1
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim AS base
# Rails app lives here
WORKDIR /rails
@ -16,11 +16,11 @@ ENV RAILS_ENV="production" \
RUN apt-get update && apt-get install -y nodejs
# Throw-away build stage to reduce size of final image
FROM base as build
FROM base AS build
# Install packages needed to build gems
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential git libpq-dev libvips pkg-config
apt-get install --no-install-recommends -y build-essential git libpq-dev libvips pkg-config libyaml-dev
# Install application gems
COPY Gemfile Gemfile.lock ./

View File

@ -1,7 +1,7 @@
# syntax = docker/dockerfile:1
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.3.6
ARG RUBY_VERSION=3.4.1
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
# Rails app lives here
@ -13,7 +13,7 @@ FROM base as build
# Install packages needed to build gems
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential git libpq-dev libvips pkg-config
apt-get install --no-install-recommends -y build-essential git libpq-dev libvips pkg-config libyaml-dev
# Install application gems
COPY Gemfile Gemfile.lock ./

22
Gemfile
View File

@ -1,6 +1,8 @@
# frozen_string_literal: true
source 'https://rubygems.org'
ruby '3.3.6'
ruby '3.4.1'
gem 'bootsnap', require: false
gem 'csv'
gem 'importmap-rails'
@ -15,15 +17,15 @@ gem 'stimulus-rails'
gem 'turbo-rails'
gem 'tzinfo-data', platforms: %i[windows jruby]
gem 'acts_as_tenant'
gem 'faker'
gem 'httparty'
gem 'jsonapi-rails'
gem 'pluck_to_hash'
gem 'rack-cors'
gem 'react-rails'
gem 'rubytree'
gem 'acts_as_tenant'
gem 'httparty'
gem 'rswag'
gem 'pluck_to_hash'
gem 'rubytree'
group :development, :test do
gem 'annotaterb'
@ -36,12 +38,16 @@ group :development, :test do
end
group :development do
gem 'rubocop'
gem 'web-console'
gem 'letter_opener_web'
gem 'rubocop'
gem 'rubocop-factory_bot', require: false
gem 'rubocop-rails', require: false
gem 'rubocop-rspec', require: false
gem 'rubocop-rspec_rails', require: false
gem 'web-console'
end
gem 'chroma'
gem 'solid_queue', '~> 1.0'
gem "devise", "~> 4.9"
gem 'devise', '~> 4.9'

View File

@ -85,7 +85,7 @@ GEM
base64 (0.2.0)
bcrypt (3.1.20)
benchmark (0.4.0)
bigdecimal (3.1.8)
bigdecimal (3.1.9)
bindex (0.8.1)
bootsnap (1.18.4)
msgpack (~> 1.2)
@ -97,7 +97,7 @@ GEM
concurrent-ruby (1.3.4)
connection_pool (2.4.1)
crass (1.0.6)
csv (3.3.1)
csv (3.3.2)
date (3.4.1)
debug (1.10.0)
irb (~> 1.10)
@ -110,7 +110,7 @@ GEM
warden (~> 1.2.3)
diff-lcs (1.5.1)
drb (2.2.1)
erubi (1.13.0)
erubi (1.13.1)
et-orbi (1.2.11)
tzinfo
execjs (2.9.1)
@ -132,7 +132,7 @@ GEM
multi_xml (>= 0.5.2)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
importmap-rails (2.0.3)
importmap-rails (2.1.0)
actionpack (>= 6.0.0)
activesupport (>= 6.0.0)
railties (>= 6.0.0)
@ -143,7 +143,7 @@ GEM
jbuilder (2.13.0)
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
json (2.8.2)
json (2.9.1)
json-schema (5.0.1)
addressable (~> 2.8)
jsonapi-deserializable (0.2.0)
@ -176,7 +176,7 @@ GEM
tomlrb (>= 1.3, < 2.1)
with_env (= 1.1.0)
xml-simple (~> 1.1.9)
logger (1.6.3)
logger (1.6.5)
loofah (2.23.1)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
@ -188,6 +188,7 @@ GEM
marcel (1.0.4)
method_source (1.1.0)
mini_mime (1.1.5)
mini_portile2 (2.8.8)
minitest (5.25.4)
money (6.19.0)
i18n (>= 0.6.4, <= 2)
@ -204,28 +205,29 @@ GEM
net-smtp (0.5.0)
net-protocol
nio4r (2.7.4)
nokogiri (1.16.8-aarch64-linux)
nokogiri (1.18.1)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nokogiri (1.16.8-arm-linux)
nokogiri (1.18.1-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.16.8-arm64-darwin)
nokogiri (1.18.1-arm-linux-gnu)
racc (~> 1.4)
nokogiri (1.16.8-x86-linux)
nokogiri (1.18.1-arm64-darwin)
racc (~> 1.4)
nokogiri (1.16.8-x86_64-darwin)
nokogiri (1.18.1-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.16.8-x86_64-linux)
nokogiri (1.18.1-x86_64-linux-gnu)
racc (~> 1.4)
orm_adapter (0.5.0)
parallel (1.26.3)
parser (3.3.6.0)
parser (3.3.7.0)
ast (~> 2.4.1)
racc
pg (1.5.9)
pluck_to_hash (1.0.2)
activerecord (>= 4.0.2)
activesupport (>= 4.0.2)
pry (0.15.0)
pry (0.15.2)
coderay (~> 1.1)
method_source (~> 1.0)
psych (5.2.2)
@ -288,7 +290,7 @@ GEM
redis-client (>= 0.22.0)
redis-client (0.22.2)
connection_pool
regexp_parser (2.9.3)
regexp_parser (2.10.0)
reline (0.6.0)
io-console (~> 0.5)
responders (3.1.1)
@ -327,7 +329,7 @@ GEM
rswag-ui (2.16.0)
actionpack (>= 5.2, < 8.1)
railties (>= 5.2, < 8.1)
rubocop (1.69.2)
rubocop (1.70.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
@ -337,16 +339,28 @@ GEM
rubocop-ast (>= 1.36.2, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.36.2)
rubocop-ast (1.37.0)
parser (>= 3.3.1.0)
rubocop-factory_bot (2.26.1)
rubocop (~> 1.61)
rubocop-rails (2.29.0)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.52.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rspec (3.4.0)
rubocop (~> 1.61)
rubocop-rspec_rails (2.30.0)
rubocop (~> 1.61)
rubocop-rspec (~> 3, >= 3.0.1)
ruby-progressbar (1.13.0)
rubytree (2.1.0)
json (~> 2.0, > 2.3.1)
rubytree (2.1.1)
json (~> 2.0, > 2.9)
rubyzip (2.3.2)
securerandom (0.4.1)
shoulda-matchers (6.4.0)
activesupport (>= 5.2.0)
solid_queue (1.1.0)
solid_queue (1.1.2)
activejob (>= 7.1)
activerecord (>= 7.1)
concurrent-ruby (>= 1.3.1)
@ -426,6 +440,10 @@ DEPENDENCIES
rspec-rails (~> 7.1.0)
rswag
rubocop
rubocop-factory_bot
rubocop-rails
rubocop-rspec
rubocop-rspec_rails
rubytree
shoulda-matchers (~> 6.0)
solid_queue (~> 1.0)
@ -456,7 +474,7 @@ CHECKSUMS
base64 (0.2.0) sha256=0f25e9b21a02a0cc0cea8ef92b2041035d39350946e8789c562b2d1a3da01507
bcrypt (3.1.20) sha256=8410f8c7b3ed54a3c00cd2456bf13917d695117f033218e2483b2e40b0784099
benchmark (0.4.0) sha256=0f12f8c495545e3710c3e4f0480f63f06b4c842cc94cec7f33a956f5180e874a
bigdecimal (3.1.8) sha256=a89467ed5a44f8ae01824af49cbc575871fa078332e8f77ea425725c1ffe27be
bigdecimal (3.1.9) sha256=2ffc742031521ad69c2dfc815a98e426a230a3d22aeac1995826a75dabfad8cc
bindex (0.8.1) sha256=7b1ecc9dc539ed8bccfc8cb4d2732046227b09d6f37582ff12e50a5047ceb17e
bootsnap (1.18.4) sha256=ac4c42af397f7ee15521820198daeff545e4c360d2772c601fbdc2c07d92af55
builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f
@ -466,13 +484,13 @@ CHECKSUMS
concurrent-ruby (1.3.4) sha256=d4aa926339b0a86b5b5054a0a8c580163e6f5dcbdfd0f4bb916b1a2570731c32
connection_pool (2.4.1) sha256=0f40cf997091f1f04ff66da67eabd61a9fe0d4928b9a3645228532512fab62f4
crass (1.0.6) sha256=dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d
csv (3.3.1) sha256=e5133b9005fd2ca61547509cd8b7eefa94663d5d36c0e73297b0ae0a35e3e767
csv (3.3.2) sha256=6ff0c135e65e485d1864dde6c1703b60d34cc9e19bed8452834a0b28a519bd4e
date (3.4.1) sha256=bf268e14ef7158009bfeaec40b5fa3c7271906e88b196d958a89d4b408abe64f
debug (1.10.0) sha256=11e28ca74875979e612444104f3972bd5ffb9e79179907d7ad46dba44bd2e7a4
devise (4.9.4) sha256=920042fe5e704c548aa4eb65ebdd65980b83ffae67feb32c697206bfd975a7f8
diff-lcs (1.5.1) sha256=273223dfb40685548436d32b4733aa67351769c7dea621da7d9dd4813e63ddfe
drb (2.2.1) sha256=e9d472bf785f558b96b25358bae115646da0dbfd45107ad858b0bc0d935cb340
erubi (1.13.0) sha256=fca61b47daefd865d0fb50d168634f27ad40181867445badf6427c459c33cd62
erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
et-orbi (1.2.11) sha256=d26e868cc21db88280a9ec1a50aa3da5d267eb9b2037ba7b831d6c2731f5df64
execjs (2.9.1) sha256=e8fd066f6df60c8e8fbebc32c6fb356b5212c77374e8416a9019ca4bb154dcfb
factory_bot (6.4.6) sha256=1a9486ce98d318d740d8f5804b885a8265a28f326ecf2bcd4ce9fb27a71a6e04
@ -482,11 +500,11 @@ CHECKSUMS
globalid (1.2.1) sha256=70bf76711871f843dbba72beb8613229a49429d1866828476f9c9d6ccc327ce9
httparty (0.22.0) sha256=78652a5c9471cf0093d3b2083c2295c9c8f12b44c65112f1846af2b71430fa6c
i18n (1.14.6) sha256=dc229a74f5d181f09942dd60ab5d6e667f7392c4ee826f35096db36d1fe3614c
importmap-rails (2.0.3) sha256=c56764941f9b637791fb87123b38f206f27cc55ef03cb19894f1994184e98cc8
importmap-rails (2.1.0) sha256=9f10c67d60651a547579f448100d033df311c5d5db578301374aeb774faae741
io-console (0.8.0) sha256=cd6a9facbc69871d69b2cb8b926fc6ea7ef06f06e505e81a64f14a470fddefa2
irb (1.14.3) sha256=c457f1f2f1438ae9ce5c5be3981ae2138dec7fb894c7d73777eeeb0a6c0d0752
jbuilder (2.13.0) sha256=7200a38a1c0081aa81b7a9757e7a299db75bc58cf1fd45ca7919a91627d227d6
json (2.8.2) sha256=dd4fa6c9c81daecf72b86ea36e56ed8955fdbb4d4dc379c93d313a59344486cf
json (2.9.1) sha256=d2bdef4644052fad91c1785d48263756fe32fcac08b96a20bb15840e96550d11
json-schema (5.0.1) sha256=bef71a82c600a42594911553522e143f7634affc198ed507ef3ded2f920a74a9
jsonapi-deserializable (0.2.0) sha256=5f0ca2d3f8404cce1584a314e8a3753be32a56054c942adfe997b87e92bce147
jsonapi-parser (0.1.1) sha256=9ee0dc031e88fc7548d56fab66f9716d1e1c06f972b529b8c4617bc42a097020
@ -499,12 +517,13 @@ CHECKSUMS
letter_opener (1.10.0) sha256=2ff33f2e3b5c3c26d1959be54b395c086ca6d44826e8bf41a14ff96fdf1bdbb2
letter_opener_web (3.0.0) sha256=3f391efe0e8b9b24becfab5537dfb17a5cf5eb532038f947daab58cb4b749860
license_finder (7.2.1) sha256=179ead19b64b170638b72fd16024233813673ac9d20d5ba75ae0b4444887ef14
logger (1.6.3) sha256=4533ce015c75d8ae442ecb9dc10e3ca82e9f36c55b829dcde0fc964f4e7ce494
logger (1.6.5) sha256=c3cfe56d01656490ddd103d38b8993d73d86296adebc5f58cefc9ec03741e56b
loofah (2.23.1) sha256=d0a07422cb3b69272e124afa914ef6d517e30d5496b7f1c1fc5b95481f13f75e
mail (2.8.1) sha256=ec3b9fadcf2b3755c78785cb17bc9a0ca9ee9857108a64b6f5cfc9c0b5bfc9ad
marcel (1.0.4) sha256=0d5649feb64b8f19f3d3468b96c680bae9746335d02194270287868a661516a4
method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5
mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef
mini_portile2 (2.8.8) sha256=8e47136cdac04ce81750bb6c09733b37895bf06962554e4b4056d78168d70a75
minitest (5.25.4) sha256=9cf2cae25ac4dfc90c988ebc3b917f53c054978b673273da1bd20bcb0778f947
money (6.19.0) sha256=ec936fa1e42f2783719241ed9fd52725d0efa628f928feea1eb5c37d5de7daf3
msgpack (1.7.2) sha256=59ab62fd8a4d0dfbde45009f87eb6f158ab2628a7c48886b0256f175166baaa8
@ -514,18 +533,18 @@ CHECKSUMS
net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8
net-smtp (0.5.0) sha256=5fc0415e6ea1cc0b3dfea7270438ec22b278ca8d524986a3ae4e5ae8d087b42a
nio4r (2.7.4) sha256=d95dee68e0bb251b8ff90ac3423a511e3b784124e5db7ff5f4813a220ae73ca9
nokogiri (1.16.8-aarch64-linux) sha256=b1d41cd9abf4180adef496cc8c9fcb5b2e38d39f5e23c8a2445362226a5df6b8
nokogiri (1.16.8-arm-linux) sha256=8cbd2971624fc073b9430d86475da031903494dcb83c2339e13f7f22a4de6fad
nokogiri (1.16.8-arm64-darwin) sha256=b7aa4e8533a720e432d09b52a2ec089b55cf3ee66c916b44a0d9b6608df7bf8c
nokogiri (1.16.8-x86-linux) sha256=f97760e6320166d48234029bed9e999521a888376bd2b7e04f4c054537154f16
nokogiri (1.16.8-x86_64-darwin) sha256=6c40d7dc444f752634bf6ee8b53a55c3cfca3f9df52be46b8abcc559ccd49e47
nokogiri (1.16.8-x86_64-linux) sha256=ed7b1f80713ac968dd93fe2b96fc3df6e448b73bd02dd77d5fc89ba92a1ed6d9
nokogiri (1.18.1) sha256=df18be7e96c34736b6abfdeda80c6e845134fb9afe2fe5d4fbc1cf1f89c68475
nokogiri (1.18.1-aarch64-linux-gnu) sha256=35837013800e34342fcbaca305f8c49231f6bd4f779bfa23fe7b4686ae82d5b8
nokogiri (1.18.1-arm-linux-gnu) sha256=3b873fd6b0cd1ad7c77e87af701075bdfd14c9a6b2f2965c5e00ed29a5627a37
nokogiri (1.18.1-arm64-darwin) sha256=d75193f284c899d225943a8944479faedd995a7573ddd5c8308ffbdf2ec55204
nokogiri (1.18.1-x86_64-darwin) sha256=d94e3aa6483577495fc8969d6b4b5c075840ce6b1ab09636a6d4177ad171051d
nokogiri (1.18.1-x86_64-linux-gnu) sha256=e516cf16ccde67ed4cc595a2621ca5ddd42562ecb24928914b0045a20a41620e
orm_adapter (0.5.0) sha256=aa5d0be5d540cbb46d3a93e88061f4ece6a25f6e97d6a47122beb84fe595e9b9
parallel (1.26.3) sha256=d86babb7a2b814be9f4b81587bf0b6ce2da7d45969fab24d8ae4bf2bb4d4c7ef
parser (3.3.6.0) sha256=25d4e67cc4f0f7cab9a2ae1f38e2005b6904d2ea13c34734511d0faad038bc3b
parser (3.3.7.0) sha256=7449011771e3e7881297859b849de26a6f4fccd515bece9520a87e7d2116119b
pg (1.5.9) sha256=761efbdf73b66516f0c26fcbe6515dc7500c3f0aa1a1b853feae245433c64fdc
pluck_to_hash (1.0.2) sha256=1599906239716f98262a41493dd7d4cb72e8d83ad3d76d666deacfc5de50a47e
pry (0.15.0) sha256=91e7925ea58c88e671b058a3a939bb529016de5ec57084b000057b2a1fec1930
pry (0.15.2) sha256=12d54b8640d3fa29c9211dd4ffb08f3fd8bf7a4fd9b5a73ce5b59c8709385b6b
psych (5.2.2) sha256=a4a9477c85d3e858086c38cf64e7096abe40d1b1eed248b01020dec0ff9906ab
public_suffix (6.0.1) sha256=61d44e1cab5cbbbe5b31068481cf16976dd0dc1b6b07bd95617ef8c5e3e00c6f
puma (6.5.0) sha256=94d1b75cab7f356d52e4f1b17b9040a090889b341dbeee6ee3703f441dc189f2
@ -546,7 +565,7 @@ CHECKSUMS
react-rails (3.2.1) sha256=2235db0b240517596b1cb3e26177ab5bc64d3a56579b0415ee242b1691f81f64
redis (5.3.0) sha256=6bf810c5ae889187f0c45f77db503310980310afa57cf1640d57f419ccda72b1
redis-client (0.22.2) sha256=31fee4b7cf04109b227327fabeaaf1fc5b652cf48a186a03bc607e40767bacc0
regexp_parser (2.9.3) sha256=4b620657ed8349d82e1331a076415c79b9dd714a5546162ddd790ea9988f6379
regexp_parser (2.10.0) sha256=cb6f0ddde88772cd64bff1dbbf68df66d376043fe2e66a9ef77fcb1b0c548c61
reline (0.6.0) sha256=57620375dcbe56ec09bac7192bfb7460c716bbf0054dc94345ecaa5438e539d2
responders (3.1.1) sha256=92f2a87e09028347368639cfb468f5fefa745cb0dc2377ef060db1cdd79a341a
rexml (3.3.9) sha256=d71875b85299f341edf47d44df0212e7658cbdf35aeb69cefdb63f57af3137c9
@ -559,14 +578,18 @@ CHECKSUMS
rswag-api (2.16.0) sha256=b653f7bd92e98be18b01ab4525d88950d7b0960e293a99f856b9efcee3ae6074
rswag-specs (2.16.0) sha256=8ba26085c408b0bd2ed21dc8015c80f417c7d34c63720ab7133c2549b5bd2a91
rswag-ui (2.16.0) sha256=a1f49e927dceda92e6e6e7c1000f1e217ee66c565f69e28131dc98b33cd3a04f
rubocop (1.69.2) sha256=762fb0f30a379bf6054588d39f1815a2a1df8f067bc0337d3fe500e346924bb8
rubocop-ast (1.36.2) sha256=566405b7f983eb9aa3b91d28aca6bc6566e356a97f59e89851dd910aef1dd1ca
rubocop (1.70.0) sha256=96751f8440b36a0ac6e9a8ab596900803118d83d6b83f2037bf8b3d7a5bc440e
rubocop-ast (1.37.0) sha256=9513ac88aaf113d04b52912533ffe46475de1362d4aa41141b51b2455827c080
rubocop-factory_bot (2.26.1) sha256=8de13cd4edcee5ca800f255188167ecef8dbfc3d1fae9f15734e9d2e755392aa
rubocop-rails (2.29.0) sha256=35bffd140c80671453aafac0e2d5ab5b3dd65736a3fc8f3936ccca226b89c234
rubocop-rspec (3.4.0) sha256=8721c13b6a8c9530a7ac481cea9423022f946fcf72428bda8289f8b57e4d4885
rubocop-rspec_rails (2.30.0) sha256=888112e83f9d7ef7ad2397e9d69a0b9614a4bae24f072c399804a180f80c4c46
ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
rubytree (2.1.0) sha256=30e8759ba060dff0dabf7e40cbaaa4df892fa34cbe9f1b3fbb00e83a3f321e4b
rubytree (2.1.1) sha256=4925016356a81730e982f1f8c3b5f8da461f18906c77d238bad4c4ba896abd41
rubyzip (2.3.2) sha256=3f57e3935dc2255c414484fbf8d673b4909d8a6a57007ed754dde39342d2373f
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
shoulda-matchers (6.4.0) sha256=9055bb7f4bb342125fb860809798855c630e05ef5e75837b3168b8e6ee1608b0
solid_queue (1.1.0) sha256=55c7b1d65f2943ec8f3deee36fcb0cae91d5fa60410b294775db9da22be8353c
solid_queue (1.1.2) sha256=178c9396d1cf0dac595c7508da90ddb397d25848ca007b5c5ed48e6ac6fc360c
sprockets (4.2.1) sha256=951b13dd2f2fcae840a7184722689a803e0ff9d2702d902bd844b196da773f97
sprockets-rails (3.5.2) sha256=a9e88e6ce9f8c912d349aa5401509165ec42326baf9e942a85de4b76dbc4119e
stimulus-rails (1.3.4) sha256=765676ffa1f33af64ce026d26b48e8ffb2e0b94e0f50e9119e11d6107d67cb06
@ -589,7 +612,7 @@ CHECKSUMS
zeitwerk (2.7.1) sha256=0945986050e4907140895378e74df1fe882a2271ed087cc6c6d6b00d415a2756
RUBY VERSION
ruby 3.3.6p108
ruby 3.4.1p0
BUNDLED WITH
2.6.1

View File

@ -1,6 +1,8 @@
# frozen_string_literal: true
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require_relative "config/application"
require_relative 'config/application'
Rails.application.load_tasks

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module ApplicationCable
class Channel < ActionCable::Channel::Base
end

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module ApplicationCable
class Connection < ActionCable::Connection::Base
end

View File

@ -0,0 +1,74 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class AffinitiesController < ApplicationController
before_action :set_group, except: :reset
def index
overridden = @group.affinities.each_with_object({}) do |affinity, acc|
acc[affinity.another_group(@group).id] = affinity.discomfort
end
for_each_group do |group_id|
overridden[group_id] || GroupAffinity::NEUTRAL
end
end
def bulk_update
affinities = params.expect(affinities: [%i[group_id affinity]]).map(&:to_h).map do |affinity|
{
group_a_id: @group.id,
group_b_id: affinity[:group_id],
discomfort: GroupAffinity::MAX_DISCOMFORT - affinity[:affinity]
}
end
GroupAffinity.upsert_all(affinities, unique_by: :uindex_group_pair)
render json: {}, status: :ok
rescue ActiveRecord::InvalidForeignKey
render json: { error: 'At least one of the group IDs provided does not exist.' }, status: :bad_request
rescue ActiveRecord::StatementInvalid
render json: { error: 'Invalid group ID or discomfort provided.' }, status: :bad_request
end
def default
hierarchy = AffinityGroupsHierarchy.new
for_each_group do |group_id|
hierarchy.default_discomfort(@group.id, group_id).to_f
end
end
def reset
hierarchy = AffinityGroupsHierarchy.new
affinities = Group.pluck(:id).combination(2).map do |(group_a_id, group_b_id)|
{
group_a_id:,
group_b_id:,
discomfort: hierarchy.default_discomfort(group_a_id, group_b_id).to_f
}
end
GroupAffinity.upsert_all(affinities, unique_by: :uindex_group_pair)
render json: {}, status: :ok
end
private
def for_each_group
Group.where.not(id: @group.id)
.pluck(:id)
.index_with { |group_id| GroupAffinity::MAX_DISCOMFORT - yield(group_id) }
.then { |affinities| render json: affinities }
end
def set_group
@group = Group.find(params[:group_id])
end
end

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class ApplicationController < ActionController::Base
set_current_tenant_through_filter
before_action :set_tenant
@ -40,9 +44,9 @@ class ApplicationController < ActionController::Base
end
def captcha_params
params.expect(captcha: [:id, :answer])
params.expect(captcha: %i[id answer])
end
def default_url_options(options = {})
options.merge(path_params: { slug: ActsAsTenant.current_tenant&.slug })
end
@ -53,7 +57,7 @@ class ApplicationController < ActionController::Base
def development_swagger?
Rails.env.test? ||
Rails.env.development? && request.headers['referer']&.include?('/api-docs/index.html')
(Rails.env.development? && request.headers['referer']&.include?('/api-docs/index.html'))
end
def set_csrf_cookie

View File

@ -1,10 +1,14 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class CaptchaController < ApplicationController
skip_before_action :authenticate_user!
skip_before_action :set_tenant
def create
id = LibreCaptcha.new.get_id
id = LibreCaptcha.new.id
render json: {
id:,
media_url: media_captcha_index_url(id:)

View File

@ -1,12 +1,16 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class ExpensesController < ApplicationController
def summary
render json: Expenses::TotalQuery.new.call
end
def index
render json: Expense.all.order(pricing_type: :asc, amount: :desc).as_json(only: %i[id name amount pricing_type])
render json: Expense.order(pricing_type: :asc, amount: :desc).as_json(only: %i[id name amount pricing_type])
end
def create
@ -27,6 +31,6 @@ class ExpensesController < ApplicationController
private
def expense_params
params.require(:expense).permit(:name, :amount, :pricing_type)
params.expect(expense: %i[name amount pricing_type])
end
end

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class GroupsController < ApplicationController
def index
query_result = Groups::SummaryQuery.new.call.as_json.map(&:deep_symbolize_keys).map do |group|
@ -39,6 +43,6 @@ class GroupsController < ApplicationController
end
def group_params
params.expect(group: [:name, :icon, :color])
params.expect(group: %i[name icon color])
end
end

View File

@ -1,10 +1,14 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
require 'csv'
class GuestsController < ApplicationController
def index
render json: Guest.all.includes(:group)
render json: Guest.includes(:group)
.left_joins(:group)
.order('groups.name' => :asc, name: :asc)
.as_json(only: %i[id name status], include: { group: { only: %i[id name] } })
@ -28,6 +32,6 @@ class GuestsController < ApplicationController
private
def guest_params
params.require(:guest).permit(:name, :group_id, :status)
params.expect(guest: %i[name group_id status])
end
end

View File

@ -1,29 +1,45 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class SummaryController < ApplicationController
def index
expense_summary = Expenses::TotalQuery.new(wedding: ActsAsTenant.current_tenant).call
guest_summary = Guest.group(:status).count
render json: {
expenses: {
projected: {
total: expense_summary['total_projected'],
guests: expense_summary['projected_guests']
},
confirmed: {
total: expense_summary['total_confirmed'],
guests: expense_summary['confirmed_guests']
},
status: {
paid: 0
}
expenses:,
guests:
}
end
private
def guests
guest_summary = Guest.group(:status).count
{
total: guest_summary.except('considered').values.sum,
confirmed: guest_summary['confirmed'].to_i,
declined: guest_summary['declined'].to_i,
tentative: guest_summary['tentative'].to_i,
invited: guest_summary['invited'].to_i
}
end
def expenses
expense_summary = Expenses::TotalQuery.new(wedding: ActsAsTenant.current_tenant).call
{
projected: {
total: expense_summary['total_projected'],
guests: expense_summary['projected_guests']
},
guests: {
total: guest_summary.except('considered').values.sum,
confirmed: guest_summary['confirmed'].to_i,
declined: guest_summary['declined'].to_i,
tentative: guest_summary['tentative'].to_i,
invited: guest_summary['invited'].to_i
confirmed: {
total: expense_summary['total_confirmed'],
guests: expense_summary['confirmed_guests']
},
status: {
paid: 0
}
}
end

View File

@ -1,8 +1,12 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class TablesArrangementsController < ApplicationController
def index
render json: TablesArrangement.all.order(discomfort: :asc).limit(3).as_json(only: %i[id name discomfort])
render json: TablesArrangement.order(discomfort: :asc).limit(3).as_json(only: %i[id name discomfort])
end
def show

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class TokensController < ApplicationController
skip_before_action :authenticate_user!
skip_before_action :set_tenant

View File

@ -1,23 +1,29 @@
# Copyright (C) 2024 Manuel Bustillo
class Users::ConfirmationsController < Devise::ConfirmationsController
clear_respond_to
respond_to :json
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
def show
super do |resource|
if resource.errors.empty?
respond_to do |format|
format.json { render json: resource, status: :ok }
format.any { redirect_to root_path }
# frozen_string_literal: true
module Users
class ConfirmationsController < Devise::ConfirmationsController
clear_respond_to
respond_to :json
def show
super do |resource|
if resource.errors.empty?
respond_to do |format|
format.json { render json: resource, status: :ok }
format.any { redirect_to root_path }
end
else
render json: {
message: 'Record invalid',
errors: resource.errors.full_messages
}, status: :unprocessable_entity
end
else
render json: {
message: 'Record invalid',
errors: resource.errors.full_messages
}, status: :unprocessable_entity
return
end
return
end
end
end
end

View File

@ -1,28 +1,34 @@
# Copyright (C) 2024 Manuel Bustillo
class Users::RegistrationsController < Devise::RegistrationsController
clear_respond_to
respond_to :json
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
before_action :validate_captcha!, only: :create
# frozen_string_literal: true
def create
wedding = Wedding.create(slug: params[:slug])
unless wedding.persisted?
render json: { errors: wedding.errors.full_messages }, status: :unprocessable_entity
return
end
module Users
class RegistrationsController < Devise::RegistrationsController
clear_respond_to
respond_to :json
ActsAsTenant.with_tenant(wedding) do
super do |user|
wedding.destroy unless user.persisted?
before_action :validate_captcha!, only: :create
def create
wedding = Wedding.create(slug: params[:slug])
unless wedding.persisted?
render json: { errors: wedding.errors.full_messages }, status: :unprocessable_entity
return
end
ActsAsTenant.with_tenant(wedding) do
super do |user|
wedding.destroy unless user.persisted?
end
end
end
end
private
private
def set_tenant
set_current_tenant(nil)
def set_tenant
set_current_tenant(nil)
end
end
end
end

View File

@ -1,6 +1,12 @@
# Copyright (C) 2024 Manuel Bustillo
class Users::SessionsController < Devise::SessionsController
clear_respond_to
respond_to :json
end
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module Users
class SessionsController < Devise::SessionsController
clear_respond_to
respond_to :json
end
end

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module TreeNodeExtension
def distance_to_common_ancestor(another_node)
return 0 if self == another_node

View File

@ -1,4 +1,8 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module ApplicationHelper
end

View File

@ -1,4 +1,8 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module ExpensesHelper
end

View File

@ -1,4 +1,8 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module GroupsHelper
end

View File

@ -1,4 +1,8 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module GuestsHelper
end

View File

@ -1,4 +1,8 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module TablesArrangementsHelper
end

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class ApplicationJob < ActiveJob::Base
# Automatically retry jobs that encountered a deadlock
# retry_on ActiveRecord::Deadlocked

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class TableSimulatorJob < ApplicationJob
queue_as :default

View File

@ -1,6 +1,10 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class ApplicationMailer < ActionMailer::Base
default from: "from@example.com"
layout "mailer"
default from: 'from@example.com'
layout 'mailer'
end

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
end

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# == Schema Information
#
# Table name: expenses

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# == Schema Information
#
# Table name: groups
@ -31,7 +35,7 @@ class Group < ApplicationRecord
validates :name, uniqueness: true
validates :name, :order, presence: true
has_many :children, class_name: 'Group', foreign_key: 'parent_id'
has_many :children, class_name: 'Group', foreign_key: 'parent_id', dependent: :nullify, inverse_of: :parent
belongs_to :parent, class_name: 'Group', optional: true
before_create :set_color
@ -41,10 +45,7 @@ class Group < ApplicationRecord
has_many :guests, dependent: :nullify
def colorize_children(generation = 1)
derived_colors = generation == 1 ? color.paint.palette.analogous(size: children.count) : color.paint.palette.decreasing_saturation
children.zip(derived_colors) do |child, raw_color|
children.zip(palette(generation)) do |child, raw_color|
final_color = raw_color.paint
final_color.brighten(60) if final_color.dark?
@ -54,8 +55,20 @@ class Group < ApplicationRecord
end
end
def affinities
GroupAffinity.where(group_a_id: id).or(GroupAffinity.where(group_b_id: id))
end
private
def palette(generation)
if generation == 1
color.paint.palette.analogous(size: children.count)
else
color.paint.palette.decreasing_saturation
end
end
def set_color
return if color.present?

View File

@ -0,0 +1,45 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# == Schema Information
#
# Table name: group_affinities
#
# id :bigint not null, primary key
# discomfort :float not null
# created_at :datetime not null
# updated_at :datetime not null
# group_a_id :uuid not null
# group_b_id :uuid not null
#
# Indexes
#
# index_group_affinities_on_group_a_id (group_a_id)
# index_group_affinities_on_group_b_id (group_b_id)
# uindex_group_pair (LEAST(group_a_id, group_b_id), GREATEST(group_a_id, group_b_id)) UNIQUE
#
# Foreign Keys
#
# fk_rails_... (group_a_id => groups.id)
# fk_rails_... (group_b_id => groups.id)
#
class GroupAffinity < ApplicationRecord
NEUTRAL = 1
MIN_DISCOMFORT = 0
MAX_DISCOMFORT = 2
belongs_to :group_a, class_name: 'Group'
belongs_to :group_b, class_name: 'Group'
validates :discomfort,
numericality: { greater_than_or_equal_to: MIN_DISCOMFORT, less_than_or_equal_to: MAX_DISCOMFORT }
def another_group(group)
return nil if group != group_a && group != group_b
group == group_a ? group_b : group_a
end
end

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# == Schema Information
#
# Table name: guests
@ -39,8 +43,8 @@ class Guest < ApplicationRecord
scope :potential, -> { where.not(status: %i[declined considered]) }
after_save :recalculate_simulations, if: :saved_change_to_status?
after_destroy :recalculate_simulations
after_save :recalculate_simulations, if: :saved_change_to_status?
has_many :seats, dependent: :delete_all

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# == Schema Information
#
# Table name: seats

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# == Schema Information
#
# Table name: tables_arrangements
@ -21,7 +25,7 @@
#
class TablesArrangement < ApplicationRecord
acts_as_tenant :wedding
has_many :seats
has_many :seats, dependent: :delete_all
has_many :guests, through: :seats
before_create :assign_name

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# == Schema Information
#
# Table name: users

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# == Schema Information
#
# Table name: weddings

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module Expenses
class TotalQuery
private attr_reader :wedding
@ -16,7 +20,7 @@ module Expenses
private
def query
<<~SQL
<<~SQL.squish
WITH guest_count AS (#{guest_count_per_status}),
expense_summary AS (#{expense_summary})
SELECT guest_count.confirmed as confirmed_guests,
@ -28,7 +32,7 @@ module Expenses
end
def expense_summary
<<~SQL
<<~SQL.squish
SELECT coalesce(sum(amount) filter (where pricing_type = 'fixed'), 0) as fixed,
coalesce(sum(amount) filter (where pricing_type = 'per_person'), 0) as variable
FROM expenses
@ -37,7 +41,7 @@ module Expenses
end
def guest_count_per_status
<<~SQL
<<~SQL.squish
SELECT COALESCE(count(*) filter(where status = #{Guest.statuses['confirmed']}), 0) as confirmed,
COALESCE(count(*) filter(where status IN (#{Guest.statuses.values_at('confirmed', 'invited', 'tentative').join(',')})), 0) as projected
FROM guests

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module Groups
class SummaryQuery
def call
@ -9,13 +13,21 @@ module Groups
:icon,
:parent_id,
:color,
*count_expressions
)
end
private
def count_expressions
[
Arel.sql('count(*) filter (where status IS NOT NULL) as total'),
Arel.sql('count(*) filter (where status = 0) as considered'),
Arel.sql('count(*) filter (where status = 10) as invited'),
Arel.sql('count(*) filter (where status = 20) as confirmed'),
Arel.sql('count(*) filter (where status = 30) as declined'),
Arel.sql('count(*) filter (where status = 40) as tentative'),
)
Arel.sql('count(*) filter (where status = 40) as tentative')
]
end
end
end

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class SerializableGroup < JSONAPI::Serializable::Resource
type 'group'

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class SerializableGuest < JSONAPI::Serializable::Resource
type 'guest'

View File

@ -1,7 +1,11 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class AffinityGroupsHierarchy < Array
include Singleton
DEFAULT_DISCOMFORT = 1
def initialize
super
@ -12,6 +16,9 @@ class AffinityGroupsHierarchy < Array
hydrate(group)
end
load_discomforts
freeze
end
def find(id)
@ -33,8 +40,35 @@ class AffinityGroupsHierarchy < Array
@references[id_a].distance_to_common_ancestor(@references[id_b])
end
def discomfort(id_a, id_b)
return 0 if id_a == id_b
@discomforts[uuid_to_int(id_a) + uuid_to_int(id_b)] || DEFAULT_DISCOMFORT
end
def default_discomfort(id_a, id_b)
return 0 if id_a == id_b
dist = distance(id_a, id_b)
return DEFAULT_DISCOMFORT if dist.nil?
Rational(dist, dist + 1)
end
private
def load_discomforts
@load_discomforts ||= GroupAffinity.pluck(:group_a_id, :group_b_id,
:discomfort).each_with_object({}) do |(id_a, id_b, discomfort), acc|
acc[uuid_to_int(id_a) + uuid_to_int(id_b)] = discomfort
end
end
def uuid_to_int(uuid)
uuid.gsub('-', '').hex
end
def hydrate(group)
group.children.each do |child|
register_child(group.id, child.id)

View File

@ -1,20 +1,22 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
class LibreCaptcha
def get_id
HTTParty.post("http://libre-captcha:8888/v2/captcha",
body: {
input_type: "text",
level: :hard,
media: 'image/png',
size: '350x100'
}.to_json
).then { |raw| JSON.parse(raw)['id'] }
def id
HTTParty.post('http://libre-captcha:8888/v2/captcha',
body: {
input_type: 'text',
level: :hard,
media: 'image/png',
size: '350x100'
}.to_json).then { |raw| JSON.parse(raw)['id'] }
end
def valid?(id:, answer:)
HTTParty.post("http://libre-captcha:8888/v2/answer",
body: { id:, answer: }.to_json
).then { |raw| JSON.parse(raw)['result'] == 'True' }
HTTParty.post('http://libre-captcha:8888/v2/answer',
body: { id:, answer: }.to_json).then { |raw| JSON.parse(raw)['result'] == 'True' }
end
end
end

View File

@ -1,10 +1,15 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module Tables
class DiscomfortCalculator
private attr_reader :table
def initialize(table:)
private attr_reader :table, :hierarchy
def initialize(table:, hierarchy: AffinityGroupsHierarchy.new)
@table = table
@hierarchy = hierarchy
end
def calculate
@ -45,12 +50,7 @@ module Tables
#
def cohesion_discomfort
table.map(&:group_id).tally.to_a.combination(2).sum do |(a, count_a), (b, count_b)|
distance = AffinityGroupsHierarchy.instance.distance(a, b)
next count_a * count_b if distance.nil?
next 0 if distance.zero?
count_a * count_b * Rational(distance, distance + 1)
count_a * count_b * hierarchy.discomfort(a, b)
end
end
end

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
require_relative '../../extensions/tree_node_extension'
module Tables
@ -9,6 +13,7 @@ module Tables
def initialize(min_per_table:, max_per_table:)
@min_per_table = min_per_table
@max_per_table = max_per_table
@hierarchy = AffinityGroupsHierarchy.new
@tables = []
end
@ -31,12 +36,6 @@ module Tables
"#{@tables.count} tables, discomfort: #{discomfort}"
end
def pretty_print
@tables.map.with_index do |table, i|
"Table #{i + 1} (#{table.count} ppl): (#{local_discomfort(table)}) #{table.map(&:name).join(', ')}"
end.join("\n")
end
def deep_dup
self.class.new(min_per_table: @min_per_table, max_per_table: @max_per_table).tap do |new_distribution|
new_distribution.tables = @tables.map(&:dup)
@ -64,7 +63,7 @@ module Tables
private
def local_discomfort(table)
table.discomfort ||= DiscomfortCalculator.new(table:).calculate
table.discomfort ||= DiscomfortCalculator.new(table:, hierarchy:).calculate
end
end
end

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module Tables
class Shift
private attr_reader :initial_solution

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module Tables
class Swap
private attr_reader :initial_solution

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module Tables
class Table < Set
attr_accessor :discomfort, :min_per_table, :max_per_table

View File

@ -1,5 +1,9 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
module VNS
class Engine
class << self

View File

@ -1,5 +1,7 @@
<%# Copyright (C) 2024 Manuel Bustillo %>
<%# Copyright (C) 2024-2025 LibreWeddingPlanner contributors %>
<!DOCTYPE html>
<html>
<head>

View File

@ -1,3 +1,5 @@
<%# Copyright (C) 2024 Manuel Bustillo %>
<%# Copyright (C) 2024-2025 LibreWeddingPlanner contributors %>
<%= yield %>

View File

@ -1,5 +1,7 @@
<%# Copyright (C) 2024 Manuel Bustillo %>
<%# Copyright (C) 2024-2025 LibreWeddingPlanner contributors %>
<p>Welcome <%= @email %>!</p>
<p>You can confirm your account email through the link below:</p>

View File

@ -1,5 +1,7 @@
<%# Copyright (C) 2024 Manuel Bustillo %>
<%# Copyright (C) 2024-2025 LibreWeddingPlanner contributors %>
<p>Hello <%= @email %>!</p>
<% if @resource.try(:unconfirmed_email?) %>

View File

@ -1,5 +1,7 @@
<%# Copyright (C) 2024 Manuel Bustillo %>
<%# Copyright (C) 2024-2025 LibreWeddingPlanner contributors %>
<p>Hello <%= @resource.email %>!</p>
<p>We're contacting you to notify you that your password has been changed.</p>

View File

@ -1,5 +1,7 @@
<%# Copyright (C) 2024 Manuel Bustillo %>
<%# Copyright (C) 2024-2025 LibreWeddingPlanner contributors %>
<p>Hello <%= @resource.email %>!</p>
<p>Someone has requested a link to change your password. You can do this through the link below.</p>

View File

@ -1,5 +1,7 @@
<%# Copyright (C) 2024 Manuel Bustillo %>
<%# Copyright (C) 2024-2025 LibreWeddingPlanner contributors %>
<p>Hello <%= @resource.email %>!</p>
<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>

View File

@ -1,6 +1,8 @@
# frozen_string_literal: true
# This file is used by Rack-based servers to start the application.
require_relative "config/environment"
require_relative 'config/environment'
run Rails.application
Rails.application.load_server

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
require_relative 'boot'
require 'rails'

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
require "bundler/setup" # Set up gems listed in the Gemfile.

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# Load the Rails application.
require_relative "application"

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
require "active_support/core_ext/integer/time"
Rails.application.configure do

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
require "active_support/core_ext/integer/time"
Rails.application.configure do

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
require "active_support/core_ext/integer/time"
# The test environment is used exclusively to run your application's

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# Pin npm packages by running ./bin/importmap
pin "application"

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
ActsAsTenant.configure do |config|
config.require_tenant = !Rails.env.test?
end

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# 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.

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
Chroma.define_palette :decreasing_saturation do
spin(20).desaturate(40)
spin(-20).desaturate(40)

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# Be sure to restart your server when you modify this file.
# Define an application-wide content security policy.

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# Assuming you have not yet modified this file, each configuration option below

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# 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.

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format. Inflections

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# Be sure to restart your server when you modify this file.
# Define an application-wide HTTP permissions policy. For further

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
Rswag::Api.configure do |c|
# Specify a root folder where Swagger JSON files are located

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
Rswag::Ui.configure do |c|
# List the Swagger endpoints that you want to be documented through the

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
class Numeric
def to_currency
Money.from_amount(self, "EUR").format

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# 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.

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
Rails.application.routes.draw do
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
get 'token' => 'tokens#show', as: :token
@ -23,7 +25,14 @@ Rails.application.routes.draw do
get '/users/confirmation', to: 'users/confirmations#show', as: :confirmation
end
resources :groups, only: %i[index create update destroy]
resources :groups, only: %i[index create update destroy] do
post 'affinities/reset', to: 'affinities#reset', on: :collection
resources :affinities, only: %i[index] do
put :bulk_update, on: :collection
get :default, on: :collection
end
end
resources :guests, only: %i[index create update destroy] do
post :bulk_update, on: :collection
end

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
class CreateExpenses < ActiveRecord::Migration[7.1]
def change
create_enum :pricing_types, ["fixed", "per_person"]

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
class CreateGuests < ActiveRecord::Migration[7.1]
def change
create_table :guests, id: :uuid do |t|

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# This migration comes from acts_as_taggable_on_engine (originally 1)

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# This migration comes from acts_as_taggable_on_engine (originally 2)

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# This migration comes from acts_as_taggable_on_engine (originally 3)

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# This migration comes from acts_as_taggable_on_engine (originally 4)

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# This migration comes from acts_as_taggable_on_engine (originally 5)

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# This migration comes from acts_as_taggable_on_engine (originally 6)

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
# frozen_string_literal: true
# This migration comes from acts_as_taggable_on_engine (originally 7)

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
class CreateTablesArrangements < ActiveRecord::Migration[7.1]
def change
create_table :tables_arrangements, id: :uuid do |t|

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
class CreateSeats < ActiveRecord::Migration[7.1]
def change
create_table :seats, id: :uuid do |t|

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
class CreateGroups < ActiveRecord::Migration[7.1]
def change
create_table :groups, id: :uuid do |t|

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
class AddParentToGroup < ActiveRecord::Migration[7.1]
def change
add_reference :groups, :parent, type: :uuid, index: true, foreign_key: { to_table: :groups }

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
class AddGroupToGuest < ActiveRecord::Migration[7.1]
def change
add_reference :guests, :group, null: false, foreign_key: true, type: :uuid

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
class AddStatusToGuest < ActiveRecord::Migration[7.1]
def change
add_column :guests, :status, :integer, default: 0

View File

@ -1,5 +1,7 @@
# Copyright (C) 2024 Manuel Bustillo
# Copyright (C) 2024-2025 LibreWeddingPlanner contributors
class DropTaggableTables < ActiveRecord::Migration[7.2]
def change
drop_table 'taggings', force: :cascade do |t|

Some files were not shown because too many files have changed in this diff Show More