From c625dcd01cb92037a72a5fc1637d360c45714943 Mon Sep 17 00:00:00 2001 From: OreskaG Date: Sun, 23 Aug 2026 19:54:51 +0300 Subject: [PATCH 01/13] feat(fullstack): add tasks --- .../fullstack-engineering.instructions.md | 51 ++++++ angular/peer-to-peer-review.md | 106 +++++------ .../tasks/angular-team-task/PRESENTATION.md | 22 +-- .../.instructions/OPEN_QUESTIONS.md | 25 +++ .../.instructions/REFERENCE_STAGE1-2_TASKS.md | 40 ++++ fullstack-engineering/.instructions/VISION.md | 61 +++++++ fullstack-engineering/README.md | 159 ++++++++++++++++ .../tasks/_template/README.md | 35 ++++ .../tasks/bug-hunting/README.md | 3 + fullstack-engineering/tasks/cv/README.md | 171 ++++++++++++++++++ .../tasks/cv/assets/create-gh-pages.png | Bin 0 -> 9462 bytes .../tasks/cv/assets/find_deploy_01.png | Bin 0 -> 9356 bytes .../tasks/cv/assets/find_deploy_02.png | Bin 0 -> 14073 bytes .../tasks/cv/assets/repository-settings.png | Bin 0 -> 40245 bytes .../tasks/cv/assets/rs-school-logo.svg | 1 + .../data-structures-algorithms/README.md | 3 + .../tasks/external-api/README.md | 3 + .../tasks/games-catalog/README.md | 3 + .../tasks/js-basic-methods/README.md | 3 + .../tasks/landing-page/README.md | 3 + .../tasks/online-store/README.md | 3 + .../tasks/own-backend/README.md | 3 + .../tasks/testing-intro/README.md | 3 + 23 files changed, 634 insertions(+), 64 deletions(-) create mode 100644 .github/instructions/fullstack-engineering.instructions.md create mode 100644 fullstack-engineering/.instructions/OPEN_QUESTIONS.md create mode 100644 fullstack-engineering/.instructions/REFERENCE_STAGE1-2_TASKS.md create mode 100644 fullstack-engineering/.instructions/VISION.md create mode 100644 fullstack-engineering/README.md create mode 100644 fullstack-engineering/tasks/_template/README.md create mode 100644 fullstack-engineering/tasks/bug-hunting/README.md create mode 100644 fullstack-engineering/tasks/cv/README.md create mode 100644 fullstack-engineering/tasks/cv/assets/create-gh-pages.png create mode 100644 fullstack-engineering/tasks/cv/assets/find_deploy_01.png create mode 100644 fullstack-engineering/tasks/cv/assets/find_deploy_02.png create mode 100644 fullstack-engineering/tasks/cv/assets/repository-settings.png create mode 100644 fullstack-engineering/tasks/cv/assets/rs-school-logo.svg create mode 100644 fullstack-engineering/tasks/data-structures-algorithms/README.md create mode 100644 fullstack-engineering/tasks/external-api/README.md create mode 100644 fullstack-engineering/tasks/games-catalog/README.md create mode 100644 fullstack-engineering/tasks/js-basic-methods/README.md create mode 100644 fullstack-engineering/tasks/landing-page/README.md create mode 100644 fullstack-engineering/tasks/online-store/README.md create mode 100644 fullstack-engineering/tasks/own-backend/README.md create mode 100644 fullstack-engineering/tasks/testing-intro/README.md diff --git a/.github/instructions/fullstack-engineering.instructions.md b/.github/instructions/fullstack-engineering.instructions.md new file mode 100644 index 000000000..4803acda2 --- /dev/null +++ b/.github/instructions/fullstack-engineering.instructions.md @@ -0,0 +1,51 @@ +--- +description: "Используй при работе над черновиком нового курса RS School (fullstack-engineering/**): вижен, роадмап, авторинг заданий и любое планирование нового fullstack-курса." +applyTo: "fullstack-engineering/**" +--- + +# Fullstack Engineering — черновик нового курса + +`fullstack-engineering/` — рабочая черновая папка нового курса RS School, который должен со временем заменить/объединить Stage 1 + Stage 2. Это **ещё не** часть официальной программы — всё здесь является предложением и активно обсуждается. + +## Ключевые файлы (источник истины, перед правкой всегда проверяй актуальное содержимое) + +- [VISION.md](../../fullstack-engineering/.instructions/VISION.md) — зачем нужен курс, целевой результат, принципы (community-first, использование AI, право студентов влиять на курс) +- [OPEN_QUESTIONS.md](../../fullstack-engineering/.instructions/OPEN_QUESTIONS.md) — нерешённые продуктовые вопросы (уровень аудитории, длительность, обязательный стек и т.д.) — проверяй перед тем, как что-то предполагать +- [README.md](../../fullstack-engineering/README.md) — черновик самой страницы курса (по структуре повторяет `stage1/README.md`), рабочее название: **«RS School. Fullstack Engineering Course»** — это единственный файл, который в итоге увидят студенты, всё остальное здесь — вспомогательные материалы для планирования +- [REFERENCE_STAGE1-2_TASKS.md](../../fullstack-engineering/.instructions/REFERENCE_STAGE1-2_TASKS.md) — справочная сводка старой программы Stage 1/2, используется как база для сравнения +- `fullstack-engineering/tasks/` — где авторятся реальные файлы заданий нового курса; шаблон для нового задания — [tasks/\_template/README.md](../../fullstack-engineering/tasks/_template/README.md) + +## Уже принятые решения (не пересматривать без явного обсуждения) + +- Курс разделён на **Часть 1** (12 недель, чистый JS, без TypeScript) и **Часть 2** (TypeScript, по структуре похожа на старый Stage 2) — TypeScript строго только в Части 2. +- Язык курса — **русский**. Английский не должен быть скрытым входным барьером. +- В Часть 1 можно попасть с нулевым знанием HTML/CSS/JS, если студент готов уделять 30+ часов в неделю. +- AI-ассистенты и агенты явно разрешены и поощряются; использование должно быть прозрачным. +- У студентов есть право влиять на курс (issue на GitHub → обсуждение → опрос → публичное решение) — это культурный принцип из VISION.md, пока не привязан к конкретной неделе/заданию. + +## Конвенция для `tasks/` (авторинг заданий) + +- Одна папка на задание: `tasks//README.md` (+ при необходимости `assets/` с картинками, JSON с примерами данных и т.п.). +- В отличие от старого Stage 1/2, здесь **нет отдельных "модулей" с теорией** — все материалы для изучения (статьи, записи вебинаров/стримов, документация) собираются прямо в README задания, в разделе «Материалы для изучения». +- Обычно у студента одна задача единовременно (кроме случаев, когда задание занимает 30–40 минут — тогда таких может быть несколько на неделю). +- Используй [tasks/\_template/README.md](../../fullstack-engineering/tasks/_template/README.md) как основу для новых заданий (разделы: Навыки → Что делать → Материалы для изучения → Требования → Как сдавать → Cross-check → Критерии оценки). +- Критерии оценки (баллы/штрафы) пока не согласованы на уровне курса — не изобретай жёсткую балльную систему для конкретного задания, если её не просили; отмечай как TBD. +- При переносе/адаптации задания из старых Stage 1/2/0.5 — приводи флоу к текущим правилам ниже, а не копируй как есть. + +### Правила флоу для индивидуальных заданий + +- Всегда **личный публичный репозиторий** студента — никаких приватных школьных репозиториев (как было в старых курсах). +- Для командных заданий формат репозитория может отличаться (например, общий репозиторий команды) — под конкретную задачу это решается отдельно. +- На cross-check всегда отправляется **ссылка на Pull Request** (а не просто "Solution URL" на задеплой, как было в rs app раньше). + +## Стилистические договорённости для этой папки + +- Проза, заголовки и подписи разделов — на русском (например, «Неделя», «Задачи», «Программа обучения»). +- Устоявшиеся англицизмы разработки оставляем латиницей, а не транслитерируем: `unit-тесты` (а не «юнит-тесты»), `middleware`, `routes` (а не «роуты»), `cross-check`, `backend`. +- README по структуре держим близко к [stage1/README.md](../../stage1/README.md) (эмодзи-заголовки разделов, Обзор/Темы/Программа обучения/Активности менторов/FAQ), но переведённым на русский. +- Не придумывай новые решения по программе курса (например, расписание cross-check, менторские активности, критерии оценки) без явной пометки, что это предположение — владелец репозитория часто это правит. + +## Рабочий стиль по этому проекту + +- Обсуждать/подтверждать одну часть многосоставного запроса за раз перед реализацией — не смешивать несвязанные изменения в одном заходе. +- Не добавлять лишний объём (новые разделы, миграции, функциональность) сверх того, что попросили. diff --git a/angular/peer-to-peer-review.md b/angular/peer-to-peer-review.md index 2a0059100..5e3061158 100644 --- a/angular/peer-to-peer-review.md +++ b/angular/peer-to-peer-review.md @@ -20,8 +20,8 @@ They do not have to be the most technically complex features. You can choose any Each Peer Review participant attends four sessions: -* one session as a presenter; -* three sessions as an expert. +- one session as a presenter; +- three sessions as an expert. In practice, this means **two Google Meet calls, or calls on any other suitable platform**: @@ -57,9 +57,9 @@ In the event of an unexpected no-show, the coordinator will assign a replacement ### Feature requirements -* The two features must come from **two different sprints**. -* Each feature must represent **complete functionality**. A simple test is whether it can be demonstrated as a user scenario with a clear beginning and end: “the user does A and gets B.” Filtering a list is a valid scenario; a button with no resulting action or a purely cosmetic improvement is not. -* The code must have been written by the student personally. +- The two features must come from **two different sprints**. +- Each feature must represent **complete functionality**. A simple test is whether it can be demonstrated as a user scenario with a clear beginning and end: “the user does A and gets B.” Filtering a list is a valid scenario; a button with no resulting action or a purely cosmetic improvement is not. +- The code must have been written by the student personally. ## Session @@ -73,9 +73,9 @@ One session lasts approximately 30–40 minutes and consists of four parts. The **presenter** creates a GitHub Gist containing the presentation plan: -* the two selected features; -* a short description of each feature; -* links to the corresponding pull requests or code. +- the two selected features; +- a short description of each feature; +- links to the corresponding pull requests or code. The Gist must be shared in the experts’ chat no later than 24 hours before the presentation. @@ -83,9 +83,9 @@ If the Gist is not shared at least 24 hours before the presentation, the present **One of the experts** acts as the selecting expert. The order is specified in the panel table: -* Expert A selects the fragment for the first session; -* Expert B selects the fragment for the second session; -* Expert C selects the fragment for the third session. +- Expert A selects the fragment for the first session; +- Expert B selects the fragment for the second session; +- Expert C selects the fragment for the third session. Before the session, the selecting expert finds a code fragment in the presenter’s repository. @@ -93,12 +93,12 @@ This preparation should take approximately 5–10 minutes: 1. Open the presenter’s repository and review the presenter’s commits or pull requests. 2. Find a fragment containing meaningful logic **outside the two announced features**. For example: + - an event handler; + - a service; + - state-management logic; + - data transformation; + - another coherent piece of application logic. - * an event handler; - * a service; - * state-management logic; - * data transformation; - * another coherent piece of application logic. 3. Do not select configuration, markup, generated code, or a purely cosmetic change. 4. The fragment should be approximately **20–50 lines**, either in one file or as one coherent section of code. 5. Save a link to the fragment and think about what you might ask the presenter. @@ -127,19 +127,19 @@ For each feature, the presenter must demonstrate at least one relevant negative Examples of negative scenarios include: -* invalid input; -* an empty state; -* a repeated action; -* missing data; -* another edge case relevant to the feature. +- invalid input; +- an empty state; +- a repeated action; +- missing data; +- another edge case relevant to the feature. ### Part 3: Expert-selected code fragment, approximately 5 minutes The selecting expert identifies the fragment they found. The presenter opens it and explains: -* what is happening in the code; -* what this part of the application is responsible for; -* why it was implemented in this way. +- what is happening in the code; +- what this part of the application is responsible for; +- why it was implemented in this way. There is no advance preparation for this part. The presenter explains the code directly from the screen. @@ -153,12 +153,12 @@ The experts ask questions. Each expert must ask at least three questions. Examples: -* “What was the most difficult part?” -* “What would you change if you were starting again?” -* “How did you identify and fix your most difficult bug?” -* “What approaches or tools did you use?” -* “What alternative solutions did you consider?” -* “What trade-offs did you make?” +- “What was the most difficult part?” +- “What would you change if you were starting again?” +- “How did you identify and fix your most difficult bug?” +- “What approaches or tools did you use?” +- “What alternative solutions did you consider?” +- “What trade-offs did you make?” At the end, each expert says aloud one particularly strong aspect of the presentation and completes the evaluation form, which should take approximately two minutes. @@ -172,24 +172,24 @@ The session may only be recorded with the consent of both the presenter and the ## Technical Issues -* If the live demo cannot be completed because of an **external issue**, such as a deployment outage, an unavailable external API, or connectivity problems, the student should demonstrate the application locally and show the relevant code. A pre-recorded video may be used as supporting material, but not as a replacement for a live demo, code walkthrough, and explanation. -* If the project cannot be launched because the student was **not properly prepared**, the experts evaluate only what was successfully demonstrated. +- If the live demo cannot be completed because of an **external issue**, such as a deployment outage, an unavailable external API, or connectivity problems, the student should demonstrate the application locally and show the relevant code. A pre-recorded video may be used as supporting material, but not as a replacement for a live demo, code walkthrough, and explanation. +- If the project cannot be launched because the student was **not properly prepared**, the experts evaluate only what was successfully demonstrated. ## Evaluation: 100 Points All criteria are evaluated as **binary observations**: observed or not observed. -* Each of the three experts evaluates the presenter independently. -* The final score is the **median** of the three scores. -* If only two experts are present, the final score is the average of their scores. +- Each of the three experts evaluates the presenter independently. +- The final score is the **median** of the three scores. +- If only two experts are present, the final score is the average of their scores. ### 1. Feature Demo: 30 Points The features meet the requirements: -* they come from two different sprints; -* each feature represents complete functionality; -* each feature is demonstrated as a scenario in which “the user does A and gets B.” +- they come from two different sprints; +- each feature represents complete functionality; +- each feature is demonstrated as a scenario in which “the user does A and gets B.” ### Feature 1: 15 Points @@ -237,8 +237,8 @@ A panel block consists of three presenter sessions attended by the same group of If an expert misses their panel block or does not submit the required evaluation forms for the block: -* **30 points are deducted from their final Peer Review score.** -* Final Peer Review score = **max(0, score − 30)**. +- **30 points are deducted from their final Peer Review score.** +- Final Peer Review score = **max(0, score − 30)**. If an expert knows in advance that they cannot attend, they must: @@ -250,29 +250,29 @@ In the event of an unexpected no-show, participants should report it in `#peer-r ### A presenter does not attend -* The experts wait for **10 minutes**. -* After 10 minutes, they report the no-show in the Discord channel `#peer-review` and tag the coordinator. -* The experts’ responsibility for that session is considered **completed**, and they receive no penalty. -* The presenter must organise one replacement session within the Peer Review period. -* The presenter should first coordinate the new session with the assigned panel. -* If this is not possible, the presenter must post in `#peer-review` and tag the coordinator so that another panel can be assigned. -* If the replacement session does not take place because of the presenter, the presenter receives **0 points for the Peer Review**. +- The experts wait for **10 minutes**. +- After 10 minutes, they report the no-show in the Discord channel `#peer-review` and tag the coordinator. +- The experts’ responsibility for that session is considered **completed**, and they receive no penalty. +- The presenter must organise one replacement session within the Peer Review period. +- The presenter should first coordinate the new session with the assigned panel. +- If this is not possible, the presenter must post in `#peer-review` and tag the coordinator so that another panel can be assigned. +- If the replacement session does not take place because of the presenter, the presenter receives **0 points for the Peer Review**. ### The presenter does not have enough experts -* With two experts, the session remains valid, and the final score is the average of the two evaluations. -* With only one expert, participants should post in `#peer-review` and tag the coordinator so that another expert can be assigned. -* The presenter does not receive a failing result because of someone else’s no-show. The absent expert receives the penalty, not the presenter. +- With two experts, the session remains valid, and the final score is the average of the two evaluations. +- With only one expert, participants should post in `#peer-review` and tag the coordinator so that another expert can be assigned. +- The presenter does not receive a failing result because of someone else’s no-show. The absent expert receives the penalty, not the presenter. ## Preparation ### Presenter 1. Select two features that meet the requirements: + - complete functionality; + - features from two different sprints; + - code written by you. - * complete functionality; - * features from two different sprints; - * code written by you. 2. Create and share the Gist at least 24 hours before the session. 3. Rehearse the demo with a timer. Fifteen minutes for two features is not much time. 4. Prepare at least one relevant negative scenario for each feature. diff --git a/angular/tasks/angular-team-task/PRESENTATION.md b/angular/tasks/angular-team-task/PRESENTATION.md index acf545304..088553ea8 100644 --- a/angular/tasks/angular-team-task/PRESENTATION.md +++ b/angular/tasks/angular-team-task/PRESENTATION.md @@ -1,28 +1,28 @@ # Team Presentation - + **Goal:** demonstrate the product and tell the team's story — how you worked together, how you learned Angular, what decisions you made. - -- **Format:** blocks of ~90 minutes, 3 teams per block, Google Meet (preferable). + +- **Format:** blocks of ~90 minutes, 3 teams per block, Google Meet (preferable). - Questions: `#questions-to-admins`. - + ## Session plan (~30 min) - + 1. **Product demo (~10 min).** Show one user story from start to finish: "the user does A, then B, and gets C." Different members lead different parts of the story. 2. **Architecture, key decisions and one failure story (~10 min).** One simple diagram of the system. Two or three important decisions: what you chose, what the alternative was, and why. Then one real failure: what broke, what you tried, how it ended. 3. **Contributions (~2 min).** Each member says in 1–2 sentences what they did and what they learned. 4. **Questions (~8 min).** Questions go to the **team**, and the team decides who answers. The best pattern: pass the question to the person who built that part. ## Scoring: 100 points, one score for the team - + The jury scores each point as **yes or no**. It happened, or it did not. No half points. The final score is the median of the jury scores. Every member who was present gets the team score. - + 1. **(10)** The demo was one user story from start to finish, not a list of features 2. **(20)** The team showed the architecture and explained at least 2 decisions with trade-offs 3. **(20)** The team told a real failure story with details -4. **(20)** Questions were answered by the whole team: for 3+ members — at least 3 different people answered; for 2 — both answered; for a solo presenter — they answered questions about *all* parts of the system +4. **(20)** Questions were answered by the whole team: for 3+ members — at least 3 different people answered; for 2 — both answered; for a solo presenter — they answered questions about _all_ parts of the system 5. **(20)** Each present member clearly said what they did. A solo presenter instead explains how they made decisions alone and what they would do differently in a team 6. **(10)** Good timing and preparation: the app worked, the demo was rehearsed -**Small teams.** If your team now has 1 or 2 members — you present anyway, and that is respected. Solo and duo teams can be nominated for Best Project on the same terms. + **Small teams.** If your team now has 1 or 2 members — you present anyway, and that is respected. Solo and duo teams can be nominated for Best Project on the same terms. ## Observers @@ -32,9 +32,9 @@ Observers do not evaluate the presenter and must not interfere with the session The session may only be recorded with the consent of both the presenter and the jury. ## Best Project nominations - + Each juror has **1 nomination for every 3 teams they watch**. A nomination is separate from points and does not change your score. It means your project genuinely stood out — for the product, a decision, or the way you handled questions. - + After all blocks, the nominations are collected and the **Best Projects list** is published, with the jury's comments on what earned the spot. ### Recommendations diff --git a/fullstack-engineering/.instructions/OPEN_QUESTIONS.md b/fullstack-engineering/.instructions/OPEN_QUESTIONS.md new file mode 100644 index 000000000..fe7cf32d5 --- /dev/null +++ b/fullstack-engineering/.instructions/OPEN_QUESTIONS.md @@ -0,0 +1,25 @@ +# Открытые вопросы по новому курсу + +## В работе / запланировано + +- Где граница допустимого использования AI и как студент подтверждает, что понимает написанный с AI код — задача признана, но пока не реализована в роадмапе Части 1. Планируем добавить примерно через пару недель работы над курсом. + +## Аудитория и результат + +- Какой результат мы обещаем на выходе: Junior Fullstack Developer или более общий Junior Software Engineer? +- Часть 1 = 12 недель (закрыто). Сколько длится Часть 2 и сколько часов в неделю она реально требует — пока не решено. + +## Технический охват + +- Базовый обязательный стек Части 1 закрыт роадмапом (JS, DOM, тестирование, алгоритмы и структуры данных, работа с API, свой backend). Остаётся решить: что именно на курсе — элективно (например, стек фронтенда для парного проекта недели 11–12). +- Должен ли каждый студент лично написать и frontend, и backend, или допустима специализация внутри команды? Частично отвечено: backend на неделе 10 — индивидуальный, но в парном проекте (недели 11–12) распределение зон ответственности уже допускается. + +## Командная работа и сообщество + +- Когда и как формируются постоянные учебные группы? +- Сколько взаимодействия со студентами реально способны потянуть менторы при текущем их числе? +- Как оценивать и учитывать личный вклад студента в командный продукт? + +## Критерии успеха + +- Что считается успехом курса: завершение программы, трудоустройство, активность в сообществе, возвращение выпускников менторами — или всё вместе и в каком приоритете? diff --git a/fullstack-engineering/.instructions/REFERENCE_STAGE1-2_TASKS.md b/fullstack-engineering/.instructions/REFERENCE_STAGE1-2_TASKS.md new file mode 100644 index 000000000..3cd569f71 --- /dev/null +++ b/fullstack-engineering/.instructions/REFERENCE_STAGE1-2_TASKS.md @@ -0,0 +1,40 @@ +# Референс: задания Stage 1–2 по неделям + +> Черновик-справочник, не часть vision. Задача — увидеть текущую программу как таймлайн заданий, чтобы от неё оттолкнуться при построении нового roadmap. Теоретические модули не перечислены, только практические задания/проекты. Разделы кросс-чеков, тестов и менторских активностей опущены. + +## Stage 1 — 11 недель, чистый frontend + +| Неделя | Задание | Что делать (кратко) | Стек | Чему учатся | +| ------ | -------------------------------------------- | -------------------------------------------------------------------------------------------------------- | --------------------------------------- | ------------------------------------------------------- | +| 1 | CV Project (Markdown & Git → HTML/CSS & Git) | Собрать и задеплоить резюме на GitHub Pages через отдельную ветку | Markdown, HTML, CSS, Git, GitHub Pages | Базовый git-flow, ветки, деплой | +| 2 | core-js-numbers, core-js-strings | Мини-katas: реализовать набор функций по числам/строкам, проверка unit-тестами | JS, Jest | Типы данных, операторы, чтение unit-тестов | +| 3 | Portfolio. Часть 1 | Адаптивная вёрстка лендинга-портфолио по макету Figma | HTML, CSS (Flex/Grid), Figma | Semantic HTML, responsive design | +| 4 | Portfolio. Часть 2 | Добавить интерактивность в готовую вёрстку | HTML, CSS, JS, DOM API | DOM, события, формы | +| 5 | core-js-conditions-n-loops, core-js-arrays | Katas на условия/циклы/массивы | JS | Логика, работа с массивами | +| 6 | Clean Code S1E1 | Рефакторинг готового TODO-приложения без изменения функциональности, один принцип чистого кода на коммит | HTML/CSS/JS | Чистый код, дисциплина коммитов, линтеры | +| 7 | basic-js-ds, basic-js | Алгоритмические katas | JS | Алгоритмы и структуры данных | +| 8 | Virtual Music Kit | Интерактивная "звуковая панель" (пианино/барабаны и т.п.), клики и клавиатура | JS, DOM, Web Audio API | DOM-манипуляции, обработка событий, звук в браузере | +| 9–10 | Pair 'em Up | Игра на память ("найди пару") — крупный самостоятельный проект | Vanilla JS, DOM, бандлер (Vite/Webpack) | Архитектура приложения без фреймворка, модули, бандлеры | +| 11 | Self-introduction | Итоговый мини-проект "расскажи о себе" + подготовка к Stage 2 screening | HTML/CSS/JS, классы/прототипы | ООП-основы, самопрезентация | + +## Stage 2 — 17–18 недель, TypeScript + инженерные практики + командный проект + +| Неделя | Задание | Что делать (кратко) | Стек | Чему учатся | +| ------ | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| 1 | Technical Screening | Устное собеседование с ментором на допуск к курсу | — | Базовая проверка знаний Stage 1 | +| 2 | News API → TS, core-js-objects, Codewars OOP | Мигрировать готовое vanilla JS приложение на TypeScript (strict-режим обязателен со следующей недели) | TypeScript, Webpack, классы/generics | Типизация существующего кода, ООП на TS | +| 3 | Code Review | Провести письменное код-ревью чужого приложения (Movie App) | Чтение JS/TS-кода | Оценка качества кода, best practices | +| 4 | RSS Puzzle | SPA-игра для тренировки английского: сборка фраз из слов, статистика | TypeScript, Web Storage, SPA-архитектура без фреймворка | Паттерны SPA, localStorage, работа с большим датасетом | +| 5 | core-js-promises, core-js-functions, CoreJS Interview #1 | Katas на промисы/функции + первое устное интервью по основам JS | JS/TS | Асинхронность, замыкания; опыт тех. интервью | +| 6–7 | Async Race | SPA для управления "гоночными машинками" через REST API: старт/стоп, статистика заездов | TypeScript, REST API, async/await, SPA | Работа с REST API, асинхронный UI, обработка ошибок | +| 8–9 | Fun Chat, Codewars Design Patterns | Чат-приложение поверх готового WebSocket-сервера | TypeScript, WebSocket | WebSocket-протокол, двусторонний обмен сообщениями | +| 10 | Presentation (recorded) | Подготовить и записать техническое выступление на выбранную тему | — | Публичные выступления, объяснение технической темы | +| 11–17 | Final Project "Tandem" | Командный (2–6 чел.) продукт по выбору команды (тренажёр, игра, приложение с AI и т.д.), 4–6 недель разработки, еженедельные чекпоинты, личная защита, командная презентация | TypeScript + стек по выбору команды (может включать AI/LLM) | Командная разработка, архитектура полноценного продукта, ответственность за свою фичу, презентация и защита | +| 18 | — | Получение сертификата, фидбек от ментора, перерыв перед Stage 3 | — | — | + +## Что бросается в глаза + +- Backend впервые появляется только в Async Race (REST API как клиент) и Fun Chat (WebSocket как клиент) — своего сервера студент нигде в Stage 1–2 не пишет. +- Unit-тесты студент в основном пишет не сам, а проходит готовые (core-js-\*, basic-js) — своих тестов на собственный проект почти нет. +- AI явно упомянут только в Tandem (финал), причём не как обязательная практика, а как один из вариантов инструмента. +- Единственный командный опыт — последние 6–8 недель курса (Tandem). До этого — только индивидуальные проекты и cross-check. diff --git a/fullstack-engineering/.instructions/VISION.md b/fullstack-engineering/.instructions/VISION.md new file mode 100644 index 000000000..b3ebd8a01 --- /dev/null +++ b/fullstack-engineering/.instructions/VISION.md @@ -0,0 +1,61 @@ +## Идея + +Мы хотим создать бесплатный русскоязычный курс, на котором студенты учатся разрабатывать веб-продукты целиком, осознанно используют AI-инструменты, работают вместе и влияют на своё обучение. + +Классическая программа Stage 1–2 даёт сильную frontend-базу, но слабо затрагивает backend, базы данных, тестирование и современную работу с AI. Новый курс должен сохранить сильные стороны программы, расширить инженерный кругозор и вернуть community-first подход в центр обучения. + +Наш ориентир — лозунг RS School: + +> **Connecting people, growing together, having fun.** + +## Результат обучения + +Выпускник курса способен: + +- создать небольшое веб-приложение: frontend, API, backend и база данных; +- покрыть важную логику unit-тестами; +- использовать Git и GitHub для совместной разработки; +- применять AI для исследования, проектирования, написания и проверки кода; +- проверять, объяснять и исправлять созданный с AI код; +- аргументировать технические решения; +- давать и принимать обратную связь; +- работать в команде и доводить проект до работающего результата. + +Мы не пытаемся за один курс подготовить эксперта сразу во frontend, backend, DevOps и AI. Студент должен увидеть систему целиком, попробовать её части на практике и выбрать направление для дальнейшего развития. + +## Технический фокус + +Backend, базы данных и инфраструктура изучаются обзорно и не заменяют отдельный курс по Node.js. При этом каждый студент должен самостоятельно написать небольшой сервер, спроектировать API и поработать с данными. + +Unit-тесты сопровождают практику на протяжении курса, а не появляются отдельной темой в конце. + +AI-ассистенты и агенты разрешены и являются частью программы. Мы хотим попробовать разные форматы: чат, coding agents и, если это будет доступно, локальный запуск небольшой модели или AI-сервиса. Студент отвечает за итоговый код независимо от того, как он был создан. Использование AI должно быть прозрачным. + +## Connecting people + +Общение — часть программы, а не побочная активность в Discord. В курсе должны быть: + +- постоянные небольшие учебные группы; +- парная и командная разработка; +- code review и содержательный cross-check; +- peer-to-peer помощь; +- совместное улучшение материалов курса. + +## Студенты имеют право голоса + +Студенты — взрослые участники сообщества, а не пассивные получатели программы. Любой студент может создать GitHub issue, раскритиковать материал, предложить изменить или подготовить pull request. + +Значимые предложения проходят понятный процесс: + +1. Публичный issue с описанием проблемы. +2. Открытое обсуждение и сбор аргументов. +3. Опрос участников, если решение затрагивает значительную часть курса. +4. Публичное решение организаторов с объяснением причин. + +Опрос не должен быть декоративным. Если его результат нельзя принять из-за безопасности, закона, инфраструктуры или обязательств школы, организаторы должны публично объяснить ограничение. + +Студенты и организаторы могут ошибаться. Совместно принятое ошибочное решение иногда полезнее правильного решения, принятого за всех. Право голоса при этом требует уважительного общения, аргументации и готовности участвовать в реализации предложений. + +## Язык и доступность + +Основной язык курса, заданий и обсуждений — русский. Английский не должен быть скрытым входным фильтром. diff --git a/fullstack-engineering/README.md b/fullstack-engineering/README.md new file mode 100644 index 000000000..58c1727b6 --- /dev/null +++ b/fullstack-engineering/README.md @@ -0,0 +1,159 @@ +# 🎓 RS School. Fullstack Engineering Course + +## 🚀 Обзор + +- 📣 **Открыт для всех, кто хочет присоединиться** +- 📅 **Длительность:** 12 недель (Часть 1 из двух; Часть 2 — на TypeScript) +- 📚 **Формат:** самостоятельное изучение + вебинары + парная/групповая работа + Discord + cross-check +- 🤖 **AI:** AI-ассистенты разрешены, использование должно быть прозрачным +- 🗣️ **Язык курса:** русский + +### 📝 Темы курса + +- Git, GitHub и вёрстка адаптивных страниц по макету +- Основы JavaScript: DOM, события, встроенные методы строк, чисел и массивов +- Хранение данных в браузере: localStorage и IndexedDB +- Поиск и исправление ошибок в чужом коде, инструменты разработчика +- Unit-тесты и основы TDD +- Алгоритмы и структуры данных: стек, очередь, связный список, дерево +- Работа с внешним API и асинхронные запросы +- Свой сервер: routes, middleware, аутентификация по токену +- Совместная разработка в общем репозитории и парная работа над проектом + +--- + +## 🛠️ Необходимые базовые знания + +- В идеале — базовые HTML/CSS/JS +- Но если готовы уделять курсу 30+ часов в неделю, можно стартовать и с нуля + +--- + +## Программа обучения + +### Неделя 1 + +- Задачи: + - [CV Project](tasks/cv/README.md) — собрать и задеплоить резюме через Git/GitHub Pages + - RS-тест «Как учиться в комьюнити» — формат обучения, cross-check +- Стек: Markdown, HTML, CSS, Git, GitHub Pages +- Чему научатся: базовый git-flow, деплой; с первого дня — культура и правила школы + +### Неделя 2 + +- Cross-check: + - Cross-check проекта [CV Project](tasks/cv/README.md) +- Задачи: + - [Landing Page. Часть 1](tasks/landing-page/README.md) — адаптивная вёрстка лендинга по макету Figma +- Стек: HTML, CSS (Flex/Grid), Figma +- Чему научатся: semantic HTML, responsive design + +### Неделя 3 + +- Cross-check: + - Cross-check проекта Landing Page. Часть 1 +- Задачи: + - [Landing Page. Часть 2](tasks/landing-page/README.md) — интерактив (попапы, слайдеры, бургер-меню) + localStorage/IndexedDB +- Стек: JS, DOM API, localStorage, IndexedDB +- Чему научатся: DOM-события, два разных браузерных хранилища данных + +### Неделя 4 + +- Cross-check: + - Cross-check проекта Landing Page. Часть 2 +- Задачи: + - [Пак JS-задач по базовым методам строк/чисел/массивов](tasks/js-basic-methods/README.md) _(конкретный набор — TBD)_ +- Стек: JS +- Чему научатся: методы строк, чисел и массивов + +### Неделя 5 + +- Задачи: + - [Bug Hunting](tasks/bug-hunting/README.md) — готовые сайты с багами в HTML/CSS/JS, нужно найти и исправить +- Стек: HTML, CSS, JS, DevTools +- Чему научатся: чтение чужого кода, отладка, DevTools + +### Неделя 6 + +- Cross-check: + - Cross-check проекта Bug Hunting +- Задачи: + - [Testing intro](tasks/testing-intro/README.md) — часть 1: unit-тесты к готовым функциям; часть 2: функции по готовым тестам (TDD) +- Стек: JS, Jest +- Чему научатся: как писать unit-тесты, чтение тестов как спецификации, TDD + +### Неделя 7 + +- Задачи: + - [Data Structures & Algorithms](tasks/data-structures-algorithms/README.md) (базовый уровень) — реализовать стек, очередь, связный список, дерево и решить задачи с ними +- Стек: JS +- Чему научатся: основы алгоритмов и структур данных + +### Неделя 8 + +- Cross-check: + - Cross-check проекта Data Structures & Algorithms +- Задачи: + - [Работа с готовым веб API](tasks/external-api/README.md) — запросы, рендер данных, обработка ошибок и загрузки +- Стек: JS, fetch/async-await, DOM +- Чему научатся: асинхронная работа с сетью, обработка ошибок API + +### Неделя 9 + +- Задачи: + - [Каталог веб-игр](tasks/games-catalog/README.md) — общий репозиторий, каждый студент добавляет свою игру +- Стек: JS, Git (совместная работа, PR, merge conflicts) +- Чему научатся: работа в общем кодовом репозитории, разрешение конфликтов слияния + +### Неделя 10 + +- Задачи: + - [Свой backend](tasks/own-backend/README.md) — сервер с несколькими роутами и middleware для проверки токена из cookies +- Стек: Node.js (http/Express), cookies, middleware +- Чему научатся: серверные роуты, паттерн middleware, базовая аутентификация по токену + +### Неделя 11–12 + +- Cross-check: + - Cross-check проекта "Свой backend" +- Задачи: + - [Онлайн-магазин](tasks/online-store/README.md) (парное задание) — каталог, корзина, фильтры; можно опираться на сервер с недели 10 +- Стек: JS, DOM/UI по выбору пары +- Чему научатся: парная разработка крупного проекта, распределение зон ответственности, code review внутри пары + +## 👨‍🏫 Активности менторов + +- [Подтверждение регистрации на курс](https://rs.school/ru/docs/mentoring-kick-off) + +## ❓ Частые вопросы + +### 🌟 Что сделать перед стартом обучения? + +1. Повторить базовый HTML/CSS/JS (см. «Необходимые базовые знания» выше) +2. Почитать [JavaScript.Info](https://learn.javascript.ru/) + +### 📚 Рекомендуемые учебники по JavaScript + +- [JavaScript.Info](https://learn.javascript.ru/) +- [Exploring JS](https://exploringjs.com/impatient-js/toc.html) +- [You Don't Know JS Yet](https://github.com/getify/You-Dont-Know-JS) + +### 💬 Где мы общаемся? + +- 🗨️ **Discord:** [Присоединиться](https://discord.gg/vD2zYUnZ5h) + +### ❓ Куда задавать вопросы? + +- 🗨️ **Discord:** [Присоединиться](https://discord.gg/vD2zYUnZ5h) + +### 🌐 Важна ли локация? + +- 🌍 Нет, курс полностью онлайн и не привязан к местоположению. + +### 🎥 Можно ли пропускать вебинары? + +- 📼 Да, вебинары записываются и доступны на [YouTube](https://youtube.com/c/rollingscopesschool) + +### 🤔 Обязательно ли смотреть вебинары? + +- 🚫 Нет, можно учиться полностью самостоятельно diff --git a/fullstack-engineering/tasks/_template/README.md b/fullstack-engineering/tasks/_template/README.md new file mode 100644 index 000000000..065d84a3c --- /dev/null +++ b/fullstack-engineering/tasks/_template/README.md @@ -0,0 +1,35 @@ +# <Название задания> + +> Шаблон-заготовка. Скопируй эту папку под новое название и замени плейсхолдеры. Всё, что нужно студенту, должно быть в этом README — без отдельных "модулей" с теорией. + +## Навыки + +`тег1` `тег2` `тег3` + +## Что делать + +Свободное описание задания: что нужно сделать, зачем, какой контекст/легенда (если уместна). + +## Материалы для изучения + +Ссылки на статьи, документацию, записи вебинаров/стримов, видео — всё, что поможет разобраться перед выполнением. + +- [Название материала](https://example.com) — статья +- [Название видео](https://example.com) — видео/вебинар (~X мин) + +## Требования + +- Пункт 1 +- Пункт 2 + +## Как сдавать + +Репозиторий, ветка, деплой (если есть), Pull Request и т.д. — конкретный порядок сдачи. + +## Cross-check + +Задание проверяется через [cross-check](https://rs.school/docs/cross-check-flow). + +## Критерии оценки + +_(TBD — модель оценивания для курса ещё не согласована, см. OPEN_QUESTIONS.md)_ diff --git a/fullstack-engineering/tasks/bug-hunting/README.md b/fullstack-engineering/tasks/bug-hunting/README.md new file mode 100644 index 000000000..41b6be326 --- /dev/null +++ b/fullstack-engineering/tasks/bug-hunting/README.md @@ -0,0 +1,3 @@ +# Bug Hunting + +> TBD — задание пока не описано. Неделя 5: готовые сайты с багами в HTML/CSS/JS — найти и исправить. См. [README.md курса](../../README.md). diff --git a/fullstack-engineering/tasks/cv/README.md b/fullstack-engineering/tasks/cv/README.md new file mode 100644 index 000000000..3a49ca023 --- /dev/null +++ b/fullstack-engineering/tasks/cv/README.md @@ -0,0 +1,171 @@ +# CV + +## Описание проекта + +CV (Curriculum Vitae) — документ, в котором соискатель описывает своё образование и опыт работы. В отличие от резюме, адаптированного под конкретную вакансию, CV показывает профессиональные достижения и навыки за весь период обучения и работы. + +## Задание + +Нужно создать своё CV с помощью языка разметки Markdown, а затем оформить его с помощью HTML и CSS. + +## Навыки + +`Git` `GitHub` `Markdown` `HTML` `CSS` `semantic HTML` + +## Материалы для изучения + +- [Git commit convention](https://rs.school/docs/git-convention) — как называть коммиты +- [Pull Request description schema](https://rs.school/docs/pull-request-review-process#pull-request-requirements-pr) — как оформить PR +- [Markdown Syntax Cheat Sheet](https://ydmitry.ru/blog/rukovodstvo-po-markdown-dlya-uproshcheniya-veb-razrabotki/) +- [HTML5 Semantic Elements](https://html5css.ru/html/html5_semantic_elements.php) +- [W3C Markup Validator](https://validator.w3.org/) — проверка валидности вёрстки +- Примеры оформления CV: [Freepik](https://www.freepik.com/free-photos-vectors/cv-template), [Canva](https://www.canva.com/resumes/templates/), [Figma Community](https://www.figma.com/community/search?resource_type=mixed&sort_by=relevancy&query=cv&editor_type=all&price=all&creators=all) + +## Содержание CV + +Рекомендации из HR-отдела EPAM: + +1. Имя +2. Контактная информация +3. Краткое описание о себе (ваши цели и приоритеты, подчеркните сильные стороны, опишите опыт работы, если он есть, или желание учиться и приобретать новые навыки) +4. Навыки (языки программирования, фреймворки, методологии, системы контроля версий и инструменты разработки, которыми вы владеете) +5. Примеры кода +6. Опыт работы (можно указать учебные проекты с использованными навыками и ссылками на исходный код) +7. Образование (включая пройденные курсы и обучение) +8. Английский язык (ваш уровень владения английским, опишите языковую практику, если она была) + +## Рекомендации по написанию CV + +- Оформление CV — на ваше усмотрение. Старайтесь сделать его качественным, можно ориентироваться на примеры из раздела материалов. +- Рекомендуется указывать реальные данные. +- Добавьте своё фото или аватар. Фото предпочтительнее. +- Укажите актуальные контакты, включая ник в Discord. +- В качестве примера кода приведите решение задачи с [Codewars](https://www.codewars.com/). Если вы ещё не решали задачи, можно использовать [эту](https://www.codewars.com/kata/50654ddff44f800200000004/train/javascript). +- Добавляйте код символами и тегами, а не картинкой. +- Для выполненных проектов указывайте название, ссылку на код на GitHub или на страницу проекта. Если проектов пока нет, используйте само это CV как первый проект. + +## Технические требования + +- Работа проверяется в последней версии Google Chrome. +- Нет ограничений на использование JS-библиотек, препроцессоров, фреймворков и любых известных технологий. + +## Требования к репозиторию + +- Задание выполняется в личном публичном репозитории. +- Название репозитория: `rsschool-cv`. + +## Требования к коммитам + +- История коммитов должна отражать процесс разработки. +- [Используйте конвенцию именования коммитов](https://rs.school/docs/git-convention). + +## Требования к Pull Request + +- Название Pull Request — по названию задания. +- [Оформите описание Pull Request по схеме](https://rs.school/docs/pull-request-review-process#pull-request-requirements-pr). +- Не мержите Pull Request из рабочей ветки в `main`. + +## Порядок работы + +Задание состоит из трёх частей. Часть 1 и Часть 2 проверяются автоматически (авто-тест), Часть 3 — через cross-check. + +### Часть 1. Markdown & Git + +1. Создать на GitHub публичный репозиторий `rsschool-cv`. В ветке `main` должен быть только один файл — `README.md`. +2. Создать ветку `gh-pages` от `main`. +3. Сделать в ветке `gh-pages` не менее 3 коммитов по [конвенции коммитов](https://rs.school/docs/git-convention) (префиксы `init:`, `feat:`, `fix:`, `refactor:`, `docs:`). +4. В ветке `gh-pages` разместить файл `cv.md`. +5. Заполнить `cv.md` своим CV на Markdown — см. «Содержание CV» выше. +6. В `README.md` ветки `gh-pages` добавить ссылку вида `https://GITHUB-USERNAME.github.io/rsschool-cv/cv`, заменив `GITHUB-USERNAME` на свой ник на GitHub. По этой ссылке должна открываться страница CV, задеплоенная на GitHub Pages. +7. Создать Pull Request из ветки `gh-pages` в ветку `main`. Название — `Markdown & Git`. Не мержить. + +> Подсказки по шагам (необязательные, не часть требований): +> +> ![создание ветки gh-pages](assets/create-gh-pages.png) +> +> Найти ссылку на задеплоенную версию можно в панели Deployments репозитория: +> +> ![поиск ссылки деплоя, шаг 1](assets/find_deploy_01.png) +> ![поиск ссылки деплоя, шаг 2](assets/find_deploy_02.png) + +#### Как сдавать Часть 1 + +Отправляется через авто-тест: выбрать задание «Markdown & Git» и нажать «Submit». Пересдавать можно сколько угодно раз до дедлайна — каждая следующая попытка перезаписывает предыдущую. + +#### Критерии оценки Часть 1 + +**Максимальный балл: 100** + +- Требования к репозиторию выполнены **+50** +- Требования к коммитам и Pull Request выполнены **+50** + +### Часть 2. HTML, CSS & Git Basics + +В этой части создаются только базовые шаблоны файлов — минимальные или пустые. Реальная вёрстка и стилизация CV делаются в Части 3. + +Некоторые правила валидации, которые проверяет авто-тест: + +- лишние пробелы в конце строк не допускаются; +- закрывающий тег или закрывающий слэш у непарного тега не допускается; +- символы `<`, `>`, `&` и т.п. должны быть заменены на escape-последовательности. + +1. Продолжить работу в репозитории `rsschool-cv`. Создать ветку `rsschool-cv-html` от ветки `gh-pages`. +2. Вести историю коммитов по той же [конвенции](https://rs.school/docs/git-convention). +3. В ветке `rsschool-cv-html` разместить файлы `index.html` и `style.css` — базовые пустые шаблоны или шаблоны с минимальным содержимым. +4. В `README.md` ветки `rsschool-cv-html` добавить ссылку вида `https://GITHUB-USERNAME.github.io/rsschool-cv/`, заменив `GITHUB-USERNAME` на свой ник на GitHub. По этой ссылке будет открываться CV в виде полноценной веб-страницы (после Части 3). +5. Создать Pull Request из ветки `rsschool-cv-html` в ветку `gh-pages`. Название — `HTML, CSS & Git Basics`. Замержить его. + +#### Как сдавать Часть 2 + +Отправляется через авто-тест: выбрать задание «HTML, CSS & Git Basics» и нажать «Submit». Пересдавать можно сколько угодно раз до дедлайна. + +#### Критерии оценки Часть 2 + +**Максимальный балл: 100** + +- Требования к репозиторию выполнены **+50** +- Требования к коммитам и Pull Request выполнены **+50** + +## Часть 3. Вёрстка CV + +Основу содержания страницы составляют данные, которые вы добавили в `cv.md` в Части 1. Эти данные можно изменять, дополнять, редактировать. Кроме текста, на страницу нужно добавить фото или аватар. + +### Требования к вёрстке + +- Вёрстка валидная. Для проверки используйте [validator.w3.org](https://validator.w3.org/). +- Вёрстка семантическая. +- При написании кода рекомендуется следовать [гайдлайну](https://codeguide.academy/html-css.html). +- Контент размещается в блоке, который горизонтально центрируется на странице. +- Страница CV должна корректно отображаться в последней версии Google Chrome. +- В footer нужно добавить ссылку на ваш GitHub, год создания страницы, [логотип курса](assets/rs-school-logo.svg) со ссылкой на курс. + +### Порядок работы Часть 3 + +1. Работа ведётся в ветке `rsschool-cv-html` репозитория `rsschool-cv`. +2. При вёрстке ориентируйтесь на «Требования к вёрстке» выше и «Критерии оценки» ниже. +3. Самостоятельно оцените свою работу по предложенным критериям. +4. Создайте Pull Request из ветки `rsschool-cv-html` в ветку `main`. Название — на ваше усмотрение, описание не требуется. **Этот Pull Request не мержить** — именно его ссылку нужно отправить на cross-check. +5. В файл `README.md` ветки `main` добавьте обе ссылки (заменив `GITHUB-USERNAME` на свой ник на GitHub), по которым должны открываться CV в формате Markdown и в виде свёрстанной страницы: + - `https://GITHUB-USERNAME.github.io/rsschool-cv/cv` + - `https://GITHUB-USERNAME.github.io/rsschool-cv/` + +### Как сдавать Часть 3 + +Задание проверяется через [cross-check](https://rs.school/docs/cross-check-flow). Отправьте ссылку на Pull Request из ветки `rsschool-cv-html` в `main` (шаг 4 выше). + +### Критерии оценки Часть 3 + +**Максимальный балл: 100** + +- Pull Request открыт из `rsschool-cv-html` в `main` и не замержен **+5** +- Ссылки на обе версии CV в `README.md` ветки `main` рабочие **+5** +- Вёрстка валидная **+10** +- Вёрстка семантическая: `header`, `main`, `footer`, `nav`, один `h1`, есть `h2` **+20** +- В footer есть ссылка на GitHub автора, год создания, логотип курса со ссылкой на курс **+10** +- Для оформления CV используются CSS-стили **+10** +- При уменьшении масштаба страницы вёрстка остаётся по центру, а не сдвигается в сторону **+10** +- На странице есть фото или аватар автора, пропорции не искажены, есть атрибут `alt` **+10** +- Навигация, контакты и список навыков оформлены как `ul > li` (или `ol > li`) **+10** +- Содержание CV (все обязательные разделы на месте и осмысленны) **+20** + +_(Черновая раскладка баллов — общая модель оценивания курса ещё не согласована, см. OPEN_QUESTIONS.md)_ diff --git a/fullstack-engineering/tasks/cv/assets/create-gh-pages.png b/fullstack-engineering/tasks/cv/assets/create-gh-pages.png new file mode 100644 index 0000000000000000000000000000000000000000..b73458369659700a5183ca21e64c2a1ecb099d52 GIT binary patch literal 9462 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 literal 0 HcmV?d00001 diff --git a/fullstack-engineering/tasks/cv/assets/find_deploy_01.png b/fullstack-engineering/tasks/cv/assets/find_deploy_01.png new file mode 100644 index 0000000000000000000000000000000000000000..417af729edf2913cb58f103077bd3a7690dfd3f2 GIT binary patch literal 9356 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 literal 0 HcmV?d00001 diff --git a/fullstack-engineering/tasks/cv/assets/find_deploy_02.png b/fullstack-engineering/tasks/cv/assets/find_deploy_02.png new file mode 100644 index 0000000000000000000000000000000000000000..1dad8abdbc2bfad7129fca99ba98e36f1de68b51 GIT binary patch literal 14073 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 diff --git a/fullstack-engineering/tasks/data-structures-algorithms/README.md b/fullstack-engineering/tasks/data-structures-algorithms/README.md new file mode 100644 index 000000000..c42d44f67 --- /dev/null +++ b/fullstack-engineering/tasks/data-structures-algorithms/README.md @@ -0,0 +1,3 @@ +# Data Structures & Algorithms + +> TBD — задание пока не описано. Неделя 7: реализация стека, очереди, связного списка, дерева + задачи с их использованием. См. [README.md курса](../../README.md). diff --git a/fullstack-engineering/tasks/external-api/README.md b/fullstack-engineering/tasks/external-api/README.md new file mode 100644 index 000000000..ecf5f2625 --- /dev/null +++ b/fullstack-engineering/tasks/external-api/README.md @@ -0,0 +1,3 @@ +# External API + +> TBD — задание пока не описано. Неделя 8: интеграция с готовым веб API — запросы, рендер данных, обработка ошибок и загрузки. См. [README.md курса](../../README.md). diff --git a/fullstack-engineering/tasks/games-catalog/README.md b/fullstack-engineering/tasks/games-catalog/README.md new file mode 100644 index 000000000..5c6da317a --- /dev/null +++ b/fullstack-engineering/tasks/games-catalog/README.md @@ -0,0 +1,3 @@ +# Games Catalog + +> TBD — задание пока не описано. Неделя 9: общий репозиторий с каталогом веб-игр, каждый студент добавляет свою игру. См. [README.md курса](../../README.md). diff --git a/fullstack-engineering/tasks/js-basic-methods/README.md b/fullstack-engineering/tasks/js-basic-methods/README.md new file mode 100644 index 000000000..36bd95b86 --- /dev/null +++ b/fullstack-engineering/tasks/js-basic-methods/README.md @@ -0,0 +1,3 @@ +# JS Basic Methods + +> TBD — задание пока не описано. Неделя 4: пак задач на встроенные методы строк, чисел и массивов. См. [README.md курса](../../README.md). diff --git a/fullstack-engineering/tasks/landing-page/README.md b/fullstack-engineering/tasks/landing-page/README.md new file mode 100644 index 000000000..c1ecfbef3 --- /dev/null +++ b/fullstack-engineering/tasks/landing-page/README.md @@ -0,0 +1,3 @@ +# Landing Page + +> TBD — задание пока не описано. Недели 2–3: адаптивная вёрстка лендинга по макету Figma (часть 1) + JS-функциональность и Web Storage (часть 2). См. [README.md курса](../../README.md). diff --git a/fullstack-engineering/tasks/online-store/README.md b/fullstack-engineering/tasks/online-store/README.md new file mode 100644 index 000000000..ffabc79c0 --- /dev/null +++ b/fullstack-engineering/tasks/online-store/README.md @@ -0,0 +1,3 @@ +# Online Store + +> TBD — задание пока не описано. Недели 11–12: парное задание — онлайн-магазин (каталог, корзина, фильтры). См. [README.md курса](../../README.md). diff --git a/fullstack-engineering/tasks/own-backend/README.md b/fullstack-engineering/tasks/own-backend/README.md new file mode 100644 index 000000000..258a9f65f --- /dev/null +++ b/fullstack-engineering/tasks/own-backend/README.md @@ -0,0 +1,3 @@ +# Own Backend + +> TBD — задание пока не описано. Неделя 10: свой сервер с несколькими роутами и middleware для проверки токена из cookies. См. [README.md курса](../../README.md). diff --git a/fullstack-engineering/tasks/testing-intro/README.md b/fullstack-engineering/tasks/testing-intro/README.md new file mode 100644 index 000000000..cc2cf0cbf --- /dev/null +++ b/fullstack-engineering/tasks/testing-intro/README.md @@ -0,0 +1,3 @@ +# Testing Intro + +> TBD — задание пока не описано. Неделя 6: unit-тесты к готовым функциям + функции по готовым тестам (TDD). См. [README.md курса](../../README.md). From f461b492ba5f3c9558bdfc04743bc00aa1a22e9a Mon Sep 17 00:00:00 2001 From: OreskaG Date: Mon, 24 Aug 2026 19:59:57 +0300 Subject: [PATCH 02/13] feat(fullstack): update README files with evaluation criteria and restructure tasks --- fullstack-engineering/README.md | 16 +- .../tasks/bug-hunting/README.md | 4 + fullstack-engineering/tasks/cv/README.md | 22 +-- .../data-structures-algorithms/README.md | 4 + .../tasks/landing-page/README-part-1.md | 153 ++++++++++++++++++ .../tasks/landing-page/README-part-2.md | 58 +++++++ .../tasks/landing-page/README.md | 3 - .../tasks/own-backend/README.md | 4 + 8 files changed, 243 insertions(+), 21 deletions(-) create mode 100644 fullstack-engineering/tasks/landing-page/README-part-1.md create mode 100644 fullstack-engineering/tasks/landing-page/README-part-2.md delete mode 100644 fullstack-engineering/tasks/landing-page/README.md diff --git a/fullstack-engineering/README.md b/fullstack-engineering/README.md index 58c1727b6..d2ab09500 100644 --- a/fullstack-engineering/README.md +++ b/fullstack-engineering/README.md @@ -42,25 +42,25 @@ ### Неделя 2 - Cross-check: - - Cross-check проекта [CV Project](tasks/cv/README.md) + - Cross-check проекта [CV Project](tasks/cv/README.md#критерии-оценки-часть-3) - Задачи: - - [Landing Page. Часть 1](tasks/landing-page/README.md) — адаптивная вёрстка лендинга по макету Figma + - [Landing Page. Часть 1](tasks/landing-page/README-part-1.md) — адаптивная вёрстка лендинга по макету Figma - Стек: HTML, CSS (Flex/Grid), Figma - Чему научатся: semantic HTML, responsive design ### Неделя 3 - Cross-check: - - Cross-check проекта Landing Page. Часть 1 + - Cross-check проекта [Landing Page. Часть 1](tasks/landing-page/README-part-1.md#критерии-оценки) - Задачи: - - [Landing Page. Часть 2](tasks/landing-page/README.md) — интерактив (попапы, слайдеры, бургер-меню) + localStorage/IndexedDB + - [Landing Page. Часть 2](tasks/landing-page/README-part-2.md) — интерактив (попапы, слайдеры, бургер-меню) + localStorage/IndexedDB - Стек: JS, DOM API, localStorage, IndexedDB - Чему научатся: DOM-события, два разных браузерных хранилища данных ### Неделя 4 - Cross-check: - - Cross-check проекта Landing Page. Часть 2 + - Cross-check проекта [Landing Page. Часть 2](tasks/landing-page/README-part-2.md#критерии-оценки) - Задачи: - [Пак JS-задач по базовым методам строк/чисел/массивов](tasks/js-basic-methods/README.md) _(конкретный набор — TBD)_ - Стек: JS @@ -76,7 +76,7 @@ ### Неделя 6 - Cross-check: - - Cross-check проекта Bug Hunting + - Cross-check проекта [Bug Hunting](tasks/bug-hunting/README.md#критерии-оценки) - Задачи: - [Testing intro](tasks/testing-intro/README.md) — часть 1: unit-тесты к готовым функциям; часть 2: функции по готовым тестам (TDD) - Стек: JS, Jest @@ -92,7 +92,7 @@ ### Неделя 8 - Cross-check: - - Cross-check проекта Data Structures & Algorithms + - Cross-check проекта [Data Structures & Algorithms](tasks/data-structures-algorithms/README.md#критерии-оценки) - Задачи: - [Работа с готовым веб API](tasks/external-api/README.md) — запросы, рендер данных, обработка ошибок и загрузки - Стек: JS, fetch/async-await, DOM @@ -115,7 +115,7 @@ ### Неделя 11–12 - Cross-check: - - Cross-check проекта "Свой backend" + - Cross-check проекта [Свой backend](tasks/own-backend/README.md#критерии-оценки) - Задачи: - [Онлайн-магазин](tasks/online-store/README.md) (парное задание) — каталог, корзина, фильтры; можно опираться на сервер с недели 10 - Стек: JS, DOM/UI по выбору пары diff --git a/fullstack-engineering/tasks/bug-hunting/README.md b/fullstack-engineering/tasks/bug-hunting/README.md index 41b6be326..4f5bc2629 100644 --- a/fullstack-engineering/tasks/bug-hunting/README.md +++ b/fullstack-engineering/tasks/bug-hunting/README.md @@ -1,3 +1,7 @@ # Bug Hunting > TBD — задание пока не описано. Неделя 5: готовые сайты с багами в HTML/CSS/JS — найти и исправить. См. [README.md курса](../../README.md). + +## Критерии оценки + +_(TBD — модель оценивания для курса ещё не согласована, см. OPEN_QUESTIONS.md)_ diff --git a/fullstack-engineering/tasks/cv/README.md b/fullstack-engineering/tasks/cv/README.md index 9945ab91e..2ae6ea14b 100644 --- a/fullstack-engineering/tasks/cv/README.md +++ b/fullstack-engineering/tasks/cv/README.md @@ -199,13 +199,15 @@ CV (Curriculum Vitae) — документ, в котором соискател **Максимальный балл: 100** -- Pull Request открыт из `rsschool-cv-html` в `main`, имеет название `CV Layout. Cross-Check`, оформлен в соответствии с требованиями и не замержен **+5** -- Ссылки на обе версии CV в `README.md` рабочие **+5** -- Вёрстка валидная **+10** -- Вёрстка семантическая: `header`, `main`, `footer`, `nav`, один `h1`, есть `h2` **+10** -- В footer есть ссылка на GitHub автора, год создания, логотип курса со ссылкой на курс **+10** -- Для оформления CV используются CSS-стили **+10** -- При уменьшении масштаба страницы вёрстка остаётся по центру, а не сдвигается в сторону **+10** -- На странице есть фото или аватар автора, пропорции не искажены, есть атрибут `alt` **+10** -- Навигация, контакты и список навыков оформлены как `ul > li` (или `ol > li`) **+10** -- Содержание CV: присутствуют все обязательные разделы (имя, контакты, информация о себе, навыки, пример кода, опыт работы или учебные проекты, образование, уровень английского языка), содержание разделов осмысленное **+20** +Сумма баллов по всем пунктам больше 100 — это специально сделанный запас, который сглаживает неточности проверки и разное понимание требований. Итоговый балл всё равно ограничен сверху 100. + +1. Pull Request открыт из `rsschool-cv-html` в `main`, имеет название `CV Layout. Cross-Check`, оформлен в соответствии с требованиями и не замержен: **+5** +2. Ссылки на обе версии CV в `README.md` рабочие: **+5** +3. Вёрстка валидна по [W3C Validator](https://validator.w3.org/): **+10** +4. Вёрстка семантическая: `header`, `main`, `footer`, `nav`, один `h1`, есть `h2`: **+10** +5. В footer есть ссылка на GitHub автора, год создания, логотип курса со ссылкой на курс: **+10** +6. Для оформления CV используются CSS-стили: **+15** +7. При уменьшении масштаба страницы вёрстка остаётся по центру, а не сдвигается в сторону: **+10** +8. На странице есть фото или аватар автора, пропорции не искажены, есть атрибут `alt`: **+10** +9. Навигация, контакты и список навыков оформлены как `ul > li` (или `ol > li`): **+15** +10. Содержание CV: присутствуют все обязательные разделы (имя, контакты, информация о себе, навыки, пример кода, опыт работы или учебные проекты, образование, уровень английского языка), содержание разделов осмысленное: **+20** diff --git a/fullstack-engineering/tasks/data-structures-algorithms/README.md b/fullstack-engineering/tasks/data-structures-algorithms/README.md index c42d44f67..fc839c00b 100644 --- a/fullstack-engineering/tasks/data-structures-algorithms/README.md +++ b/fullstack-engineering/tasks/data-structures-algorithms/README.md @@ -1,3 +1,7 @@ # Data Structures & Algorithms > TBD — задание пока не описано. Неделя 7: реализация стека, очереди, связного списка, дерева + задачи с их использованием. См. [README.md курса](../../README.md). + +## Критерии оценки + +_(TBD — модель оценивания для курса ещё не согласована, см. OPEN_QUESTIONS.md)_ diff --git a/fullstack-engineering/tasks/landing-page/README-part-1.md b/fullstack-engineering/tasks/landing-page/README-part-1.md new file mode 100644 index 000000000..5061a0046 --- /dev/null +++ b/fullstack-engineering/tasks/landing-page/README-part-1.md @@ -0,0 +1,153 @@ +# Landing Page + +## Описание проекта + +Landing Page — задание, в котором нужно создать одностраничный сайт (лендинг) на тему по своему выбору: сначала сверстать адаптивную страницу по дизайну, затем добавить интерактивность и работу с браузерными хранилищами данных. + +В отличие от заданий, где все делают вёрстку по одному и тому же макету, здесь у вас есть творческая свобода: вы сами придумываете тему лендинга (или берёте одну из примеров ниже) и с помощью Figma AI создаёте по обезличенному шаблону собственный уникальный дизайн. Перед стартом задания пройдёт стрим, на котором покажут, как пользоваться Figma AI для этого. + +При этом часть требований жёстко зафиксирована и одинакова для всех — шапка и подвал сайта, минимальный набор секций и функциональности. Это даёт свободу в содержании и креативе, но сохраняет единые технические критерии проверки. + +## Навыки + +`HTML` `CSS` `Figma` `Figma AI` `JavaScript` `DOM` `localStorage` `IndexedDB` + +## Из чего состоит задание + +Задание разбито на две части, каждая длится одну неделю и оценивается через отдельный cross-check: + +- **Часть 1. Вёрстка** — этот файл: выбор темы, дизайн в Figma AI по шаблону, адаптивная семантическая вёрстка. +- [Часть 2. Функциональность](README-part-2.md) — интерактивность (бургер-меню, слайдер, модалка, валидация формы, переключение темы) + сохранение данных в localStorage и IndexedDB. + +## Выбор темы лендинга + +Тему можно придумать полностью самостоятельно. Если пока нет идеи, можно взять один из примеров: + +- кофейня / кафе +- спортзал / фитнес-студия +- языковые курсы +- стоматология / клиника +- барбершоп +- бьюти-салон +- IT-курс / буткемп +- SaaS-продукт / стартап +- музыкальная группа +- благотворительное событие +- доставка еды +- автосервис +- приют для животных + +Тема должна допускать естественное появление всех обязательных блоков задания: карточек для слайдера/карусели (услуги, меню, отзывы, портфолио и т.п.), формы заявки/записи/обратной связи и модального окна. Если тема настолько специфична, что это невозможно, лучше выбрать другую. + +### Примеры старых лендингов курса — для вдохновения + +Раньше на курсе уже было несколько похожих заданий с лендингами на разные темы. Смотреть на них стоит не как на образец для копирования 1-в-1, а как на примеры того, какими бывают структура, секции и легенда лендинга: + +- [Portfolio](../../../tasks/portfolio/portfolio.md) — лендинг-портфолио фотографа +- [Coffee House](../../../tasks/coffee-house/coffee-house.md) — сайт кофейни +- [Library](../../../tasks/library/library.md) — сайт по подбору и продаже книг +- [Plants](../../../tasks/plants/plants.md) — сайт садовых услуг +- [Travel](../../../tasks/travel/travel.md) — сайт для планирования путешествий +- [Online Zoo](../../../tasks/online-zoo/online-zoo.md) — сайт приюта для животных +- [Simple Singolo](../../../tasks/stage-0/simple-singolo.md) — бизнес-лендинг с табами и слайдером + +## Обязательные header и footer (общие для обеих частей) + +Независимо от темы и дизайна, во всех работах должны быть одинаковые по структуре шапка и подвал — именно они проверяются с точностью до пикселя. + +### Header + +- Логотип/название лендинга — текстом или инлайн-SVG, не скриншотом. +- Навигация: список (`nav > ul > li > a`) с якорными ссылками на все основные секции страницы. +- Кнопка/иконка переключения светлой/тёмной темы (разметка — в Части 1, реальное переключение и сохранение выбора — в Части 2). +- Бургер-меню для мобильной версии (разметка — в Части 1, поведение — в Части 2). + +### Footer + +- Логотип/название лендинга. +- Копирайт с годом создания сайта. +- Ссылка на курс RS School. + +## Материалы для изучения + +- Запись стрима «Как пользоваться Figma AI» — TBD, добавим ссылку ближе к старту задания. +- Ссылка на обезличенный Figma-шаблон — TBD. +- [Старт в Figma для верстальщика](https://htmlacademy.ru/blog/soft/figma) +- [Инструкция по работе в Figma для верстальщика](https://breezzly.ru/guides/start-v-figma-dlya-verstalshhika) +- [Верстка сайта с нуля из Figma (плейлист)](https://www.youtube.com/playlist?list=PL5_s7xdj2Vsw-bCx5nOZJMFIiHwRgok--) +- [Guideline по HTML/CSS](https://codeguide.academy/html-css.html#html) + +## Требования к Части 1: Вёрстка + +### Что делать + +1. Выберите тему лендинга — самостоятельно или из примеров выше. +2. Создайте свою копию обезличенного Figma-шаблона и с помощью Figma AI сгенерируйте дизайн под свою тему. Обязательно посмотрите стрим перед началом работы. +3. Доработайте сгенерированный дизайн вручную там, где нужно — Figma AI не обязан сразу дать пиксель-перфектный и логичный результат. +4. Сверстайте адаптивную страницу по получившемуся макету. + +### Минимальный набор секций + +- Не менее 4 контентных секций, не считая header и footer. +- Секция с карточками (не менее 8 штук) — в Части 2 станет слайдером/каруселью. +- Модальное окно, которое открывается по клику на карточку из этой секции и показывает дополнительную информацию о ней (например, развёрнутое описание, более крупное фото, детали услуги) — по умолчанию скрыто. +- Секция с формой заявки/записи/бронирования (конкретный смысл — под вашу тему): минимум поля — имя, способ связи (телефон или email), комментарий. В Части 2 данные успешной отправки будут сохраняться в IndexedDB. + +### Технические требования + +- Вёрстка валидная, семантическая, соответствует получившемуся макету. +- Корректно отображается в последней версии Google Chrome. +- Соответствие макету проверяется на ширине экрана 1440px, 768px и 380px (выбор промежуточных брейкпоинтов — на ваше усмотрение). На всех промежуточных ширинах между 1440px и 380px: нет горизонтального скролла, вёрстка адаптивна, весь контент сохранён, пропорции изображений не искажены. +- Использование HTML-препроцессоров и шаблонизаторов (Pug и т.п.) не допускается. +- Использование CSS-фреймворков (Bootstrap и т.п.) не допускается. +- CSS-препроцессоры (SASS/SCSS) и [modern-normalize](https://github.com/sindresorhus/modern-normalize) допускаются. +- TypeScript не допускается. +- Использование готовых JS-библиотек для слайдеров/модалок (Swiper и т.п.) не допускается — в Части 2 всё пишется самостоятельно. +- Секции/картинки не должны быть вставлены скриншотом макета — только тегами и реальными изображениями (фото/иконки). +- Код читаемый, без минификации; при использовании сборщика (Vite/Webpack) — с включёнными source maps. + +## Требования к репозиторию + +- Задание выполняется в личном публичном репозитории `rsschool-landing-page`. +- Ветка `main` должна оставаться пустой (только `README.md`, `.gitignore` и т.п.). +- Часть 1 выполняется в ветке `landing-page`, созданной от `main`. +- Часть 2 выполняется в ветке `landing-page-part-2`, созданной от `landing-page` (см. [README-part-2.md](README-part-2.md)). +- Внутренняя структура проекта — на ваше усмотрение. + +## Как сдавать Часть 1 + +- Работа ведётся в ветке `landing-page`. +- Задеплойте страницу (например, через GitHub Pages). +- Откройте Pull Request из `landing-page` в `main`, не мержите его. +- Отправьте ссылку на этот Pull Request на cross-check. + +## Cross-check + +Задание проверяется через [cross-check](https://rs.school/docs/cross-check-flow). Проверяется валидность вёрстки, соответствие макету на ширине 1440px, 768px и 380px, адаптивность на промежуточных ширинах, отсутствие горизонтального скролла. + +## Критерии оценки + +**Максимальный балл: 100** + +Сумма баллов по всем пунктам больше 100 — это специально сделанный запас, который сглаживает неточности проверки и разное понимание требований. Итоговый балл всё равно ограничен сверху 100. + +1. Header и footer реализованы pixel perfect (в header: лого, nav, кнопка темы, разметка бургер-меню; в footer: лого, копирайт с годом создания, ссылка на курс) на ширине 1440px, 768px и 380px; допустимое отклонение — до 10px по горизонтали и вертикали при сохранении визуального сходства: **+10** +2. Навигация в header построена как `nav > ul > li > a`: **+5** +3. Остальные секции визуально соответствуют получившемуся у вас макету (не pixel perfect — оценивается сходство: расположение блоков, отступы, шрифты, цвета) на ширине 1440px, 768px и 380px. Чтобы проверяющий мог сравнить вёрстку с макетом, добавьте в Pull Request публичную ссылку на сгенерированный и использованный вами Figma-макет (проверьте, что она открывается в режиме инкогнито): **+10** +4. Не менее 4 контентных секций, не считая header и footer: **+5** +5. Секция с карточками (не менее 8 штук): **+10** +6. Модальное окно открывается по клику на карточку и по умолчанию скрыто в разметке: **+10** +7. Секция с формой заявки/записи/бронирования с нужными полями (имя, способ связи, комментарий): **+10** +8. На всех промежуточных ширинах между 1440px и 380px отсутствует горизонтальный скролл, вёрстка адаптивна, весь контент сохранён: **+10** +9. Вёрстка валидна по [W3C Validator](https://validator.w3.org/): **+10** +10. Семантическая вёрстка: теги `header`, `main`, `footer`, `section`, один `h1` на странице: **+5** +11. На странице есть `favicon`: **+5** +12. У всех значимых `` заполнен осмысленный `alt`: **+5** +13. Кнопки, ссылки и карточки интерактивны (hover/focus): плавный переход стилей (transition), не влияющий на соседние элементы: **+5** +14. Плавная прокрутка по якорным ссылкам навигации: **+5** +15. Lighthouse Performance (DevTools, мобильный режим) не ниже 70: **+5** + +### Штрафы + +- Использование запрещённых технологий (CSS/JS-фреймворки, TypeScript, готовые библиотеки слайдеров/модалок, HTML-препроцессоры и т.п.): **-100** +- Секции или картинки вставлены скриншотом макета вместо вёрстки тегами: **-100** diff --git a/fullstack-engineering/tasks/landing-page/README-part-2.md b/fullstack-engineering/tasks/landing-page/README-part-2.md new file mode 100644 index 000000000..7aaf2d5dd --- /dev/null +++ b/fullstack-engineering/tasks/landing-page/README-part-2.md @@ -0,0 +1,58 @@ +# Landing Page. Часть 2: Функциональность + +Продолжение [Части 1](README-part-1.md) — добавьте интерактивность и работу с браузерными хранилищами к странице, свёрстанной ранее. + +## Что делать + +1. Продолжите работу в ветке `landing-page-part-2`, созданной от `landing-page`. +2. Добавьте JS-интерактивность к секциям и элементам, размеченным в Части 1. +3. Реализуйте переключение темы и историю заявок, как описано в требованиях ниже. + +## Требования + +### Интерактивность + +- Бургер-меню открывается/закрывается по клику, закрывается по клику на пункт меню/оверлей. +- Слайдер/карусель работает от кнопок вперёд/назад (свайп — по желанию); реализация полностью своя, без готовых библиотек. +- Модальное окно открывается/закрывается (кнопка закрытия, клик по оверлею, `Esc`). +- Форма валидируется на клиенте: обязательные поля, понятные сообщения об ошибках, невозможность отправить некорректные данные. + +### Переключение темы + localStorage (обязательно) + +- Кнопка/иконка переключения темы, добавленная в header в Части 1, должна реально переключать светлую/тёмную тему оформления страницы. +- Выбранная тема сохраняется в `localStorage` и применяется при повторном открытии страницы. + +### История заявок + IndexedDB (обязательно) + +- При успешной отправке формы запись (введённые поля + дата/время) сохраняется в IndexedDB, а не только "исчезает" после отправки. +- На странице есть блок/модалка «Ваши заявки» (название — на ваше усмотрение по теме), который при загрузке страницы читает и показывает все ранее сохранённые в IndexedDB записи. +- Разница между хранилищами должна быть логичной, а не формальной: `localStorage` — простое хранение состояния интерфейса (тема), `IndexedDB` — хранение коллекции структурированных записей (заявки). + +### Технические требования + +- Все технические требования Части 1 остаются в силе. +- Используется нативный `IndexedDB` API — сторонние библиотеки-обёртки (`idb`, `dexie`, `localforage` и т.п.) не допускаются; можно написать свои небольшие промис-хелперы. +- Использование готовых библиотек для слайдера/модалки/валидации (Swiper, SweetAlert и т.п.) не допускается. +- jQuery и другие устаревшие библиотеки не допускаются. +- JS-фреймворки (React, Vue, Angular и т.п.) не допускаются. +- TypeScript не допускается. + +## Материалы для изучения + +- [localStorage — MDN](https://developer.mozilla.org/ru/docs/Web/API/Window/localStorage) +- [IndexedDB — javascript.info](https://learn.javascript.ru/indexeddb) +- [Working with IndexedDB — MDN](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB) + +## Как сдавать + +- Работа ведётся в ветке `landing-page-part-2`, созданной от `landing-page`. +- Откройте Pull Request из `landing-page-part-2` в `landing-page`, не мержите его. +- Отправьте ссылку на этот Pull Request на cross-check. + +## Cross-check + +Задание проверяется через [cross-check](https://rs.school/docs/cross-check-flow). Проверяется вся реализованная функциональность, включая корректную работу переключения темы и истории заявок после перезагрузки страницы. + +## Критерии оценки + +_(TBD — модель оценивания для курса ещё не согласована, см. OPEN_QUESTIONS.md)_ diff --git a/fullstack-engineering/tasks/landing-page/README.md b/fullstack-engineering/tasks/landing-page/README.md deleted file mode 100644 index c1ecfbef3..000000000 --- a/fullstack-engineering/tasks/landing-page/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Landing Page - -> TBD — задание пока не описано. Недели 2–3: адаптивная вёрстка лендинга по макету Figma (часть 1) + JS-функциональность и Web Storage (часть 2). См. [README.md курса](../../README.md). diff --git a/fullstack-engineering/tasks/own-backend/README.md b/fullstack-engineering/tasks/own-backend/README.md index 258a9f65f..167f0e13e 100644 --- a/fullstack-engineering/tasks/own-backend/README.md +++ b/fullstack-engineering/tasks/own-backend/README.md @@ -1,3 +1,7 @@ # Own Backend > TBD — задание пока не описано. Неделя 10: свой сервер с несколькими роутами и middleware для проверки токена из cookies. См. [README.md курса](../../README.md). + +## Критерии оценки + +_(TBD — модель оценивания для курса ещё не согласована, см. OPEN_QUESTIONS.md)_ From 2cd3370a95cf1d9c9a0eb97ea04e7d66d2b3e894 Mon Sep 17 00:00:00 2001 From: OreskaG Date: Mon, 24 Aug 2026 21:46:33 +0300 Subject: [PATCH 03/13] feat(fullstack): update evaluation criteria and add landing page task --- .../fullstack-engineering.instructions.md | 5 ++ .../tasks/cv/cross-check.json | 6 +- .../landing-page/cross-check-part-1.json | 90 +++++++++++++++++++ 3 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 fullstack-engineering/tasks/landing-page/cross-check-part-1.json diff --git a/.github/instructions/fullstack-engineering.instructions.md b/.github/instructions/fullstack-engineering.instructions.md index 4803acda2..4801c6f30 100644 --- a/.github/instructions/fullstack-engineering.instructions.md +++ b/.github/instructions/fullstack-engineering.instructions.md @@ -30,6 +30,11 @@ applyTo: "fullstack-engineering/**" - Обычно у студента одна задача единовременно (кроме случаев, когда задание занимает 30–40 минут — тогда таких может быть несколько на неделю). - Используй [tasks/\_template/README.md](../../fullstack-engineering/tasks/_template/README.md) как основу для новых заданий (разделы: Навыки → Что делать → Материалы для изучения → Требования → Как сдавать → Cross-check → Критерии оценки). - Критерии оценки (баллы/штрафы) пока не согласованы на уровне курса — не изобретай жёсткую балльную систему для конкретного задания, если её не просили; отмечай как TBD. +- Если критерии оценки для задания всё же согласованы и написаны, оформляй их так: + - нумерованный список (не маркированный) с баллом в конце строки, например `1. ...: **+10**`; + - сумма баллов по пунктам сознательно делается больше максимального балла (запас ~10%, как в старых заданиях Library/Plants) — это сглаживает неточности проверки; итоговый балл всё равно ограничен максимумом, это поясняется отдельным предложением сразу после "Максимальный балл: N"; + - штрафы (`### Штрафы`) — отдельным списком после основных критериев, с указанием конкретного отрицательного числа (например `**-100**`), а не формулировкой "обнуление баллов"; + - рядом с README нужно добавить `cross-check.json` с тем же списком критериев (см. пример в [tasks/cv/cross-check.json](../../fullstack-engineering/tasks/cv/cross-check.json)) — при любом изменении критериев в README обязательно обновляй и JSON, они не должны расходиться. - При переносе/адаптации задания из старых Stage 1/2/0.5 — приводи флоу к текущим правилам ниже, а не копируй как есть. ### Правила флоу для индивидуальных заданий diff --git a/fullstack-engineering/tasks/cv/cross-check.json b/fullstack-engineering/tasks/cv/cross-check.json index 70a8a7edb..3e67e3f0d 100644 --- a/fullstack-engineering/tasks/cv/cross-check.json +++ b/fullstack-engineering/tasks/cv/cross-check.json @@ -13,7 +13,7 @@ }, { "type": "subtask", - "text": "Вёрстка валидная", + "text": "Вёрстка валидна по validator.w3.org", "max": 10 }, { @@ -29,7 +29,7 @@ { "type": "subtask", "text": "Для оформления CV используются CSS-стили", - "max": 10 + "max": 15 }, { "type": "subtask", @@ -44,7 +44,7 @@ { "type": "subtask", "text": "Навигация, контакты и список навыков оформлены как `ul > li` (или `ol > li`)", - "max": 10 + "max": 15 }, { "type": "subtask", diff --git a/fullstack-engineering/tasks/landing-page/cross-check-part-1.json b/fullstack-engineering/tasks/landing-page/cross-check-part-1.json new file mode 100644 index 000000000..8194066a9 --- /dev/null +++ b/fullstack-engineering/tasks/landing-page/cross-check-part-1.json @@ -0,0 +1,90 @@ +{ + "taskName": "Landing Page. Часть 1: Вёрстка", + "criteria": [ + { + "type": "subtask", + "text": "Header и footer реализованы pixel perfect (в header: лого, nav, кнопка темы, разметка бургер-меню; в footer: лого, копирайт с годом создания, ссылка на курс) на ширине 1440px, 768px и 380px; допустимое отклонение — до 10px по горизонтали и вертикали при сохранении визуального сходства", + "max": 10 + }, + { + "type": "subtask", + "text": "Навигация в header построена как `nav > ul > li > a`", + "max": 5 + }, + { + "type": "subtask", + "text": "Остальные секции визуально соответствуют получившемуся у студента макету (не pixel perfect — оценивается сходство: расположение блоков, отступы, шрифты, цвета) на ширине 1440px, 768px и 380px; в Pull Request добавлена публичная ссылка на использованный Figma-макет", + "max": 10 + }, + { + "type": "subtask", + "text": "Не менее 4 контентных секций, не считая header и footer", + "max": 5 + }, + { + "type": "subtask", + "text": "Секция с карточками (не менее 8 штук)", + "max": 10 + }, + { + "type": "subtask", + "text": "Модальное окно открывается по клику на карточку и по умолчанию скрыто в разметке", + "max": 10 + }, + { + "type": "subtask", + "text": "Секция с формой заявки/записи/бронирования с нужными полями (имя, способ связи, комментарий)", + "max": 10 + }, + { + "type": "subtask", + "text": "На всех промежуточных ширинах между 1440px и 380px отсутствует горизонтальный скролл, вёрстка адаптивна, весь контент сохранён", + "max": 10 + }, + { + "type": "subtask", + "text": "Вёрстка валидна по validator.w3.org", + "max": 10 + }, + { + "type": "subtask", + "text": "Семантическая вёрстка: теги `header`, `main`, `footer`, `section`, один `h1` на странице", + "max": 5 + }, + { + "type": "subtask", + "text": "На странице есть favicon", + "max": 5 + }, + { + "type": "subtask", + "text": "У всех значимых `` заполнен осмысленный `alt`", + "max": 5 + }, + { + "type": "subtask", + "text": "Кнопки, ссылки и карточки интерактивны (hover/focus): плавный переход стилей (transition), не влияющий на соседние элементы", + "max": 5 + }, + { + "type": "subtask", + "text": "Плавная прокрутка по якорным ссылкам навигации", + "max": 5 + }, + { + "type": "subtask", + "text": "Lighthouse Performance (DevTools, мобильный режим) не ниже 70", + "max": 5 + }, + { + "type": "penalty", + "text": "Использование запрещённых технологий (CSS/JS-фреймворки, TypeScript, готовые библиотеки слайдеров/модалок, HTML-препроцессоры и т.п.)", + "max": -100 + }, + { + "type": "penalty", + "text": "Секции или картинки вставлены скриншотом макета вместо вёрстки тегами", + "max": -100 + } + ] +} From 93e0223b50e49bdf9a70b58ede455d205ff515cf Mon Sep 17 00:00:00 2001 From: OreskaG Date: Mon, 24 Aug 2026 22:55:30 +0300 Subject: [PATCH 04/13] feat: add evaluation criteria for Landing Page Part 2 functionality --- .../tasks/landing-page/README-part-2.md | 21 +++++- .../landing-page/cross-check-part-2.json | 70 +++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 fullstack-engineering/tasks/landing-page/cross-check-part-2.json diff --git a/fullstack-engineering/tasks/landing-page/README-part-2.md b/fullstack-engineering/tasks/landing-page/README-part-2.md index 7aaf2d5dd..767c1e82b 100644 --- a/fullstack-engineering/tasks/landing-page/README-part-2.md +++ b/fullstack-engineering/tasks/landing-page/README-part-2.md @@ -55,4 +55,23 @@ ## Критерии оценки -_(TBD — модель оценивания для курса ещё не согласована, см. OPEN_QUESTIONS.md)_ +**Максимальный балл: 100** + +Сумма баллов по всем пунктам больше 100 — это специально сделанный запас, который сглаживает неточности проверки и разное понимание требований. Итоговый балл всё равно ограничен сверху 100. + +1. Бургер-меню открывается/закрывается по клику; закрывается по клику на пункт меню или на оверлей: **+10** +2. Слайдер/карусель переключает карточки по кнопкам вперёд/назад, реализован без готовых библиотек: **+10** +3. Модальное окно открывается по клику на карточку, закрывается по кнопке закрытия, клику на оверлей и по `Esc`: **+10** +4. Форма валидируется на клиенте: обязательные поля проверяются, при ошибке показывается понятное сообщение, отправить некорректные данные невозможно: **+10** +5. Кнопка переключения темы реально меняет оформление страницы (светлая/тёмная): **+10** +6. Выбранная тема сохраняется в `localStorage` и применяется при повторном открытии страницы: **+10** +7. При успешной отправке формы запись (поля формы + дата/время) сохраняется в IndexedDB: **+15** +8. Блок «Ваши заявки» при загрузке страницы читает и отображает все ранее сохранённые в IndexedDB записи: **+15** +9. После перезагрузки страницы тема и список заявок остаются прежними — сохранённое состояние переживает reload: **+10** +10. Используется нативный `IndexedDB` API без сторонних библиотек-обёрток (`idb`, `dexie`, `localforage` и т.п.): **+5** +11. В консоли DevTools нет ошибок при обычном использовании страницы (открытие, отправка формы, переключение темы, работа слайдера/модалки): **+5** + +### Штрафы + +- Использование запрещённых технологий (JS-фреймворки, TypeScript, готовые библиотеки для слайдера/модалки/валидации, сторонние обёртки для IndexedDB и т.п.): **-100** +- Переключение темы или история заявок реализованы «для вида», без реального сохранения в localStorage/IndexedDB: **-100** diff --git a/fullstack-engineering/tasks/landing-page/cross-check-part-2.json b/fullstack-engineering/tasks/landing-page/cross-check-part-2.json new file mode 100644 index 000000000..6b8c05c7a --- /dev/null +++ b/fullstack-engineering/tasks/landing-page/cross-check-part-2.json @@ -0,0 +1,70 @@ +{ + "taskName": "Landing Page. Часть 2: Функциональность", + "criteria": [ + { + "type": "subtask", + "text": "Бургер-меню открывается/закрывается по клику; закрывается по клику на пункт меню или на оверлей", + "max": 10 + }, + { + "type": "subtask", + "text": "Слайдер/карусель переключает карточки по кнопкам вперёд/назад, реализован без готовых библиотек", + "max": 10 + }, + { + "type": "subtask", + "text": "Модальное окно открывается по клику на карточку, закрывается по кнопке закрытия, клику на оверлей и по Esc", + "max": 10 + }, + { + "type": "subtask", + "text": "Форма валидируется на клиенте: обязательные поля проверяются, при ошибке показывается понятное сообщение, отправить некорректные данные невозможно", + "max": 10 + }, + { + "type": "subtask", + "text": "Кнопка переключения темы реально меняет оформление страницы (светлая/тёмная)", + "max": 10 + }, + { + "type": "subtask", + "text": "Выбранная тема сохраняется в localStorage и применяется при повторном открытии страницы", + "max": 10 + }, + { + "type": "subtask", + "text": "При успешной отправке формы запись (поля формы + дата/время) сохраняется в IndexedDB", + "max": 15 + }, + { + "type": "subtask", + "text": "Блок «Ваши заявки» при загрузке страницы читает и отображает все ранее сохранённые в IndexedDB записи", + "max": 15 + }, + { + "type": "subtask", + "text": "После перезагрузки страницы тема и список заявок остаются прежними — сохранённое состояние переживает reload", + "max": 10 + }, + { + "type": "subtask", + "text": "Используется нативный IndexedDB API без сторонних библиотек-обёрток (idb, dexie, localforage и т.п.)", + "max": 5 + }, + { + "type": "subtask", + "text": "В консоли DevTools нет ошибок при обычном использовании страницы (открытие, отправка формы, переключение темы, работа слайдера/модалки)", + "max": 5 + }, + { + "type": "penalty", + "text": "Использование запрещённых технологий (JS-фреймворки, TypeScript, готовые библиотеки для слайдера/модалки/валидации, сторонние обёртки для IndexedDB и т.п.)", + "max": -100 + }, + { + "type": "penalty", + "text": "Переключение темы или история заявок реализованы «для вида», без реального сохранения в localStorage/IndexedDB", + "max": -100 + } + ] +} From b41460a892ab4a19ebf04af88b81054b2cec2874 Mon Sep 17 00:00:00 2001 From: OreskaG Date: Sun, 30 Aug 2026 13:18:13 +0300 Subject: [PATCH 05/13] feat(engineer): week 4 --- fullstack-engineering/README.md | 2 +- .../tasks/js-basic-methods/README.md | 70 ++++++++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/fullstack-engineering/README.md b/fullstack-engineering/README.md index d2ab09500..089129cca 100644 --- a/fullstack-engineering/README.md +++ b/fullstack-engineering/README.md @@ -62,7 +62,7 @@ - Cross-check: - Cross-check проекта [Landing Page. Часть 2](tasks/landing-page/README-part-2.md#критерии-оценки) - Задачи: - - [Пак JS-задач по базовым методам строк/чисел/массивов](tasks/js-basic-methods/README.md) _(конкретный набор — TBD)_ + - [JS Basic Methods](tasks/js-basic-methods/README.md) — Core JS Numbers/Strings/Arrays/Conditions & Loops + Codewars (авто-тест RS App) - Стек: JS - Чему научатся: методы строк, чисел и массивов diff --git a/fullstack-engineering/tasks/js-basic-methods/README.md b/fullstack-engineering/tasks/js-basic-methods/README.md index 36bd95b86..53f4e3318 100644 --- a/fullstack-engineering/tasks/js-basic-methods/README.md +++ b/fullstack-engineering/tasks/js-basic-methods/README.md @@ -1,3 +1,71 @@ # JS Basic Methods -> TBD — задание пока не описано. Неделя 4: пак задач на встроенные методы строк, чисел и массивов. См. [README.md курса](../../README.md). +## Навыки + +`JavaScript` `String` `Number` `Array` `встроенные методы` `Jest` `Codewars` + +## Что делать + +Нужно реализовать четыре готовых набора задач на встроенные методы чисел, строк и массивов, а также логику условий и циклов, плюс решить набор задач на [Codewars](https://www.codewars.com/). + +Каждый из четырёх наборов — отдельный репозиторий с заготовками функций и Jest-тестами; задача — заставить все тесты стать зелёными. + +- [Core JS Numbers](https://github.com/rolling-scopes-school/core-js-numbers) — 37 функций: округление, преобразование чисел в строку и обратно, простые числа, тригонометрия, случайные числа и другие операции с числами. +- [Core JS Strings](https://github.com/rolling-scopes-school/core-js-strings) — 28 функций: пробелы, подстроки, палиндромы, шаблонные строки, ROT13, парсинг e-mail и другие операции со строками. +- [Core JS Arrays](https://github.com/rolling-scopes-school/core-js-arrays) — 30 функций: фильтрация, дедупликация, многомерные массивы, разбиение на чанки, сортировка и другие операции с массивами. +- [Core JS Conditions & Loops](https://github.com/rolling-scopes-school/core-js-conditions-n-loops-tasks) — 15 функций: конвертация в римские числа, спиральная матрица, поворот матрицы, сортировка и другие задачи на условия и циклы **без использования** встроенных методов `String`/`Array`/`Math`. + +Отдельно — список задач на Codewars, см. раздел «Задачи на Codewars» ниже. + +## Материалы для изучения + +- [MDN: String](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/String) +- [MDN: Number](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Number) +- [MDN: Math](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math) +- [MDN: Array](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array) +- [JavaScript.Info: Числа](https://learn.javascript.ru/number) +- [JavaScript.Info: Строки](https://learn.javascript.ru/string) +- [JavaScript.Info: Массивы](https://learn.javascript.ru/array) + +## Задачи на Codewars + +Список задач с [Codewars](https://www.codewars.com/) на числа и строки (тема «Numbers and Strings»): + +- 8 kyu [Hello World](https://www.codewars.com/kata/function-1-hello-world) +- 8 kyu [Quarter of the Year](https://www.codewars.com/kata/quarter-of-the-year) +- 8 kyu [Capitalization and Mutability](https://www.codewars.com/kata/capitalization-and-mutability) +- 8 kyu [Century From Year](https://www.codewars.com/kata/century-from-year) +- 8 kyu [Convert a Number to a String](https://www.codewars.com/kata/convert-a-number-to-a-string) +- 8 kyu [Convert a String to a Number](https://www.codewars.com/kata/convert-a-string-to-a-number) +- 8 kyu [Convert to Binary](https://www.codewars.com/kata/convert-to-binary) +- 8 kyu [Even or Odd](https://www.codewars.com/kata/even-or-odd) +- 8 kyu [Fake Binary](https://www.codewars.com/kata/fake-binary/javascript) +- 7 kyu [Largest Square Inside a Circle](https://www.codewars.com/kata/largest-square-inside-a-circle) +- 7 kyu [Number of Decimal Digits](https://www.codewars.com/kata/number-of-decimal-digits) +- 8 kyu [Opposite Number](https://www.codewars.com/kata/opposite-number) +- 7 kyu [Perimeter Sequence](https://www.codewars.com/kata/perimeter-sequence) +- 8 kyu [Remove First and Last Character](https://www.codewars.com/kata/remove-first-and-last-character) +- 8 kyu [Remove String Spaces](https://www.codewars.com/kata/remove-string-spaces) +- 7 kyu [String Ends With?](https://www.codewars.com/kata/string-ends-with) +- 8 kyu [Simple Multiplication](https://www.codewars.com/kata/simple-multiplication) +- 8 kyu [String Repeat](https://www.codewars.com/kata/string-repeat) +- 8 kyu [Student's Final Grade](https://www.codewars.com/kata/students-final-grade) +- 8 kyu [Switch It Up!](https://www.codewars.com/kata/switch-it-up) +- 8 kyu [Traffic Light](https://www.codewars.com/kata/thinkful-logic-drills-traffic-light) +- 8 kyu [Third Angle of a Triangle](https://www.codewars.com/kata/third-angle-of-a-triangle) +- 8 kyu [Transportation on Vacation](https://www.codewars.com/kata/transportation-on-vacation) +- 8 kyu [Type of Sum](https://www.codewars.com/kata/type-of-sum) +- 8 kyu [Will you make it?](https://www.codewars.com/kata/will-you-make-it) + +Решать задачи нужно прямо на сайте Codewars, под своим аккаунтом. + +## Как сдавать + +- Каждый из четырёх репозиториев сдаётся отдельно через авто-тест в [RS App](https://app.rs.school/): открыть вкладку `Auto-Test`, выбрать нужное задание (`Core JS Numbers` / `Core JS Strings` / `Core JS Arrays` / `Core JS Conditions-n-loops`) и нажать «Submit». +- Задачи на Codewars сдаются одним общим авто-тестом: вкладка `Auto-Test` → выбрать `Codewars` → указать свой никнейм на Codewars → «Submit». + +Пересдавать можно сколько угодно раз до дедлайна — каждая следующая попытка перезаписывает предыдущую. + +## Cross-check + +Не требуется — все задания проверяются автоматически. From d1b48875a48261e1f25e2836108c018dd06cfc33 Mon Sep 17 00:00:00 2001 From: OreskaG Date: Thu, 3 Sep 2026 22:27:54 +0300 Subject: [PATCH 06/13] feat(bug-hunting): update README and add cross-check criteria for tasks --- .../tasks/bug-hunting/README.md | 72 ++++- .../tasks/bug-hunting/cross-check.json | 247 ++++++++++++++++++ 2 files changed, 317 insertions(+), 2 deletions(-) create mode 100644 fullstack-engineering/tasks/bug-hunting/cross-check.json diff --git a/fullstack-engineering/tasks/bug-hunting/README.md b/fullstack-engineering/tasks/bug-hunting/README.md index 4f5bc2629..b1cdb9819 100644 --- a/fullstack-engineering/tasks/bug-hunting/README.md +++ b/fullstack-engineering/tasks/bug-hunting/README.md @@ -1,7 +1,75 @@ # Bug Hunting -> TBD — задание пока не описано. Неделя 5: готовые сайты с багами в HTML/CSS/JS — найти и исправить. См. [README.md курса](../../README.md). +## Что делать + +Перед вами готовый проект из пяти небольших страниц. Всё выглядит почти работающим, но в код специально внесли **45 багов**: часть ломает вёрстку (CSS), часть — логику (JavaScript). Ваша задача — как настоящий разработчик, который получил чужой проект с багрепортом, найти и исправить каждый баг, опираясь на описание ожидаемого поведения. + +Стартовый проект лежит в репозитории [Rss-bug-hunting](https://github.com/OreskaG/Rss-bug-hunting). Полный список багов по каждой странице (в формате «что не так → как должно быть») находится в его `README.md` — это и есть ваш багрепорт. HTML-разметка на всех страницах **корректна** и показывает, каким должен быть итог; исправлять нужно только CSS и JavaScript. + +Пять заданий с растущей сложностью: + +| # | Страница | Тип багов | Багов | +| --- | -------------------- | ---------- | ----- | +| 1 | Прайс-таблица | CSS | 8 | +| 2 | Портфолио-галерея | CSS | 7 | +| 3 | Список задач (To-Do) | JavaScript | 10 | +| 4 | Корзина | JavaScript | 10 | +| 5 | Каталог с фильтрами | JavaScript | 10 | + +## Навыки + +`HTML` `CSS` `JavaScript` `DevTools` `debugging` `чтение чужого кода` `Git` `GitHub` + +## Материалы для изучения + +### Отладка и DevTools + +- [Обзор Chrome DevTools](https://developer.chrome.com/docs/devtools/overview) — что умеет панель разработчика +- [Инспектирование и правка CSS](https://developer.chrome.com/docs/devtools/css) — как искать баги вёрстки +- [Отладка JavaScript: breakpoints](https://developer.chrome.com/docs/devtools/javascript) — пошаговое выполнение кода +- [Отладка в браузере (learn.javascript.ru)](https://learn.javascript.ru/debugging-chrome) — breakpoints и console на русском +- [Console API](https://developer.chrome.com/docs/devtools/console) — вывод и проверка значений + +### Работа с Git и GitHub + +- [Git commit convention](https://rs.school/docs/git-convention) — как называть коммиты +- [Pull Request description schema](https://rs.school/docs/mentoring/pull-request-review-process#pull-request-requirements-pr) — как оформить PR + +## Требования + +- Задание выполняется в **личном публичном форке** репозитория [Rss-bug-hunting](https://github.com/OreskaG/Rss-bug-hunting). +- Исправляйте только **CSS и JavaScript**, структуру HTML менять не нужно — она корректна и задаёт эталонный результат. +- Баги исправляются в соответствии с описанием в багрепорте (README форка). +- Ведите историю коммитов по [конвенции коммитов](https://rs.school/docs/git-convention). +- Работа проверяется в последней версии Google Chrome. + +## Как сдавать + +1. Сделайте **Fork** репозитория [Rss-bug-hunting](https://github.com/OreskaG/Rss-bug-hunting) к себе на GitHub. +2. Создайте ветку от `main` (например, `fix/bugs`) и исправляйте баги, коммитя по ходу работы. +3. Откройте **Pull Request из ветки с исправлениями в свой `main`** (не в `main` оригинального репозитория). Не мержите его — на проверку отправляется ссылка именно на этот Pull Request. +4. Задеплойте свою версию проекта, чтобы её можно было открыть по ссылке. Подойдёт любой хостинг статических страниц — например, GitHub Pages или Netlify. +5. [Оформите описание Pull Request по схеме](https://rs.school/docs/mentoring/pull-request-review-process#pull-request-requirements-pr) и добавьте в него ссылку на деплой. + +## Cross-check + +Задание проверяется через [cross-check](https://rs.school/docs/cross-check-flow). После выдачи задания, но до дедлайна зайдите в [rs app](https://app.rs.school/), выберите **Cross-Check: Submit**, в выпадающем списке выберите название задания, в поле **Solution URL** добавьте ссылку **на Pull Request** и нажмите **Submit**. ## Критерии оценки -_(TBD — модель оценивания для курса ещё не согласована, см. OPEN_QUESTIONS.md)_ +**Максимальный балл: 200** + +Каждый исправленный баг оценивается в **+5 баллов**. Всего 45 багов — по ним максимально набирается 225 баллов; это сознательный запас (~12%), который сглаживает неточности проверки. Итоговый балл всё равно ограничен сверху 200. + +Полный перечень багов с описанием «что не так → как должно быть» — в [README стартового репозитория](https://github.com/OreskaG/Rss-bug-hunting). Баллы по заданиям: + +1. Задание 1. Прайс-таблица — 8 багов: **+40** +2. Задание 2. Портфолио-галерея — 7 багов: **+35** +3. Задание 3. Список задач (To-Do) — 10 багов: **+50** +4. Задание 4. Корзина — 10 багов: **+50** +5. Задание 5. Каталог с фильтрами — 10 багов: **+50** + +### Штрафы + +- Pull Request оформлен не по схеме или в его описании нет ссылки на рабочий деплой: **-100** +- История коммитов не ведётся или коммиты не соответствуют [конвенции](https://rs.school/docs/git-convention): **-100** diff --git a/fullstack-engineering/tasks/bug-hunting/cross-check.json b/fullstack-engineering/tasks/bug-hunting/cross-check.json new file mode 100644 index 000000000..10cfdf090 --- /dev/null +++ b/fullstack-engineering/tasks/bug-hunting/cross-check.json @@ -0,0 +1,247 @@ +{ + "taskName": "Bug Hunting", + "criteria": [ + { "type": "title", "title": "Задание 1. Прайс-таблица (CSS)" }, + { + "type": "subtask", + "text": "Тарифы стоят в один ряд по горизонтали", + "max": 5 + }, + { + "type": "subtask", + "text": "Тариф «Pro» выделен рамкой толщиной 2px цвета #2563eb", + "max": 5 + }, + { + "type": "subtask", + "text": "У фич вертикальные отступы 6px и зелёный маркер-галочка ✓", + "max": 5 + }, + { + "type": "subtask", + "text": "Кнопки «Выбрать» с синим фоном #2563eb", + "max": 5 + }, + { + "type": "subtask", + "text": "Цена тёмная и контрастная (цвет #0f172a)", + "max": 5 + }, + { + "type": "subtask", + "text": "Внутренние отступы карточки: 32px сверху и снизу, 24px слева и справа", + "max": 5 + }, + { + "type": "subtask", + "text": "Кнопки «Выбрать» расположены на одной высоте у всех карточек", + "max": 5 + }, + { + "type": "subtask", + "text": "Углы скруглены на 12px, между карточками промежуток 24px", + "max": 5 + }, + + { "type": "title", "title": "Задание 2. Портфолио-галерея (CSS)" }, + { + "type": "subtask", + "text": "Карточки стоят в ряд, по 3 в строке", + "max": 5 + }, + { + "type": "subtask", + "text": "При нехватке места карточки переносятся на новую строку", + "max": 5 + }, + { "type": "subtask", "text": "Между карточками промежуток 20px", "max": 5 }, + { + "type": "subtask", + "text": "Блок галереи центрирован по горизонтали", + "max": 5 + }, + { + "type": "subtask", + "text": "Картинки без искажения, обрезаны под размер блока (высота 200px)", + "max": 5 + }, + { + "type": "subtask", + "text": "При наведении карточка плавно (0.2s) приподнимается на 8px, тень усиливается", + "max": 5 + }, + { + "type": "subtask", + "text": "Теги стоят в один горизонтальный ряд с промежутком 8px", + "max": 5 + }, + + { "type": "title", "title": "Задание 3. Список задач To-Do (JS)" }, + { + "type": "subtask", + "text": "По одиночному клику задача добавляется в список", + "max": 5 + }, + { + "type": "subtask", + "text": "Пустая строка (в том числе из пробелов) не добавляется, показывается сообщение", + "max": 5 + }, + { + "type": "subtask", + "text": "Можно добавлять любое количество задач подряд, список не ломается", + "max": 5 + }, + { + "type": "subtask", + "text": "Одиночный клик по тексту задачи зачёркивает её", + "max": 5 + }, + { + "type": "subtask", + "text": "Повторный клик убирает зачёркивание", + "max": 5 + }, + { + "type": "subtask", + "text": "Клик по «✕» убирает задачу из списка и из счётчика", + "max": 5 + }, + { + "type": "subtask", + "text": "Счётчик показывает количество невыполненных задач", + "max": 5 + }, + { + "type": "subtask", + "text": "Фильтры «Активные», «Выполненные», «Все» работают корректно", + "max": 5 + }, + { + "type": "subtask", + "text": "Список задач без дублей: элементов ровно столько, сколько добавлено", + "max": 5 + }, + { + "type": "subtask", + "text": "«Очистить выполненные» удаляет только выполненные задачи", + "max": 5 + }, + + { "type": "title", "title": "Задание 4. Корзина (JS)" }, + { + "type": "subtask", + "text": "Клик по «В корзину» добавляет товар в корзину", + "max": 5 + }, + { + "type": "subtask", + "text": "Повторное добавление того же товара увеличивает количество, а не создаёт вторую строку", + "max": 5 + }, + { + "type": "subtask", + "text": "Кнопка «+» увеличивает количество товара на 1", + "max": 5 + }, + { + "type": "subtask", + "text": "Кнопка «−» уменьшает количество на 1, но не ниже 1", + "max": 5 + }, + { + "type": "subtask", + "text": "Сумма строки равна цене товара, умноженной на его количество", + "max": 5 + }, + { + "type": "subtask", + "text": "Итог равен сумме всех строк корзины", + "max": 5 + }, + { + "type": "subtask", + "text": "Бейдж показывает суммарное количество товаров (сумму количеств)", + "max": 5 + }, + { + "type": "subtask", + "text": "Промокод SALE10 даёт скидку 10%, при других или пустом коде скидки нет", + "max": 5 + }, + { + "type": "subtask", + "text": "«Очистить корзину» удаляет все товары", + "max": 5 + }, + { + "type": "subtask", + "text": "При пустой корзине показывается «Корзина пуста», итог равен 0", + "max": 5 + }, + + { "type": "title", "title": "Задание 5. Каталог с фильтрами (JS)" }, + { + "type": "subtask", + "text": "По умолчанию, без выбранных фильтров, показаны все товары", + "max": 5 + }, + { + "type": "subtask", + "text": "После смены фильтра на странице только подходящие карточки, старые не остаются", + "max": 5 + }, + { + "type": "subtask", + "text": "Поиск не зависит от регистра букв", + "max": 5 + }, + { + "type": "subtask", + "text": "Поиск находит товар по части названия", + "max": 5 + }, + { + "type": "subtask", + "text": "Фильтр показывает только товары выбранной категории", + "max": 5 + }, + { + "type": "subtask", + "text": "«Цена ↑» сортирует по возрастанию, «Цена ↓» — по убыванию", + "max": 5 + }, + { + "type": "subtask", + "text": "«По умолчанию» возвращает товары в исходном порядке", + "max": 5 + }, + { + "type": "subtask", + "text": "Поиск, категория и сортировка действуют одновременно (комбинируются)", + "max": 5 + }, + { + "type": "subtask", + "text": "«Найдено: N» показывает количество товаров после фильтрации", + "max": 5 + }, + { + "type": "subtask", + "text": "«Сбросить фильтры» очищает поиск, сбрасывает категорию и сортировку, показывает все товары", + "max": 5 + }, + + { "type": "title", "title": "Штрафы" }, + { + "type": "penalty", + "text": "Pull Request оформлен не по схеме или в его описании нет ссылки на рабочий деплой", + "max": -100 + }, + { + "type": "penalty", + "text": "История коммитов не ведётся или коммиты не соответствуют конвенции", + "max": -100 + } + ] +} From 2ea21a0d6866964125e07ff21213f28deccfea77 Mon Sep 17 00:00:00 2001 From: OreskaG <86929232+OreskaG@users.noreply.github.com> Date: Mon, 7 Sep 2026 21:38:53 +0300 Subject: [PATCH 07/13] Remove 'Exploring JS' from recommended books --- fullstack-engineering/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/fullstack-engineering/README.md b/fullstack-engineering/README.md index 4299c7308..95dcc7fb6 100644 --- a/fullstack-engineering/README.md +++ b/fullstack-engineering/README.md @@ -152,7 +152,6 @@ ### 📚 Рекомендуемые учебники по JavaScript - [JavaScript.Info](https://learn.javascript.ru/) -- [Exploring JS](https://exploringjs.com/impatient-js/toc.html) - [You Don't Know JS Yet](https://github.com/getify/You-Dont-Know-JS) ### 💬 Где общаться и задавать вопросы? From 1e518d476b0b1fbae10738117bf6150b5a3ba584 Mon Sep 17 00:00:00 2001 From: OreskaG <86929232+OreskaG@users.noreply.github.com> Date: Mon, 7 Sep 2026 21:43:16 +0300 Subject: [PATCH 08/13] Fix formatting of test list in README Removed extra brackets from test list in README. --- fullstack-engineering/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fullstack-engineering/README.md b/fullstack-engineering/README.md index 95dcc7fb6..49247338d 100644 --- a/fullstack-engineering/README.md +++ b/fullstack-engineering/README.md @@ -45,9 +45,9 @@ - [CV Project](tasks/cv/) — собрать и задеплоить резюме через Git и GitHub Pages - Тесты: - - [[St1] RSS Test](modules/week-01/rs-school-intro.md) - - [[St1] Git test](modules/week-01/git-github.md) - - [[St1] Fundamentals of the Internet](modules/week-01/development-tools.md) + - [St1] RSS Test + - [St1] Git test + - [St1] Fundamentals of the Internet - Стек: Markdown, HTML, CSS, Git, GitHub Pages - Чему научатся: базовому процессу работы с Git, публикации проектов через GitHub Pages, а также культуре и правилам RS School From f6ea52ffd98c7afe5b129727cb2e67fb00ecbef7 Mon Sep 17 00:00:00 2001 From: OreskaG Date: Sun, 20 Sep 2026 11:16:20 +0300 Subject: [PATCH 09/13] docs(fullstack-engineering): update course structure and details for clarity --- .../fullstack-engineering.instructions.md | 6 +- .../.instructions/OPEN_QUESTIONS.md | 8 +- fullstack-engineering/README.md | 123 ++++++++++-------- 3 files changed, 74 insertions(+), 63 deletions(-) diff --git a/.github/instructions/fullstack-engineering.instructions.md b/.github/instructions/fullstack-engineering.instructions.md index 4801c6f30..d18a367a0 100644 --- a/.github/instructions/fullstack-engineering.instructions.md +++ b/.github/instructions/fullstack-engineering.instructions.md @@ -17,9 +17,9 @@ applyTo: "fullstack-engineering/**" ## Уже принятые решения (не пересматривать без явного обсуждения) -- Курс разделён на **Часть 1** (12 недель, чистый JS, без TypeScript) и **Часть 2** (TypeScript, по структуре похожа на старый Stage 2) — TypeScript строго только в Части 2. -- Язык курса — **русский**. Английский не должен быть скрытым входным барьером. -- В Часть 1 можно попасть с нулевым знанием HTML/CSS/JS, если студент готов уделять 30+ часов в неделю. +- Текущая программа организована как последовательные этапы: «Основы» (12 недель, JavaScript/TypeScript), React (12 недель), Node.js (10 недель) и финальный командный этап RS Tandem & AI SDLC (ориентировочно 6–8 недель). +- Для курса в целом не фиксируется единый язык материалов: язык и формат могут различаться между этапами и конкретными заданиями. +- На этап «Основы» можно попасть с нулевым знанием HTML/CSS/JS, если студент готов уделять 30+ часов в неделю. - AI-ассистенты и агенты явно разрешены и поощряются; использование должно быть прозрачным. - У студентов есть право влиять на курс (issue на GitHub → обсуждение → опрос → публичное решение) — это культурный принцип из VISION.md, пока не привязан к конкретной неделе/заданию. diff --git a/fullstack-engineering/.instructions/OPEN_QUESTIONS.md b/fullstack-engineering/.instructions/OPEN_QUESTIONS.md index fe7cf32d5..e0677a6d5 100644 --- a/fullstack-engineering/.instructions/OPEN_QUESTIONS.md +++ b/fullstack-engineering/.instructions/OPEN_QUESTIONS.md @@ -2,17 +2,17 @@ ## В работе / запланировано -- Где граница допустимого использования AI и как студент подтверждает, что понимает написанный с AI код — задача признана, но пока не реализована в роадмапе Части 1. Планируем добавить примерно через пару недель работы над курсом. +- Где граница допустимого использования AI и как студент подтверждает, что понимает написанный с AI код — задача признана, но пока не реализована в роадмапе этапа «Основы». Планируем добавить примерно через пару недель работы над курсом. ## Аудитория и результат - Какой результат мы обещаем на выходе: Junior Fullstack Developer или более общий Junior Software Engineer? -- Часть 1 = 12 недель (закрыто). Сколько длится Часть 2 и сколько часов в неделю она реально требует — пока не решено. +- Этап «Основы» = 12 недель (закрыто). Длительность и фактическая нагрузка остальных этапов требуют отдельного подтверждения по мере подготовки программ. ## Технический охват -- Базовый обязательный стек Части 1 закрыт роадмапом (JS, DOM, тестирование, алгоритмы и структуры данных, работа с API, свой backend). Остаётся решить: что именно на курсе — элективно (например, стек фронтенда для парного проекта недели 11–12). -- Должен ли каждый студент лично написать и frontend, и backend, или допустима специализация внутри команды? Частично отвечено: backend на неделе 10 — индивидуальный, но в парном проекте (недели 11–12) распределение зон ответственности уже допускается. +- Базовый обязательный стек этапа «Основы» закрыт текущим роадмапом (JS, TypeScript, DOM, тестирование, алгоритмы и структуры данных, работа с API, свой backend). Остаётся решить: что именно будет обязательным или элективным на следующих этапах. +- Должен ли каждый студент лично написать и frontend, и backend, или допустима специализация внутри команды? Частично отвечено: backend на неделе 11 — индивидуальный, но в командном проекте распределение зон ответственности уже допускается. ## Командная работа и сообщество diff --git a/fullstack-engineering/README.md b/fullstack-engineering/README.md index d5e5ba64f..a1d20c0cb 100644 --- a/fullstack-engineering/README.md +++ b/fullstack-engineering/README.md @@ -3,10 +3,26 @@ ## 🚀 Обзор - 📣 **Открыт для всех, кто хочет присоединиться** -- 📅 **Структура и длительность:** курс состоит из двух частей. Первая часть рассчитана на 12 недель и представлена ниже. Во второй части обучение продолжится с использованием TypeScript. Продолжительность и программа второй части будут опубликованы позднее. +- 📅 **Структура и длительность:** обучение состоит из последовательных этапов. Сейчас идёт этап «Основы» — 12 недель; его программа представлена ниже. - 📚 **Формат:** самостоятельное изучение + вебинары + парная/групповая работа + Discord + cross-check - 🤖 **AI:** AI-ассистенты разрешены, но их использование должно быть прозрачным -- 🗣️ **Язык курса:** русский + +## 🧭 Этапы обучения + +1. **Основы: JavaScript/TypeScript** — 12 недель, идёт сейчас. Каждая неделя посвящена одной теме: вёрстка, DOM, debugging, clean code, promises и async/await, TypeScript. +2. **React** — 12 недель, с менторами. Это стандартный отдельный курс RS School по React: [регистрация](https://wearecommunity.io/events/rs-react-2026q4). +3. **Node.js** — 10 недель. Адаптированная версия курса RS School по Node.js. +4. **RS Tandem & AI SDLC** — финальный командный проект продолжительностью ориентировочно 6–8 недель, с менторами. + +Параллельно всему курсу работает [AI Club](https://t.me/rs_ai_club) — факультатив для тех, кто хочет глубже изучать AI-инструменты. Для участия не обязательна подписка на платные AI-сервисы. + +### Сертификаты + +Сертификат Full Stack получают участники, которые прошли все этапы: «Основы», React, Node.js и RS Tandem, а также технические интервью. За этапы React и Node.js выдаются отдельные сертификаты, как и на обычных курсах RS School. + +У базового этапа «Основы» отдельного сертификата нет. Участники, набравшие не менее 70% от результата лучшего студента, получают приоритет при распределении ментора на следующем этапе. + +Таким образом, выпускник получает три сертификата: React, Node.js и итоговый Full Stack. ### 📝 Темы курса @@ -17,7 +33,6 @@ - Unit-тесты и основы TDD - Алгоритмы и структуры данных: стек, очередь, связный список, дерево - Работа с внешним API и асинхронные запросы -- Свой сервер: routes, middleware, аутентификация по токену - Совместная разработка в общем репозитории и парная работа над проектом --- @@ -85,24 +100,25 @@ #### 22 сентября 2026 года - Теоретические модули: - - [DOM API](modules/week-03/dom-api.md) - - [События](modules/week-03/events.md) - - [HTML-формы и валидация](modules/week-03/html-forms-validation.md) + - [CSS Grid Layout](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/css-grid) + - [Адаптивный веб-дизайн](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/responsive-web-design) + - [Позиционирование в CSS. Flexbox](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/css-positioning) + - [Медиазапросы](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/media-queries) - Видеоматериалы RS School: - - [События в JavaScript](https://www.youtube.com/watch?v=VJEpE6DaOYo) + - [Основы SCSS (Sass). Flexbox и Grid Layout](https://www.youtube.com/watch?v=MOrQRgP8kbo) - Тесты: + - [St1] Media Queries & Responsive - [St1] JS Basics - [St1] JS Types - - [St1] DOM Api - - [St1] DOM Events - - [St1] HTML Form + - [St1] JS Evolution + - [St1] CSS Grid + - [St1] CSS Positioning & Flexbox - Cross-check: - Cross-check проекта [Landing Page. Часть 1](tasks/landing-page/README-part-1.md#критерии-оценки) -- Задача **Landing Page**: - - [Общее описание задачи](tasks/landing-page/README.md) - - [Часть 2. Функциональность](tasks/landing-page/README-part-2.md) — бургер-меню, слайдер, переключение категорий, дополнительные карточки и модальное окно с выбором параметров -- **Стек**: HTML, CSS, JavaScript, DOM API -- **Чему научатся**: работе с DOM, HTML-формами и браузерными событиями, динамическому отображению данных и реализации интерактивных компонентов +- Видеоматериалы: + - [Основы Codewars](https://www.youtube.com/live/RChY6XMi6ws) +- **Стек**: HTML, CSS, JavaScript, Flexbox, Grid, медиазапросы +- **Чему научатся**: адаптивной вёрстке с помощью Flexbox, Grid и медиазапросов, а также основам JavaScript и современным возможностям языка ### Неделя 4 @@ -111,11 +127,8 @@ - Теоретические модули: - [Область видимости и функции](modules/week-04/scope-and-functions.md) - [Эволюция JavaScript](modules/week-04/javascript-evolution.md) -- Видеоматериалы RS School: - - [Основы Codewars](https://www.youtube.com/live/RChY6XMi6ws) - Тесты: - [St1] JS Scope & Functions - - [St1] JS Evolution - Практика по JavaScript: - [core-js-conditions-n-loops](https://github.com/rolling-scopes-school/core-js-conditions-n-loops-tasks) — задачи на условные конструкции и циклы - [core-js-arrays](https://github.com/rolling-scopes-school/core-js-arrays) — задачи на работу с массивами @@ -132,10 +145,8 @@ - Теоретические модули: - [Chrome DevTools](modules/week-05/chrome-devtools.md) - - [Clean Code](modules/week-05/clean-code.md) - Тесты: - [St1] DevTools Test - - [St1] Clean-code - Задача **Bug Hunting**: - [Описание задачи](tasks/bug-hunting/README.md) — найти и исправить ошибки в HTML, CSS и JavaScript на нескольких готовых веб-страницах - **Стек**: HTML, CSS, JavaScript, Chrome DevTools @@ -156,8 +167,29 @@ #### 20 октября 2026 года +- //ToDo: обновить эту неделю + - Теоретические модули: - - [Алгоритмы и структуры данных. Часть 1](modules/week-07/algorithms-data-structures-part-1.md) + - [Закрепление основ Git](modules/week-09/git-basics-reinforcement.md) + - [Линтеры, форматтеры и Husky](modules/week-09/linters-formatters-husky.md) + - [Clean Code](modules/week-05/clean-code.md) +- Тесты: + - [St1] Git & GitHub #2 + - [St1] Linters, Formatters, and Husky + - [St1] Clean-code +- Задача **Clean Code**: + - [Clean Code] +- **Стек**: JavaScript, Git, ESLint, Prettier, Husky +- **Чему научатся**: созданию браузерных игр, работе в общем репозитории, соблюдению единого стиля кода и разрешению конфликтов слияния + +### Неделя 8 + +#### 27 октября 2026 года + +- //ToDo: TypeScript + Linter, Husky, Prettier + +- Теоретические модули: + - [Алгоритмы и структуры данных. Часть 1](modules/week-07/algorithms-data-structures-part-1.md) — O-notation - [Основы объектно-ориентированного программирования](modules/week-07/oop-basics.md) - Тесты: - [St1] Test Algorithms & Data structures @@ -167,9 +199,17 @@ - **Стек**: JavaScript - **Чему научатся**: основам алгоритмов и структур данных, оценке сложности алгоритмов и применению принципов ООП при реализации структур данных -### Неделя 8 +### Неделя 9 -#### 27 октября 2026 года +#### 3 ноября 2026 года + +- //ToDo: functional programming — scope, lexical environment, context, this (call, apply, bind) + +### Неделя 10 + +#### 10 ноября 2026 года + +- //ToDo: Event Loop, Async — TypeScript - Теоретический модуль: - [Обзор клиент-серверного взаимодействия](modules/week-08/client-server-interaction.md) @@ -182,26 +222,9 @@ - **Стек**: JavaScript, Fetch API, async/await, DOM API - **Чему научатся**: основам клиент-серверного взаимодействия, асинхронной работе с сетью и обработке ошибок API -### Неделя 9 - -#### 3 ноября 2026 года - -- Теоретические модули: - - [Закрепление основ Git](modules/week-09/git-basics-reinforcement.md) - - [Линтеры, форматтеры и Husky](modules/week-09/linters-formatters-husky.md) - - [Canvas API](modules/week-09/canvas-api.md) -- Тесты: - - [St1] Git & GitHub #2 - - [St1] Linters, Formatters, and Husky - - [St1] Canvas API -- Задача **Каталог веб-игр**: - - [Каталог веб-игр](tasks/games-catalog/README.md) — общий репозиторий, каждый студент добавляет свою игру -- **Стек**: JavaScript, Canvas API, Git, ESLint, Prettier, Husky -- **Чему научатся**: созданию браузерных игр, работе в общем репозитории, соблюдению единого стиля кода и разрешению конфликтов слияния - -### Неделя 10 +### Неделя 11–12 -#### 10 ноября 2026 года +#### 17 ноября 2026 года - Теоретический модуль: - [Node.js](modules/week-10/nodejs.md) @@ -210,21 +233,9 @@ - **Стек**: Node.js (HTTP/Express), cookies, middleware - **Чему научатся**: основам Node.js, серверным маршрутам, паттерну middleware и базовой аутентификации по токену -### Неделя 11–12 - -#### 17 ноября 2026 года - -- Теоретические модули: - - [Сборщики модулей](modules/week-11-12/bundlers.md) - - [Webpack](modules/week-11-12/webpack.md) -- Тесты: - - [St1] Introduction to Bundlers - - Test Webpack Basics [RU] -- Cross-check: - - Cross-check проекта [Свой backend](tasks/own-backend/README.md#критерии-оценки) - Задача **Онлайн-магазин**: - - [Онлайн-магазин](tasks/online-store/README.md) (парное задание) — каталог, корзина, фильтры; можно опираться на сервер с недели 10 -- **Стек**: JavaScript, DOM API, сборщик модулей и UI-подход по выбору пары + - [Онлайн-магазин](tasks/online-store/README.md) (парное задание) — каталог, корзина, фильтры; можно опираться на сервер с недели 11 +- **Стек**: JavaScript, DOM API, Node.js, сборщик модулей и UI-подход по выбору пары - **Чему научатся**: настройке сборки проекта, парной разработке крупного приложения, распределению зон ответственности и проведению code review внутри пары ## 👨‍🏫 Активности менторов From e1429cbad404b06365faddfea113f92400f99396 Mon Sep 17 00:00:00 2001 From: OreskaG Date: Sun, 20 Sep 2026 12:06:26 +0300 Subject: [PATCH 10/13] docs(fullstack-engineering): update links and descriptions for course tasks and modules --- fullstack-engineering/README.md | 40 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/fullstack-engineering/README.md b/fullstack-engineering/README.md index a1d20c0cb..2f6c8da66 100644 --- a/fullstack-engineering/README.md +++ b/fullstack-engineering/README.md @@ -88,7 +88,7 @@ - [core-js-numbers](https://github.com/rolling-scopes-school/core-js-numbers) — задачи на работу с числами - [core-js-strings](https://github.com/rolling-scopes-school/core-js-strings) — задачи на работу со строками - Cross-check: - - Cross-check проекта [CV Project](tasks/cv/README.md#критерии-оценки-часть-3) + - [CV Project](tasks/cv/README.md#критерии-оценки-часть-3) - Задача **Landing Page**: - [Общее описание задачи](tasks/landing-page/README.md) - [Часть 1. Вёрстка](tasks/landing-page/README-part-1.md) — две страницы, адаптивная вёрстка, светлая и тёмная темы с сохранением выбора пользователя @@ -100,25 +100,25 @@ #### 22 сентября 2026 года - Теоретические модули: - - [CSS Grid Layout](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/css-grid) - - [Адаптивный веб-дизайн](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/responsive-web-design) - - [Позиционирование в CSS. Flexbox](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/css-positioning) - - [Медиазапросы](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/media-queries) + - [DOM API](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/dom-api) + - [События](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/events) + - [HTML-формы и валидация](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/html-form) - Видеоматериалы RS School: - - [Основы SCSS (Sass). Flexbox и Grid Layout](https://www.youtube.com/watch?v=MOrQRgP8kbo) + - [События в JavaScript](https://www.youtube.com/watch?v=VJEpE6DaOYo) - Тесты: - - [St1] Media Queries & Responsive - - [St1] JS Basics - - [St1] JS Types - - [St1] JS Evolution - - [St1] CSS Grid - - [St1] CSS Positioning & Flexbox + - [St1] [HTML Form](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/html-form) + - [St1] [DOM Api](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/dom-api) + - [St1] [DOM Events](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/events) + - [St1] [JS Basics](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/js-basics) + - [St1] [JS Types](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/js-basics) + - [St1] [JS Evolution](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/js-evolution) - Cross-check: - - Cross-check проекта [Landing Page. Часть 1](tasks/landing-page/README-part-1.md#критерии-оценки) -- Видеоматериалы: - - [Основы Codewars](https://www.youtube.com/live/RChY6XMi6ws) -- **Стек**: HTML, CSS, JavaScript, Flexbox, Grid, медиазапросы -- **Чему научатся**: адаптивной вёрстке с помощью Flexbox, Grid и медиазапросов, а также основам JavaScript и современным возможностям языка + - [Landing Page. Часть 1](tasks/landing-page/README-part-1.md#критерии-оценки) +- Задача **Landing Page**: + - [Общее описание задачи](tasks/landing-page/README.md) + - [Часть 2. Функциональность](tasks/landing-page/README-part-2.md) — бургер-меню, слайдер или карусель, переключение категорий, дополнительные карточки, модальное окно и параметры карточки +- **Стек**: HTML, CSS, JavaScript, DOM API +- **Чему научатся**: работе с DOM, HTML-формами и браузерными событиями, динамическому отображению данных и реализации интерактивных компонентов ### Неделя 4 @@ -133,7 +133,7 @@ - [core-js-conditions-n-loops](https://github.com/rolling-scopes-school/core-js-conditions-n-loops-tasks) — задачи на условные конструкции и циклы - [core-js-arrays](https://github.com/rolling-scopes-school/core-js-arrays) — задачи на работу с массивами - Cross-check: - - Cross-check проекта [Landing Page. Часть 2](tasks/landing-page/README-part-2.md#критерии-оценки) + - [Landing Page. Часть 2](tasks/landing-page/README-part-2.md#критерии-оценки) - Задача **JS Basic Methods**: - [Описание задачи](tasks/js-basic-methods/README.md) — работа с числами, строками и массивами, условными конструкциями и циклами, а также решение задач Codewars с автопроверкой в RS App - **Стек**: JavaScript @@ -157,7 +157,7 @@ #### 13 октября 2026 года - Cross-check: - - Cross-check проекта [Bug Hunting](tasks/bug-hunting/README.md#критерии-оценки) + - [Bug Hunting](tasks/bug-hunting/README.md#критерии-оценки) - Задача **Testing Intro**: - [Testing intro](tasks/testing-intro/README.md) — часть 1: unit-тесты к готовым функциям; часть 2: функции по готовым тестам (TDD) - **Стек**: JavaScript, Jest @@ -216,7 +216,7 @@ - Тест: - [St1] Client - Server interaction - Cross-check: - - Cross-check проекта [Data Structures & Algorithms](tasks/data-structures-algorithms/README.md#критерии-оценки) + - [Data Structures & Algorithms](tasks/data-structures-algorithms/README.md#критерии-оценки) - Задача **Работа с готовым Web API**: - [Работа с готовым веб API](tasks/external-api/README.md) — запросы, рендер данных, обработка ошибок и загрузки - **Стек**: JavaScript, Fetch API, async/await, DOM API From 79666e3392b70edaf85991cf756d454eafdf4dad Mon Sep 17 00:00:00 2001 From: OreskaG Date: Sun, 27 Sep 2026 14:46:37 +0300 Subject: [PATCH 11/13] docs(fullstack-engineering): update module links and add new resources for JavaScript topics --- fullstack-engineering/README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/fullstack-engineering/README.md b/fullstack-engineering/README.md index 2f6c8da66..ca948e769 100644 --- a/fullstack-engineering/README.md +++ b/fullstack-engineering/README.md @@ -125,19 +125,20 @@ #### 29 сентября 2026 года - Теоретические модули: - - [Область видимости и функции](modules/week-04/scope-and-functions.md) - - [Эволюция JavaScript](modules/week-04/javascript-evolution.md) + - [Область видимости и функции](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/functions) +- Видеоматериалы RS School: + - [Основы Codewars](https://youtube.com/live/RChY6XMi6ws?feature=share) - Тесты: - - [St1] JS Scope & Functions + - [St1] [JS Scope & Functions](https://github.com/rolling-scopes-school/tasks/tree/master/stage1/modules/functions) - Практика по JavaScript: - [core-js-conditions-n-loops](https://github.com/rolling-scopes-school/core-js-conditions-n-loops-tasks) — задачи на условные конструкции и циклы - [core-js-arrays](https://github.com/rolling-scopes-school/core-js-arrays) — задачи на работу с массивами - Cross-check: - - [Landing Page. Часть 2](tasks/landing-page/README-part-2.md#критерии-оценки) -- Задача **JS Basic Methods**: - - [Описание задачи](tasks/js-basic-methods/README.md) — работа с числами, строками и массивами, условными конструкциями и циклами, а также решение задач Codewars с автопроверкой в RS App + - [Landing Page. Часть 2](tasks/landing-page/README.md#часть-2-функциональность) +- Задачи: + - [Codejam (Eldritch Horror)](https://github.com/Luffi2539/eldritch-codejam) - **Стек**: JavaScript -- **Чему научатся**: работе с функциями и областями видимости, современными возможностями JavaScript, методами строк, чисел и массивов, условными конструкциями и циклами +- **Чему научатся**: работе с функциями и областями видимости, условными конструкциями и циклами, массивами ### Неделя 5 From 90eb55e6f1e97017c9ff1272b54bfca383e6a1b6 Mon Sep 17 00:00:00 2001 From: OreskaG Date: Mon, 28 Sep 2026 19:43:26 +0300 Subject: [PATCH 12/13] docs: update README and add Memory Game task criteria --- fullstack-engineering/README.md | 4 +- tasks/memory-game/cross-check.json | 174 +++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 tasks/memory-game/cross-check.json diff --git a/fullstack-engineering/README.md b/fullstack-engineering/README.md index ca948e769..652e79ea2 100644 --- a/fullstack-engineering/README.md +++ b/fullstack-engineering/README.md @@ -136,7 +136,7 @@ - Cross-check: - [Landing Page. Часть 2](tasks/landing-page/README.md#часть-2-функциональность) - Задачи: - - [Codejam (Eldritch Horror)](https://github.com/Luffi2539/eldritch-codejam) + - [Memory Game](https://github.com/rolling-scopes-school/tasks/tree/master/tasks/memory-game) - **Стек**: JavaScript - **Чему научатся**: работе с функциями и областями видимости, условными конструкциями и циклами, массивами @@ -148,6 +148,8 @@ - [Chrome DevTools](modules/week-05/chrome-devtools.md) - Тесты: - [St1] DevTools Test +- Cross-check: + - [Memory Game](https://github.com/rolling-scopes-school/tasks/tree/master/tasks/memory-game) - Задача **Bug Hunting**: - [Описание задачи](tasks/bug-hunting/README.md) — найти и исправить ошибки в HTML, CSS и JavaScript на нескольких готовых веб-страницах - **Стек**: HTML, CSS, JavaScript, Chrome DevTools diff --git a/tasks/memory-game/cross-check.json b/tasks/memory-game/cross-check.json new file mode 100644 index 000000000..194b5912a --- /dev/null +++ b/tasks/memory-game/cross-check.json @@ -0,0 +1,174 @@ +{ + "taskName": "Memory Game", + "criteria": [ + { + "type": "title", + "title": "Генерация разметки — 15 баллов" + }, + { + "type": "subtask", + "text": "Интерфейс создан через `document.createElement` или собственные обёртки над ним. В исходном `` есть только `