bloc_concurrency
Benutzerdefinierte Ereignistransformatoren, inspiriert von ember concurrency. Speziell für den Einsatz mit dem Bloc-Zustandsverwaltungs-Paket entwickelt.
Eine Mobile Anwendung für die MIREA - Russische Technologische Universität, die einen Stundenplan, Nachrichten und viele andere Funktionen enthält
Benutzerdefinierte Ereignistransformatoren, inspiriert von ember concurrency. Speziell für den Einsatz mit dem Bloc-Zustandsverwaltungs-Paket entwickelt.
Eine Erweiterung der Bloc-Zustandsverwaltungsbibliothek, die Zustände automatisch speichert und wiederherstellt.
Öffnen Sie Bildschirme, Snackbars und Dialoge ohne Kontext, verwalten Sie Zustände und injizieren Sie Abhängigkeiten einfach mit GetX.
Flutter-Plugin für Google Analytics for Firebase, eine App-Messlösung, die Einblicke in die App-Nutzung und Benutzerengagement auf Android und iOS bietet.
Flutter-Plugin für Firebase Cloud Messaging, eine plattformübergreifende Messaging-Lösung, mit der Sie Nachrichten zuverlässig auf Android und iOS übermitteln können.
Ein Builder, der generierte stark typisierte Routenhelfer für das Paket: go_router unterstützt
v5.9.3Ein Flutter-Plugin zur Anpassung von Bildschirm und Schriftgröße. Garantiert ein gutes Aussehen auf verschiedenen Modellen
v8.3.2Der Nr. 1 nichtkommerziell ausgerichtete Kartenclient für Flutter: einfach zu bedienen, vielseitig, anbieterunabhängig, vollständig plattformübergreifend und 100 % rein Flutter
v10.1.0Offizielle Erweiterungsbild, unterstützt Platzhalter (Laden)/Fehlerzustand, Netzwerk-Cache, Zoom/Pan, Fotobetrachter, Seitenauszug, Editor (Zuschneiden, Drehen, Spiegeln), Malen usw.
v3.2.1Hochgradig anpassbarer, funktionsreicher Kalender-Widget für Flutter.
Ein Flutter-Widget zum Rendern von statischem HTML und CSS als Flutter-Widgets.
v3.0.0Dieses Erweiterungspaket ermöglicht
{"path":"packages/academic_calendar"}^1.0.1^3.5.0{"path":"packages/ads_ui"}^1.1.0{"path":"packages/analytics_repository"}^7.0.0{"path":"packages/app_ui"}{"path":"packages/article_repository"}^9.2.0^0.3.0^4.1.3^5.1.1^3.2.0^3.0.0{"path":"packages/campus_repository"}^5.0.0^1.16.2^1.1.2^1.18.0{"path":"packages/community_catalog_repository"}{"path":"packages/community_repository"}{"path":"packages/connectivity_client"}^1.0.2{"path":"packages/deep_link_client"}{"git":{"url":"https://github.com/0niel/device_calendar.git","ref":"develop"}}^5.1.2^1.0.2{"git":{"url":"https://github.com/0niel/dot_navigation_bar.git","ref":"master"}}^0.6.0^1.1.1^2.0.5^10.0.1^12.0.0-beta.4^2.0.0^12.1.2^4.4.0^16.1.1^1.1.1{"sdk":"flutter"}^4.5.0^9.1.1^3.3.1^3.0.0-beta.2^3.0.0-beta.2^3.0.0-beta.2^3.0.0-beta.2^3.0.0-beta.2^2.0.8{"sdk":"flutter"}^8.2.2^3.1.0+7447^2.4.3^3.3.1^11.5.1^11.0.0^5.9.3^10.0.0^1.1.0^0.7.0^0.8.0^2.0.5^6.0.0{"sdk":"flutter"}^0.8.03.1.0{"path":"packages/friends_repository"}{"path":"packages/gamification_repository"}^14.0.2^17.1.00.9.1^1.2.2^1.1.5^11.0.0^1.1.2^0.20.24.12.0^0.9.1{"path":"packages/local_auth_client"}{"path":"packages/local_notifications_client"}{"path":"packages/local_notifications_repository"}^2.0.2+1^1.1.1{"path":"packages/lost_and_found_repository"}^0.5.0^1.15.0^2.0.0{"path":"packages/mini_apps_repository"}^7.2.0{"path":"packages/network_location_client"}{"path":"packages/news_blocks"}{"path":"packages/news_blocks_ui"}{"path":"packages/news_repository"}{"path":"packages/nfc_pass_client"}{"path":"packages/nfc_pass_repository"}^4.4.0{"path":"packages/package_info_client"}^10.1.0^1.0.0^1.0.1^2.1.13.12.0^2.11.0^2.5.2+1{"path":"packages/permission_client"}{"path":"packages/storage/persistent_storage"}^0.15.0^3.0.2{"path":"packages/preferences_repository"}{"path":"packages/promo_repository"}^4.1.0^3.0.0^1.5.1^0.28.0^3.3.2{"path":"packages/schedule"}{"path":"packages/schedule_exporter_repository"}{"path":"packages/schedule_repository"}{"path":"packages/storage/secure_storage"}9.20.09.20.09.20.0{"path":"packages/service_catalog_repository"}{"path":"packages/share_launcher"}^13.1.0^2.0.11^0.2.12^1.0.2^7.4.0{"path":"packages/stac_bridge"}{"path":"packages/storage/storage"}^1.1.0^2.1.1{"path":"packages/study_groups_repository"}{"path":"packages/auth_client/supabase_authentication_client"}^2.8.3^32.1.23^32.2.3^3.0.3^0.10.0{"path":"packages/auth_client/token_storage"}^1.3.3any^2.0.0^0.1.0{"path":"packages/university_provider"}^6.1.12{"path":"packages/user_repository"}^4.5.3^0.9.0^2.9.2^0.4.0+20.2.9^6.6.1^8.0.0^1.1.2^1.1.2^10.0.02.15.1any^5.3.2^0.14.1{"sdk":"flutter"}3.2.5^4.1.16.14.0^1.0.5^2.4.210.3.03.1.3Englischer Projektschnappschuss. Aktuelle Inhalte auf GitHub.
Открытая платформа студенческого приложения на Flutter. Репозиторий можно адаптировать под другой университет без форка бизнес-логики: tenant, публичный брендинг и deep links задаются конфигурацией, а университетские источники данных подключаются через нормализованный ingest-контракт Supabase.
Конфигурация по умолчанию сохраняет совместимость с РТУ МИРЭА. Встроенный MIREA-фетчер выключен по умолчанию и не должен использоваться для другого tenant.
lib/<feature>, а
переиспользуемые клиенты, модели и репозитории — в Dart workspace packages/.bloc/hydrated_bloc для состояния, yx_scope для dependency injection и
go_router для навигации.json_serializable для генерируемых immutable-моделей и JSON DTO.Основной поток данных:
внешний источник -> Python worker -> Edge Function /ingest
-> Supabase RPC/таблицы -> repository -> BLoC -> Flutter UI
Flutter не должен обращаться к внутренним таблицам или использовать
service_role. Привилегированная запись контента проходит через защищённую
функцию supabase/functions/ingest, а схема БД
изменяется только миграциями из
supabase/migrations.
Нужны Flutter, FVM и Java 17 для
Android. Версия Flutter закреплена в .fvmrc.
dart pub global activate fvm
fvm install
fvm flutter pub get
Создайте две локальные compile-time конфигурации:
cp .env.example .env
cp config/university.example.json config/university.local.json
В PowerShell используйте Copy-Item вместо cp. В .env укажите публичные
SUPABASE_URL и SUPABASE_PUBLISHABLE_KEY. В
config/university.local.json задайте tenant и брендинг. Затем проверьте
конфигурацию и сгенерируйте код:
fvm dart run tool/configure_university.dart
fvm dart run build_runner build
Запуск development flavor на Android/iOS/macOS:
fvm flutter run \
--flavor development \
--target lib/main/main_development.dart \
--dart-define-from-file=.env \
--dart-define-from-file=config/university.local.json \
--dart-define-from-file=config/firebase.local.json
Firebase-файл опционален: без него Analytics и FCM корректно отключаются.
Нативные google-services.json, GoogleService-Info.plist и сгенерированный
firebase_options.dart не являются частью открытого исходного кода.
Для Windows уберите --flavor development. Подробности о схеме конфигурации и
режиме --check описаны в
docs/university-configuration.md.
Локальные .env, tenant-файлы, Firebase-конфигурация, ключи подписи и Telegram
session-файлы нельзя коммитить. Пример university config содержит только
публичные значения и не заменяет настройку собственных Firebase/Supabase
проектов.
Локальная конфигурация находится в supabase/config.toml. Для работы с
миграциями нужен Supabase CLI и Docker:
supabase start
supabase db reset
Не изменяйте уже применённые миграции: создавайте новую через
supabase migration new <name>. Секрет ingest-функции хранится только на
сервере и в локальном окружении worker.
Для одного tenant задайте Edge secrets INGEST_API_KEY и
INGEST_ORGANIZATION_ID. Общий backend нескольких университетов должен
использовать INGEST_TENANT_KEYS — JSON-карту organization_id к отдельному
ключу каждого worker. Не используйте один неприкреплённый ключ для всех tenant.
Worker находится в tools/social_media_fetcher и использует
uv. Он нормализует контент и отправляет его в
Edge ingest; напрямую в БД не пишет.
Для RSS/Atom и официальных API предпочтителен no-code путь через self-hosted
n8n: импортируйте готовый
rss-to-ingest.json и
используйте HTTP Request node для Facebook Graph API, YouTube, Mastodon или
иного документированного API. Python-коннектор оставлен для источников, которым
нужна пользовательская сессия или особая обработка, например Telegram Stories.
Полный контракт и правила расширения — в
tools/social_media_fetcher/docs/architecture.md.
cd tools/social_media_fetcher
cp .env.example .env
uv sync --locked
uv run python worker.py
MIREA_ENABLED=true допустим только при APP_ORGANIZATION_ID=mirea. Telegram
подключается явно через TELEGRAM_CHANNELS и TELEGRAM_STORY_CHANNELS. Для
пользовательской Telegram-сессии используйте отдельный согласованный аккаунт и
setup_telegram_session.py; полученный session string считается секретом и не
должен попадать в логи, issues или Git.
Stories-медиа загружается только через подписанные Storage URL. Workflow
cleanup-story-media.yml независимо от Telegram-сессии удаляет истёкшие и
осиротевшие объекты; для него задаются SUPABASE_URL,
INGEST_ORGANIZATION_ID и tenant-bound INGEST_API_KEY.
fvm dart analyze --fatal-warnings
fvm flutter test
cd tools/social_media_fetcher
uv run ruff format --check .
uv run ruff check .
uv run pytest
CI повторяет анализ и тесты Flutter и ключевых workspace-пакетов, проверки Python worker, format/lint/type-check Edge ingest и fresh replay Supabase миграций. CI имеет только read-доступ к репозиторию. Релиз Shorebird запускается только вручную отдельным workflow.
Перед pull request прочитайте CONTRIBUTING.md и CODE_OF_CONDUCT.md. Уязвимости нельзя публиковать в обычных issues — используйте SECURITY.md.
Проект распространяется по лицензии MIT.