{"id":50695762,"url":"https://github.com/hngprojects/zedu-desktop","last_synced_at":"2026-06-09T06:08:40.536Z","repository":{"id":356825651,"uuid":"1228282778","full_name":"hngprojects/zedu-desktop","owner":"hngprojects","description":"Flutter Repo For Zedu Desktop","archived":false,"fork":false,"pushed_at":"2026-05-09T22:43:22.000Z","size":1486,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-10T00:37:16.030Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hngprojects.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-03T20:40:32.000Z","updated_at":"2026-05-09T22:24:43.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hngprojects/zedu-desktop","commit_stats":null,"previous_names":["hngprojects/zedu-desktop"],"tags_count":null,"template":false,"template_full_name":"hngprojects/flutter-starter","purl":"pkg:github/hngprojects/zedu-desktop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hngprojects%2Fzedu-desktop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hngprojects%2Fzedu-desktop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hngprojects%2Fzedu-desktop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hngprojects%2Fzedu-desktop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hngprojects","download_url":"https://codeload.github.com/hngprojects/zedu-desktop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hngprojects%2Fzedu-desktop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34093841,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-09T06:08:39.658Z","updated_at":"2026-06-09T06:08:40.531Z","avatar_url":"https://github.com/hngprojects.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zedu Desktop\n\nA lean Flutter app using Clean Architecture, Material 3, and Riverpod. The codebase is organized for desktop and mobile targets, with an **auth** feature (login, session, and API wiring) as the reference vertical slice.\n\n## Stack\n\n- Flutter 3.x / Dart `^3.11`\n- Material 3, Roboto and Lato fonts (see `pubspec.yaml`)\n- Riverpod, GetIt, GoRouter\n- Dio, `flutter_dotenv`\n- `flutter_secure_storage`, `flutter_svg`\n- Mocktail (tests), `flutter_lints` plus strict analyzer language flags in `analysis_options.yaml`\n\n## Project layout\n\n```txt\n.\n├── .env.example          # Tracked template; bundled as a Flutter asset\n├── lib/\n│   ├── main.dart\n│   ├── app/\n│   │   └── app.dart\n│   ├── core/\n│   │   ├── core.dart\n│   │   ├── api_utils/        # ApiBaseService, failures, auth interceptor\n│   │   ├── config/           # AppConfig, env loader, flavor\n│   │   ├── locator/\n│   │   ├── navigator/        # GoRouter (e.g. login route)\n│   │   ├── secure_storage/\n│   │   ├── theme/\n│   │   ├── utils/\n│   │   └── widgets/\n│   └── features/\n│       ├── features.dart\n│       └── auth/\n│           ├── auth.dart\n│           ├── data/\n│           ├── domain/\n│           └── presentation/\n├── test/\n│   ├── helpers/\n│   ├── unit/features/auth/data/\n│   └── widget/features/auth/presentation/views/\n├── analysis_options.yaml\n├── pubspec.yaml\n└── README.md\n```\n\n## Architecture\n\nEach feature owns its UI, business rules, repository contract, and data implementation.\n\n```txt\npresentation -\u003e domain \u003c- data\n```\n\n- `app`: bootstrap and root `MaterialApp.router`.\n- `core`: shared infrastructure (DI, HTTP, env, routing, theme, secure storage).\n- `features`: vertical modules; today this is **`auth`** (login flow and session models).\n\nExample flow:\n\n```txt\nLoginView\n  -\u003e auth providers (Riverpod)\n  -\u003e AuthRepository\n  -\u003e AuthRemoteDataSource\n  -\u003e ApiBaseService\n```\n\n## Core rules\n\nKeep `core` small. Add shared code only when more than one feature needs it.\n\nGood `core` candidates: app config, dependency injection, API client and failures, navigation, secure storage, logging, theme, and cross-cutting utilities.\n\n## Barrel exports\n\nEvery folder that exposes reusable Dart files should have a barrel file.\n\nUse **exactly these two root-barrel imports** when you need shared core plus feature exports (same order and URIs as `lib/features/auth/data/datasource/auth_remote_datasource.dart`):\n\n```dart\nimport 'package:zedu/core/core.dart';\nimport 'package:zedu/features/features.dart';\n```\n\nIf you rename the app in `pubspec.yaml`, update the `package:` name in both lines to match.\n\nExport chain:\n\n```txt\nleaf files -\u003e layer barrel -\u003e feature barrel -\u003e features.dart\nshared core files -\u003e core.dart\n```\n\nRules:\n\n- Add new exports whenever you add a reusable file.\n- Prefer `core/core.dart` for shared app infrastructure.\n- Prefer `features/features.dart` when code needs feature-level exports.\n- Inside a feature, use the narrowest useful barrel when `features.dart` would create an import cycle—often a **layer** barrel (`data/data.dart`, `domain/domain.dart`, `presentation/presentation.dart`) or a **subfolder** barrel.\n\n**Narrower than `features.dart`:** import that feature’s barrel first, e.g. `lib/features/auth/auth.dart`. Reach for layer or subfolder barrels only when you need a smaller slice to break a cycle or keep dependencies obvious.\n\n## Configuration\n\nEnv keys are read from **dotenv** after `loadAppEnv()` in `main.dart`. The repo bundles **`.env.example`** as a Flutter asset so `flutter analyze` and first runs work on a clean clone without a local `.env`.\n\n`loadAppEnv()` tries `.env` first, then `.env.example`. Only `.env.example` is listed under `flutter.assets` by default (avoids missing-asset warnings when `.env` is gitignored). If you want to package a root `.env` for a build, add `- .env` under `flutter.assets` and ensure that file exists on the machine that runs `flutter build`.\n\n1. Copy `.env.example` to `.env` for local overrides, or edit values in `.env.example` for experiments (avoid committing secrets).\n2. Prefer CI variables or `--dart-define` for production secrets.\n\n```txt\nAPI_BASE_URL=https://example.com/api\nUSE_MOCK_DATA=false\nAPP_FLAVOR=development\n```\n\n`USE_MOCK_DATA` accepts `true` / `false` (also `1` / `0`, `yes` / `no`). `APP_FLAVOR` accepts `development`, `staging`, or `production` (case-insensitive).\n\n### Overrides for CI or release builds\n\n`--dart-define` overrides dotenv when you need non-file config:\n\n```sh\nflutter run --dart-define=API_BASE_URL=https://api.example.com --dart-define=USE_MOCK_DATA=false --dart-define=APP_FLAVOR=production\n```\n\nDefaults when neither `.env` / `.env.example` nor defines set a value (see `AppConfig.fromEnvironment` and `AppFlavorConfig`):\n\n```txt\nAPI_BASE_URL=https://example.com/api\nUSE_MOCK_DATA=false\nAPP_FLAVOR=development\n```\n\n## Clone\n\nThe repository root **is** the Flutter project (`pubspec.yaml` and `lib/` at the top level).\n\n```sh\ngit clone https://github.com/hngprojects/zedu-desktop.git\ncd zedu-desktop\n```\n\n## Quick start\n\n```sh\nflutter pub get\nflutter run\n```\n\nOptional: create a local `.env` from the template.\n\n```sh\ncp .env.example .env\n```\n\nWindows (PowerShell):\n\n```powershell\nCopy-Item .env.example .env\n```\n\n## Common commands\n\n```sh\ndart format lib test\nflutter analyze\nflutter test\n```\n\nUse `flutter analyze` for this project so the Flutter SDK and bundled assets resolve correctly.\n\n## Testing\n\nTests mirror the app layout:\n\n- `test/helpers`: reusable test setup (e.g. `TestMaterialApp`)\n- `test/unit`: datasources, repositories, and services\n- `test/widget`: views and important UI flows\n\nMock dependencies at the layer boundary being tested.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhngprojects%2Fzedu-desktop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhngprojects%2Fzedu-desktop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhngprojects%2Fzedu-desktop/lists"}