diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index dd95416..ed98222 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,3 +1,5 @@ + + ## Ссылка на задачу или issue (обязательно) @@ -5,6 +7,7 @@ ## Чек лист (обязательно) + - [ ] Код соответствует рекомендациям и требованиям проекта. - [ ] Проверил анализатор на предмет ошибок и предупреждений. - [ ] Название ПР соответствует [требованиям проекта](../tools/rfc/RFC-documentation.md). @@ -12,6 +15,7 @@ - [ ] Добавлены необходимые тесты, если требуется. ## Скриншоты (желательно) +
Показать diff --git a/README.md b/README.md index e4c722c..6966935 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,15 @@ -
# 🚀 Friflex Flutter Starter - Корпоративный шаблон -
-
- ![Flutter](https://img.shields.io/badge/Flutter-3.32.0+-02569B?style=for-the-badge&logo=flutter&logoColor=white) ![Dart](https://img.shields.io/badge/Dart-3.8.0+-0175C2?style=for-the-badge&logo=dart&logoColor=white) ![Version](https://img.shields.io/badge/Version-v0.0.1-green?style=for-the-badge) ![License](https://img.shields.io/badge/License-MIT-blue?style=for-the-badge) -**Корпоративный стартовый шаблон для разработки масштабируемых Flutter-приложений** +Корпоративный стартовый шаблон для разработки масштабируемых Flutter-приложений [📋 Документация](#-документация) • [🏗️ Архитектура](#️-архитектура) • [🚀 Быстрый старт](#-быстрый-старт) • [🔧 Конфигурация](#-конфигурация) -
- --- ## 📖 Описание проекта @@ -162,33 +156,33 @@ enum AppEnv { ### 🛠️ Установка -1. **Клонирование проекта** +#### Клонирование проекта ```bash git clone https://github.com/smmarty/friflex_starter.git cd friflex_starter ``` -2. **Установка зависимостей** +#### Установка зависимостей ```bash flutter pub get ``` -3. **Генерация файлов** +#### Генерация файлов ```bash dart run build_runner build --delete-conflicting-outputs flutter packages pub run flutter_gen ``` -4. **Запуск приложения** +#### Запуск приложения ```bash flutter run ``` -5. **Замените название пакета на ваш** +#### Замените название пакета на ваш ### 🎯 Запуск с разными окружениями @@ -263,7 +257,7 @@ dart run build_runner build --delete-conflicting-outputs | 🏗️ [RFC-projects_structure.md](./tools/rfc/RFC-projects_structure.md) | Структура проекта | | 📝 [RFC-documentation.md](./tools/rfc/RFC-documentation.md) | Правила документирования | | 🔧 [RFC-managing_generated_files.md](./tools/rfc/RFC-managing_generated_files.md) | Рекомендации по управлению сгенерированными файлами | -| 🌐 [RFC-managing_pubspec_lock.md](./tools/rfc/RFC-managing_pubspec_lock.md) | Рекомендации по управлению pubspec.lock +| 🌐 [RFC-managing_pubspec_lock.md](./tools/rfc/RFC-managing_pubspec_lock.md) | Рекомендации по управлению pubspec.lock | ## 🎯 Особенности и нюансы @@ -294,9 +288,4 @@ Copyright © 2025 Friflex LLC. Все права защищены. --- - -
- -*Разработано с любовью командой Friflex ❤️* - -
+### Разработано с любовью командой Friflex ❤️ diff --git a/tools/rfc/RFC-README.md b/tools/rfc/RFC-README.md index 13c69ca..60bd6e9 100644 --- a/tools/rfc/RFC-README.md +++ b/tools/rfc/RFC-README.md @@ -1,31 +1,37 @@ -## Рекомендованный Readme для проектов -#### Приложение [ProjectName] +# Приложение [ProjectName] ## Структура проекта - - проект архитектурно делится на три слоя: data, domain и presentation; - - все [features] реализуются в отдельных папках, с внутренним делением на слои; + +- проект архитектурно делится на три слоя: data, domain и presentation; +- все [features] реализуются в отдельных папках, с внутренним делением на слои; ## Основные пакеты и реализации (обновляется при добавлении или изменении) - - управление роутингом: [go_router](https://pub.dev/packages/go_router); - - основной state manager: [flutter_bloc](https://pub.dev/packages/flutter_bloc); - - di: ручная реализация через InheritedWidget; - - работа с ресурсами: [flutter_gen](https://pub.dev/packages/flutter_gen); - - анализатор: используем [friflex_lint_rules](https://pub.friflex.com/packages/friflex_lint_rules), с правилами написания кода от компании.; - - для хранения защищенных данных - [flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage); - - для хранения данных - [shared_preferences](https://pub.dev/packages/shared_preferences); - - для работы с API - [dio](https://pub.dev/packages/dio); + +- управление роутингом: [go_router](https://pub.dev/packages/go_router); +- основной state manager: [flutter_bloc](https://pub.dev/packages/flutter_bloc); +- di: ручная реализация через InheritedWidget; +- работа с ресурсами: [flutter_gen](https://pub.dev/packages/flutter_gen); +- анализатор: используем [friflex_lint_rules](https://pub.friflex.com/packages/friflex_lint_rules), с правилами написания кода от компании.; +- для хранения защищенных данных - [flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage); +- для хранения данных - [shared_preferences](https://pub.dev/packages/shared_preferences); +- для работы с API - [dio](https://pub.dev/packages/dio); ## Инструкция по запуску проекта - - [Инструкция по запуску проекта](./tools/rfc/RFC-build.md) + +- [Инструкция по запуску проекта](./tools/rfc/RFC-build.md) ## Стиль написания кода - - [Стиль написания кода](./*ools*/rfc/RFC-codestyle.md) + +- [Стиль написания кода](./*ools*/rfc/RFC-codestyle.md) ## Внесение изменений в код - - [Внесение изменений в код](./tools/rfc/RFC-gitflow.md) -## Структура проекта - - [Структура проекта](./tools/rfc/RFC-projects_structure.md) +- [Внесение изменений в код](./tools/rfc/RFC-gitflow.md) + +## Документация по структуре проекта + +- [Структура проекта](./tools/rfc/RFC-projects_structure.md) ## Ведение документации и комментариев в проекте - - [Ведение документации и комментариев в проекте](./tools/rfc/RFC-documentation.md) \ No newline at end of file + +- [Ведение документации и комментариев в проекте](./tools/rfc/RFC-documentation.md) diff --git a/tools/rfc/RFC-codestyle.md b/tools/rfc/RFC-codestyle.md index d5c7bde..aee969e 100644 --- a/tools/rfc/RFC-codestyle.md +++ b/tools/rfc/RFC-codestyle.md @@ -8,13 +8,16 @@ ## Именование ### Интерфейсы + Утверждены два вида объявления интерфейсов: + 1. Все интерфейсы в приложении должны начинаться с заглавной буквы "**I**". Например: **IAuthRepository**, **IProfileRepository**, **IMainRunner** и т.д. Таким образом, сразу видно, что работаешь с интерфейсом. Пример: + ```dart /// Интерфейс - **IUserRepository** abstract interface class IUserRepository {} @@ -29,6 +32,7 @@ class UserRepositoryLocal implements IUserRepository {} ``` ### Классы - Репозитории + Репозитории должны содержать в конце название источника данных (если используется мок или локальное хранилище).\ Основная реализация, не должна содержать постфикса. @@ -36,66 +40,84 @@ class UserRepositoryLocal implements IUserRepository {} Основная реализация (prod и stage окружения) - **AuthRepository** Мок (мок данные) - **AuthRepositoryMock**\ Локальное хранилище (например бд или просто имитация данных) - **AuthRepositoryLocal** - + ### Файлы + Используется snake_case. Название файла должно иметь следующую структуру: [раздел]_[тип].dart Пример: user_details_screen.dart, shop_entity.dart ### Классы + Название классов UpperCamelCase. Для создание приватных классов используем префикс _ . Название класса в конце должно содержать в себе тип. Пример: **UserEntity**, **AdultDialog** ## Методы + Название метода в начале должно содержать в себе действие(глагол): - - fetch - - put - - update - - delete и так далее +- fetch +- put +- update +- delete и так далее -Пример: +Пример: + ```dart int fetchFirstElement(){} ``` + Пример: + ```dart void updateFirstElement(){}; ``` + Название метода не должно содержать в себе And/Or и метод соответственно не должен выполнять подобную логику. ## Переменные и константы + Константы именуются также lowerCamelCase. -Пример: +Пример: + ```dart const String carItem ``` -или + +или + ```dart final userName; ``` + ## Виджеты + Виджеты именуются UpperCamelCase. В названии виджетов не должно содержаться слово widget. ### Экраны -Экраны, используемые в роутинге, именуются с постфиксом Screen. + +Экраны, используемые в роутинге, именуются с постфиксом Screen. Например, **ShopListScreen**. ### Содержимое экрана -Виджеты, отображающие содержимое экрана, именуются с постфиксом View. + +Виджеты, отображающие содержимое экрана, именуются с постфиксом View. Например, **ShopListView**. ### Глобальные виджеты -Глобальные виджеты именуются с приставкой App. + +Глобальные виджеты именуются с приставкой App. Например, **AppButton**. ## Структура класса + Объявления элементов класса должны располагаться в следующем порядке: + 1. **Constructors** - constructors - named-constructors diff --git a/tools/rfc/RFC-documentation.md b/tools/rfc/RFC-documentation.md index 13336c5..1450d27 100644 --- a/tools/rfc/RFC-documentation.md +++ b/tools/rfc/RFC-documentation.md @@ -2,25 +2,29 @@ ## Документация -### Основные правила ведения документации в проекте: +### Основные правила ведения документации в проекте + - документация оформляется над описываемым объектом с использованием '///'; - документацией необходимо покрывать все классы, конструкторы, поля, геттеры, сеттеры, методы, фабрики, все кастомные объекты; - документация должна: - - указывать на назначение объекта; - - содержать исчерпывающее описание объекта; - - быть краткой и емкой; - - быть понятной для любого разработчика. + - указывать на назначение объекта; + - содержать исчерпывающее описание объекта; + - быть краткой и емкой; + - быть понятной для любого разработчика. ## Шаблоны и примеры документации объектов -### Документация классов: +### Документация классов + ```dart /// {@template new_class} /// Класс для реализации {описание назначения и реализуемого функционала в классе}. /// {@endtemplate} class NewClass {} ``` + Пример: + ```dart /// {@template app_button} /// Класс для реализации кастомизированной кнопки. @@ -28,11 +32,12 @@ class AppButton {} ``` -### Документация конструкторов и фабрик: +### Документация конструкторов и фабрик -Если конструктор один, то достаточно указать {@macro new_class}. +Если конструктор один, то достаточно указать {@macro new_class}. {@macro new_class} дублирует на конструктор указанную в рамках описания класса документацию, поэтому описание класса должно в таком случае включать все передаваемые в конструктор параметры Если конструкторов несколько, описания должны отражать их отличия друг от друга. Фабрики описываются по такому же принципу. + ```dart ///{@macro new_class} const NewClass(); @@ -43,8 +48,10 @@ factory NewClass.fromJson(Map json) ``` -### Документация полей классов: +### Документация полей классов + В классе необходимо описывать каждое поле по отдельности. Если поле ссылается на другое поле или зависит от него, необходимо это указывать в описании. + ```dart /// Возраст пользователя. final int age; @@ -53,7 +60,8 @@ final bool isAdult; ``` -### Документация геттеров/сеттеров: +### Документация геттеров/сеттеров + ```dart /// Получения доступа к {описание данных, которые получает геттер} int get newGetter => ... @@ -62,8 +70,10 @@ set newSetter (int setterValue) => ... ``` -### Документация методов: +### Документация методов + Методы должны описывать их основное назначение. Если метод сложный, требуется указывать дополнительное описание его работы ниже через пропущенную строку. Если метод принимает какие-либо параметры, каждый параметр должен быть описан по отдельности списком с прямой ссылкой. Если метод возвращает какие-либо значения, они должны быть описаны. Желательно указать, что вернет метод в случае возникновения ошибки. + ```dart /// Метод для {описание назначения метода}. /// {описание особенностей работы метода}. @@ -73,7 +83,9 @@ ... } ``` + Пример: + ```dart /// Метод для расчета температуры. /// Принимает: @@ -88,16 +100,20 @@ ## Комментарии -### Основные правила комментирования кода в проекте: +### Основные правила комментирования кода в проекте + - комментарии оформляются над описываемым участком кода с использованием '//'; - комментировать необходимо те участки кода, которые действительно нуждаются в дополнительном описании; - комментарий не должен повторять легко читаемые участки кода -Например: +Например: + ```dart if(flag != true) // не нужно описывать как "Если значение не равно true... ``` + Например: + ```dart if(isAurora){ // Так как Аврора не может открывать WebView, @@ -107,7 +123,8 @@ ## TODO -### Основные правила создания TODO в проекте: +### Основные правила создания TODO в проекте + - TODO оформляются согласно условиям форматирования линтера с указанием имени разработчика, кто находится в контексте проблемы и сможет ее прокомментировать; - TODO необходимо оставлять на тех участках кода, которые требуют дальнейшей доработки; -- если известно, в рамках какой задачи будет доработан помечаемый участок кода, ссылку на задаче необходимо оставить в скобках. \ No newline at end of file +- если известно, в рамках какой задачи будет доработан помечаемый участок кода, ссылку на задаче необходимо оставить в скобках. diff --git a/tools/rfc/RFC-gitflow.md b/tools/rfc/RFC-gitflow.md index 648be57..e65a501 100644 --- a/tools/rfc/RFC-gitflow.md +++ b/tools/rfc/RFC-gitflow.md @@ -1,60 +1,69 @@ + # Ведение проекта в git ## Создание commits/pull-request + - язык описания PR - Русский; - описание должно отражать краткую суть изменений; - коммит/PR должен содержать: - - исчерпывающую информацию об изменениях; - - ссылку на задачу в таск-трекер; - - Перечисление deprecated-кода (если есть). + - исчерпывающую информацию об изменениях; + - ссылку на задачу в таск-трекер; + - Перечисление deprecated-кода (если есть). + ### Типы коммитов согласно convention -* **feat**: — новая функция -* **fix**: — исправление ошибок -* **refactor**: — Изменение кода, которое не исправляет ошибку и не добавляет функции (рефакторинг кода). -* **build**: — изменения, влияющие на систему сборки или внешние зависимости (примеры областей (scope): android, ios, linux и так далее). -* **docs**: — изменения только в документации -* **chore** - добавление/обновление/настройка инструментов и библиотек (пример: pubspec.yaml). -* **test**: — добавление недостающих тестов или исправление существующих тестов. -* **ci**: — изменения в файлах конфигурации и скриптах CI (примеры областей: папка CI). + +- **feat**: — новая функция + +- **fix**: — исправление ошибок +- **refactor**: — Изменение кода, которое не исправляет ошибку и не добавляет функции (рефакторинг кода). +- **build**: — изменения, влияющие на систему сборки или внешние зависимости (примеры областей (scope): android, ios, linux и так далее). +- **docs**: — изменения только в документации +- **chore** - добавление/обновление/настройка инструментов и библиотек (пример: pubspec.yaml). +- **test**: — добавление недостающих тестов или исправление существующих тестов. +- **ci**: — изменения в файлах конфигурации и скриптах CI (примеры областей: папка CI). ### Правила именования веток Имена веток должны соответствовать convention, чтобы обеспечить консистентность и читаемость. -- Ветки feature должны начинаться с `feat/`. -- Ветки hotfix должны начинаться с `fix/` и так далее -- Используйте номер задачи из таск-трекера в имени ветки. -- Добавьте краткое описание задачи, используя snake_case или kebab-case. +- Ветки feature должны начинаться с `feat/`. +- Ветки hotfix должны начинаться с `fix/` и так далее +- Используйте номер задачи из таск-трекера в имени ветки. +- Добавьте краткое описание задачи, используя snake_case или kebab-case. Пример: -* `feat/PRIME-123_authentication` -* `fix/PRIME-456_typo_in_button` -* `fix/PRIME-456-typo-in-button` +- `feat/PRIME-123_authentication` +- `fix/PRIME-456_typo_in_button` +- `fix/PRIME-456-typo-in-button` ## Схема разработки новой features -![](./tools/res/images/developing.jpg) + +![Схема разработки новой features](./tools/res/images/developing.jpg) ## Создание релиза -![](./tools/res/images/release.jpg) + +![Схема создания релиза](./tools/res/images/release.jpg) ### Добавление новых features - - создаем ветку feat/(уникальный номер задачи) (название feature), -Пример: PRIME-17 Добавить_локальный_репозиторий; - - вносим изменения; - - делаем коммит только на то, что касается изменений связанных с этой задачей; - - по завершению задачи - создаем Pull Request с названием по правилам https://commitlint.io/. - Пример: feat(app,di,auth,scripts,pubspec): PRIME-17 Добавить локальный репозиторий. + +- создаем ветку feat/(уникальный номер задачи) (название feature), +Пример: **PRIME-17 Добавить_локальный_репозиторий**; +- вносим изменения; +- делаем коммит только на то, что касается изменений связанных с этой задачей; +- по завершению задачи - создаем Pull Request с названием по правилам . + Пример: **feat(app,di,auth,scripts,pubspec): PRIME-17 Добавить локальный репозиторий**. Где, PRIME- это обязательный префикс(с помощью него автоматически подтягивается ссылка на задачу), число 17 это уникальный номер задачи из трекера. В описание к PR добавляем ссылку на задачу и описание внесенных изменений, и пояснения(если требуется); - - после завершения CodeReview создаем squash commit в ветку main (название коммит(а), должно быть такое же как название pull request) ; - - после того как ветка с новой feature попало в main - удаляем ветку; +- после завершения CodeReview создаем squash commit в ветку main (название коммит(а), должно быть такое же как название pull request) ; +- после того как ветка с новой feature попало в main - удаляем ветку; ### Создание release - - создаем ветку из main (release/release_0.0.1+1); - - добавляем в changelog.md описание изменений в этой версии (обычно это список коммитов, от предыдущей версии): - - делаем сборки, отправляем на тестирование; - - получаем баг-лист от тестировщиков, делаем фиксы; - - отправляем на следующий раунд тестирования и.т.д; - - после проверки и получения разрешение от другого разработчика - создаем tag c номером версии (0.0.1+1), создаем релиз, фиксируем версию и squash commit в ветку main и development; - - после того как release попал в main - удаляем ветку; + +- создаем ветку из main (release/release_0.0.1+1); +- добавляем в changelog.md описание изменений в этой версии (обычно это список коммитов, от предыдущей версии): +- делаем сборки, отправляем на тестирование; +- получаем баг-лист от тестировщиков, делаем фиксы; +- отправляем на следующий раунд тестирования и.т.д; +- после проверки и получения разрешение от другого разработчика - создаем tag c номером версии (0.0.1+1), создаем релиз, фиксируем версию и squash commit в ветку main и development; +- после того как release попал в main - удаляем ветку; diff --git a/tools/rfc/RFC-managing_generated_files.md b/tools/rfc/RFC-managing_generated_files.md index cdb2f5f..f1102da 100644 --- a/tools/rfc/RFC-managing_generated_files.md +++ b/tools/rfc/RFC-managing_generated_files.md @@ -1,30 +1,30 @@ -### Управление сгенерированными файлами +# Управление сгенерированными файлами На проекте встречаются файлы, автоматически создаваемые инструментами генерации кода -(например, файлы с расширениями *.g.dart, *.freezed.dart, -а также файлы, связанные с protobuf и другими генераторами кода). +(например, файлы с расширениями *.g.dart,*.freezed.dart, +а также файлы, связанные с protobuf и другими генераторами кода). Необходимость контролировать такие файлы в репозитории вызывает ряд обсуждений. См [issue](https://github.com/smmarty/flutter_team/issues/22). -### Проблемы включения сгенерированных файлов в репозиторий +## Проблемы включения сгенерированных файлов в репозиторий - 1. Частые изменения. Сгенерированные файлы могут автоматически обновляться даже при отсутствии изменений в исходном коде, что приводит к ненужным изменениям в репозитории. - 2. Конфликты при слиянии веток. Различия в таких файлах могут вызывать конфликты, которые не связаны с реальными изменениями, усложняя процесс работы над кодом. - 3. Усложнение кода при проверке. Изменения в автоматически сгенерированных файлах попадают в PR, затрудняя код-ревью. - 4. Недостоверность содержимого main. Нет гарантии, что в основной ветке всегда будут корректные версии сгенерированных файлов. + 1. Частые изменения. Сгенерированные файлы могут автоматически обновляться даже при отсутствии изменений в исходном коде, что приводит к ненужным изменениям в репозитории. + 2. Конфликты при слиянии веток. Различия в таких файлах могут вызывать конфликты, которые не связаны с реальными изменениями, усложняя процесс работы над кодом. + 3. Усложнение кода при проверке. Изменения в автоматически сгенерированных файлах попадают в PR, затрудняя код-ревью. + 4. Недостоверность содержимого main. Нет гарантии, что в основной ветке всегда будут корректные версии сгенерированных файлов. -### Проблемы при добавлении сгенерированных файлов в .gitignore +## Проблемы при добавлении сгенерированных файлов в .gitignore - 1. Необходимость предварительной генерации. При добавлении таких файлов в .gitignore для проверки кода в пайплайне необходимо добавлять этап генерации при каждом изменении в PR. + 1. Необходимость предварительной генерации. При добавлении таких файлов в .gitignore для проверки кода в пайплайне необходимо добавлять этап генерации при каждом изменении в PR. Это критично на крупных проектах, так как генерация файлов может занимать несколько минут. - 2. Неудобства для разработчиков. Разработчикам потребуется вручную генерировать файлы на локальной машине при каждом чекауте. - 3. Неактуальный код в main. Основная ветка без предварительно сгенерированных файлов станет неработоспособной, а сборка потребует добавления этапа генерации, что увеличит время и нагрузку на серверы. + 2. Неудобства для разработчиков. Разработчикам потребуется вручную генерировать файлы на локальной машине при каждом чекауте. + 3. Неактуальный код в main. Основная ветка без предварительно сгенерированных файлов станет неработоспособной, а сборка потребует добавления этапа генерации, что увеличит время и нагрузку на серверы. -### Рекомендации: +## Рекомендации - 1. Оставлять сгенерированные файлы в репозитории. + 1. Оставлять сгенерированные файлы в репозитории. Это позволит сохранить работоспособность основного кода без необходимости постоянной генерации файлов на всех этапах. При этом рекомендуется: - - Периодически актуализировать файлы в основных ветках; - - Контролировать конфликты при слиянии веток и исключать ненужные изменения в этих файлах. - 2. Обучение команды. Важно информировать команду о причинах хранения сгенерированных файлов в репозитории и о правилах работы с ними. \ No newline at end of file + - Периодически актуализировать файлы в основных ветках; + - Контролировать конфликты при слиянии веток и исключать ненужные изменения в этих файлах. + 2. Обучение команды. Важно информировать команду о причинах хранения сгенерированных файлов в репозитории и о правилах работы с ними. diff --git a/tools/rfc/RFC-managing_pubspec_lock.md b/tools/rfc/RFC-managing_pubspec_lock.md index aa6e159..7df0393 100644 --- a/tools/rfc/RFC-managing_pubspec_lock.md +++ b/tools/rfc/RFC-managing_pubspec_lock.md @@ -1,25 +1,25 @@ # Управление файлом pubspec.lock На проекте возникает необходимость определить стратегию работы с файлом pubspec.lock. -Данный файл может либо храниться в репозитории, либо быть добавлен в .gitignore. +Данный файл может либо храниться в репозитории, либо быть добавлен в .gitignore. Оба варианта имеют свои преимущества и недостатки, которые следует учесть. См [issue](https://github.com/smmarty/flutter_team/issues/20) -#### Аргументы за хранение pubspec.lock - - 1. Повторяемость сборки. Файл фиксирует конкретные версии зависимостей, обеспечивая единообразие версий для всех разработчиков и сред сборки. - 2. Избежание неожиданных изменений. Новые версии зависимостей могут внести изменения, способные нарушить сборку или логику приложения. Наличие pubspec.lock позволяет контролировать изменения и избегать неожиданных обновлений. - 3. Стабильность CI/CD. Зафиксированные версии зависимостей способствуют стабильным сборкам и тестам в CI-процессах. - 4. Рекомендации Dart. Dart рекомендует хранить pubspec.lock в репозитории для приложений, чтобы обеспечить стабильность окружения. (См. документацию.) +## Аргументы за хранение pubspec.lock -#### Аргументы против хранения pubspec.lock + 1. Повторяемость сборки. Файл фиксирует конкретные версии зависимостей, обеспечивая единообразие версий для всех разработчиков и сред сборки. + 2. Избежание неожиданных изменений. Новые версии зависимостей могут внести изменения, способные нарушить сборку или логику приложения. Наличие pubspec.lock позволяет контролировать изменения и избегать неожиданных обновлений. + 3. Стабильность CI/CD. Зафиксированные версии зависимостей способствуют стабильным сборкам и тестам в CI-процессах. + 4. Рекомендации Dart. Dart рекомендует хранить pubspec.lock в репозитории для приложений, чтобы обеспечить стабильность окружения. (См. документацию.) - 1. Частые изменения. pubspec.lock обновляется при каждом изменении зависимостей, что увеличивает количество коммитов и PR, связанных только с обновлением зависимостей. +## Аргументы против хранения pubspec.lock -### Рекомендации: + 1. Частые изменения. pubspec.lock обновляется при каждом изменении зависимостей, что увеличивает количество коммитов и PR, связанных только с обновлением зависимостей. - 1. ХРАНИТЬ pubspec.lock для ПРИЛОЖЕНИЙ. - 2. НЕ ХРАНИТЬ pubspec.lock ДЛЯ ПАКЕТОВ. - 3. Решение для переключаемых зависимостей (GMS/HMS). - При изменении зависимостей, таких как GMS/HMS, может возникать несовместимость версий. Flutter пока не поддерживает флаворы на уровне зависимостей pubspec (см. [Flutter issue #46979](https://github.com/flutter/flutter/issues/46979)), +## Рекомендации + + 1. ХРАНИТЬ pubspec.lock для ПРИЛОЖЕНИЙ. + 2. НЕ ХРАНИТЬ pubspec.lock ДЛЯ ПАКЕТОВ. + 3. Решение для переключаемых зависимостей (GMS/HMS). + При изменении зависимостей, таких как GMS/HMS, может возникать несовместимость версий. Flutter пока не поддерживает флаворы на уровне зависимостей pubspec (см. [Flutter issue #46979](https://github.com/flutter/flutter/issues/46979)), поэтому рекомендуем хранить по дефолту GMS pubspec.lock как базовый. diff --git a/tools/rfc/RFC-projects_structure.md b/tools/rfc/RFC-projects_structure.md index f2cf9fa..5306c87 100644 --- a/tools/rfc/RFC-projects_structure.md +++ b/tools/rfc/RFC-projects_structure.md @@ -11,25 +11,24 @@ - **/ios** - папка, содержащая нативный код для IOS - **/env** - папка, с внешними переменными окружения - **/lib** - код на Dart, Flutter-приложение - - **/app** - содержит основные настройки нашего приложения - - **/impls** - реализация интерфейсов - - **/interfaces** - объявление интерфейсов - - **/data** - общие поставщики данных - - **/domain** - общий слой - - **/presentation** - общий слой - - **/di** - файлы конфигурации зависимостей. - - **/routing** - все, что касается роутинга - - **/features** - фичи приложения, для каждой фичи создается отдельная папка - - **/feature_name** - подробнее см в разделе Структура feature папок - - **/data** - - **/domain** - - **/presentation** - - **/gen** - для сгенерированных файлов - - **/targets** - таргеты для сборок - - **/prod.dart** - сборка для prod - - **/dev.dart** - сборка разработки на моковых репозиториях - - **/stage.dart** - сборка для stage окружения - + - **/app** - содержит основные настройки нашего приложения + - **/impls** - реализация интерфейсов + - **/interfaces** - объявление интерфейсов + - **/data** - общие поставщики данных + - **/domain** - общий слой + - **/presentation** - общий слой + - **/di** - файлы конфигурации зависимостей. + - **/routing** - все, что касается роутинга + - **/features** - фичи приложения, для каждой фичи создается отдельная папка + - **/feature_name** - подробнее см в разделе Структура feature папок + - **/data** + - **/domain** + - **/presentation** + - **/gen** - для сгенерированных файлов + - **/targets** - таргеты для сборок + - **/prod.dart** - сборка для prod + - **/dev.dart** - сборка разработки на моковых репозиториях + - **/stage.dart** - сборка для stage окружения ## Пример структуры feature папок @@ -44,32 +43,38 @@ - **/presentation** - слой представления - **/screens** - все экраны должны заканчиваться на Screen, например UserProfileScreen. - **/components** - виджеты, которые необходимы для работы в presentation слое. Например: SuperButton, AppTextFields итд. -# Пояснение к структуре feature папок -## Data (слой данных) Этот слой является поставщиком данных. - - Repository - сущность, которая реализует внутри себя предоставление данных. Должен реализовывать какой либо интерфейс репозитория из domain слоя. - - DTO - Dto(Data Transfer Object) модели, и модели с которыми происходит работа в data слое. Например: UserDto; +## Пояснение к структуре feature папок -## Domain (слой бизнес логики) - - Entity - должны быть в максимально удобном виде для работы внутри Domain и Presentation. Например: UserEntity, ShopEntity; - - State - управления состоянием - state manager - - Service - различные сервисы, для выполнения различных задач. - - interfaces - интерфейсы репозиториев, которые используются в domain слое. +### Data (слой данных) Этот слой является поставщиком данных -## Presentation (слой представления) - - сomponents - widget'ы которые реализуют работу какого либо визуального компонента(Buttons,TextFields,Lists, итд). Например: ShopList, RateButton. Модальные окна. - - screens - widget'ы которые представляют собой экран приложения. Например: UserInfoScreen. +- Repository - сущность, которая реализует внутри себя предоставление данных. Должен реализовывать какой либо интерфейс репозитория из domain слоя. +- DTO - Dto(Data Transfer Object) модели, и модели с которыми происходит работа в data слое. Например: UserDto; -# Основные правила общения объектов между папками +### Domain (слой бизнес логики) -## В рамках всего приложения - - объекты внутри фичи должны быть инкапсулированы и не могут использоваться в других feature; - - если есть необходимость использовать объект в нескольких feature, его нужно вынести в папку app и использовать как глобальный для всего приложения; - - сервис, который должен быть использован в нескольких feature, создается как отдельная feature; - - если создаваемый сервис является платформно-зависимым, его необходимо выносить в app_services. В приложении должен быть только интерфейс. +- Entity - должны быть в максимально удобном виде для работы внутри Domain и Presentation. Например: UserEntity, ShopEntity; +- State - управления состоянием - state manager +- Service - различные сервисы, для выполнения различных задач. +- interfaces - интерфейсы репозиториев, которые используются в domain слое. -## В рамках одной feature - - объекты data слоя не должны ничего знать про объекты слоя presentation. Имеют доступ к объектам entity из domain слоя для преобразования DTO в Entity ; - - объекты domain слоя не должны ничего знать про объекты слоя data, используемый экземпляр репозитория передается в объекты domain слоя через интерфейс репозитория, расположенного в этом же domain слое; - - объекты domain слоя не должны ничего знать про слой presentation, не должны использовать компоненты библиотек ui, material, cupertino, widget и прочих, не должны использовать context; - - объекты presentation слоя не должны ничего знать про объекты слоя data, все взаимодействия непосредственно через объекты слоя domain. \ No newline at end of file +### Presentation (слой представления) + +- сomponents - widget'ы которые реализуют работу какого либо визуального компонента(Buttons,TextFields,Lists, итд). Например: ShopList, RateButton. Модальные окна. +- screens - widget'ы которые представляют собой экран приложения. Например: UserInfoScreen. + +## Основные правила общения объектов между папками + +### В рамках всего приложения + +- объекты внутри фичи должны быть инкапсулированы и не могут использоваться в других feature; +- если есть необходимость использовать объект в нескольких feature, его нужно вынести в папку app и использовать как глобальный для всего приложения; +- сервис, который должен быть использован в нескольких feature, создается как отдельная feature; +- если создаваемый сервис является платформно-зависимым, его необходимо выносить в app_services. В приложении должен быть только интерфейс. + +### В рамках одной feature + +- объекты data слоя не должны ничего знать про объекты слоя presentation. Имеют доступ к объектам entity из domain слоя для преобразования DTO в Entity ; +- объекты domain слоя не должны ничего знать про объекты слоя data, используемый экземпляр репозитория передается в объекты domain слоя через интерфейс репозитория, расположенного в этом же domain слое; +- объекты domain слоя не должны ничего знать про слой presentation, не должны использовать компоненты библиотек ui, material, cupertino, widget и прочих, не должны использовать context; +- объекты presentation слоя не должны ничего знать про объекты слоя data, все взаимодействия непосредственно через объекты слоя domain.