
Explore how to build a scalable Flutter app using clean architecture, Supabase backend, and Bloc state management, demonstrated through the Community Board App to ensure maintainable, testable code.
Explore building a scalable Flutter app with Supabase by implementing a notification-based community board featuring real-time comments, likes, post-creation notifications, authentication, profile management, infinite scrolling, and event-based synchronization.
Explore an event-based architecture with loose coupling and state synchronization for post creation, updates, deletions, profile changes, and post lists, using a Binix monorepo to separate features into packages.
Develop a scalable Flutter app using Supabase, clean architecture, and Block for state management through hands-on backend and frontend development.
Learn to use the dataclass-generated extension in VS Code to auto-create data classes with constructors, toString, copyWith, fromJSONFactory, toJSON, and equality support.
Test the dataclass generator by creating, copying, and comparing a person object; override equality and hashCode with equatable for value-based equality.
Master bloc and freezed extensions for flutter: auto-generate bloc and cubit boilerplate with bloc extension, and use code actions and snippets like pts and fromJson for json_serializable.
Explore how Dart function types implement a call method to make functions callable objects and enable conditional nullable calls; create callable classes to simplify clean architecture use cases.
Explore error handling with the either type to show and manage errors concisely in API calls, replacing repetitive try-catch with a type-safe, functional approach using a simple fetch product example.
Explore the either type to separate error and success paths with left and right, where left holds error and right holds value, and handle them using fold or match.
Learn how to use the json_serializable package to serialize and deserialize data classes with fromJSON and toJSON methods, converting snake_case to camelCase, and generate code with BuildRunner.
Demonstrates json_serializable primer by building a user data retrieval flow with a UserRepository, json decoding, type casting, and error handling for UserNotFound, including converting snake_case to camelCase.
Learn how the injectable package automates GetIt registrations to simplify dependency management in growing Flutter apps, using add singleton, add lazy singleton, and add factory annotations for loose coupling.
Learn how Injectable automates dependency registration in the Injectable Primer app, which fetches random advice from AdviceLib, and configure GetIt with AddModule, AddSingleton, AddLazySingleton, and AddInjectable, using BuildRunner and InjectableGenerator.
Explore a clean architecture folder structure for a flutter app, wiring RandomAdviceRepository, data sources, api service, and RandomAdvicePage, while injecting http client for testability and flexibility.
Learn to implement a random advice feature using bloc/qubit patterns, a random advice repository, and injectable for automatic dependency injection.
build a community board app using clean architecture with auth, post, profile, and search features, following Robert Martin's three-tier approach and promoting loose coupling.
Explore Roessi-Martin's clean architecture, detailing four concentric circles, the dependency rule, and how inner business rules guide scalability, maintainability, and easier testing of code.
Explore how to apply clean architecture by refining the three-tier structure—UI, business logic, and repository—through loosely coupled interfaces, the domain layer with entities and use cases, and state management considerations.
understand how 3-tier clean architecture separates domain into use cases and presentation, with a controller, use case interactor, and presenter coordinating input, business logic, and ui state via ports.
Explore clean architecture principles that separate domain logic from external data sources using repositories, a data layer, and domain repository interfaces to enable dependency inversion and scalable data access.
Design a robust, feature-driven folder structure for a clean architecture Flutter app, organizing code into core and features with domain, data, and presentation layers.
Adopt a monorepo architecture to scale Flutter projects with clean architecture, Bloc state management, and Supabase, unifying core, domain, and data layers for reusable, consistent code.
Create a monorepo with core, domain, and data super base packages, configure pubspec.yaml with publishTo none, implement a barrel file to expose APIs via a use case interface with fpdart.
Configure domain and data superbase packages for a flutter app, set pubspec dependencies (equatable, fvdart, core, domain), create src, enable code generation with json serializable and build runner.
Configure analysis_options.yaml to apply Flutter lint rules and exclude build and tool directories. Tailor analyzer and linter settings to reduce warnings, address generated files, and enforce practices for Flutter code.
Set up the blog app by creating core and features folders under lib, then configure a SuperBase project and environment variables with a .env file.
Delete the existing code, make main async, load env vars with flutter.env, initialize SuperBase, configure getit and Injectable, and run a basic MaterialApp to verify setup.
Build a robust backend with Postgres and Supabase by creating the profiles table via the SQL editor, linking to auth.users, and defining id, username, role, and timestamps.
Separate public profiles from the Auth.Users table to enhance security, data separation, and flexibility, linking profiles to users with a foreign key and on delete cascade for integrity.
Store avatars and post images via Supabase storage using public buckets and text URLs, improving performance, cost, and scalability with rls security.
Enable row-level security on the profiles table and define policies for authenticated reads and updates to each user's own profile, with column-level protections and default denies.
Implement row level security on posts table to control who can see, create, modify, and delete posts, using GetUserRole and isAdmin to enforce admin-only creation and author-based updates and deletions.
Set up row level security policies for the comments and likes tables to restrict actions to authenticated users and their own records, with admins allowed to delete any comments.
Explore implementing row level security for storage in Superbase, defining select, insert, update, and delete policies for post images and avatars, including ownership checks and bucket-specific rules.
Define the public.handleNewUser function and onAuth user-created trigger to automatically create a profile in public.profiles on sign-up, using security definer to run with the owner's privileges.
Implement TriggerSetTimeStamp and before update triggers on profiles, posts, and comments to auto set the updated_at timestamp to now, ensuring a single write and avoiding after-update loops.
Create the update comments count function and trigger to automatically adjust the post's commentsCount on insert or delete, using security definer to bypass RLS and modify the POST table.
Develop UpdateLikesCount trigger and OnLikeChangeUpdatePostLikesCount to auto-update post likes in the posts table, and implement HandleLike to toggle likes via JSON responses.
Create the UpdateUserProfile function with security definer to atomically update the username and avatar URL in public.profiles and auth.users for the current user, and return the updated profiles set.
Create post display and comment display views to join posts, profiles, and likes for a clean main feed while enforcing security invoker and aliases.
Implement the get_my_posts function to fetch a user's posts with pagination and the search_posts function to perform full-text search on titles and content using a gene index, returning PostDisplayView rows.
Learn how to implement createPost, updatePost, createComment, and updateComment functions with Supabase, returning PostDisplayView and CommentDisplayView while wiring authentication and routing in a scalable flutter app.
Implement the authentication feature with sign-up, login, and logout, and describe how Supabase issues and stores a JWT, auto-refreshes it, and links new users to public.profiles.
Define core error handling by separating exceptions and failures, and build a domain with their classes plus a use case interface for parameterized and no-param flows.
Define the domain layer for authentication with a pure user entity, an auth repository interface, and use cases for sign up, login, and logout, decoupled from the outside world.
Establish import principles to avoid circular dependencies with barrel files. Import specific files within a package and avoid cross-folder barrel files to prevent crashes and debugging headaches.
Explore how the data layer defines the user model by extending the domain entity, parsing JSON from external sources, and implementing factory constructors from Supabase users and profile data.
Define an abstract auth remote data source interface and implement it with Supabase, enabling dependency inversion and testability; include onAuthStateChanged, signup, login, and logout with robust error handling.
Implement the AuthRepositoryInput class that implements the AuthRepository interface to wire AuthRemoteDataSource, manage onAuthStateChanges via a string controller, and handle signup, login, and logout with left failures or right null.
Learn how the presentation layer wires blocks, use cases, repositories, and data sources with injectable, register module, and lazy singletons, guided by builder runner in watch mode.
Build a sealed class based state template for a scalable flutter app, using generics, Equatable, and factory constructors to manage initial, loading, success, and failure with preview data for CRUD.
define an authentication bloc to monitor the global auth state via superbase, handle logout, and propagate states (unknown, authenticated, unauthenticated) through an authentication state with a separate authentication events system.
Register the authentication block as a singleton to ensure a single source of truth for app-wide authentication state, avoiding race conditions; the block subscribes to onAuthStateChanged and GoRouter redirects accordingly.
Create a reusable login bloc by aliasing sealed login states with TypeDev, define LoginRequest with email and password, and use an injectable LoginUseCase to emit loading, success (void), or failure.
Create the signup bloc mirroring the login flow, define sign-up state and events with a username, wire the sign-up use case, and handle loading, success, and failure.
Set up a routing backbone with GoRouter to display login and signup UI, implementing a two-widget page and view structure, and outline the app’s pages for posts, profiles, and search.
Define routes and names as constants with RootPath to prevent typos, covering splash, login, signup; post, search, profile; post edit, profile edit; create, user detail, post detail.
Create a stateful shell for bottom navigation using Go router, with a scaffold-with-navbar wrapping tabs and a three-item bottom bar.
Configure GoRouter with a go-router-refresh-stream to monitor authentication state and drive redirects, showing splash or navigating to login, signup, or post content based on auth status.
Present a GoRouter setup for a scalable Flutter app, defining splash, login, sign-off, post creation and user detail routes, bottom navigation with indexedStack, and an authentication-aware error page.
Register gorouter as a singleton in the di module using createRouter and the authentication block, then wire it to materialApp.router via routerConfig and verify in the emulator.
Open the loginpage.dat file, convert LoginView to a StatefulWidget, and wire a form with a global key and email and password controllers.
Connect the login UI to a login block, validate inputs, and respond to state changes with a block consumer, showing loading indicators and error snack bars.
Transform the signup page from stateless to stateful, reuse login logic, add username and confirm password fields with validators, and wire signup events to complete the flow.
Test sign-up and login workflows using the authentication dashboard and email provider settings. Implement a log off button, validate inputs, and explore role changes via triggers and jsonb metadata.
Define the postDisplay entity in the domain layer, using postDisplayView to assemble post, profile, and like data for the UI, and generate equatable and copyWidth utilities to maintain immutable data.
Define a post repository interface and a getPost use case to fetch posts with pagination (offset and limit), returning either a failure or a list of postDisplay entities.
Implement PostDisplayModel in the data layer to fulfill the post repository contract, parse JSON from Supabase into a PostDisplay entity, and map snake_case JSON to camelCase Dart fields with JSONSerializable.
Learn to implement a clean architecture data layer by defining an abstract PostRemoteDataSource, wiring a SuperBasePostRemoteDataSource, and a PostRepositoryInput that handles pagination with offset and limit, including error handling.
Register GetPostUseCase, PostRepository, and PostRemoteDataSource in the module using lazy singletons and interfaces, and expose the use case as a factory for the posts presentation.
Create post list bloc in the presentation layer to fetch posts from Supabase, display them with pagination, refresh, and likes, and define UI states and events for loading and paging.
Develop the PostListBlock to connect PostList events with the getPost use case, manage loading with an isBusy flag, and implement pagination and refresh for infinite scrolling.
Explore post listing in a Flutter app using bloc for state management, displaying postList with pagination, pull-to-refresh, and postCard like interactions.
build a post card widget to display author avatar, name, date, title, image, content, and like and comment counts, with navigation to post detail and user detail via go router.
Apply clean architecture to post creation, moving from domain to data to presentation layers, and implement use cases, DTOs, and repository interfaces for image upload and post storage.
Define post data source in the data layer using SuperBase, implementing createPost and uploadPostImage in SuperBaseRemoteDataSource. Connect to the repository to expose post creation and image upload results via PostDisplayModel.
Implement post creation in the blog app's presentation layer by wiring CreatePostUseCase and UploadPostImageUseCase in the RegisterModule, and building PostFormState, PostFormEvent, and PostFormBlock to manage image upload and post creation.
Creates a post-form page for creating and editing posts, with image selection and preview, form validation, and bloc-driven submission connected to the post-form blog via getIt.
Read authentication state with Bloc Builder to show admin-only post creation, then test creating posts with images via the PostCreate route in a Supabase-backed flow.
Publish and listen to global events with a singleton global event bus to update the post list when a new post is created via PostCreatedDispatch.
Compare the global event bus for instant in-app updates with super bass realtime across devices, and learn cost-conscious strategies for real-time updates in a scalable Flutter app.
Build the domain and data layers for a post detail page by fetching post details and comments. Define PostDisplay and CommentDisplay entities and implement getPostDetail and getComments use cases.
Learn how the data layer uses Superbase to implement post detail and comments, with fromJSON, JSONSerializable, and JSONKey mappings for snake_case to camelCase fields in display models.
Register getPostDetailUseCase and getCommentsUseCase in the di module, create PostDetailBlock to manage post detail and comments, define PostDetailStatus and PostDetailState with PostDetailFetched, and run build_runner.
Create a comment list block for a post detail page, implementing loading, loaded, failure, fetching next page, refreshing, and transient failure states with pagination via a get comments use case.
Create a post detail page by wiring post detail and common list blocks with multi-block provider, enabling pagination and a nested post and comment list in a custom scroll view.
Learn to build a common comment list in flutter with a commentCard, including avatar, username, time, and content, plus loading, error states, and user detail navigation.
Implement a toggle like feature across domain, data, and presentation layers, using optimistic updates and a global event bus to synchronize like status and count.
Explore implementing an optimistic like feature in a Flutter app using PostListBloc and GlobalEventBus, including toggleLikeUseCase, optimistic UI updates, server sync, and cross-page post updates.
Implement a dedicated like feature in PostDetailBlock with a PostDetailLike toggled event, optimistic updates, server calls, and a global event bus synchronizing likes across screens.
Define create, edit, and delete comment as abstract domain functions and implement them via the post repository across the domain, data, and presentation layers.
Learn to add, edit, and delete comments via a remote data source in a scalable Flutter app, with authentication, RPC calls, and repository integration.
Register use cases in the di module and extend the comment list bloc with edit, delete, and create events, updating post details via get post detail use case.
Explore the CommentListBloc's handling of CarmenDeleted and comment edits, including optimistic state updates, error handling, post detail refresh, and triggering __commentListRefillRequested to refresh comments.
Add a reusable comment input field with an edit/delete menu on each comment card at the post detail page, wired to the comment list block by postId and auto-scroll.
On the post detail page, the comment card now shows edit and delete menus; authors can edit, admins can delete; includes dialogs and progress indicators.
Learn domain, data, and presentation approach to post deletion and editing in a Flutter app, implementing deletePost and deletePostFolder, updatePost, and related use cases.
Learn to implement post deletion and update in a clean architecture Flutter app with Supabase, including data source interfaces, authentication checks, storage deletion, and RPC-based updates.
Register delete post and delete post folder use cases in the di module, then implement post detail block deletion and a global event bus to refresh the post list.
Extend the post form block to support editing by adding prefilled data via post form prefilled, a post edited event, and use cases getPostDetailUseCase and updatePostUseCase.
Enable author-only edit and delete actions on the post detail page, navigate to the post form with existing data, and confirm deletion through a confirmation dialog.
Teach how post form page supports edit mode by pre-filling data from the existing post, managing images, and providing consistent loading states using a saving flag within Bloc architecture.
Implement the profile feature's domain layer by defining the profile repository and use cases (get profile and update profile), including avatar upload and deletion.
Implement the data layer by building a profile repository and a remote data source for superbase, converting exceptions to domain failures and providing getProfile, updateProfile, uploadAvatar, and deleteAvatar.
Registers data sources, repositories, and use cases in the profile feature with di lazy singleton, builds the my profile page, fetches the current user via getProfileUseCase, and shows admin posts.
Define a getMyPost use case in the domain layer to fetch a user's posts by userId with offset and limit, preserving post feature and profile data separation.
Explore building a reactive Flutter app with a global event bus, registering GetMyPostUseCase, and implementing ProfileUpdatedDispatched to refresh posts across blocks when a profile changes.
Implement the MyPostListBloc in Flutter to manage a user-specific post list, reusing PostListState, handling fetch, refresh, next-page loading, like toggles, and global events via use cases.
Explore implementing myPostListBloc interactions, including optimistic like toggles, server requests, and rollback on failure, while syncing updates via globalEventBus, and handling post create, update, delete, and profile changes.
Leverage profile and post list blocks to build a dynamic MyProfile page, using multi-block providers, getIt, and event-driven loading, with BlockBuilder and BlockListener for loading states, errors, and retry.
Build the UnderscoreProfileContentStayList and MyPostList widgets to show admin profiles and posts, enable pull-to-refresh and infinite scroll via ScrollNotificationType NotificationListener, and use cached network avatars.
Build a user profile page in a scalable Flutter app using bloc, fetch profiles by user id, and show admin posts; create a user profile blog with events and states.
Build a dynamic user profile page with the User Profile Block and My Post List Block. Load data via cascade events and handle transient failures with a Block Listener.
Edit profile page uses a form UI to edit name and avatar, passes data between blocks with image picker, and triggers update profile use case, notifying the global event bus.
Add an edit button to myProfilePage and navigate to the edit profile page, wiring a profile block and a stateful form with image selection and validation.
Implement a clean architecture search feature that finds posts and users by keywords, defining domain specifications, a repository interface, and use cases bridging domain, data, and presentation.
Implement the data layer's repository interface and use Supabase data sources to fetch posts and users, parsing JSON data into postDisplayModel and userModel for the domain layer.
Register data sources, repositories, and use cases for the search feature in the presentation layer, then build the search bloc with lazy singleton di registration to manage ui state.
Implement a debounced search bloc using event transformer to connect query changes and tab switches to live user and post searches, handling loading, success, and failure states with clean architecture.
Explain the search post alike toggled flow in search bloc, implementing optimistic post updates. Update via like toggle use case and rollback on failure using transient failure and server results.
Inject the search block into the search page, wrap with the block provider, inject via getIt, and use a text editing controller with a tab interface for users and posts.
Develop a Flutter search page for users and posts with loading, error, and empty states, displaying avatars and navigable results via GoRouter and like toggles.
Refactor the flutter app blocks by centralizing identical pagination and toggle-like logic into dedicated handlers. Maintain independent event handling for the blocks and implement pagination handler and toggle-like handler.
Build a generic paginationhandler that injects a FetchPostStrategy, supports FetchNextPage and FetchOneToRefill, uses GetLatestState to refresh the latest state, and updates posts with CopyThePost, CopiedHasReachedMax, and TransientFailure.
Refactor bloc pagination using a PageNationHandler to fetch next pages and refill posts in PostList and MyPostList blocks, improving maintainability and reliability in a scalable flutter app.
Develop a reusable ToggleLikeHandler for post lists, leveraging optimistic updates, a like API, and a global event bus, while noting PostDetailBlock handles a single post.
Refactor bloc across PostListBlock, myPostList block, and search blocks by introducing ToggleLikeHandler, wiring ToggleLikeUseCase and GlobalEventBus, and updating OnPostLikeToggleEventHandler to emit state changes and reflect likes.
"Go beyond Flutter basics and become an architect capable of designing professional, production-ready apps."
Are you ready to move past simple Counter or TODO apps and tackle the complex challenges of real-world services? If you’ve experienced the frustration of code becoming tangled as you add features, or felt the fragility of your app with every small change, this course is designed for you.
This is more than just a tutorial on building an app; it is a deep dive into proven development methodologies for creating scalable and maintainable applications that stand the test of time.
[2026 Verified & Maintained]
The architectural patterns and Supabase configurations taught here are continuously monitored against the latest Flutter ecosystem to ensure they remain the industry standard today.
Why This Course Matters in the AI Era
In an era where AI can generate code snippets in seconds, what is the role of a professional developer?
Beyond Snippets: AI is excellent at writing functions, but it cannot yet design a complex, interconnected system. Understanding Clean Architecture means you know how to organize those AI-generated pieces into a scalable whole.
The Architect’s Advantage: As AI lowers the barrier to entry for coding, the market will be flooded with "fragmented code." The true value will lie in the Architect—the one who can manage technical debt, ensure maintainability, and design a robust "vessel" (Architecture) to hold the logic.
Future-Proof Your Career: This course evolves you from a "coder" who follows instructions to an "architect" who masters AI as a tool, rather than being replaced by it.
The Three Pillars of This Course
We will build a high-performance 'Community Board' app from scratch, grounded in three essential technical pillars for large-scale projects:
Robust Architecture (Clean Architecture): Bring order to chaotic code. Learn to separate concerns into distinct layers, creating a structure that is easy to test, maintain, and evolve.
Modern Backend (Supabase): Bypass complex server setups. Leverage Supabase—a powerful Backend-as-a-Service—to implement databases, authentication, and realtime features in a fraction of the time.
Efficient State Management (BLoC & Event Bus): Master BLoC, the industry standard for Flutter, and combine it with a Global Event Bus architecture to synchronize data across multiple screens with elegance and precision.
Key Learning Features
Build a Real-World Community App: Implement industry-standard features including Authentication, Post CRUD, Real-time likes/comments, Profile management, and Reactive search.
Professional Monorepo Setup: Learn to decouple features into independent packages to maximize code reusability and manage large-scale projects like a pro.
Advanced Streams & Real-time Control: Master Supabase Realtime for instant data syncing and utilize advanced stream techniques like Debounce and switchMap for an optimized search experience.
The Essence of Scalability: Design an architecture so flexible that you could swap your state management tool without touching a single line of your core business logic.
Curriculum Roadmap
Foundations: Master the VS Code environment and essential productivity tools to eliminate boilerplate code.
Architecture: Establish core principles of Clean Architecture, focusing on the dependency rule and separation of concerns.
Infrastructure: Build a Monorepo environment and design a Supabase backend (SQL, RLS, Functions, and Triggers).
Development: Implement core features (Auth, Posts, Search) using BLoC combined with a Global Event Bus.
Advanced: Deep dive into Supabase Realtime for live data detection and UI synchronization.
Next Level: Project review and a strategic look at how this architecture extends to other state management libraries.
Who is this course for?
Flutter developers who have built basic apps and are ready to tackle professional, production-ready architectures.
Developers struggling with maintenance as their projects grow and seeking "Clean Architecture" as a definitive solution.
Solo developers or startup engineers who want to launch high-performance apps quickly using Supabase (BaaS).
Job seekers looking to showcase "Scalable App Design" and "Monorepo Management" skills in their professional portfolio.
Prerequisites
Flutter & Dart Basics: You should be comfortable with basic widgets and have a foundational understanding of asynchronous programming (async/await).
State Management Exposure: Experience with any state management solution (Provider, Riverpod, GetX, etc.) is helpful. Even if you are new to BLoC, you will be able to follow along.
Basic SQL Knowledge: A basic understanding of reading/writing data is recommended. Complex database policies (RLS) and functions will be covered step-by-step.
Lecture Materials and Source Code Provided
High-quality PDF slides: PDF presentation materials containing key theories and architecture diagrams for each section are provided. (Download from the Resources tab for each section)
Final source code provided:
Foundation Level: Complete code for productivity tools and core syntax (such as data_class) covered in Section 3 is provided.
Main Project: The monorepo structure and final implementation code for the entire community_board app starting in Section 4 is provided.
Links to the source code and usage instructions will be provided in detail in the first lecture of Sections 3 & 4.
Don't just learn 'how' to build; understand 'why' we design this way. Join me on this journey to elevate your development skills to the next level!