{"id":16584512,"url":"https://github.com/anmarchenko/igroteka","last_synced_at":"2025-10-29T08:30:23.599Z","repository":{"id":139918296,"uuid":"425556978","full_name":"anmarchenko/igroteka","owner":"anmarchenko","description":"Backend for the game backlog management app","archived":false,"fork":false,"pushed_at":"2024-11-17T14:06:09.000Z","size":607,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-01T23:51:03.394Z","etag":null,"topics":["backlog","elixir","games","igdb","phoenix","phoenix-framework"],"latest_commit_sha":null,"homepage":"https://igroteka.cc","language":"Elixir","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/anmarchenko.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}},"created_at":"2021-11-07T16:33:53.000Z","updated_at":"2024-11-17T14:06:12.000Z","dependencies_parsed_at":"2023-09-19T16:44:06.573Z","dependency_job_id":"abffd866-3b4a-4f87-8e6e-5a18d32d2f66","html_url":"https://github.com/anmarchenko/igroteka","commit_stats":null,"previous_names":["anmarchenko/igroteka","altmer/igroteka"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anmarchenko%2Figroteka","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anmarchenko%2Figroteka/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anmarchenko%2Figroteka/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anmarchenko%2Figroteka/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anmarchenko","download_url":"https://codeload.github.com/anmarchenko/igroteka/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238791895,"owners_count":19531027,"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","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":["backlog","elixir","games","igdb","phoenix","phoenix-framework"],"created_at":"2024-10-11T22:44:50.419Z","updated_at":"2025-10-29T08:30:17.892Z","avatar_url":"https://github.com/anmarchenko.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Igroteka\n\nThis is the backend API for my gaming backlog app. I use it on a daily basis to keep track of video games I played/want to play/playing now. It uses [IGDB](https://www.igdb.com), [howlongtobeat.com](https://howlongtobeat.com) and [opencritic.com](https://opencritic.com) as data sources. You can read more about this project on my [personal website](https://www.amarchenko.de/igroteka/).\n\n## Prerequisites\n\n- [twitch API client id](https://dev.twitch.tv) for [IGDB API](https://api-docs.igdb.com/#getting-started)\n- [Opencritic API key](https://rapidapi.com/opencritic-opencritic-default/api/opencritic-api)\n- [elixir](https://elixir-lang.org)\n- [postgres](https://www.postgresql.org)\n\n## Run locally\n\nAdd `config/dev.secret.exs` file with the following contents:\n\n```elixir\nimport Config\n\nconfig :skaro, :igdb,\n  client_id: \"your_twitch_client_id\",\n  client_secret: \"your_twitch_client_secret\"\n\nconfig :skaro, :opencritic, api_key: \"your_opencritic_rapidapi_key\"\n\nconfig :skaro, Skaro.Repo,\n  username: \"your_postgres_user\",\n  password: \"your_postgres_user_password\",\n```\n\nRun the following commands to setup dependencies and create the database:\n\n```bash\nmix deps.get\nmix ecto.setup\n```\n\nRun server:\n\n```bash\nmix phx.server\n```\n\nVerify that it is running by navigating to `http://localhost:4000` in your browser: if you see message \"Welcome to skaro\" then it's running.\n\nAfter that you can setup and run [frontend app](https://github.com/anmarchenko/igroteka_fe). To use it navigate to `http://localhost:3000` and login with `admin@skaro.com/12345678`. Have fun testing the app!\n\n## Run tests\n\n```bash\nmix test\n```\n\n## Lint\n\n```bash\nmix credo --strict\n```\n\n## Deployment\n\nI run the app on [fly.io](https://fly.io). See the Fly.io documentation on running an Elixir application [here](https://fly.io/docs/elixir/getting-started/). The release configuration is in the [fly.toml](https://github.com/anmarchenko/igroteka/blob/master/fly.toml).\n\nTLDR: perform first deploy by running `fly launch` and subsequent deploys by running `fly deploy`.\n\n## CI\n\nThis repository uses [GitHub Actions](https://github.com/features/actions) to deploy from `master` branch. The [main.yml](https://github.com/anmarchenko/igroteka/blob/master/.github/workflows/main.yml) file defines the single workflow (for now) - fly.io deployment.\n\n## How do we model gaming backlog\n\nTODO: move this to hexdocs.\n\nPhoenix contexts are used to model different domains that exist in this app.\n\n### [Accounts](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/accounts)\n\nAuthentication and user management.\n\nModels:\n\n- [User](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/accounts/user.ex) - **root aggregate** of this context, represents an application's user.\n\nFunction modules:\n\n- [Users](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/accounts/users.ex) - CRUD actions to manage users.\n- [Sessions](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/accounts/sessions.ex) - authentication code.\n\n### [Core](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/core)\n\nIn Igroteka \"Core\" means \"everything related to Game that is our core domain\".\n\nModels:\n\n- [Game](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/core/game.ex) - **root aggregate**, represents a video game.\n- [Company](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/core/company.ex) - represents a gamedev company (might be developer or publisher or both).\n- [Platform](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/core/platform.ex) - platform where the game was released at some point in time (for example PlayStation 2 or NES).\n- [Genre](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/core/genre.ex) - genre(s) that game belongs to (Action, RPG, etc).\n- [Theme](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/core/theme.ex) - theme of the game.\n- [Image](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/core/image.ex) - screenshot or poster for the game.\n- [Video](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/core/video.ex) - video about this game on external resource (YouTube).\n- [Franchise](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/core/franchise.ex) - franchise the game belongs to (eg. Zelda, Mario, God of War).\n- [ExternalLink](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/core/external_link.ex) - link to some external resource (for example official website, twitter account).\n\nFunction modules:\n\n- [Core](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/core/core.ex) - functions that find and return games using IGDB services.\n\n### [Backlog](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/backlog)\n\nThis context deals with user's backlog - all the games that user wants to play or played in the past or playing right now. Backlog context revolves around the concept of \"Entry\" that represents a single game in user's backlog.\n\nThe most important attribute of Entry is **status** which can be one of the following:\n\n- wishlist - games that user would like to buy\n- backlog - games that user owns but did not play yet\n- playing - games that user plays right now\n- beaten - games that user played and considers to be *\"done\"*\n\nModels:\n\n- [Entry](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/backlog/entry.ex) - **root aggregate**, represents a single game in user's backlog.\n- [AvailablePlatform](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/backlog/available_platform.ex) - an additional model that represents a platform where the game from the given backlog entry was released. This model exists because we need to provide a way for the user to select on which platform they are going to play this game.\n\nFunction modules:\n\n- [Entries](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/backlog/entries.ex) - CRUD operations for Backlog context.\n\n### [Playthrough](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/playthrough)\n\nPlaythrough context deals with data on what would it take to beat the game.\n\nModels:\n\n- [PlaythroughTime](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/playthrough/playthrough_time.ex) - connected to Game, represents hours one needs to beat the game in one of the playstyles (Main Quest / Main + Side Quests / Completionist).\n\nInterfaces:\n\n- [Remote](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/playthrough/remote.ex) - defines behaviour for any service that fetches playthrough data from external provider.\n\nFunction modules:\n\n- [Playthrough](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/playthrough/playthrough.ex) - fetches from remote and stores playthrough data.\n\n### [Reviews](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/reviews)\n\nReviews context works with critics scores and reviews for games.\n\nModels:\n\n- [Rating](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/reviews/rating.ex) - represents median critics score and samples of critics reviews.\n\nInterfaces:\n\n- [Remote](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/reviews/remote.ex) - defines behaviour for services that fetch reviews from external provider.\n\nFunction modules:\n\n- [Reviews](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/reviews/reviews.ex) - fetches from remote and stores scores and reviews data.\n\n### [IGDB](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/igdb)\n\nThis context encapsulates code that talks to IGDB API. NOTE: Not a domain context as it doesn't have any models.\n\nFunction modules:\n\n- [IGDB](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/igdb/igdb.ex) - calls IGDB API and parses the JSON response to produce Core models.\n- [Token](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/igdb/token.ex) - fetches API token from Twitch.\n\n### [Howlongtobeat](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/howlongtobeat)\n\nThis context has functions that scrape and parse howlongtobeat.com pages. NOTE: Not a domain context as it doesn't have any models.\n\nFunction modules:\n\n- [Howlongtobeat](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/howlongtobeat/howlongtobeat.ex) - context facade, implements Remote interface from Playthrough context.\n- [Client](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/howlongtobeat/client.ex) - retrieves and parses information from \u003chttps://howlongtobeat.com\u003e.\n\n### [Opencritic](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/opencritic/opencritic.ex)\n\nThis context provides a way to work with Opencritic API. NOTE: Not a domain context as it doesn't have any models.\n\nFunction models:\n\n- [Opencritic](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/opencritic/opencritic.ex) - context facade, implements Remote interface from Reviews context.\n- [Client](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/opencritic/client.ex) - calls Opencritic API and parses the response.\n- [Mapper](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro/opencritic/mapper.ex) - provides transformations for Opencritic data.\n\n## API\n\nThis app provides REST-like API for a frontend application.\nThe following endpoints are provided:\n\n### [SessionController](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro_web/controllers/session_controller.ex)\n\n`POST /sessions` - creates session from email and password provided in body; returns JWT token.\n\n### [UserController](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro_web/controllers/user_controller.ex)\n\n`GET /current_user` - returns user info based on authentication header\n\n`GET /users/{id}` - returns user info by ID\n\n`PUT /users/{id}` - updates user's info\n\n`PUT /users/{id}/update_password` - changes user's password\n\n### [GameController](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro_web/controllers/game_controller.ex)\n\n`GET /games` - filters and returns a list of games from IGDB (possible filters are: by developer, by publisher, by search term, new games, top games overall, top games by year)\n\n`GET /games/{id}` - returns game's info from IGDB by game ID\n\n### [BacklogEntryController](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro_web/controllers/backlog_entry_controller.ex)\n\nThis resource manages backlog entries aka games that are in your backlog.\n\n`GET /backlog_entries` - filters backlog entries for current user\n\n`GET /backlog_entries/{id}` - returns backlog entry\n\n`POST /backlog_entries` - adds the game to the backlog\n\n`PUT /backlog_entries/{id}` - updates backlog entry\n\n`DELETE /backlog_entries/{id}` - removes the game from the user's backlog\n\n### [BacklogFilterController](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro_web/controllers/backlog_filter_controller.ex)\n\n`GET /backlog_filters` - returns filters view model for user's backlog (available release years and platforms for example)\n\n### [ScreenshotController](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro_web/controllers/screenshot_controller.ex)\n\n`GET /screenshots` - returns a list of screenshots for a given game\n\n### [PlaythroughTimeController](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro_web/controllers/playthrough_time_controller.ex)\n\n`GET /playthrough_times/{game_id}` - returns info on how long is the game to play\n\n### [ReviewController](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro_web/controllers/review_controller.ex)\n\n`GET /reviews/{game_id}` - returns critics rating and reviews for the game\n\n### [CompanyController](https://github.com/anmarchenko/igroteka/blob/master/lib/skaro_web/controllers/company_controller.ex)\n\n`GET /companies/{id}` - returns information about game development company (developer or publisher)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanmarchenko%2Figroteka","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanmarchenko%2Figroteka","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanmarchenko%2Figroteka/lists"}