{"id":29717330,"url":"https://github.com/rubygarage/interview-rails","last_synced_at":"2026-03-11T13:14:25.184Z","repository":{"id":151091028,"uuid":"372653774","full_name":"rubygarage/interview-rails","owner":"rubygarage","description":null,"archived":false,"fork":false,"pushed_at":"2021-05-31T23:53:29.000Z","size":248,"stargazers_count":2,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-28T21:59:21.050Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rubygarage.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-05-31T23:49:16.000Z","updated_at":"2023-11-12T11:32:07.000Z","dependencies_parsed_at":"2023-04-18T20:17:25.151Z","dependency_job_id":null,"html_url":"https://github.com/rubygarage/interview-rails","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rubygarage/interview-rails","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubygarage%2Finterview-rails","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubygarage%2Finterview-rails/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubygarage%2Finterview-rails/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubygarage%2Finterview-rails/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rubygarage","download_url":"https://codeload.github.com/rubygarage/interview-rails/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubygarage%2Finterview-rails/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278779701,"owners_count":26044431,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-24T07:08:09.821Z","updated_at":"2025-10-07T13:12:17.097Z","avatar_url":"https://github.com/rubygarage.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Boilerplate Rails API\n\n## Docker\n\nInstall [docker and docker-compose](https://docs.docker.com/compose/install/)\n```\nsudo apt-get install docker docker-compose\n```\n\n### Run the project\n\n```\ndocker-compose up\n```\n\n### Running the tests\n\n```\nbin/docker rspec\n```\n\n### Building API documentation\nGenerate a request spec file:\n```\nrails generate rspec:swagger API::MyController\n```\nBuilding api documentation is pretty easy, just run:\n\n```\nrake rswag\n```\n\nand find it into:\n\n```\n./api-docs/index.html\n```\n\n### Running Rails console\n\n```\nbin/docker rails c\n```\n\n### Running linters\n\n```\nlefthook run all\n```\n\n### Using DIP\n\nYou can develop you application with `DIP`([more info](https://github.com/bibendi/dip))\n\nFor running services with docker.\n\n```\ndip run `the name of service`\n```\n\nLaunch application with all services.\n```\ndip provision\n```\n\nList all available run commands.\n```\ndip ls\n```\n### Sentry Notifire\n\nTo start work with sentry you should add dsn key to credentials under `sentry_dsn` name.\n\nTo get first error with `Sentry` raise `Raven.capture_exception` with exception as an argument.\n\nMore information [here](https://docs.sentry.io/platforms/ruby/guides/rails/)\n\n### Password complexity for User\n\nMust contain at least 8 characters, of which: At list one upper case, at list one lowe case,\n\nat list one number, at list one special symbols from the list: `-_!@#$%^\u0026*`.\n\nFor example: `qwertY1@`\n\n### Handling JSON API URI query with Trailblazer nested operations\n\n| Operation | Description | HTTP request example |\n| --- | --- | --- |\n| ```Api::V1::Lib::Operation::Filtering``` | Sets JSON API filtering with ```all_filters``` as default matcher | ```GET /users?filter[email-eq]=user@email.com\u0026filter[name-cont]=son\u0026match=any_filters``` |\n| ```Api::V1::Lib::Operation::PerformFiltering``` | Provides JSON API filtering with ```ctx[:filter_options]``` options | ```GET /users?filter[email-eq]=user@email.com\u0026filter[name-cont]=son\u0026match=any_filters``` |\n| ```Api::V1::Lib::Operation::Sorting``` | Sets JSON API sorting | ```GET /users?sort=name,-age``` |\n| ```Api::V1::Lib::Operation::PerformOrdering``` | Provides JSON API sorting | ```GET /users?sort=name,-age``` |\n| ```Api::V1::Lib::Operation::Inclusion``` | Provides JSON API inclusion of related resources. Dot-separated relationship path supporting not implemented at this time | ```GET /users?include=team,organization``` |\n| ```Api::V1::Lib::Operation::Pagination``` | Provides JSON API pagination with offset strategy. Accepts ```AciveRelation``` or ```Array``` as collection. By default returns 25 items per page | ```GET /users?page[number]=1\u0026page[size]=1``` |\n\n### Trailblazer macroses\n\n| Macros | Description |\n| --- | --- |\n| ```Macro::Assign``` | Provides to assign into context value from other context/context chains |\n| ```Macro::AddContractError``` | Provides to set custom error to namespaced contract |\n| ```Macro::Contract::Schema``` | Provides to use ```Dry::Validation.Schema``` as operation contract |\n| ```Macro::Decorate``` | Provides to decorate ctx object with specified decorator. Supports object or collection as model |\n| ```Macro::Inject``` | Provides to set dependency injection in operations |\n| ```Macro::LinksBuilder``` | Provides to proxy resource path to ```Service::JsonApi::Paginator``` and sets composed links into context |\n| ```Macro::Model``` | Provides to assign model into context. Supports assign by relation chain, relation find_by |\n| ```Macro::ModelRemove``` | Provides to destroy and delete model. |\n| ```Macro::Renderer``` | Provides to render operation result with specified serializer with strict following Jsonapi specification |\n| ```Macro::Semantic``` | Provides to set value of semantic marker (```semantic_success``` or ```semantic_failure```) into context |\n| ```Macro::Policy``` | Set semantic marker ```semantic_failure``` to equel ```:forbidden``` and add errors if no policy|\n\n### Services\n\n| Service | Description |\n| --- | --- |\n| ```Service::Pagy``` | Wrapes active record collection / array into ```Pagy``` |\n| ```Service::JsonApi::Paginator``` | Buildes pagination links with ```Pagy``` |\n| ```Service::JsonApi::ResourceSerializer``` | ```FastJson``` serializer factory |\n| ```Service::JsonApi::ResourceErrorSerializer``` | Resource error serializer service with strict following Jsonapi specification |\n| ```Service::JsonApi::HashErrorSerializer``` | Hash error serializer service with strict following Jsonapi specification |\n| ```Service::JsonApi::UriQueryErrorSerializer``` | URI query error serializer service with strict following Jsonapi specification |\n| ```Api::V1::Lib::Service::JsonApi::ColumnsBuilder``` | Auxiliary service for performing validation dependencies for filtering/sorting operations. Build collection with ```Api::V1::Lib::Service::JsonApi::Column``` instances |\n\n### Constants\n\n| Constant | Description |\n| --- | --- |\n| ```JsonApi::Filtering::PREDICATES``` | Available JSON API filter predicates by column type |\n| ```JsonApi::Filtering::OPERATORS``` | Available JSON API filter matchers |\n| ```JsonApi::Pagination::MINIMAL_VALUE``` | Pagination per page configuration |\n| ```Constants::TokenNamespace::SESSION``` | Session JWT token namespace |\n| ```Constants::TokenNamespace::RESET_PASSWORD``` | Reset password JWT token namespace |\n\n### Application base classes\n\n| Class | Description |\n| --- | --- |\n| ```ApplicationEndpoint``` | Base class that responsible for handling statuses of HTTP-responses, works with DefaultEndpoint concern |\n| ```ApiController``` | Base application controller class that available for unauthorized users |\n| ```ApplicationOperation``` | Base application operation class |\n| ```ApplicationContract``` | Base application contract class. Use it for build/update entity. Otherwise use ```Dry::Validation.Schema``` |\n| ```ApplicationDecorator``` | Base application decorator class |\n| ```ApplicationSerializer``` | Base application serializer class |\n| ```ApplicationWorker``` | Base application worker class |\n\n### Upload files\n\nBoilerplate used `Shrine` for upload files local and to S3.\nCreate you own uploader and inherit it from `ApplicationUploader`.\nFor more [info](https://shrinerb.com/docs/getting-started)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubygarage%2Finterview-rails","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubygarage%2Finterview-rails","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubygarage%2Finterview-rails/lists"}