maxsim-flutter 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +21 -0
  3. package/README.md +445 -0
  4. package/claude-plugin/.claude-plugin/plugin.json +46 -0
  5. package/claude-plugin/agents/flutter-setup-agent.md +54 -0
  6. package/claude-plugin/commands/flutter-add.md +32 -0
  7. package/claude-plugin/commands/flutter-create.md +28 -0
  8. package/claude-plugin/commands/flutter-migrate.md +28 -0
  9. package/claude-plugin/skills/flutter-scaffolding/SKILL.md +109 -0
  10. package/dist/claude-setup/agent-writer.d.ts +21 -0
  11. package/dist/claude-setup/agent-writer.d.ts.map +1 -0
  12. package/dist/claude-setup/agent-writer.js +365 -0
  13. package/dist/claude-setup/agent-writer.js.map +1 -0
  14. package/dist/claude-setup/claude-md-generator.d.ts +7 -0
  15. package/dist/claude-setup/claude-md-generator.d.ts.map +1 -0
  16. package/dist/claude-setup/claude-md-generator.js +428 -0
  17. package/dist/claude-setup/claude-md-generator.js.map +1 -0
  18. package/dist/claude-setup/commands-writer.d.ts +7 -0
  19. package/dist/claude-setup/commands-writer.d.ts.map +1 -0
  20. package/dist/claude-setup/commands-writer.js +303 -0
  21. package/dist/claude-setup/commands-writer.js.map +1 -0
  22. package/dist/claude-setup/hooks-writer.d.ts +3 -0
  23. package/dist/claude-setup/hooks-writer.d.ts.map +1 -0
  24. package/dist/claude-setup/hooks-writer.js +34 -0
  25. package/dist/claude-setup/hooks-writer.js.map +1 -0
  26. package/dist/claude-setup/index.d.ts +10 -0
  27. package/dist/claude-setup/index.d.ts.map +1 -0
  28. package/dist/claude-setup/index.js +9 -0
  29. package/dist/claude-setup/index.js.map +1 -0
  30. package/dist/claude-setup/mcp-config-writer.d.ts +3 -0
  31. package/dist/claude-setup/mcp-config-writer.d.ts.map +1 -0
  32. package/dist/claude-setup/mcp-config-writer.js +42 -0
  33. package/dist/claude-setup/mcp-config-writer.js.map +1 -0
  34. package/dist/claude-setup/plugin-assembler.d.ts +2 -0
  35. package/dist/claude-setup/plugin-assembler.d.ts.map +1 -0
  36. package/dist/claude-setup/plugin-assembler.js +3 -0
  37. package/dist/claude-setup/plugin-assembler.js.map +1 -0
  38. package/dist/claude-setup/prd-generator.d.ts +10 -0
  39. package/dist/claude-setup/prd-generator.d.ts.map +1 -0
  40. package/dist/claude-setup/prd-generator.js +295 -0
  41. package/dist/claude-setup/prd-generator.js.map +1 -0
  42. package/dist/claude-setup/setup-orchestrator.d.ts +11 -0
  43. package/dist/claude-setup/setup-orchestrator.d.ts.map +1 -0
  44. package/dist/claude-setup/setup-orchestrator.js +46 -0
  45. package/dist/claude-setup/setup-orchestrator.js.map +1 -0
  46. package/dist/claude-setup/skill-writer.d.ts +3 -0
  47. package/dist/claude-setup/skill-writer.d.ts.map +1 -0
  48. package/dist/claude-setup/skill-writer.js +256 -0
  49. package/dist/claude-setup/skill-writer.js.map +1 -0
  50. package/dist/cli/commands/add.d.ts +16 -0
  51. package/dist/cli/commands/add.d.ts.map +1 -0
  52. package/dist/cli/commands/add.js +414 -0
  53. package/dist/cli/commands/add.js.map +1 -0
  54. package/dist/cli/commands/create.d.ts +3 -0
  55. package/dist/cli/commands/create.d.ts.map +1 -0
  56. package/dist/cli/commands/create.js +161 -0
  57. package/dist/cli/commands/create.js.map +1 -0
  58. package/dist/cli/commands/list.d.ts +12 -0
  59. package/dist/cli/commands/list.d.ts.map +1 -0
  60. package/dist/cli/commands/list.js +148 -0
  61. package/dist/cli/commands/list.js.map +1 -0
  62. package/dist/cli/commands/migrate.d.ts +3 -0
  63. package/dist/cli/commands/migrate.d.ts.map +1 -0
  64. package/dist/cli/commands/migrate.js +332 -0
  65. package/dist/cli/commands/migrate.js.map +1 -0
  66. package/dist/cli/index.d.ts +3 -0
  67. package/dist/cli/index.d.ts.map +1 -0
  68. package/dist/cli/index.js +34 -0
  69. package/dist/cli/index.js.map +1 -0
  70. package/dist/cli/ui/prompts.d.ts +9 -0
  71. package/dist/cli/ui/prompts.d.ts.map +1 -0
  72. package/dist/cli/ui/prompts.js +74 -0
  73. package/dist/cli/ui/prompts.js.map +1 -0
  74. package/dist/cli/ui/spinner.d.ts +2 -0
  75. package/dist/cli/ui/spinner.d.ts.map +1 -0
  76. package/dist/cli/ui/spinner.js +5 -0
  77. package/dist/cli/ui/spinner.js.map +1 -0
  78. package/dist/cli/version-check.d.ts +7 -0
  79. package/dist/cli/version-check.d.ts.map +1 -0
  80. package/dist/cli/version-check.js +92 -0
  81. package/dist/cli/version-check.js.map +1 -0
  82. package/dist/core/config/defaults.d.ts +3 -0
  83. package/dist/core/config/defaults.d.ts.map +1 -0
  84. package/dist/core/config/defaults.js +21 -0
  85. package/dist/core/config/defaults.js.map +1 -0
  86. package/dist/core/config/loader.d.ts +4 -0
  87. package/dist/core/config/loader.d.ts.map +1 -0
  88. package/dist/core/config/loader.js +38 -0
  89. package/dist/core/config/loader.js.map +1 -0
  90. package/dist/core/config/schema.d.ts +406 -0
  91. package/dist/core/config/schema.d.ts.map +1 -0
  92. package/dist/core/config/schema.js +119 -0
  93. package/dist/core/config/schema.js.map +1 -0
  94. package/dist/core/context.d.ts +57 -0
  95. package/dist/core/context.d.ts.map +1 -0
  96. package/dist/core/context.js +99 -0
  97. package/dist/core/context.js.map +1 -0
  98. package/dist/core/detector.d.ts +28 -0
  99. package/dist/core/detector.d.ts.map +1 -0
  100. package/dist/core/detector.js +200 -0
  101. package/dist/core/detector.js.map +1 -0
  102. package/dist/core/validator.d.ts +7 -0
  103. package/dist/core/validator.d.ts.map +1 -0
  104. package/dist/core/validator.js +35 -0
  105. package/dist/core/validator.js.map +1 -0
  106. package/dist/index.d.ts +21 -0
  107. package/dist/index.d.ts.map +1 -0
  108. package/dist/index.js +14 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/modules/composer.d.ts +50 -0
  111. package/dist/modules/composer.d.ts.map +1 -0
  112. package/dist/modules/composer.js +122 -0
  113. package/dist/modules/composer.js.map +1 -0
  114. package/dist/modules/definitions/analytics/module.d.ts +7 -0
  115. package/dist/modules/definitions/analytics/module.d.ts.map +1 -0
  116. package/dist/modules/definitions/analytics/module.js +28 -0
  117. package/dist/modules/definitions/analytics/module.js.map +1 -0
  118. package/dist/modules/definitions/api/module.d.ts +7 -0
  119. package/dist/modules/definitions/api/module.d.ts.map +1 -0
  120. package/dist/modules/definitions/api/module.js +41 -0
  121. package/dist/modules/definitions/api/module.js.map +1 -0
  122. package/dist/modules/definitions/auth/module.d.ts +7 -0
  123. package/dist/modules/definitions/auth/module.d.ts.map +1 -0
  124. package/dist/modules/definitions/auth/module.js +53 -0
  125. package/dist/modules/definitions/auth/module.js.map +1 -0
  126. package/dist/modules/definitions/cicd/module.d.ts +7 -0
  127. package/dist/modules/definitions/cicd/module.d.ts.map +1 -0
  128. package/dist/modules/definitions/cicd/module.js +34 -0
  129. package/dist/modules/definitions/cicd/module.js.map +1 -0
  130. package/dist/modules/definitions/core/module.d.ts +7 -0
  131. package/dist/modules/definitions/core/module.d.ts.map +1 -0
  132. package/dist/modules/definitions/core/module.js +31 -0
  133. package/dist/modules/definitions/core/module.js.map +1 -0
  134. package/dist/modules/definitions/database/module.d.ts +8 -0
  135. package/dist/modules/definitions/database/module.d.ts.map +1 -0
  136. package/dist/modules/definitions/database/module.js +47 -0
  137. package/dist/modules/definitions/database/module.js.map +1 -0
  138. package/dist/modules/definitions/deep-linking/module.d.ts +7 -0
  139. package/dist/modules/definitions/deep-linking/module.d.ts.map +1 -0
  140. package/dist/modules/definitions/deep-linking/module.js +48 -0
  141. package/dist/modules/definitions/deep-linking/module.js.map +1 -0
  142. package/dist/modules/definitions/i18n/module.d.ts +7 -0
  143. package/dist/modules/definitions/i18n/module.d.ts.map +1 -0
  144. package/dist/modules/definitions/i18n/module.js +37 -0
  145. package/dist/modules/definitions/i18n/module.js.map +1 -0
  146. package/dist/modules/definitions/push/module.d.ts +7 -0
  147. package/dist/modules/definitions/push/module.d.ts.map +1 -0
  148. package/dist/modules/definitions/push/module.js +40 -0
  149. package/dist/modules/definitions/push/module.js.map +1 -0
  150. package/dist/modules/definitions/theme/module.d.ts +7 -0
  151. package/dist/modules/definitions/theme/module.d.ts.map +1 -0
  152. package/dist/modules/definitions/theme/module.js +42 -0
  153. package/dist/modules/definitions/theme/module.js.map +1 -0
  154. package/dist/modules/registry.d.ts +50 -0
  155. package/dist/modules/registry.d.ts.map +1 -0
  156. package/dist/modules/registry.js +104 -0
  157. package/dist/modules/registry.js.map +1 -0
  158. package/dist/modules/resolver.d.ts +42 -0
  159. package/dist/modules/resolver.d.ts.map +1 -0
  160. package/dist/modules/resolver.js +140 -0
  161. package/dist/modules/resolver.js.map +1 -0
  162. package/dist/ralph/prd-generator.d.ts +2 -0
  163. package/dist/ralph/prd-generator.d.ts.map +1 -0
  164. package/dist/ralph/prd-generator.js +3 -0
  165. package/dist/ralph/prd-generator.js.map +1 -0
  166. package/dist/ralph/ralph-converter.d.ts +2 -0
  167. package/dist/ralph/ralph-converter.d.ts.map +1 -0
  168. package/dist/ralph/ralph-converter.js +3 -0
  169. package/dist/ralph/ralph-converter.js.map +1 -0
  170. package/dist/ralph/story-sizer.d.ts +2 -0
  171. package/dist/ralph/story-sizer.d.ts.map +1 -0
  172. package/dist/ralph/story-sizer.js +3 -0
  173. package/dist/ralph/story-sizer.js.map +1 -0
  174. package/dist/scaffold/engine.d.ts +40 -0
  175. package/dist/scaffold/engine.d.ts.map +1 -0
  176. package/dist/scaffold/engine.js +233 -0
  177. package/dist/scaffold/engine.js.map +1 -0
  178. package/dist/scaffold/file-writer.d.ts +22 -0
  179. package/dist/scaffold/file-writer.d.ts.map +1 -0
  180. package/dist/scaffold/file-writer.js +68 -0
  181. package/dist/scaffold/file-writer.js.map +1 -0
  182. package/dist/scaffold/post-processors/build-runner.d.ts +2 -0
  183. package/dist/scaffold/post-processors/build-runner.d.ts.map +1 -0
  184. package/dist/scaffold/post-processors/build-runner.js +5 -0
  185. package/dist/scaffold/post-processors/build-runner.js.map +1 -0
  186. package/dist/scaffold/post-processors/dart-format.d.ts +2 -0
  187. package/dist/scaffold/post-processors/dart-format.d.ts.map +1 -0
  188. package/dist/scaffold/post-processors/dart-format.js +5 -0
  189. package/dist/scaffold/post-processors/dart-format.js.map +1 -0
  190. package/dist/scaffold/post-processors/flutter-pub-get.d.ts +2 -0
  191. package/dist/scaffold/post-processors/flutter-pub-get.d.ts.map +1 -0
  192. package/dist/scaffold/post-processors/flutter-pub-get.js +5 -0
  193. package/dist/scaffold/post-processors/flutter-pub-get.js.map +1 -0
  194. package/dist/scaffold/renderer.d.ts +20 -0
  195. package/dist/scaffold/renderer.d.ts.map +1 -0
  196. package/dist/scaffold/renderer.js +75 -0
  197. package/dist/scaffold/renderer.js.map +1 -0
  198. package/dist/scaffold/template-helpers.d.ts +25 -0
  199. package/dist/scaffold/template-helpers.d.ts.map +1 -0
  200. package/dist/scaffold/template-helpers.js +115 -0
  201. package/dist/scaffold/template-helpers.js.map +1 -0
  202. package/dist/types/config.d.ts +4 -0
  203. package/dist/types/config.d.ts.map +1 -0
  204. package/dist/types/config.js +2 -0
  205. package/dist/types/config.js.map +1 -0
  206. package/dist/types/module.d.ts +85 -0
  207. package/dist/types/module.d.ts.map +1 -0
  208. package/dist/types/module.js +2 -0
  209. package/dist/types/module.js.map +1 -0
  210. package/dist/types/project.d.ts +13 -0
  211. package/dist/types/project.d.ts.map +1 -0
  212. package/dist/types/project.js +2 -0
  213. package/dist/types/project.js.map +1 -0
  214. package/package.json +80 -0
  215. package/templates/core/analysis_options.yaml.hbs +21 -0
  216. package/templates/core/lib/app.dart.hbs +20 -0
  217. package/templates/core/lib/core/providers/app_providers.dart.hbs +3 -0
  218. package/templates/core/lib/core/router/app_router.dart.hbs +19 -0
  219. package/templates/core/lib/core/theme/app_theme.dart.hbs +15 -0
  220. package/templates/core/lib/features/home/data/models/.gitkeep +0 -0
  221. package/templates/core/lib/features/home/data/repositories/.gitkeep +0 -0
  222. package/templates/core/lib/features/home/domain/entities/.gitkeep +0 -0
  223. package/templates/core/lib/features/home/domain/repositories/.gitkeep +0 -0
  224. package/templates/core/lib/features/home/presentation/pages/home_page.dart.hbs +18 -0
  225. package/templates/core/lib/features/home/presentation/widgets/.gitkeep +0 -0
  226. package/templates/core/lib/main.dart.hbs +11 -0
  227. package/templates/core/pubspec.yaml.hbs +30 -0
  228. package/templates/core/test/widget_test.dart.hbs +16 -0
  229. package/templates/modules/analytics/lib/features/analytics/data/observers/analytics_route_observer.dart.hbs +53 -0
  230. package/templates/modules/analytics/lib/features/analytics/data/services/firebase_analytics_service.dart.hbs +39 -0
  231. package/templates/modules/analytics/lib/features/analytics/domain/services/analytics_service.dart.hbs +25 -0
  232. package/templates/modules/analytics/lib/features/analytics/presentation/providers/analytics_provider.dart.hbs +17 -0
  233. package/templates/modules/analytics/pubspec.partial.yaml +2 -0
  234. package/templates/modules/api/lib/features/api/data/datasources/api_client.dart.hbs +171 -0
  235. package/templates/modules/api/lib/features/api/data/interceptors/auth_interceptor.dart.hbs +25 -0
  236. package/templates/modules/api/lib/features/api/data/interceptors/retry_interceptor.dart.hbs +42 -0
  237. package/templates/modules/api/lib/features/api/data/repositories/api_repository_impl.dart.hbs +21 -0
  238. package/templates/modules/api/lib/features/api/domain/exceptions/api_exception.dart.hbs +31 -0
  239. package/templates/modules/api/lib/features/api/domain/repositories/api_repository.dart.hbs +8 -0
  240. package/templates/modules/api/lib/features/api/presentation/providers/api_provider.dart.hbs +17 -0
  241. package/templates/modules/api/pubspec.partial.yaml +7 -0
  242. package/templates/modules/auth/lib/features/auth/data/datasources/auth_remote_datasource.dart.hbs +181 -0
  243. package/templates/modules/auth/lib/features/auth/data/models/auth_user_model.dart.hbs +27 -0
  244. package/templates/modules/auth/lib/features/auth/data/repositories/auth_repository_impl.dart.hbs +49 -0
  245. package/templates/modules/auth/lib/features/auth/domain/entities/user_entity.dart.hbs +18 -0
  246. package/templates/modules/auth/lib/features/auth/domain/repositories/auth_repository.dart.hbs +22 -0
  247. package/templates/modules/auth/lib/features/auth/domain/usecases/register_usecase.dart.hbs +20 -0
  248. package/templates/modules/auth/lib/features/auth/domain/usecases/sign_in_usecase.dart.hbs +15 -0
  249. package/templates/modules/auth/lib/features/auth/domain/usecases/sign_out_usecase.dart.hbs +11 -0
  250. package/templates/modules/auth/lib/features/auth/presentation/pages/login_page.dart.hbs +118 -0
  251. package/templates/modules/auth/lib/features/auth/presentation/pages/register_page.dart.hbs +131 -0
  252. package/templates/modules/auth/lib/features/auth/presentation/providers/auth_provider.dart.hbs +31 -0
  253. package/templates/modules/auth/pubspec.partial.yaml +13 -0
  254. package/templates/modules/cicd/.github/workflows/ci.yml.hbs +45 -0
  255. package/templates/modules/cicd/.gitlab-ci.yml.hbs +53 -0
  256. package/templates/modules/cicd/bitbucket-pipelines.yml.hbs +39 -0
  257. package/templates/modules/cicd/pubspec.partial.yaml +1 -0
  258. package/templates/modules/database/lib/features/database/data/datasources/database_datasource.dart.hbs +115 -0
  259. package/templates/modules/database/lib/features/database/data/repositories/database_repository_impl.dart.hbs +73 -0
  260. package/templates/modules/database/lib/features/database/domain/repositories/database_repository.dart.hbs +10 -0
  261. package/templates/modules/database/lib/features/database/presentation/providers/database_provider.dart.hbs +43 -0
  262. package/templates/modules/database/pubspec.partial.yaml +27 -0
  263. package/templates/modules/deep-linking/lib/features/deep_linking/data/datasources/deep_link_datasource.dart.hbs +18 -0
  264. package/templates/modules/deep-linking/lib/features/deep_linking/data/repositories/deep_link_repository_impl.dart.hbs +14 -0
  265. package/templates/modules/deep-linking/lib/features/deep_linking/domain/repositories/deep_link_repository.dart.hbs +7 -0
  266. package/templates/modules/deep-linking/lib/features/deep_linking/presentation/providers/deep_link_provider.dart.hbs +57 -0
  267. package/templates/modules/deep-linking/pubspec.partial.yaml +2 -0
  268. package/templates/modules/i18n/l10n.yaml.hbs +5 -0
  269. package/templates/modules/i18n/lib/core/l10n/l10n_config.dart.hbs +29 -0
  270. package/templates/modules/i18n/lib/core/l10n/l10n_provider.dart.hbs +20 -0
  271. package/templates/modules/i18n/lib/l10n/app_de.arb.hbs +27 -0
  272. package/templates/modules/i18n/lib/l10n/app_en.arb.hbs +27 -0
  273. package/templates/modules/i18n/pubspec.partial.yaml +7 -0
  274. package/templates/modules/push/lib/features/push/data/datasources/push_datasource.dart.hbs +124 -0
  275. package/templates/modules/push/lib/features/push/data/repositories/push_repository_impl.dart.hbs +28 -0
  276. package/templates/modules/push/lib/features/push/domain/repositories/push_repository.dart.hbs +31 -0
  277. package/templates/modules/push/lib/features/push/presentation/providers/push_provider.dart.hbs +34 -0
  278. package/templates/modules/push/pubspec.partial.yaml +8 -0
  279. package/templates/modules/theme/lib/core/theme/app_theme.dart.hbs +74 -0
  280. package/templates/modules/theme/lib/core/theme/theme_provider.dart.hbs +46 -0
  281. package/templates/modules/theme/pubspec.partial.yaml +2 -0
@@ -0,0 +1,31 @@
1
+ import 'package:flutter_riverpod/flutter_riverpod.dart';
2
+ import 'package:riverpod_annotation/riverpod_annotation.dart';
3
+ import '../../data/datasources/auth_remote_datasource.dart';
4
+ import '../../data/repositories/auth_repository_impl.dart';
5
+ import '../../domain/entities/user_entity.dart';
6
+ import '../../domain/repositories/auth_repository.dart';
7
+
8
+ part 'auth_provider.g.dart';
9
+
10
+ @riverpod
11
+ AuthRemoteDataSource authDataSource(Ref ref) {
12
+ {{#ifEquals modules.auth.provider "firebase"}}
13
+ return FirebaseAuthDataSource();
14
+ {{/ifEquals}}
15
+ {{#ifEquals modules.auth.provider "supabase"}}
16
+ return SupabaseAuthDataSource();
17
+ {{/ifEquals}}
18
+ {{#ifEquals modules.auth.provider "custom"}}
19
+ return CustomAuthDataSource();
20
+ {{/ifEquals}}
21
+ }
22
+
23
+ @riverpod
24
+ AuthRepository authRepository(Ref ref) {
25
+ return AuthRepositoryImpl(ref.watch(authDataSourceProvider));
26
+ }
27
+
28
+ @riverpod
29
+ Stream<UserEntity?> authState(Ref ref) {
30
+ return ref.watch(authRepositoryProvider).authStateChanges;
31
+ }
@@ -0,0 +1,13 @@
1
+ {{#ifEquals modules.auth.provider "firebase"}}
2
+ dependencies:
3
+ firebase_core: ^3.8.0
4
+ firebase_auth: ^5.3.4
5
+ {{/ifEquals}}
6
+ {{#ifEquals modules.auth.provider "supabase"}}
7
+ dependencies:
8
+ supabase_flutter: ^2.8.2
9
+ {{/ifEquals}}
10
+ {{#ifEquals modules.auth.provider "custom"}}
11
+ dependencies:
12
+ dio: ^5.7.0
13
+ {{/ifEquals}}
@@ -0,0 +1,45 @@
1
+ {{#ifEquals modules.cicd.provider "github"}}
2
+ name: CI
3
+
4
+ on:
5
+ push:
6
+ branches: [main, develop]
7
+ pull_request:
8
+ branches: [main, develop]
9
+
10
+ jobs:
11
+ flutter:
12
+ name: Flutter CI
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - name: Checkout repository
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Set up Flutter
20
+ uses: subosito/flutter-action@v2
21
+ with:
22
+ flutter-version: 'stable'
23
+ channel: 'stable'
24
+ cache: true
25
+
26
+ - name: Install dependencies
27
+ run: flutter pub get
28
+
29
+ - name: Verify formatting
30
+ run: dart format --output=none --set-exit-if-changed .
31
+
32
+ - name: Analyze code
33
+ run: flutter analyze --fatal-infos
34
+
35
+ - name: Run tests
36
+ run: flutter test --coverage
37
+
38
+ - name: Build Android APK
39
+ run: flutter build apk --debug
40
+
41
+ - name: Upload coverage
42
+ uses: codecov/codecov-action@v4
43
+ with:
44
+ file: coverage/lcov.info
45
+ {{/ifEquals}}
@@ -0,0 +1,53 @@
1
+ {{#ifEquals modules.cicd.provider "gitlab"}}
2
+ image: ghcr.io/cirruslabs/flutter:stable
3
+
4
+ stages:
5
+ - validate
6
+ - test
7
+ - build
8
+
9
+ variables:
10
+ PUB_CACHE: "$CI_PROJECT_DIR/.pub-cache"
11
+
12
+ cache:
13
+ key: "$CI_COMMIT_REF_SLUG"
14
+ paths:
15
+ - .pub-cache/
16
+ - .dart_tool/
17
+
18
+ format:
19
+ stage: validate
20
+ script:
21
+ - flutter pub get
22
+ - dart format --output=none --set-exit-if-changed .
23
+
24
+ analyze:
25
+ stage: validate
26
+ script:
27
+ - flutter pub get
28
+ - flutter analyze --fatal-infos
29
+
30
+ test:
31
+ stage: test
32
+ script:
33
+ - flutter pub get
34
+ - flutter test --coverage
35
+ artifacts:
36
+ reports:
37
+ coverage_report:
38
+ coverage_format: cobertura
39
+ path: coverage/cobertura.xml
40
+
41
+ build_apk:
42
+ stage: build
43
+ script:
44
+ - flutter pub get
45
+ - flutter build apk --debug
46
+ artifacts:
47
+ paths:
48
+ - build/app/outputs/flutter-apk/app-debug.apk
49
+ expire_in: 1 week
50
+ only:
51
+ - main
52
+ - develop
53
+ {{/ifEquals}}
@@ -0,0 +1,39 @@
1
+ {{#ifEquals modules.cicd.provider "bitbucket"}}
2
+ image: ghcr.io/cirruslabs/flutter:stable
3
+
4
+ pipelines:
5
+ default:
6
+ - step:
7
+ name: Validate & Test
8
+ caches:
9
+ - gradle
10
+ script:
11
+ - flutter pub get
12
+ - dart format --output=none --set-exit-if-changed .
13
+ - flutter analyze --fatal-infos
14
+ - flutter test --coverage
15
+
16
+ branches:
17
+ main:
18
+ - step:
19
+ name: Validate & Test
20
+ script:
21
+ - flutter pub get
22
+ - flutter analyze --fatal-infos
23
+ - flutter test --coverage
24
+ - step:
25
+ name: Build Android APK
26
+ script:
27
+ - flutter pub get
28
+ - flutter build apk --debug
29
+ artifacts:
30
+ - build/app/outputs/flutter-apk/*.apk
31
+
32
+ develop:
33
+ - step:
34
+ name: Validate & Test
35
+ script:
36
+ - flutter pub get
37
+ - flutter analyze --fatal-infos
38
+ - flutter test --coverage
39
+ {{/ifEquals}}
@@ -0,0 +1 @@
1
+ # CI/CD module has no pubspec dependencies
@@ -0,0 +1,115 @@
1
+ {{#ifEquals modules.database.engine "drift"}}
2
+ import 'dart:io';
3
+
4
+ import 'package:drift/drift.dart';
5
+ import 'package:drift/native.dart';
6
+ import 'package:path/path.dart' as p;
7
+ import 'package:path_provider/path_provider.dart';
8
+
9
+ part 'database_datasource.g.dart';
10
+
11
+ @DriftDatabase(tables: [])
12
+ class AppDatabase extends _$AppDatabase {
13
+ AppDatabase() : super(_openConnection());
14
+
15
+ @override
16
+ int get schemaVersion => 1;
17
+
18
+ @override
19
+ MigrationStrategy get migration => MigrationStrategy(
20
+ onCreate: (m) async {
21
+ await m.createAll();
22
+ },
23
+ onUpgrade: (m, from, to) async {
24
+ // Add migration steps here as the schema evolves.
25
+ },
26
+ );
27
+
28
+ static QueryExecutor _openConnection() {
29
+ return LazyDatabase(() async {
30
+ final dir = await getApplicationDocumentsDirectory();
31
+ final file = File(p.join(dir.path, '{{project.name}}.db'));
32
+ return NativeDatabase.createInBackground(file);
33
+ });
34
+ }
35
+
36
+ Future<void> clearAll() async {
37
+ // Delete all rows from each table.
38
+ // Add table.deleteAll() calls here for each table you define.
39
+ }
40
+ }
41
+ {{/ifEquals}}
42
+ {{#ifEquals modules.database.engine "hive"}}
43
+ import 'package:hive_ce_flutter/hive_flutter.dart';
44
+
45
+ abstract class HiveDatabaseDataSource {
46
+ Future<void> initialize();
47
+ Future<void> close();
48
+ Future<void> clearAll();
49
+ }
50
+
51
+ class HiveDatabaseDataSourceImpl implements HiveDatabaseDataSource {
52
+ // Register adapters and open boxes here as you add domain models.
53
+ // Example:
54
+ // Hive.registerAdapter(MyModelAdapter());
55
+ // await Hive.openBox<MyModel>('myModels');
56
+
57
+ @override
58
+ Future<void> initialize() async {
59
+ await Hive.initFlutter();
60
+ // TODO: register adapters and open boxes
61
+ }
62
+
63
+ @override
64
+ Future<void> close() async {
65
+ await Hive.close();
66
+ }
67
+
68
+ @override
69
+ Future<void> clearAll() async {
70
+ // Delete all boxes to reset local state.
71
+ await Hive.deleteFromDisk();
72
+ }
73
+ }
74
+ {{/ifEquals}}
75
+ {{#ifEquals modules.database.engine "isar"}}
76
+ import 'package:isar/isar.dart';
77
+ import 'package:path_provider/path_provider.dart';
78
+
79
+ abstract class IsarDatabaseDataSource {
80
+ Future<void> initialize();
81
+ Future<void> close();
82
+ Future<void> clearAll();
83
+ }
84
+
85
+ class IsarDatabaseDataSourceImpl implements IsarDatabaseDataSource {
86
+ late Isar _isar;
87
+
88
+ Isar get isar => _isar;
89
+
90
+ // Add your collection schemas to the list below as you define them.
91
+ // Example: schemas: [MyModelSchema]
92
+ static const List<CollectionSchema<dynamic>> _schemas = [];
93
+
94
+ @override
95
+ Future<void> initialize() async {
96
+ final dir = await getApplicationDocumentsDirectory();
97
+ _isar = await Isar.open(
98
+ _schemas,
99
+ directory: dir.path,
100
+ );
101
+ }
102
+
103
+ @override
104
+ Future<void> close() async {
105
+ await _isar.close();
106
+ }
107
+
108
+ @override
109
+ Future<void> clearAll() async {
110
+ await _isar.writeTxn(() async {
111
+ await _isar.clear();
112
+ });
113
+ }
114
+ }
115
+ {{/ifEquals}}
@@ -0,0 +1,73 @@
1
+ import '../../domain/repositories/database_repository.dart';
2
+ {{#ifEquals modules.database.engine "drift"}}
3
+ import '../datasources/database_datasource.dart';
4
+
5
+ class DatabaseRepositoryImpl implements DatabaseRepository {
6
+ final AppDatabase _db;
7
+
8
+ const DatabaseRepositoryImpl(this._db);
9
+
10
+ @override
11
+ Future<void> initialize() async {
12
+ // Drift opens the database lazily on first query; no explicit init needed.
13
+ }
14
+
15
+ @override
16
+ Future<void> close() async {
17
+ await _db.close();
18
+ }
19
+
20
+ @override
21
+ Future<void> clearAll() async {
22
+ await _db.clearAll();
23
+ }
24
+ }
25
+ {{/ifEquals}}
26
+ {{#ifEquals modules.database.engine "hive"}}
27
+ import '../datasources/database_datasource.dart';
28
+
29
+ class DatabaseRepositoryImpl implements DatabaseRepository {
30
+ final HiveDatabaseDataSource _dataSource;
31
+
32
+ const DatabaseRepositoryImpl(this._dataSource);
33
+
34
+ @override
35
+ Future<void> initialize() async {
36
+ await _dataSource.initialize();
37
+ }
38
+
39
+ @override
40
+ Future<void> close() async {
41
+ await _dataSource.close();
42
+ }
43
+
44
+ @override
45
+ Future<void> clearAll() async {
46
+ await _dataSource.clearAll();
47
+ }
48
+ }
49
+ {{/ifEquals}}
50
+ {{#ifEquals modules.database.engine "isar"}}
51
+ import '../datasources/database_datasource.dart';
52
+
53
+ class DatabaseRepositoryImpl implements DatabaseRepository {
54
+ final IsarDatabaseDataSource _dataSource;
55
+
56
+ const DatabaseRepositoryImpl(this._dataSource);
57
+
58
+ @override
59
+ Future<void> initialize() async {
60
+ await _dataSource.initialize();
61
+ }
62
+
63
+ @override
64
+ Future<void> close() async {
65
+ await _dataSource.close();
66
+ }
67
+
68
+ @override
69
+ Future<void> clearAll() async {
70
+ await _dataSource.clearAll();
71
+ }
72
+ }
73
+ {{/ifEquals}}
@@ -0,0 +1,10 @@
1
+ abstract class DatabaseRepository {
2
+ /// Initialize the database connection and run any pending migrations.
3
+ Future<void> initialize();
4
+
5
+ /// Close the database connection and release resources.
6
+ Future<void> close();
7
+
8
+ /// Delete all data from the database (useful for logout/reset flows).
9
+ Future<void> clearAll();
10
+ }
@@ -0,0 +1,43 @@
1
+ import 'package:flutter_riverpod/flutter_riverpod.dart';
2
+ import 'package:riverpod_annotation/riverpod_annotation.dart';
3
+ import '../../data/datasources/database_datasource.dart';
4
+ import '../../data/repositories/database_repository_impl.dart';
5
+ import '../../domain/repositories/database_repository.dart';
6
+
7
+ part 'database_provider.g.dart';
8
+
9
+ {{#ifEquals modules.database.engine "drift"}}
10
+ @Riverpod(keepAlive: true)
11
+ AppDatabase appDatabase(Ref ref) {
12
+ final db = AppDatabase();
13
+ ref.onDispose(db.close);
14
+ return db;
15
+ }
16
+
17
+ @Riverpod(keepAlive: true)
18
+ DatabaseRepository databaseRepository(Ref ref) {
19
+ return DatabaseRepositoryImpl(ref.watch(appDatabaseProvider));
20
+ }
21
+ {{/ifEquals}}
22
+ {{#ifEquals modules.database.engine "hive"}}
23
+ @Riverpod(keepAlive: true)
24
+ HiveDatabaseDataSource hiveDatabaseDataSource(Ref ref) {
25
+ return HiveDatabaseDataSourceImpl();
26
+ }
27
+
28
+ @Riverpod(keepAlive: true)
29
+ DatabaseRepository databaseRepository(Ref ref) {
30
+ return DatabaseRepositoryImpl(ref.watch(hiveDatabaseDataSourceProvider));
31
+ }
32
+ {{/ifEquals}}
33
+ {{#ifEquals modules.database.engine "isar"}}
34
+ @Riverpod(keepAlive: true)
35
+ IsarDatabaseDataSource isarDatabaseDataSource(Ref ref) {
36
+ return IsarDatabaseDataSourceImpl();
37
+ }
38
+
39
+ @Riverpod(keepAlive: true)
40
+ DatabaseRepository databaseRepository(Ref ref) {
41
+ return DatabaseRepositoryImpl(ref.watch(isarDatabaseDataSourceProvider));
42
+ }
43
+ {{/ifEquals}}
@@ -0,0 +1,27 @@
1
+ {{#ifEquals modules.database.engine "drift"}}
2
+ dependencies:
3
+ drift: ^2.22.1
4
+ sqlite3_flutter_libs: ^0.5.28
5
+ path_provider: ^2.1.5
6
+ path: ^1.9.0
7
+ dev_dependencies:
8
+ drift_dev: ^2.22.1
9
+ build_runner: ^2.4.13
10
+ {{/ifEquals}}
11
+ {{#ifEquals modules.database.engine "hive"}}
12
+ dependencies:
13
+ hive_ce_flutter: ^2.8.0
14
+ path_provider: ^2.1.5
15
+ dev_dependencies:
16
+ hive_ce_generator: ^1.8.3
17
+ build_runner: ^2.4.13
18
+ {{/ifEquals}}
19
+ {{#ifEquals modules.database.engine "isar"}}
20
+ dependencies:
21
+ isar: ^3.1.0+1
22
+ isar_flutter_libs: ^3.1.0+1
23
+ path_provider: ^2.1.5
24
+ dev_dependencies:
25
+ isar_generator: ^3.1.0+1
26
+ build_runner: ^2.4.13
27
+ {{/ifEquals}}
@@ -0,0 +1,18 @@
1
+ import 'package:app_links/app_links.dart';
2
+
3
+ abstract class DeepLinkDataSource {
4
+ Stream<Uri> get onDeepLink;
5
+ Future<Uri?> getInitialLink();
6
+ }
7
+
8
+ class AppLinksDataSource implements DeepLinkDataSource {
9
+ final AppLinks _appLinks;
10
+
11
+ AppLinksDataSource({AppLinks? appLinks}) : _appLinks = appLinks ?? AppLinks();
12
+
13
+ @override
14
+ Stream<Uri> get onDeepLink => _appLinks.uriLinkStream;
15
+
16
+ @override
17
+ Future<Uri?> getInitialLink() => _appLinks.getInitialLink();
18
+ }
@@ -0,0 +1,14 @@
1
+ import '../../domain/repositories/deep_link_repository.dart';
2
+ import '../datasources/deep_link_datasource.dart';
3
+
4
+ class DeepLinkRepositoryImpl implements DeepLinkRepository {
5
+ final DeepLinkDataSource _dataSource;
6
+
7
+ DeepLinkRepositoryImpl(this._dataSource);
8
+
9
+ @override
10
+ Stream<Uri> get onDeepLink => _dataSource.onDeepLink;
11
+
12
+ @override
13
+ Future<Uri?> getInitialLink() => _dataSource.getInitialLink();
14
+ }
@@ -0,0 +1,7 @@
1
+ abstract class DeepLinkRepository {
2
+ /// Stream of incoming deep link URIs.
3
+ Stream<Uri> get onDeepLink;
4
+
5
+ /// Get the initial deep link that launched the app, if any.
6
+ Future<Uri?> getInitialLink();
7
+ }
@@ -0,0 +1,57 @@
1
+ import 'package:flutter_riverpod/flutter_riverpod.dart';
2
+ import 'package:go_router/go_router.dart';
3
+ import 'package:riverpod_annotation/riverpod_annotation.dart';
4
+ import '../../data/datasources/deep_link_datasource.dart';
5
+ import '../../data/repositories/deep_link_repository_impl.dart';
6
+ import '../../domain/repositories/deep_link_repository.dart';
7
+
8
+ part 'deep_link_provider.g.dart';
9
+
10
+ @riverpod
11
+ DeepLinkDataSource deepLinkDataSource(Ref ref) {
12
+ return AppLinksDataSource();
13
+ }
14
+
15
+ @riverpod
16
+ DeepLinkRepository deepLinkRepository(Ref ref) {
17
+ return DeepLinkRepositoryImpl(ref.watch(deepLinkDataSourceProvider));
18
+ }
19
+
20
+ /// Handles incoming deep links by navigating with go_router.
21
+ /// Call this provider in your app's root widget to activate deep link handling.
22
+ @riverpod
23
+ Stream<Uri> deepLinkStream(Ref ref) {
24
+ return ref.watch(deepLinkRepositoryProvider).onDeepLink;
25
+ }
26
+
27
+ /// Notifier that sets up deep link handling with go_router.
28
+ @riverpod
29
+ class DeepLinkHandler extends _$DeepLinkHandler {
30
+ @override
31
+ Future<void> build() async {
32
+ final repo = ref.watch(deepLinkRepositoryProvider);
33
+
34
+ // Handle the initial link that launched the app
35
+ final initialLink = await repo.getInitialLink();
36
+ if (initialLink != null) {
37
+ _navigate(initialLink);
38
+ }
39
+
40
+ // Listen for incoming links while app is running
41
+ final subscription = repo.onDeepLink.listen(_navigate);
42
+ ref.onDispose(subscription.cancel);
43
+ }
44
+
45
+ void _navigate(Uri uri) {
46
+ // The router will handle the navigation based on go_router config.
47
+ // Scheme: {{modules.deepLinking.scheme}}, Host: {{modules.deepLinking.host}}
48
+ final router = ref.read(routerProvider);
49
+ router.go(uri.path, extra: uri.queryParameters);
50
+ }
51
+ }
52
+
53
+ // Provide the router instance — override this in your app's provider scope.
54
+ @riverpod
55
+ GoRouter router(Ref ref) {
56
+ throw UnimplementedError('Override routerProvider with your GoRouter instance');
57
+ }
@@ -0,0 +1,2 @@
1
+ dependencies:
2
+ app_links: ^6.3.3
@@ -0,0 +1,5 @@
1
+ arb-dir: lib/l10n
2
+ template-arb-file: app_{{modules.i18n.defaultLocale}}.arb
3
+ output-localization-file: app_localizations.dart
4
+ output-class: AppLocalizations
5
+ nullable-getter: false
@@ -0,0 +1,29 @@
1
+ import 'package:flutter/material.dart';
2
+ import 'package:flutter_localizations/flutter_localizations.dart';
3
+ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
4
+
5
+ export 'package:flutter_gen/gen_l10n/app_localizations.dart';
6
+
7
+ /// Localization configuration for the application.
8
+ ///
9
+ /// Provides [localizationsDelegates] and [supportedLocales] to be passed
10
+ /// to [MaterialApp] or [CupertinoApp].
11
+ class L10nConfig {
12
+ const L10nConfig._();
13
+
14
+ /// Delegates required by [MaterialApp.localizationsDelegates].
15
+ static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = [
16
+ AppLocalizations.delegate,
17
+ GlobalMaterialLocalizations.delegate,
18
+ GlobalWidgetsLocalizations.delegate,
19
+ GlobalCupertinoLocalizations.delegate,
20
+ ];
21
+
22
+ /// The list of locales supported by this application.
23
+ static const List<Locale> supportedLocales = AppLocalizations.supportedLocales;
24
+ }
25
+
26
+ /// Extension on [BuildContext] to conveniently access [AppLocalizations].
27
+ extension L10nExtension on BuildContext {
28
+ AppLocalizations get l10n => AppLocalizations.of(this)!;
29
+ }
@@ -0,0 +1,20 @@
1
+ import 'package:flutter/material.dart';
2
+ import 'package:flutter_riverpod/flutter_riverpod.dart';
3
+ import 'package:riverpod_annotation/riverpod_annotation.dart';
4
+
5
+ part 'l10n_provider.g.dart';
6
+
7
+ /// Notifier that manages the current [Locale] for the application.
8
+ /// Use [localeProvider] to watch the locale and [LocaleNotifier.setLocale]
9
+ /// to change it at runtime.
10
+ @riverpod
11
+ class LocaleNotifier extends _$LocaleNotifier {
12
+ @override
13
+ Locale build() => const Locale('{{modules.i18n.defaultLocale}}');
14
+
15
+ /// Sets the active locale.
16
+ void setLocale(Locale locale) => state = locale;
17
+
18
+ /// Resets to the default locale.
19
+ void resetToDefault() => state = const Locale('{{modules.i18n.defaultLocale}}');
20
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "@@locale": "de",
3
+ "appTitle": "{{project.name}}",
4
+ "@appTitle": {
5
+ "description": "Der Titel der Anwendung"
6
+ },
7
+ "welcomeMessage": "Willkommen bei {{project.name}}",
8
+ "@welcomeMessage": {
9
+ "description": "Willkommensnachricht auf dem Startbildschirm"
10
+ },
11
+ "errorGeneric": "Etwas ist schiefgelaufen. Bitte versuche es erneut.",
12
+ "@errorGeneric": {
13
+ "description": "Allgemeine Fehlermeldung"
14
+ },
15
+ "retry": "Wiederholen",
16
+ "@retry": {
17
+ "description": "Beschriftung für den Wiederholen-Button"
18
+ },
19
+ "cancel": "Abbrechen",
20
+ "@cancel": {
21
+ "description": "Beschriftung für den Abbrechen-Button"
22
+ },
23
+ "ok": "OK",
24
+ "@ok": {
25
+ "description": "Beschriftung für den OK-Button"
26
+ }
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "@@locale": "en",
3
+ "appTitle": "{{project.name}}",
4
+ "@appTitle": {
5
+ "description": "The title of the application"
6
+ },
7
+ "welcomeMessage": "Welcome to {{project.name}}",
8
+ "@welcomeMessage": {
9
+ "description": "Welcome message shown on the home screen"
10
+ },
11
+ "errorGeneric": "Something went wrong. Please try again.",
12
+ "@errorGeneric": {
13
+ "description": "Generic error message"
14
+ },
15
+ "retry": "Retry",
16
+ "@retry": {
17
+ "description": "Label for retry button"
18
+ },
19
+ "cancel": "Cancel",
20
+ "@cancel": {
21
+ "description": "Label for cancel button"
22
+ },
23
+ "ok": "OK",
24
+ "@ok": {
25
+ "description": "Label for OK button"
26
+ }
27
+ }