{"id":19269261,"url":"https://github.com/gvozdenkov/algoschool","last_synced_at":"2026-04-12T17:38:51.927Z","repository":{"id":203096260,"uuid":"708699228","full_name":"gvozdenkov/algoschool","owner":"gvozdenkov","description":"Visualization of some algorithms / frontend","archived":false,"fork":false,"pushed_at":"2024-07-12T10:32:20.000Z","size":4615,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-05T12:42:32.531Z","etag":null,"topics":["adaptive-layouts","cypress","cypress-component-testing","docker","github-workflow","jest","react","scss","typescript"],"latest_commit_sha":null,"homepage":"https://gvozdenkov.github.io/algoschool/","language":"TypeScript","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/gvozdenkov.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":"2023-10-23T07:56:40.000Z","updated_at":"2024-07-12T14:17:34.000Z","dependencies_parsed_at":"2024-11-09T20:29:18.394Z","dependency_job_id":null,"html_url":"https://github.com/gvozdenkov/algoschool","commit_stats":null,"previous_names":["gvozdenkov/algorithms","gvozdenkov/algorithmic-school"],"tags_count":0,"template":false,"template_full_name":"yandex-praktikum/algososh","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gvozdenkov%2Falgoschool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gvozdenkov%2Falgoschool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gvozdenkov%2Falgoschool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gvozdenkov%2Falgoschool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gvozdenkov","download_url":"https://codeload.github.com/gvozdenkov/algoschool/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240371761,"owners_count":19790888,"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":["adaptive-layouts","cypress","cypress-component-testing","docker","github-workflow","jest","react","scss","typescript"],"created_at":"2024-11-09T20:19:05.797Z","updated_at":"2025-12-30T21:07:31.565Z","avatar_url":"https://github.com/gvozdenkov.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/gvozdenkov/algoschool/actions/workflows/cypress.yml\"\u003e\n    \u003cimg src=\"https://github.com/gvozdenkov/algoschool/actions/workflows/cypress.yml/badge.svg?event=push\u0026style=flat\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"http://commitizen.github.io/cz-cli/\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=flat\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"http://commitizen.github.io/cz-cli/\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Feature--Sliced-Design?style=flat\u0026labelColor=262224\u0026color=F2F2F2\u0026logoWidth=18\u0026logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAYAAAC3g3x9AAAACXBIWXMAAALFAAACxQGJ1n/vAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA/SURBVHgB7dKxCgAgCIThs/d/51JoNQIdDrxvqMXlR4FmFs92KDIX/wI7JSdDN+eHtkxIycnQvMNW8hN/crsDc5QgGX9NvT0AAAAASUVORK5CYII=\" /\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n\u003cbr /\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://gvozdenkov.github.io/algoschool/\"\u003e\n    \u003cimg src=\"README_static/logo_slogan.svg\" alt=\"Fibonacci Algorithmic School logo\" height=\"80\"\u003e\n  \u003c/a\u003e\n  \u003cbr/\u003e\u003cbr/\u003e\n  \u003cp align=\"center\"\u003eAlgorithms playground\u003c/p\u003e\n  \u003cbr/\u003e\n\u003c/div\u003e\n\n---\n\n\u003cdiv align=\"center\"\u003e\n  \u003ch4\u003e\u003ca href=\"https://gvozdenkov.github.io/algoschool/\"\u003eLive demo\u003c/a\u003e\u003c/h4\u003e\n\u003c/div\u003e\n\n![reverse string](README_static/main_screen.png)\n\n|                                             |                                                |                                               |\n| :-----------------------------------------: | :--------------------------------------------: | :-------------------------------------------: |\n| ![reverse string](README_static/string.png) |  ![fibonacci sequence](README_static/fib.png)  | ![array sort methods](README_static/sort.png) |\n| ![reverse string](README_static/stack.png)  | ![fibonacci sequence](README_static/queue.png) | ![array sort methods](README_static/list.png) |\n\n## О проекте\n\nУчебный проект. Визуализация работы некоторых алгоритмов и структур данных. Я постарался\nорганизовать проект максимально близко к продакшену. Код покрыт тестами, настроены линтеры и CI.\n\n[Дизайн макет](https://www.figma.com/file/RIkypcTQN5d37g7RRTFid0/Algososh_external_link?node-id=0%3A1),\nно я изменил цветовую схему на более строгую.\n\nСайт корректно отображается на всех размерах экранов.\n\n## Технические решения\n\n### Сборка\n\nПроект собирается с помощью `vite`, потому что `CRA` уже не рекомендовался для создания нового\nпроекта React. Запуск с [помощью докера](#local-development-with-docker)\n\n### Архитектура\n\n- Использовал относительо новую, но набирающую популярность, методологию\n  [FSD](https://feature-sliced.design/ru/docs/get-started/overview) для организации кода фронтенда.\n\n- Использую новый `React Router v6` и ленивую загрузку роутов.\n\n### Pre-commit actions\n\n1.  `ESLint` и `Stylelint` проверяют `TS/SCSS` staged файлы.\n2.  `Prettier` автоматически форматирует код.\n3.  Запускаются все тесты `jest`\n4.  `Commitlint` проверяет коммит на соответствие\n    [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). Можно пошагово создать\n    корректное сообщение коммита с помощь cli `commitizen`: скрипт `yarn cz`\n    \u003cbr\u003e\u003cbr\u003e![img](README_static/commitlint-cli.png)\n\nЕсли любой из этапов не проходит, коздание коммита отменяется. Это минизирует попадание ошибочного\nкода в коммит и унифицирует сообщения коммитов.\n\n### Тестирование\n\nКод покрыт тестами:\n\n- юнит-тесты `jest` для проверки работы алгоритмов.\n- e2e тесты `cypress` для проверки правильной визуализации всех страниц.\n- тесты компонентов React с помощью `Cypress Component Testing`. Отностиельно новый инструмент для\n  разработки и тестирования компонентов.\n\nНастроена интеграция с `cypress cloud` для визуализации и мониторинга результатов тестирования.\n\n### CI\n\n1. Настроил `github workflow` для запуска всех тестов при пуше в любую ветку, кроме `main`. Разделил\n   стадию билда от тестов, чтобы оптимизировать прогон тестов.\n   \u003cbr\u003e\u003cbr\u003e![img](README_static/cypress-ci-workflow.png)\u003cbr\u003e\u003cbr\u003e\n2. Защитил ветку `main` от прямого пуша. Обновить ветку `main` можно только через PR. Причём должны\n   обязательно успешно завершиться все `actions` по тестированию в рабочей ветке. Таким образом\n   нерабочий код не может (_но это не точно_) попасть в `main`.\n3. Настроил автоматическую публикацию сайта на `gh-pages` при вливании PR в `main`.\n\n## Tech stack\n\n- React with TS\n- SCSS\n- Vite bundler\n- Jest\n- Cypress\n\n## Local Development with Docker\n\n```bash\ngit clone git@github.com:gvozdenkov/algoschool.git\ncd algoschool\ndocker compose -f compose.dev.yaml up\n\n# or use Makefile\nmake run-dev\n\n# open http://localhost:3010\n\n# create new branch and work in it. Merge to main only via PR\n\n```\n\n## Local Development\n\nuse node 18 and above\n\n```bash\ngit clone git@github.com:gvozdenkov/algoschool.git\ncd algoschool\nyarn\n\n# or npm install\nyarn dev\n# or npm run dev\n\n# open http://localhost:5173\n```\n\n| script           | Description                                                                                                              |\n| ---------------- | ------------------------------------------------------------------------------------------------------------------------ |\n| `dev`            | Запускает vite dev server без `cypress`                                                                                  |\n| `dev-ct`         | Запускает vite dev server и `cypress open --component` для разработки и тестирования компонентов                         |\n| `dev-e2e`        | Запускает vite dev server и `cypress open --e2e` для e2e тестирования                                                    |\n| `build`          | билд проекта                                                                                                             |\n| `lint`           | проверки `eslint`                                                                                                        |\n| `typecheck`      | проверка typescript компилятором `tsc`                                                                                   |\n| `prettier:write` | исправляет ошибки форматирования                                                                                         |\n| `prettier:check` | проверяет ошибки форматирования (используется в CI перед тестами cypress.yaml)                                           |\n| `stylelint:fix`  | `stylelint` исправляет .scss стили                                                                                       |\n| `test:cy`        | запуск всех тестов `cypress`                                                                                             |\n| `test:jest`      | запуск всех тестов `jest`                                                                                                |\n| `cz`             | cli утилита для созадния коммита по рекомендациям [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) |\n\n## Дальнейшие планы\n\n1. Добавить [линтер](https://github.com/feature-sliced/steiger) для методологии\n   [FSD](https://feature-sliced.design/ru/docs/get-started/overview)\n2. Перевезти проект на [Remix.run](https://remix.run/) фреймворк. Лучше CEO, быстрее индексация.\n3. Внедрить `Storybook` для разработки и тестирования компонентов в изоляции. Уже добавлены\n   зависимости и скрипты запуска. Но пока там пусто.\n\n\u003cdetails\u003e\n\u003csummary\u003eWorkflow setup details\u003c/summary\u003e\n\n### Lint staged files\n\nUsed `husky` \u0026 `lint-staged` packages to lint \u0026 format staged files only\n\n```sh\n# .husky/_/pre-commit\nyarn lint-staged \u0026\u0026 yarn test:jest -o\n\n```\n\n`.lintstagedrc.json` setup sequential running commands for .js|ts|jsx|tsx files in order of array\nitems\n\n```json\n{\n  \"*.(js|ts|jsx|tsx)\": [\"yarn prettier:write\", \"yarn lint\"],\n  \"*.md\": \"yarn prettier:write\"\n}\n```\n\n### Commit messages\n\nThis project is [Commitizen](https://www.npmjs.com/package/commitizen?activeTab=readme) friendly. So\nyou can easy create commits in a step by step guide by run:\n\nIf you are mannually create commit message it will be linted with `commitlint` to lint commit\nmessages acording with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).\n\n```bash\nyarn cz\n# or\nnpm run cz\n```\n\nCommitizen \u0026 commitlint setup:\n\n1. Used ligthweight `cz-git` adapter for `commitizen` to generate cli interface for `yarn cz`\n2. Setup `cz-git` with `.czrc` file\n3. Setup `commitlint` with `commitlint.config.ts`\n\n```json\n\"devDependencies\": {\n  \"@commitlint/cli\": \"^18.4.3\",\n  \"@commitlint/config-conventional\": \"^18.4.3\",\n  \"@commitlint/format\": \"^18.4.3\",\n\n  \"commitizen\": \"^4.3.0\",\n  \"cz-git\": \"^1.8.0\",\n}\n```\n\n### Code formating\n\nUsed Prettier (exact 2.8.7 version) for formatting and Eslint for linting only. So setup\n\n```json\n\"devDependencies\": {\n  \"eslint\": \"^8.53.0\",\n  \"prettier\": \"2.8.7\",\n  \"eslint-plugin-prettier\": \"4.2.1\",\n  \"eslint-config-prettier\": \"^9.0.0\",\n}\n```\n\nSettup eslint to highlight style errors with prettier:\n\n```cjs\n// .eslintrc.cjs\nmodule.exports = {\n  // ...\n  extends: [\n    'eslint:recommended',\n    'plugin:@typescript-eslint/recommended-type-checked',\n    // ...\n    // prettier must be the last in extends\n    'prettier',\n  ],\n  // ...\n  plugins: ['prettier'],\n  rules: {\n    'prettier/prettier': ['error'],\n    // ...\n  },\n};\n```\n\nSetup CI to check code formating\n\n```yaml\n# cypress.yaml\n\n- run: yarn lint\n\n# only check format, not write\n- run: yarn prettier:check\n```\n\nImport order sorting:\n\nUsed `prettier-plugin-sort-imports` package for prettier to format order of imports\n\n```js\n//https://chriscoyier.net/2022/08/09/javascript-import-sorting/\n\n// .prettierrc\n\"importOrder\": [\n    \"react\",\n    \"\u003cTHIRD_PARTY_MODULES\u003e\",\n    \"^(#shared/(config|constants|types|hooks|lib)).*$\",\n    \"^(#shared/ui).*$\",\n    // Any local imports that AREN'T styles.\n    \"^(\\\\.|\\\\.\\\\.)/(.(?!.(css|scss)))*$\",\n    // Styles\n    \".(css|scss)$\"\n  ],\n  \"importOrderSeparation\": true,\n  \"importOrderSortSpecifiers\": true,\n  \"importOrderCaseInsensitive\": true,\n```\n\n### Stylelint `.scss`\n\n1. Install:\n\n```bash\nyarn add -D stylelint stylelint-config-standard-scss stylelint-config-prettier-scss stylelint-config-clean-order\n```\n\n2. Setup stylelint `.stylelintrc.json`:\n\n```json\n{\n  \"extends\": [\n    \"stylelint-config-standard-scss\",\n    \"stylelint-config-clean-order/error\",\n    \"stylelint-config-prettier-scss\"\n  ],\n  \"rules\": {\n    \"selector-class-pattern\": \"^(?:[a-z][a-z0-9]*)(?:(__|_|-)[a-z0-9]+)*$\",\n    \"scss/at-extend-no-missing-placeholder\": null\n  }\n}\n```\n\n`selector-class-pattern` to check BEM style names\n\n3. Add script in `package.json` to lint and autofix fixable issues\n\n```diff\n+ \"stylelint:fix\": \"stylelint '**/*.scss' --fix\",\n```\n\n4. Edit `.lintstagedrc.json` to automatic fix all fixable style issues in pre-commit acion\n\n```diff\n{\n  \"*.(js|ts|jsx|tsx)\": [\"yarn prettier:write\", \"yarn lint\"],\n  \"*.md\": \"yarn prettier:write\"\n  # suddenly `yarn stylelint:fix` don't work:( it crash lint-staged with empty-commit error\n+ \"*.{css,scss}\": \"stylelint '**/*.scss' --fix\",\n}\n```\n\n5. Setup VS Code `settings.json` to autofix stylelint issues on save\n\nInstall official Stylelint extenstion!\n\n```diff\n+  \"editor.codeActionsOnSave\": {\n+     \"source.fixAll.stylelint\": true\n+  },\n+  \"css.validate\": false,\n+  \"scss.validate\": false,\n+  \"less.validate\": false,\n+  \"stylelint.validate\": [\"css\", \"less\", \"postcss\", \"scss\"],\n+  \"stylelint.config\": null, //use settings from .stylelintrc.json\n```\n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgvozdenkov%2Falgoschool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgvozdenkov%2Falgoschool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgvozdenkov%2Falgoschool/lists"}