-
Notifications
You must be signed in to change notification settings - Fork 19
Architecture Overview
So, you've opened the repo and found a bunch of folders. Don't panic.
We organize the project as a monorepo containing multiple packages. This helps us separate the "app logic" from the "design system" and the "linting rules."
All the code that matters lives in the packages/ directory.
This is the main Flutter application. It contains 99% of the business logic, screens, and data handling. If you're fixing a bug or adding a feature, you'll be working here.
This is our internal design system. It contains reusable widgets (cards, buttons, icons) and theme definitions.
-
Why separate it? It forces us to build generic, reusable UI components that aren't tightly coupled to the app's specific logic.
-
Rule of Thumb: If you are building a generic "Card" that just displays text, it probably belongs here. If it fetches data from an API, it belongs in
uni_app.
This package contains our custom linting rules. It ensures we all write code the same way.
We loosely follow the Model-View-Controller (MVC) pattern.
If you look inside packages/uni_app/lib/, you'll see the structure reflects this:
This folder defines what our data looks like and holds the application state.
-
entities/: Plain Dart classes that represent things likeExam,Course, orRestaurant. Many of these are annotated for the database (ObjectBox). -
providers/: The glue that holds the app together. We use Riverpod here to manage state and expose data to the UI.- See specific docs: State Management (Riverpod)
This is what the user sees.
- Organized by feature (e.g.,
schedule/,exams/,profile/). - Each folder usually contains the main page file (e.g.,
schedule_page.dart) and awidgets/folder for parts specific to that page.
This is where we handle fetching data, parsing it, and saving it.
-
fetchers/: Classes responsible for getting data. They decide whether to pull from the network or local storage. -
parsers/: Our app often has to scrape HTML from the university portal. This folder contains the messy logic that turns raw HTML strings into beautiful Dart objects. -
local_storage/: Interfaces for our ObjectBox database.
You'll also see a few other important directories in lib/:
Sigarra is the name of the university's information system. This folder contains the specific logic for interacting with its endpoints (both API and HTML scraping).
Handling authentication with the university system is complex. This folder manages the login flows, session persistence, and cookies.
- See specific docs: Authentication Flow
DO NOT EDIT FILES HERE. These are files created automatically by build_runner and intl_utils. They handle things like JSON serialization, database adapters, and translation strings.
- See specific docs: Code Generation
Here is how data usually moves through the app:
-
View: A user opens the Schedule Page. The widget asks the
schedule_providerfor data. -
Model (Provider): The provider checks if it has data. If not, it calls the
ScheduleFetcher. -
Controller (Fetcher):
- The
ScheduleFetchercheckslocal_storagefor cached data. - If the cache is empty or expired, it calls the
NetworkRouter.
- The
- Network: The app requests the schedule from Sigarra (HTML or API).
-
Controller (Parser): The raw response is passed to a
Parser, which converts it into a list ofLectureobjects. - Controller (Storage): The fetcher saves these new objects to the database for next time.
- Model (Provider): The provider updates its state with the new list.
- View: The UI rebuilds to show the schedule.