Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Microapps e Flutter: Escalando o desenvolviment...
Search
Vinícius Oliveira
January 29, 2022
Programming
510
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Microapps e Flutter: Escalando o desenvolvimento mobile
Vinícius Oliveira
January 29, 2022
More Decks by Vinícius Oliveira
See All by Vinícius Oliveira
Evolução da Arquitetura do Magalu e os Desafios da Modularização
viniciusmo
0
66
Construindo SDKs móveis escaláveis (KMM + Clean Architecture) - caso de uso unicoIDTech
viniciusmo
0
59
Flutter Brasil - Caso de Uso Unico 2022
viniciusmo
0
80
CODECON - Design System - Genoma
viniciusmo
0
85
Estendendo seu app com Flutter
viniciusmo
0
160
Miniapps Magalu: Transformando um Super App em um SO
viniciusmo
0
460
Mobile Platform Teams: Como construímos e entregamos SDK`s escaláveis com qualidade.
viniciusmo
0
140
Treinando um modelo com AutoML Vision Edge
viniciusmo
0
110
Other Decks in Programming
See All in Programming
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
120
Loosening the Reins: Go Generics Get More Flexible
kuro_kurorrr
0
330
承認済みなのに差戻しできてしまうバグ、型で潰せます
shinchit
0
110
Claude CodeとAgentCore Gatewayを繋ぐ際の認証認可 / Authentication and authorization when connecting Claude Code with AgentCore Gateway
har1101
2
380
komatsuna「分散システムにおけるバグ分析手法」
komatsunaqa
0
280
いまどきの Codex で開発する visionOS アプリの開発スタイルについて
karad
0
160
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
1.2k
FastAPI の並行処理モデルを完全に理解する
hoto17296
8
3k
仕様書を書く前にハーネスを作る - Agent Native開発は「探索を速く、判定を固く」
gotalab555
4
1.8k
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
1
2k
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
580
ソフトウェアラスタライザ
fadis
1
660
Featured
See All Featured
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
390
The Pragmatic Product Professional
lauravandoore
37
7.4k
Discover your Explorer Soul
emna__ayadi
2
1.3k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
510
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
2
3.8k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
Designing Powerful Visuals for Engaging Learning
tmiket
1
510
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
410
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
810
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.4k
Transcript
Microapps e Flutter: Escalando o desenvolvimento mobile MOBILE Vinícius Moisés
Tech Lead Rodrigo Plácido Tech Lead
Grupo Boticário 2 GRUPO BOTICÁRIO Representante Eudora Revendedor O Boticário
O Boticário Minha Revenda Digital Beleza na Web
Cenário 3 CENÁRIO - Dois apps que resolvem o mesmo
problem a - Stacks diferente s - Times distinto s - Duas bases de códig o - Feature não é compartilhada Representante Eudora Revendedor O Boticário
Como escalar?
Flutter 5 FLUTTER - Performanc e - Integração com código
nativ o - Movimento de mercado
Arquitetura de microapps 6 ARQUITETURA DE MICROAPPS - Modula r
- Agnóstica a marc a - Testabilidad e - Manutençã o - Autonomia squad s - Feature disponível em todos app s - Produtividade
7 ARQUITETURA DE MICROAPPS
IMG Microapp 8 ARQUITETURA DE MICROAPPS
IMG App 9 ARQUITETURA DE MICROAPPS class EudoraApp extends MainModule
{ @override List<Bind> get binds => [ Bind((_) => EudoraBloc()), ... ]; @override List<ModularRouter> get routers => [ ModularRouter('/login', module: LoginMicroApp()), ... ]; @override Widget get bootstrap => EudoraWidget(); }
Microapp 10 ARQUITETURA DE MICROAPPS class LoginMicroApp extends ChildModule {
@override List<Bind> get binds { final authenticationRepository = AuthRepositoryImpl(); return [ Bind((i) => AuthBloc(authenticationRepository: authenticationRepository)), Bind((i) => ForgotPasswordBloc()) ]; } @override List<ModularRouter> get routers => [ ModularRouter('/login', child: (_, args) => LoginPage()), ModularRouter('/forgot_password', child: (_, args) => ForgotPasswordPage()), ]; static Inject get to => Inject<LoginMicroApp>.of(); }
Design System
IMG Design System 12 DESIGN SYSTEM - Agnóstico a marc
a - Baseado em temas
IMG Microapp Login 13 DESIGN SYSTEM
IMG Theme 14 DESIGN SYSTEM class EudoraTheme implements Theme {
@override FontFamily fontFamily() { return FontFamily(primary: 'MyriadPro', secondary: 'OpenSans'); } @override ThemeColor color() { return ThemeColor( appBackground: Color(0xfff6f6f6), brandPrimary: Color(0xff472d75), ...); } @override FontSize fontSize() { return FontSize( bodyMedium: 3.5 * baseValue, auxiliarSmall: 3 * baseValue, ...); } @override BorderWidth borderWidth() {...} @override CornerRadius cornerRadius() {...} @override Margin margin() {...} @override Padding padding() {...} }
Testes
IMG Unitários 16 TESTES blocTest( 'should emit [PaymentLoadInProgress, PaymentLoadSuccess] when
PaymentStarted is added', build: () => paymentBloc, act: (paymentBloc) { when(basketClient.getOrderPayment()) .thenAnswer((_) => Future.value(orderPayment)); paymentBloc.add(PaymentStarted()); }, expect: [ PaymentLoadInProgress(), PaymentLoadSuccess( paymentPlans: filteredPayments, total: orderPayment.total, subtotal: orderPayment.subtotal, ) ], );
IMG Widgets 17 TESTES testWidgets('should call bloc event when button
is clicked', (tester) async { await tester.pumpWidget(_buildApp()); await tester.pumpAndSettle(); await tester.tap(find.text(Strings.buttonGetPassword)); await tester.pumpAndSettle(); verify(forgotPasswordBloc.add(ForgotPasswordRequested(email: ''))) .called(1); });
IMG Integração 18 TESTES test('should return ProductResponse when search', ()
async { final term = 'term'; final page = 1; final pageSize = 20; final expectedResponse = ProductSearchResponseExpected() final mockResponse = MockResponse() ..httpCode = 200 ..body = await 'product_search_response.json'.read() ..headers = {'content-type': 'application/json; charset=utf-8'}; mockWebServer.enqueueResponse(mockResponse); final response = await searchDataProvider.search(term, page, pageSize); final request = mockWebServer.takeRequest(); expect(request.uri.path, '/search/products'); expect(request.method, 'GET'); expect(expectedResponse, response); });
CI/CD
IMG CI/CD 20 CI/CD - Monorep o - Bitris e
- fastlan e - dartanalyze r - Danger
Obrigadx! MOBILE