Skip to content

Commit 00d5755

Browse files
committed
feat(mobile): add forui UI library and upgrade Flutter to 3.38
- Add forui ^0.17.0 as UI component library (shadcn-ui style for Flutter) - Upgrade Flutter SDK from 3.32 to 3.38, Dart SDK from 3.8 to 3.10 - Integrate FTheme with system brightness detection in main.dart - Add FLocalizations delegates for i18n support - Fix Riverpod dependencies (3.0.x) and retrofit_generator (10.x) versions - Update README.md and README.ko.md with correct Flutter version - Fix lint-format-guide.md with accurate Biome/Ruff configurations
1 parent e159bc5 commit 00d5755

File tree

7 files changed

+1199
-53
lines changed

7 files changed

+1199
-53
lines changed

.agent/rules/lint-format-guide.md

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ See `biome.json` at project root.
5050
- Indent: 2 spaces
5151
- Quotes: double
5252
- Semicolons: required
53-
- Trailing commas: all
53+
- Trailing commas: ES5
5454
- Line width: 100
5555

5656
### Lint Categories
@@ -88,8 +88,8 @@ See `biome.json` at project root.
8888
See `ruff.toml` in `apps/api/` and `apps/worker/`.
8989

9090
### Key Rules
91-
- Line length: 100
92-
- Target: Python 3.13
91+
- Line length: 88
92+
- Target: Python 3.12
9393
- Indent: 4 spaces
9494
- Quotes: double
9595

@@ -99,8 +99,10 @@ See `ruff.toml` in `apps/api/` and `apps/worker/`.
9999
- **I**: isort (import sorting)
100100
- **UP**: pyupgrade
101101
- **B**: flake8-bugbear
102+
- **S**: bandit (security)
102103
- **SIM**: flake8-simplify
103104
- **ASYNC**: flake8-async
105+
- **RUF**: Ruff-specific
104106

105107
### Editor Integration
106108
```json
@@ -147,29 +149,30 @@ terraform validate
147149

148150
## Pre-commit Hooks
149151

150-
Husky + lint-staged runs on every commit:
152+
mise runs tasks on every commit via git hooks:
151153

152-
```json
153-
// package.json
154-
{
155-
"lint-staged": {
156-
"*.{js,jsx,ts,tsx,json,css,md}": [
157-
"biome check --write"
158-
]
159-
}
160-
}
154+
```bash
155+
# Setup git hooks (run once)
156+
git config core.hooksPath .git/hooks
157+
158+
# Create pre-commit hook
159+
echo '#!/bin/sh
160+
mise git:pre-commit' > .git/hooks/pre-commit
161+
chmod +x .git/hooks/pre-commit
162+
163+
# Create commit-msg hook
164+
echo '#!/bin/sh
165+
mise git:commit-msg "$1"' > .git/hooks/commit-msg
166+
chmod +x .git/hooks/commit-msg
161167
```
162168

163-
For Python, add to `.pre-commit-config.yaml`:
164-
```yaml
165-
repos:
166-
- repo: https://github.com/astral-sh/ruff-pre-commit
167-
rev: v0.8.0
168-
hooks:
169-
- id: ruff
170-
args: [--fix]
171-
- id: ruff-format
172-
```
169+
The pre-commit task runs lint for changed apps:
170+
- `apps/api/` changes → `mise //apps/api:lint`
171+
- `apps/web/` changes → `mise //apps/web:lint`
172+
- `apps/worker/` changes → `mise //apps/worker:lint`
173+
- `apps/mobile/` changes → `mise //apps/mobile:lint`
174+
175+
The commit-msg task validates commit messages using commitlint.
173176

174177
## CI Integration
175178

README.ko.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
graph TB
1111
subgraph Client["클라이언트"]
1212
Web[Next.js 16<br/>React 19]
13-
Mobile[Flutter 3.32<br/>Riverpod]
13+
Mobile[Flutter 3.38<br/>Riverpod]
1414
end
1515
1616
subgraph GCP["GCP Cloud Run"]
@@ -43,7 +43,7 @@ graph TB
4343

4444
## 주요 기능
4545

46-
- **모던 스택**: Next.js 16 + React 19, FastAPI, Flutter 3.32, TailwindCSS v4
46+
- **모던 스택**: Next.js 16 + React 19, FastAPI, Flutter 3.38, TailwindCSS v4
4747
- **타입 안전성**: TypeScript, Pydantic, Dart 전체 타입 지원
4848
- **인증**: better-auth 기반 OAuth (Google, GitHub, Facebook)
4949
- **국제화**: next-intl (웹), Flutter ARB (모바일), 공용 i18n 패키지
@@ -59,7 +59,7 @@ graph TB
5959
|--------|------|
6060
| **프론트엔드** | Next.js 16, React 19, TailwindCSS v4, shadcn/ui, TanStack Query, Jotai |
6161
| **백엔드** | FastAPI, SQLAlchemy (async), PostgreSQL 16, Redis 7 |
62-
| **모바일** | Flutter 3.32, Riverpod 3, go_router 17, Firebase Crashlytics, Fastlane |
62+
| **모바일** | Flutter 3.38, Riverpod 3, go_router 17, Firebase Crashlytics, Fastlane |
6363
| **워커** | FastAPI + CloudTasks/PubSub |
6464
| **인프라** | Terraform, GCP (Cloud Run, Cloud SQL, Cloud Storage, CDN) |
6565
| **CI/CD** | GitHub Actions, Workload Identity Federation |
@@ -139,7 +139,8 @@ fullstack-starter/
139139
│ ├── mobile/ # Flutter 모바일 앱
140140
│ └── infra/ # Terraform 인프라
141141
├── packages/
142-
│ └── i18n/ # 공용 다국어 패키지 (Source of Truth)
142+
│ ├── i18n/ # 공용 다국어 패키지 (Source of Truth)
143+
│ └── shared/ # 공용 유틸리티
143144
├── .agent/rules/ # AI 에이전트 가이드라인
144145
├── .serena/ # Serena MCP 설정
145146
└── .github/workflows/ # CI/CD
@@ -177,6 +178,7 @@ mise tasks --all
177178
| `mise //apps/api:test` | 테스트 실행 |
178179
| `mise //apps/api:lint` | 린터 실행 |
179180
| `mise //apps/api:format` | 코드 포맷 |
181+
| `mise //apps/api:typecheck` | 타입 체크 |
180182
| `mise //apps/api:migrate` | 마이그레이션 실행 |
181183
| `mise //apps/api:migrate:create` | 새 마이그레이션 생성 |
182184
| `mise //apps/api:gen:openapi` | OpenAPI 스키마 생성 |
@@ -194,6 +196,8 @@ mise tasks --all
194196
| `mise //apps/web:build` | 프로덕션 빌드 |
195197
| `mise //apps/web:test` | 테스트 실행 |
196198
| `mise //apps/web:lint` | 린터 실행 |
199+
| `mise //apps/web:format` | 코드 포맷 |
200+
| `mise //apps/web:typecheck` | 타입 체크 |
197201
| `mise //apps/web:gen:api` | API 클라이언트 생성 |
198202

199203
</details>
@@ -207,6 +211,7 @@ mise tasks --all
207211
| `mise //apps/mobile:build` | 빌드 |
208212
| `mise //apps/mobile:test` | 테스트 실행 |
209213
| `mise //apps/mobile:lint` | 분석기 실행 |
214+
| `mise //apps/mobile:format` | 코드 포맷 |
210215
| `mise //apps/mobile:gen:l10n` | 다국어 파일 생성 |
211216
| `mise //apps/mobile:gen:api` | API 클라이언트 생성 |
212217

@@ -220,6 +225,7 @@ mise tasks --all
220225
| `mise //apps/worker:dev` | 워커 시작 |
221226
| `mise //apps/worker:test` | 테스트 실행 |
222227
| `mise //apps/worker:lint` | 린터 실행 |
228+
| `mise //apps/worker:format` | 코드 포맷 |
223229

224230
</details>
225231

@@ -260,8 +266,8 @@ packages/i18n/source/ja.arb # 일본어
260266
# 빌드하여 각 앱에 배포
261267
mise i18n:build
262268
# 생성되는 파일:
263-
# - apps/web/messages/*.json (Nested JSON)
264-
# - apps/mobile/lib/l10n/app_*.arb (Flutter ARB)
269+
# - apps/web/src/config/messages/*.json (Nested JSON)
270+
# - apps/mobile/lib/i18n/messages/app_*.arb (Flutter ARB)
265271
```
266272

267273
## 환경 설정

README.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Production-ready fullstack monorepo template with Next.js 16, FastAPI, Flutter,
1010
graph TB
1111
subgraph Client
1212
Web[Next.js 16<br/>React 19]
13-
Mobile[Flutter 3.32<br/>Riverpod]
13+
Mobile[Flutter 3.38<br/>Riverpod]
1414
end
1515
1616
subgraph GCP["GCP Cloud Run"]
@@ -43,7 +43,7 @@ graph TB
4343

4444
## Key Features
4545

46-
- **Modern Stack**: Next.js 16 + React 19, FastAPI, Flutter 3.32, TailwindCSS v4
46+
- **Modern Stack**: Next.js 16 + React 19, FastAPI, Flutter 3.38, TailwindCSS v4
4747
- **Type Safety**: Full type support with TypeScript, Pydantic, and Dart
4848
- **Authentication**: OAuth with better-auth (Google, GitHub, Facebook)
4949
- **Internationalization**: next-intl (web), Flutter ARB (mobile), shared i18n package
@@ -59,7 +59,7 @@ graph TB
5959
|-------|------------|
6060
| **Frontend** | Next.js 16, React 19, TailwindCSS v4, shadcn/ui, TanStack Query, Jotai |
6161
| **Backend** | FastAPI, SQLAlchemy (async), PostgreSQL 16, Redis 7 |
62-
| **Mobile** | Flutter 3.32, Riverpod 3, go_router 17, Firebase Crashlytics, Fastlane |
62+
| **Mobile** | Flutter 3.38, Riverpod 3, go_router 17, Firebase Crashlytics, Fastlane |
6363
| **Worker** | FastAPI + CloudTasks/PubSub |
6464
| **Infrastructure** | Terraform, GCP (Cloud Run, Cloud SQL, Cloud Storage, CDN) |
6565
| **CI/CD** | GitHub Actions, Workload Identity Federation |
@@ -139,7 +139,8 @@ fullstack-starter/
139139
│ ├── mobile/ # Flutter mobile app
140140
│ └── infra/ # Terraform infrastructure
141141
├── packages/
142-
│ └── i18n/ # Shared i18n package (Source of Truth)
142+
│ ├── i18n/ # Shared i18n package (Source of Truth)
143+
│ └── shared/ # Shared utilities
143144
├── .agent/rules/ # AI agent guidelines
144145
├── .serena/ # Serena MCP config
145146
└── .github/workflows/ # CI/CD
@@ -177,6 +178,7 @@ mise tasks --all
177178
| `mise //apps/api:test` | Run tests |
178179
| `mise //apps/api:lint` | Run linter |
179180
| `mise //apps/api:format` | Format code |
181+
| `mise //apps/api:typecheck` | Type check |
180182
| `mise //apps/api:migrate` | Run migrations |
181183
| `mise //apps/api:migrate:create` | Create new migration |
182184
| `mise //apps/api:gen:openapi` | Generate OpenAPI schema |
@@ -194,6 +196,8 @@ mise tasks --all
194196
| `mise //apps/web:build` | Production build |
195197
| `mise //apps/web:test` | Run tests |
196198
| `mise //apps/web:lint` | Run linter |
199+
| `mise //apps/web:format` | Format code |
200+
| `mise //apps/web:typecheck` | Type check |
197201
| `mise //apps/web:gen:api` | Generate API client |
198202

199203
</details>
@@ -207,6 +211,7 @@ mise tasks --all
207211
| `mise //apps/mobile:build` | Build |
208212
| `mise //apps/mobile:test` | Run tests |
209213
| `mise //apps/mobile:lint` | Run analyzer |
214+
| `mise //apps/mobile:format` | Format code |
210215
| `mise //apps/mobile:gen:l10n` | Generate localizations |
211216
| `mise //apps/mobile:gen:api` | Generate API client |
212217

@@ -220,6 +225,7 @@ mise tasks --all
220225
| `mise //apps/worker:dev` | Start worker |
221226
| `mise //apps/worker:test` | Run tests |
222227
| `mise //apps/worker:lint` | Run linter |
228+
| `mise //apps/worker:format` | Format code |
223229

224230
</details>
225231

@@ -260,8 +266,8 @@ packages/i18n/source/ja.arb # Japanese
260266
# Build and deploy to each app
261267
mise i18n:build
262268
# Generated files:
263-
# - apps/web/messages/*.json (Nested JSON)
264-
# - apps/mobile/lib/l10n/app_*.arb (Flutter ARB)
269+
# - apps/web/src/config/messages/*.json (Nested JSON)
270+
# - apps/mobile/lib/i18n/messages/app_*.arb (Flutter ARB)
265271
```
266272

267273
## Configuration

apps/mobile/lib/core/router/router.g.dart

Lines changed: 51 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/mobile/lib/main.dart

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart';
66
import 'package:flutter/material.dart';
77
import 'package:flutter_localizations/flutter_localizations.dart';
88
import 'package:flutter_riverpod/flutter_riverpod.dart';
9+
import 'package:forui/forui.dart';
910

1011
import 'core/router/router.dart';
1112
import 'core/theme/app_theme.dart';
@@ -49,19 +50,26 @@ class MyApp extends ConsumerWidget {
4950
@override
5051
Widget build(BuildContext context, WidgetRef ref) {
5152
final router = ref.watch(routerProvider);
53+
final brightness = MediaQuery.platformBrightnessOf(context);
54+
final isDark = brightness == Brightness.dark;
55+
final fTheme = isDark ? FThemes.zinc.dark : FThemes.zinc.light;
5256

53-
return MaterialApp.router(
54-
title: 'Fullstack Starter',
55-
theme: AppTheme.light,
56-
darkTheme: AppTheme.dark,
57-
themeMode: ThemeMode.system,
58-
routerConfig: router,
59-
localizationsDelegates: const [
60-
GlobalMaterialLocalizations.delegate,
61-
GlobalWidgetsLocalizations.delegate,
62-
GlobalCupertinoLocalizations.delegate,
63-
],
64-
supportedLocales: const [Locale('ko'), Locale('en'), Locale('ja')],
57+
return FTheme(
58+
data: fTheme,
59+
child: MaterialApp.router(
60+
title: 'Fullstack Starter',
61+
theme: AppTheme.light,
62+
darkTheme: AppTheme.dark,
63+
themeMode: ThemeMode.system,
64+
routerConfig: router,
65+
localizationsDelegates: const [
66+
GlobalMaterialLocalizations.delegate,
67+
GlobalWidgetsLocalizations.delegate,
68+
GlobalCupertinoLocalizations.delegate,
69+
...FLocalizations.localizationsDelegates,
70+
],
71+
supportedLocales: const [Locale('ko'), Locale('en'), Locale('ja')],
72+
),
6573
);
6674
}
6775
}

0 commit comments

Comments
 (0)