Universe/release v1 - #61
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR looks like the first “release” cut that wires together several cross-cutting features across the monorepo (backend Fastify API + Next.js frontend + Flutter app), notably: in-app notifications + push integration, calendar CRUD, lost & found “community board”, and RAG pipeline improvements.
Changes:
- Added a backend in-app notification center (DB table + API) and integrated it into key flows (gate scans, attendance, messages, announcements, results) plus Flutter UI/badges.
- Added calendar module end-to-end (backend routes + frontend teacher/admin pages + shared calendar API client).
- Expanded lost & found to include a community board + comments API and new admin/teacher UI pages; plus various UI cleanup (removed placeholder preferences/dark mode).
Reviewed changes
Copilot reviewed 93 out of 99 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Reworked top-level product/architecture documentation for the “Universe-System” monorepo. |
| package-lock.json | Lockfile updates for new deps (e.g., react-hot-toast) and transitive changes. |
| firebase-debug.log | Removed generated debug log from repo. |
| apps/frontend/src/shared/lib/api-client.ts | New shared fetch helper for frontend API calls. |
| apps/frontend/src/shared/components/layout/sidebarConfig.ts | Added “Lost & Found” menu entry for admin. |
| apps/frontend/src/shared/components/layout/Sidebar.tsx | Removed placeholder dark mode toggle from sidebar footer. |
| apps/frontend/src/features/school/lib/school-api.ts | Extended overview stats type to include classroom present count. |
| apps/frontend/src/features/rag/lib/rag-api.ts | Updated policy document model to use status + error_message fields. |
| apps/frontend/src/features/calendar/lib/calendar-api.ts | New calendar API wrapper using shared api-client. |
| apps/frontend/src/app/teacher/profile/page.tsx | Removed unused preference toggles/UI. |
| apps/frontend/src/app/teacher/overview/page.tsx | Absentees stat now uses classroom-present metric. |
| apps/frontend/src/app/teacher/lost-and-found/page.tsx | Teacher lost & found page now loads from backend + uses toast feedback. |
| apps/frontend/src/app/teacher/calendar/page.tsx | Teacher calendar now loads events from backend API and adds refresh hook. |
| apps/frontend/src/app/security/profile/page.tsx | Removed unused preference toggles/UI. |
| apps/frontend/src/app/layout.tsx | Added react-hot-toast Toaster at the app root. |
| apps/frontend/src/app/admin/students/page.tsx | Simplified tabs (general only) and adjusted selection behavior. |
| apps/frontend/src/app/admin/profile/page.tsx | Removed unused preference toggles/UI. |
| apps/frontend/src/app/admin/overview/policies/page.tsx | Updated document status UI (processing/completed/failed) with error tooltip. |
| apps/frontend/src/app/admin/lost-and-found/page.tsx | New admin lost & found management page hitting backend board endpoints. |
| apps/frontend/src/app/admin/calendar/page.tsx | Admin calendar now does CRUD via backend calendar API. |
| apps/frontend/package.json | Added react-hot-toast dependency. |
| apps/flutter/test/widget_test.dart | Replaced widget boot smoke test with NotificationModel unit test. |
| apps/flutter/pubspec.yaml | Added app_settings dependency. |
| apps/flutter/pubspec.lock | Locked app_settings and transitive deps. |
| apps/flutter/lib/main.dart | Injected new viewmodels/services into UniverseApp construction. |
| apps/flutter/lib/firebase_options.dart | Switched Android Firebase config to dart-define environment values. |
| apps/flutter/lib/features/splash/views/welcome_screen.dart | Removed “Skip (Dev)” button from welcome screen. |
| apps/flutter/lib/features/settings/views/terms_of_service_screen.dart | Added Terms of Service screen. |
| apps/flutter/lib/features/settings/views/settings_screen.dart | Wired notification toggles to a SettingsViewModel + added policy/TOS navigation. |
| apps/flutter/lib/features/settings/views/privacy_policy_screen.dart | Added Privacy Policy screen. |
| apps/flutter/lib/features/settings/viewmodels/settings_viewmodel.dart | Added settings state management + push permission handling. |
| apps/flutter/lib/features/settings/repositories/settings_repository.dart | Added settings API repository for Flutter. |
| apps/flutter/lib/features/settings/models/settings_model.dart | Added settings model + JSON mapping/copyWith. |
| apps/flutter/lib/features/notifications/views/notifications_screen.dart | Replaced mock notifications with real list powered by NotificationsViewModel. |
| apps/flutter/lib/features/notifications/viewmodels/notifications_viewmodel.dart | Added notification list/unread state + optimistic mark-read. |
| apps/flutter/lib/features/notifications/repositories/notifications_repository.dart | Added notifications API repository (list/count/mark read). |
| apps/flutter/lib/features/notifications/models/notification_model.dart | Added notification model + derived UI metadata + relative time formatting. |
| apps/flutter/lib/features/messages/views/teacher_inbox_screen.dart | Optimistic send UX + pending state indicator + error snackbars. |
| apps/flutter/lib/features/messages/viewmodels/messages_viewmodel.dart | Added optimistic “pending” message insertion with rollback on failure. |
| apps/flutter/lib/features/messages/models/message_models.dart | Added isPending field + copyWith; excluded isPending from JSON caching. |
| apps/flutter/lib/features/lost_and_found/viewmodels/lost_found_viewmodel.dart | Added lost & found board viewmodel. |
| apps/flutter/lib/features/lost_and_found/repositories/lost_found_repository.dart | Added lost & found API repository for Flutter. |
| apps/flutter/lib/features/lost_and_found/models/lost_found_model.dart | Added lost & found post/comment models and status mapping. |
| apps/flutter/lib/features/dashboard/views/dashboard_screen.dart | Added notification badge counts + pull-to-refresh + bell overlay fed by real notifications. |
| apps/flutter/lib/features/contact_teacher/views/teacher_chat_screen.dart | Optimistic send UX + pending indicator + error snackbar. |
| apps/flutter/lib/features/chatbot/views/chatbot_screen.dart | Added “thinking” placeholder bubble/indicator for better bot UX. |
| apps/flutter/lib/features/auth/viewmodels/auth_viewmodel.dart | Wrapped biometric auth in try/catch with a user-facing error state. |
| apps/flutter/lib/features/attendance/views/attendance_screen.dart | Added “late/unmarked” status color handling. |
| apps/flutter/lib/core/services/firebase_service.dart | Added local notification payload deep-linking + permission request helper + message callbacks. |
| apps/flutter/lib/core/navigation/app_router.dart | Added routes for Privacy Policy and Terms of Service. |
| apps/flutter/lib/core/di/service_locator.dart | Registered new repositories/viewmodels (settings, lost&found, notifications). |
| apps/flutter/lib/core/constants/app_routes.dart | Added route constants for privacy and terms screens. |
| apps/flutter/lib/core/api/api_endpoints.dart | Added notifications API endpoint constants. |
| apps/flutter/lib/app.dart | Wired FCM events to NotificationsViewModel + deep-link routing; added providers. |
| apps/flutter/android/app/google-services.json | Removed committed Firebase config (now injected by CI). |
| apps/flutter/android/app/build.gradle.kts | Added release signing via key.properties with debug fallback. |
| apps/flutter/android/.gitignore | Ensured google-services.json is ignored (CI-injected). |
| apps/backend/src/modules/users/users.routes.ts | Added authenticated /settings endpoints for user settings. |
| apps/backend/src/modules/users/users.controller.ts | Implemented getSettings/updateSettings backed by prisma.userSettings. |
| apps/backend/src/modules/users/settings.schema.ts | Added zod schema for settings updates. |
| apps/backend/src/modules/school/school.service.ts | Added todayClassroomPresent metric to overview stats. |
| apps/backend/src/modules/results/results.service.ts | Notified parents when results are published. |
| apps/backend/src/modules/rag/services/generation.service.ts | Increased context size + added general-knowledge fallback/disclaimer behavior. |
| apps/backend/src/modules/rag/services/chunker.service.ts | Updated PDF chunker to use new pdf-parse API and ensure worker cleanup. |
| apps/backend/src/modules/rag/controllers/query.controller.ts | Added general-answer fallback when retrieval returns no chunks. |
| apps/backend/src/modules/rag/controllers/ingest.controller.ts | Migrated policy docs to status field + stored error_message on failure. |
| apps/backend/src/modules/rag/controllers/documents.controller.ts | Exposed status + error_message in document list API. |
| apps/backend/src/modules/notifications/notifications.service.ts | Added notifyUser/notifyUsers helpers (persist in-app + gate push via settings). |
| apps/backend/src/modules/notifications/notifications.routes.ts | Added authenticated notifications API routes. |
| apps/backend/src/modules/notifications/notifications.controller.ts | Implemented list/unread-count/mark-read/read-all endpoints. |
| apps/backend/src/modules/messages/messages.controller.ts | Switched message push to notification service (persist + push). |
| apps/backend/src/modules/lost-found/lost-found.schema.ts | Added createCommentSchema for comments API. |
| apps/backend/src/modules/lost-found/lost-found.routes.ts | Added community board and comment endpoints. |
| apps/backend/src/modules/lost-found/lost-found.controller.ts | Implemented community board aggregation and comment creation. |
| apps/backend/src/modules/gate/gate.scheduler.ts | Added parent notifications for daily auto-checkout. |
| apps/backend/src/modules/gate/gate.controller.ts | Switched parent gate push to notification service (persist + push). |
| apps/backend/src/modules/calendar/calendar.schema.ts | Added zod schemas for calendar CRUD. |
| apps/backend/src/modules/calendar/calendar.routes.ts | Added authenticated calendar CRUD routes (admin-only for writes). |
| apps/backend/src/modules/calendar/calendar.controller.ts | Implemented calendar CRUD using Prisma. |
| apps/backend/src/modules/attendance/attendance.controller.ts | Attendance timeline now unions attendance + gate dates; added parent notifications on mark/submit. |
| apps/backend/src/modules/announcements/announcements.controller.ts | Added notifyUsers for app users (parents/teachers) + push-only for students. |
| apps/backend/src/app.ts | Registered new calendar and notifications route modules. |
| apps/backend/prisma/schema.prisma | Added Notification, CalendarEvent, UserSettings, LostFoundComment, and PolicyDocument status fields. |
| apps/backend/prisma/rag_raw_sql.sql | Added explicit GRANTs for Supabase roles + hybrid_search EXECUTE grants. |
| apps/backend/prisma/policy_document_status.sql | SQL migration script for policy document status/error_message. |
| apps/backend/prisma/notifications_table.sql | SQL script to create notifications table/indexes (idempotent). |
| apps/backend/package.json | Removed @types/pdf-parse dev dependency. |
| .github/workflows/flutter-release.yml | Added APK build + release workflow with secret injection and signing. |
| .github/workflows/ci.yml | Added PR CI workflow (backend unit+integration tests, flutter tests). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+10
to
+16
| const res = await fetch(`${BASE}${path}`, { | ||
| credentials: 'include', | ||
| headers: { | ||
| ...(hasBody ? { 'Content-Type': 'application/json' } : {}), | ||
| ...options.headers, | ||
| }, | ||
| ...options, |
Comment on lines
+61
to
+80
| const fetchItems = useCallback(async () => { | ||
| const res = await request<BoardPost[]>("/api/lost-found/board"); | ||
| if (res.ok && mountedRef.current) { | ||
| const mapped: LostFoundItem[] = res.data.map((item) => ({ | ||
| id: item.id, | ||
| type: item.type, | ||
| title: item.title, | ||
| description: item.description, | ||
| location: item.location, | ||
| date: item.timeAgo, | ||
| postedBy: item.authorName, | ||
| postedByRole: item.role as PostedByRole, | ||
| status: item.status === "unclaimed" || item.status === "open" ? "active" : "claimed", | ||
| bgColor: item.type === "lost" ? "bg-red-50" : "bg-emerald-50", | ||
| tags: [] | ||
| })); | ||
| setItems(mapped); | ||
| setIsLoading(false); | ||
| } | ||
| }, []); |
Comment on lines
+123
to
134
| const endpoint = form.type === 'found' ? '/api/lost-found/items' : '/api/lost-found/reports'; | ||
| const body = form.type === 'found' ? { | ||
| item_name: form.title, | ||
| description: form.description, | ||
| found_at: form.location, | ||
| found_date: form.date || new Date().toISOString() | ||
| } : { | ||
| item_name: form.title, | ||
| description: form.description, | ||
| location: form.location, | ||
| date: form.date || new Date().toISOString().split("T")[0], | ||
| postedBy: "Samantha Perera", | ||
| postedByRole: "teacher", | ||
| status: "active", | ||
| bgColor: form.type === "lost" ? "bg-orange-100" : "bg-teal-100", | ||
| tags: [], | ||
| student_id: "", // Teacher posting lost report needs a student ID? Maybe only for parents. | ||
| date_lost: form.date || new Date().toISOString() | ||
| }; |
Comment on lines
+109
to
+121
| const endpoint = form.type === 'found' ? '/api/lost-found/items' : '/api/lost-found/reports'; | ||
| const body = form.type === 'found' ? { | ||
| item_name: form.title, | ||
| description: form.description, | ||
| found_at: form.location, | ||
| found_date: form.date || new Date().toISOString() | ||
| } : { | ||
| item_name: form.title, | ||
| description: form.description, | ||
| student_id: "", // Admin might need to select a student if posting LOST. | ||
| date_lost: form.date || new Date().toISOString() | ||
| }; | ||
|
|
Comment on lines
+122
to
+128
| const res = await request(endpoint, { method: 'POST', body: JSON.stringify(body) }); | ||
| if (res.ok) { | ||
| toast.success("Posted successfully"); | ||
| setShowModal(false); | ||
| setForm(EMPTY_FORM); | ||
| window.location.reload(); | ||
| } else { |
| cache: true | ||
|
|
||
| - name: Inject google-services.json | ||
| run: echo '${{ secrets.GOOGLE_SERVICES_JSON }}' > apps/flutter/android/app/google-services.json |
Comment on lines
+11
to
+16
| Future<Map<String, String>> _getAuthHeaders() async { | ||
| final token = await _secureStorage.getAccessToken(); | ||
| return { | ||
| 'Authorization': 'Bearer $token', | ||
| }; | ||
| } |
Comment on lines
+11
to
+16
| Future<Map<String, String>> _getAuthHeaders() async { | ||
| final token = await _secureStorage.getAccessToken(); | ||
| return { | ||
| 'Authorization': 'Bearer $token', | ||
| }; | ||
| } |
Comment on lines
+35
to
+44
| Future<void> loadSettings() async { | ||
| setLoading(true); | ||
| try { | ||
| final remoteSettings = await _repository.getSettings(); | ||
| _settings = remoteSettings; | ||
| print('Settings loaded: ${_settings?.toJson()}'); | ||
| notifyListeners(); | ||
| } catch (e) { | ||
| print('Error loading settings: $e'); | ||
| setError(e.toString()); |
Comment on lines
10
to
+15
| static const FirebaseOptions android = FirebaseOptions( | ||
| apiKey: 'AIzaSyDummy1234567890ABCDEFGHIJKLMNOPQRS', | ||
| appId: '1:451261949462:android:abc123def456ghi789jkl', | ||
| messagingSenderId: '451261949462', | ||
| apiKey: String.fromEnvironment('FIREBASE_API_KEY', defaultValue: 'AIzaSyA26E5DcOTTE-tDHurMeU6j7d6A1QPgrvs'), | ||
| appId: String.fromEnvironment('FIREBASE_APP_ID', defaultValue: '1:746560263890:android:2ef9040c8213ecf5e53f0b'), | ||
| messagingSenderId: '746560263890', | ||
| projectId: 'universe-fireabse', | ||
| storageBucket: 'universe-fireabse.appspot.com', | ||
| storageBucket: 'universe-fireabse.firebasestorage.app', |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.