# Context
- https://digital.dclg.gov.uk/jira/browse/CLDC-2316
- Implement bulk upload sales for new collection year 2023
- This is a first pass implementation and will probably have some bugs in it and we can address over time
# Changes
- Add CSV parser for sales 2023 to handle CSV structure
- Tweak collection window validation so error now contextual to year selected for upload
- Handle arbitrary ordering of CSV columns
- Fix ordering of errors in report and now ordered by cell
- Added `Upload your file again` link styled as button on error report to match lettings experience
- Update tooling to convert logs to 2023 csv rows with support for random column ordering
# Known issues
- There seem to be some issues with how UPRN is handled if the UPRN cannot be validated.
- For the above I think there is dependency on https://github.com/communitiesuk/submit-social-housing-lettings-and-sales-data/pull/1570 which should clear any errored fields so users can continue to create logs and fix within the service
# Context
- https://digital.dclg.gov.uk/jira/browse/CLDC-2294
- When bulk upload returns a results page it would be useful if colleagues of the uploader can see this page to help fix errors
- It would also be useful if support users can see these reports to help diagnose bulk upload errors
# Changes
- Added `pundit` gem to handle authorization
- Bulk upload results previously only accessible to the bulk uploader. Now they can be seen by users in the same org as the uploader and also support users
* refactor with extract method
* can filter logs by bulk upload
* hide log creation button when viewing bulk upload
- this affects the logs index page filtering logs from a specific bulk
upload
* add info banner to bulk upload logs
* placeholder for bulk upload logs header
* when resuming bulk upload set filters
* fill place holder with remaining logs to fix
* add interstitial to resume if logs resolved
* after resolving bulk upload logs show interstitial
* fix linting error
* extract view variable to helper method
* CLDC-1195: remove access keys
* 🤏 content fixes (#539)
* Remove ??
* Set hhmemb to totadult and tchild sum if hhmemb is not given (#540)
* Set hhmemb to totadult and tchild sum if hhmemb is not given
Co-authored-by: Ted <tedbooton@gmail.com>
Co-authored-by: Dushan <dushan@madetech.com>
* lint
* update method
* calculate hhmemb from details provided
Co-authored-by: Ted <tedbooton@gmail.com>
Co-authored-by: Dushan <dushan@madetech.com>
* Fix condition affects question (illness type)
* map tshortfall value (#543)
* Make case log status rely on subsection status so they can't get out of sync
* Fix complete case log fixture
* Fix Reason preference reason and lettings allocation answer option import
* don't route to hbrentshortfall if hb is 7 (#544)
* Age known believe import fixes (#545)
* amend fixture to make test fail
* fix failing test
* lint fixes
* Enable dynamically dependent answer options
* Refactor ecstat age check
* Dry depends on evaluation
* Derive major repairs for import
* Add white other
* Set major repair date
* Majorrepairs will never match
* Rubocop
* Cldc 1149 radio buttons filter (#548)
* radio button
* radio button again
* rubocop versioning issue fixed
* linux and darwin
* Fix Gemfile
* rubocop
* erb lint
Co-authored-by: baarkerlounger <db@slothlife.xyz>
* Set tshortfall to 0 if it should exists but is not provided (#550)
* Set tshortfall to 0 if it should exists but is not provided
* check if tshortfall is overridden
* Save correct la if postcode is invalid (#551)
* Allow illness type to be refused (#553)
* Radio button on log filter is now preset to "All" (#552)
* Radio button on log filter is now preset to "All"
* lint fixes
* removed instance @ variable
* CLDC-744-joint-tenancy-validation (#549)
* add joint tenancy validation
* fix validation and spec
* improvements
* updates
* lint fixes
* fix typo
* change message displayed on hhmemb page
* Add docs dir to dockerignore and cfignore (#555)
* Add files via upload (#554)
Adding Delta Discovery file
* Improve DB seeding (#556)
* Improve DB seeding
* Don't seed LA Rent Ranges in test
* Add navigation items helper
* Fix specs and linters
* Works but helper is hard to test
* add check to prevent error on hhmemb if joint is nil (#560)
* add failing spec
* add check to prevent error on hhmemb if joint is nil
* Refactor for testability
* Spec nav bar highlighting from user perspective
* CLDC-1218: Fix hbrentshortfall import (#558)
* Infer hbrentshortfall not known if tshortfall not provided and overridden
* Reorder import
* Referral can be internal for homeless (#561)
* Set case log ID offset at export (#562)
* Make tshortfall optional based on hidden tshortfall_known question (#563)
* Make tshortfall optional based on hidden tshortfall_known question
* Add test for optional
* Add test for JSON derived and dependent on false options
* Test routing
* Fix optionality
* Inactive users (#564)
* Allow users to be marked as inactive
* Import inactive users
* add missing field to seeded user for dev env
* Map joint tenancy field (#565)
* Use rake task to send onboarding emails (#566)
* Use rake task to send onboarding emails
* Wrap host lookup so it's easily stubbable
* Rake task can be called outside the rails environment so need to pass host in
* Not part of the usual app flow so contain to rake task
* Including routes helper in a rake task is a rabbit hole
* Use ENV var rather than param for host
* Sort case log index table by most recent by default (#567)
* Add sheltered accom field (#568)
* Remove needs type question until we support supported housing logs (#569)
* Fix routing for tshortfall (#571)
* Fix routing for tshortfall
* HB 7 and 8 don't exist in 22/23 anymore
* Add visiblly hidden change link text for details known questions
* Fix repeated use of Password in error summary (and use smart quotes)
* Make logs link less ambiguous
* Cldc 1217 retirement soft validation (#570)
* Interruption screen refactor
* Add test for retirement_age_for_person
Co-authored-by: Stéphane Meny <smeny@users.noreply.github.com>
* Rubocop
* update 22-23 form
* fix failures
* lint fixes
* remove whitespace
* remove commented code
* make spec file use translations instead of content
* update content
* lint fixes
* fix typo
* fix question wording
* fix failing spec
* add full stop
Co-authored-by: Stéphane Meny <smeny@users.noreply.github.com>
Co-authored-by: Dushan Despotovic <dushan@madetech.com>
* Hide inactive users and allow support users to view all users (#576)
* Hide inactive users and allow support users to view all users
* Enable support users to invite users to any organisation
* Add pagination to user views
* Update config/locales/devise.en.yml
Co-authored-by: Paul Robert Lloyd <paulrobertlloyd@users.noreply.github.com>
* remove letting_in_sheltered_accomodation field (#577)
* remove letting_in_sheltered_accomodation field
This field is now duplicated by the shelteredaccom field
* lint fixes
* fix all failing specs
* Generisize pagination links
* CLDC-1101: Case log filter by organisation (#522)
* Rename org filter
* Ensure filters work when ID is passed
* UI init
* Lint
* Fix filter nesting
* Reduce width
* Set checked status of filters correctly
* Test filter presence
* Add filter test
* Rubocop
* Tweak styles for autocomplete within filter
Co-authored-by: Paul Robert Lloyd <me+git@paulrobertlloyd.com>
* CLDC-1224: Tenancy type and tenancy length (#578)
* Fix value mapping for tenancy type 22/23
* Update secure helper
* Null safe
* Spec update
* Update mandatory
* Use helper
* Remove joint tenancy hitn text and add don't know option (#579)
* Export improvements (#581)
* improved export - set start point for reference
* remove completed status from exports
* Added exception handling to export
* Improved tests, replaced rescue block with Sentry
Co-authored-by: Kat <katrina@madetech.com>
* Update logs table column heading to say ‘Status’, not ‘Completed’
* Show ‘Data protection officer’ and/or ‘Key contact’ tags in users table
* Update heading, label and hint text for user details
* Fix organisation filter (#582)
* Filter values correctly
* Remove filter value if hidden
* Return empty string rather than nil for accessible autocomplete
* Additional test for accessible automcomplete defaulting
* Add status tag helper
* Add missing ‘or’ divider on joint tenancy question
* Use dash not hyphen in answer options
* CLDC-1118: Implement data export structure (CDS) (#587)
Co-authored-by: Dushan Despotovic <dushan@madetech.com>
* CLDC-1217: Retirement soft validation (#586)
* Don't trigger soft validation if tenant prefers not to say
* Update gender content
* Fix spec description
* Enable support users to download user details (#589)
* Enable support users to download user details
* Download all users
* Rubocop
* Preload organisations to remove n+1 queries
* Confirmable (#580)
* Confirmable
* Remove obsolete rake task
* Skip confirmation for inactive users
* Send beta onboarding template if migrated from Softwire
* Default controller
* Use correct link
* Redirect confirmation to set password
* Confirm account within 3 days
* Only redirect to set password if not previously set
* Rubocop
* Confirm factory bot users
* Set password condition
* Changing email requires reconfirming
* No need to explicitly trigger email, devise does that for us now
* Remove flash banner
* Mock notify
* Mock in the right spec
* Test redirect and text
* User is confirmable
* Rubocop
* Redirect to url so we don't bypass authenticity token
* Update content
* Add test for resend invite flow
* Update link to resend confirmation email
* Rename password reset resend confirmation partial
* Expired link error page
* Remove resend confirmation link
* Update seed
* Expory contact
* Time zone
Co-authored-by: Paul Robert Lloyd <me+git@paulrobertlloyd.com>
* Attempt at fixing S3 error when saving Zip file (#590)
* Enable better other field validation labels
* Removing gaps caused by empty exports (#591)
* Add Sentry instrumentation (#593)
* Avoid NoMethodError when Sentry is not initialised
* Instrument collection_start_year
* Removes Sentry custom instrumentation
* test for user being in dev env not being asked for 2fa
* code for user being in dev env not being asked for 2fa
* pulled out of support person context, this should work for any user in dev env
* rubocop
* matching wording
* only support user atm need 2fa, so making this explicit
* Perf (#592)
* Memoize start year
* Reset
* Recalculate rather than reset
* Fix heisenspec (order independent array comparison) (#596)
* Redirect confirmed users to sign in
* Add support for CSV export (#598)
* Cldc 1102 admin organisations page (#557)
* Get all organisations in controller
* Display organisations data in the table
* Route to logs for specific organisation
* add tests
* update spec
* lint fixes
* set up failing test for organisation logs page
* fix failing test
* write test for organisations support user page
* Update a organisation page test and lint
* added pagination test with next and previous links and total count for support user
* test for pagination in organisations title
* Added "Organisations" to to organisations page title
* add pagination test for organisations page 2, remove second before block
* Add the remaining pagination tests
* Redirect when accessing organisation logs by non support user
* Test for displaying logs for specific organisation
* Add test for org name
* Add a failing log filter test for specific org
* Extract filter methods into a helper
* Allow logs filtering for specific org
* Fix test, support user was creating an extra org, remove orgs filter for specific org
* Remove redundant test, lint
* Reuse primary navigation component and add sub navigation for support users
* allow support users edit or and add sub navigation to about this org
* allow support users to access the edit org page
* only allow to edit existing editable fields
* display correct values in the organisations table
* allow support user to update org
* user table component for organisations table
* use guard clause for organisation logs page
* remove create a new lettings log from organisation logs
* Move case logs filter from helpers to modules
* lint erb
* yarn lint
* bring back if statement in logs controller
* update modules import
* let!
* test for links first in the org cotroller spec
* interpolate number of orgs
* conditionally render sub navigation
Co-authored-by: Kat <katrina@madetech.com>
Co-authored-by: Dushan Despotovic <dushan@madetech.com>
Co-authored-by: JG <moarpheus@gmail.com>
* Bump nokogiri from 1.13.5 to 1.13.6 (#601)
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.13.5 to 1.13.6.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.13.5...v1.13.6)
---
updated-dependencies:
- dependency-name: nokogiri
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* CLDC-1124: User search (#600)
* Add search by name for users
Co-authored-by: baarkerlounger <baarkerlounger@users.noreply.github.com>
* Search is now non case sensitive
* Made search work for data co-ordinators
Co-authored-by: baarkerlounger <baarkerlounger@users.noreply.github.com>
* Refactored to scope
* Added search by email
Co-authored-by: baarkerlounger <baarkerlounger@users.noreply.github.com>
* WIP Commit - added test for if search term matches a name and an email address simultaneously. Also changed search result caption for organisations to display "Matches X of Y users"
* Rubocop
* Preload org
* Linting
* Refactor filtered_users into module
* Only adjust query param if searched
* Add data coordinator tests
* Add table caption spec
* Dupe attribute
* Refactor into Search ViewComponent
* Rubocop
* Unit test user scopes
Co-authored-by: Ted <ted.booton@madetech.com>
Co-authored-by: baarkerlounger <baarkerlounger@users.noreply.github.com>
* Use dedicated styles for each navigation component
* Use dedicated styles for each navigation component
* Use simpler markup for table captions
* Use table component for logs list
* Correct markup for user and organisation tables
* Email allowlist (#603)
* Email allowlist
* Set rails master key in deploy pipelines
* CLDC-1258: Handle invalid void date during import (#604)
* Now we raise an exception if a non-existing organisation is referenced by a case log
* The void date is not imported if it is after the tenancy start date
* make organisations list page default view for support user login (#605)
* Use seperate components for primary and sub navigation
* Add LA org mapping
* Rubocop
* User search fixes (#607)
* Update query message
* Add clear search link
* Set input value
* Use gem component
* Move to list partial pattern
* Partial path
* Update spec
* Rubocop
* Unit test filter module
* Rubocop
* Add search result to page title if searched
* Add missing horizontal rule
* Use form_group attributes for search input
Co-authored-by: Paul Robert Lloyd <me+git@paulrobertlloyd.com>
* CLDC-1225: At import updates relationship to child when a person is under 16 (#609)
* Organisation search (#610)
* Add search to organisations
* Fix title
* Spec page title
* Don't seed org in test
* Handles unicode characters in postcode (#612)
* CSV download only includes users in search result
* Updates exported fields based on May 25th feedback (#613)
* Cldc 1223 pregnancy soft validations (#602)
* update hard validation limits for pregnancy age, remove hard validation if there are no females at all
* Add soft validations for pregnancy
* make the error message consistent
* Only check the values for the members with details known in the household
* Show interruption screen when resident details are updated
* Route back to check answers after an interruption screen and back to previous page if no is selected on the interruption screen
Co-authored-by: baarkerlounger <baarkerlounger@users.noreply.github.com>
* update validation messages
* fix a test
* fix a typo
Co-authored-by: baarkerlounger <baarkerlounger@users.noreply.github.com>
* Avoid variable number of columns during CSV export (#614)
* CLDC-1277: no route matches bug (#615)
* don't display the save and go to the next incomplete section button if it errors 🤷♀️
* use 2022/23c fixture for in the test
* Allow support users and data coordinators to toggle active users
* Add a link to deactivate page
* add deactivate page
* Show if user is deactivated and fix form
* Show deactivated user in the user list
* Show reactivate user link for deactivated users
* add reactivate user page
* Refactor
* remove unused method, route and lint
* fix routes
* Only allow active users to log in
* Add flash banner for successful toggle, fix styles
* FIx more styling
* prevent editing deactivated user
* lint
* reset confirmed_at, password and sign in count when deactivated. Send reactivation email if user has previously logged in
* Use dash not hyphen in confirmation page button and links
* Content: Deactivate/reactivate account, not the user
* Send confirmation email to both, old and new email addresses
* Add possessive gem for names formatting
* Use hidden input field for active value
* lint
* Only send beta onboarding emails if the user hasn't previously logged in
* Don't clear the password for deactivated user
* refactor sending confirmation emails
Co-authored-by: kiddhustle <kiddhustle@wiardweb.com>
Co-authored-by: Paul Robert Lloyd <paulrobertlloyd@users.noreply.github.com>
Co-authored-by: baarkerlounger <db@slothlife.xyz>
Co-authored-by: baarkerlounger <5101747+baarkerlounger@users.noreply.github.com>
Co-authored-by: Ted <tedbooton@gmail.com>
Co-authored-by: Dushan <dushan@madetech.com>
Co-authored-by: Dushan <47317567+dushan-madetech@users.noreply.github.com>
Co-authored-by: Ted-U <92022120+Ted-U@users.noreply.github.com>
Co-authored-by: sona-mhclg <77793209+sona-mhclg@users.noreply.github.com>
Co-authored-by: Paul Robert Lloyd <me+git@paulrobertlloyd.com>
Co-authored-by: Stéphane Meny <smeny@users.noreply.github.com>
Co-authored-by: JG <moarpheus@gmail.com>
Co-authored-by: J G <7750475+moarpheus@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ted <ted.booton@madetech.com>
Co-authored-by: baarkerlounger <baarkerlounger@users.noreply.github.com>
* Update query message
* Add clear search link
* Set input value
* Use gem component
* Move to list partial pattern
* Partial path
* Update spec
* Rubocop
* Unit test filter module
* Rubocop
* Add search result to page title if searched
* Add missing horizontal rule
* Use form_group attributes for search input
Co-authored-by: Paul Robert Lloyd <me+git@paulrobertlloyd.com>
* Confirmable
* Remove obsolete rake task
* Skip confirmation for inactive users
* Send beta onboarding template if migrated from Softwire
* Default controller
* Use correct link
* Redirect confirmation to set password
* Confirm account within 3 days
* Only redirect to set password if not previously set
* Rubocop
* Confirm factory bot users
* Set password condition
* Changing email requires reconfirming
* No need to explicitly trigger email, devise does that for us now
* Remove flash banner
* Mock notify
* Mock in the right spec
* Test redirect and text
* User is confirmable
* Rubocop
* Redirect to url so we don't bypass authenticity token
* Update content
* Add test for resend invite flow
* Update link to resend confirmation email
* Rename password reset resend confirmation partial
* Expired link error page
* Remove resend confirmation link
* Update seed
* Expory contact
* Time zone
Co-authored-by: Paul Robert Lloyd <me+git@paulrobertlloyd.com>
This commit fixes the tests that failed as a result of the introduction
of the created_by column in the case log table. The tests were failing as
it is now necessary to have a created_by for a case log
* Works but relies on routes ordering
* Add helper test
* Actually work
* Test edit password auth even though we don't have a route for it
* Add spec description
* Consistency
* Show validation error if user email already exists instead of crashing
* Use translation strings
* When answer option is mapped just display directly
* Validate provider type presence
* Infer la from postcode
* Fix other tests and lint
* Add routing based on inferred la
* reset la to inferred false
* Use postcodes io gem
* reset values if la cannot be inferred
* Fix tests
* Scope auth for org pages
* Scope user methods
* Refactor form UI controller
* More tests for access
* Consistently return not found for scoped auth
* Add ADR
* Authenticate bulk uploads
* Authenticate soft validations controller
* Scope bulk upload to user's org for now
* Pass through current user
* Update docs/adr/adr-012-controller-http-return-statuses.md
Co-authored-by: Dushan <47317567+dushan-madetech@users.noreply.github.com>
* Update spec/requests/case_log_controller_spec.rb
Co-authored-by: Dushan <47317567+dushan-madetech@users.noreply.github.com>
Co-authored-by: Dushan <47317567+dushan-madetech@users.noreply.github.com>
* Add renttype column
* infer renttype value from rent_type
* Fix typo
* Add renttype column
* infer renttype value from rent_type
* Fix typo
* Update inferred fields in the db
* Disable rubocop for datetime
* remove new line
* refactor
* Add organisation model and user association
* Add user admin panel
* email
* Update seeds
* Update spec
* Case logs belong to organisations
* Org case log association
* Add user case log association
* User case log helper methods
* Org case log relation helpers
* Case log index page only shows your organisations case logs
* No access to tasklist page for logs that aren't associated with your org
* No access to form pages for case logs that aren't owned or managed by your org
* Check answers access
* Submit form access
* Refactor out not found methods
* Allow user admin update without password
* Update feature specs
* Rubocop
* Update case log specs
* Test admin user update without password
* Spec grammar
* Refactor feature specs into smaller units
* DRY spec helpers
* Bump Turbo
* Use database ID assignment everywhere we need ID to reduce flakiness
* Update gemfile.lock
* Email is unique
* Selenium deprecation
* Don't need let bang
* Remove the uneeded extra options
* Remove flaky test mitigations that didn't work
* Use lockstep to remove test flakiness
* Dry up condition evaluation
* Spec admin user edit form
* Test income refused derivation
* Set valid incref
* Test Case Log deletion failures
* Test other household member age validations
* Test all reasonable preference validation paths
* Spec case logs admin table
* Spec admin user admin index
* Dashboard controller panel specs
* Spec panel contents
* Add create specs
* Don't assign non db ids if we don't need them
* Fix specs for new section
* Fix up fields
* Refactor routing
* Tenant code is now in About This Log
* Invert form definition routing syntax
* Make GDPR acceptance explicit dependency
* Add ReadMe description
* Add ADR for form routing logic
* Update JSON schema
* Add frontend gem repo to readme
* Rubocop
Devise is a commonly used gem for user authentication and management. Using
rails generators and Devise allows us to get a lot of boilerplate code for
user authentication and management and means we don't have to revinvent the
wheel. Styling will need to be done for the necessary pages and there are
likely to be bits of generated code that can be deleted. This will act as
a starting point to be built up from using TDD.
* Remove condition_effects_prefer_not_to_say field
* Change reason type
* Remove prefer not to say from illness
* add majorrepairs,propcode and infer postcode
* Update previous location and la
* Update majorrepairs, national and reasonpref
* Update housing benefits fields
* rename file
* Add previous postcode
* Move inferred postcode to model
* refactor infered poscode method
* Remove unneeded import
* update miration and some mappings
* Remove duplicate migration command
Devise is a commonly used gem for user authentication and management. Using
rails generators and Devise allows us to get a lot of boilerplate code for
user authentication and management and means we don't have to revinvent the
wheel. Styling will need to be done for the necessary pages and there are
likely to be bits of generated code that can be deleted. This will act as
a starting point to be built up from using TDD.
* migration wip
* change field names to lowercase and fix the tests
* Change national and ethnic field types and map to correct enums
* change ecstat column types
* Change prevten field type
* Change homeless field type
* Change benefit cap field type
* Put db enums in one folder and add a few new field changes"
* change field type for housing needs
* Change illness field type
* display checkbox answers
* cbl, chr, cap
* Change tenancy and tenancylength field types
* Change landlord and rsnvac field types
* Change unittype_gn field type
* Reasonble preference displaying on check answers
* update more field types
* Fix typo in comumn name
* Change more types
* Test fixes
* Add adr
* fix some tests
* run migration
* Fix tests
Co-authored-by: Matthew Phelan <matthew.phelan@madetech.com>
* Init
* Add some tests
* Add failing spec
* Move soft validations into a module
* Update test
* Rubocop
* Scope are auto created by enums
* Rename folder to validations
* No instance variable
* Commit both lines
* Add error indication
* Make partial slightly more generic
* Fix back link
* Write failing test
* All specs currently passing. Can this be real?
* Check page should have an override question
* Fix back button for check answers pages
* Don't really need a wrapper method for the validations
* We're really validating a page here not a question
* Dup variable
* Bit of a nasty hack but maybe better than deriving back link?
* Set a no cache header instead of reloading
* Move a teeny bit of logic out of the controller
* Rubocop
* Extract method
* Add next page path method with conditional routing
* Rename method
* Fix the tests and add files to .gitignore
* Make get_next_page_path a private method
* WIP test for total question count
* Change back button to use rails navigation
* Make total number of questions work with conditional routing and run rubocop
* Add tests for conditional question displaying
* Add conditional routing to the check answers page
* push 1 failure
* make total_questions step over the form like a user would and gather relevand questions
* Fix the tests
* fixed checks answers labels
* small refactors and rubocop
* remove unused code from get next page path
Co-authored-by: Kat <katrina@madetech.com>
Co-authored-by: magicmilo <milobascombe@gmail.com>
* Add checked answers values as true if they are passed back as case log params from the form
* Allow changing/unticking saved checkbox values
* rubocop
* Save keys for checkboxes instead of labels
* Add conditional effects keys and table fields
* Add reasonable preference reason keys and table fields
* Redo the migrations
* Move method call around
* Update case_log params before checking them with page_params
* Reload case log rather than multiple lookups
* Refactor checkbox question selection
* Refactor out the need to get list of checkbox questions
* Spec merging of answers across different question types
* Update readme to include checkbox question data model assumptions
* Fix postcode duplication
Co-authored-by: baarkerlounger <db@slothlife.xyz>