From fbab4f729d24af4298dff54f7a8feaaf1fda4c27 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Wed, 4 Feb 2026 10:56:07 -0500 Subject: [PATCH 01/12] Bump client and staff app versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Increment build versions for mobile apps: krowwithus_client 0.0.1-M3+5 → 0.0.1-M3+6 and krowwithus_staff 0.0.1-M3+3 → 0.0.1-M3+4 in their pubspec.yaml files. No other changes. --- apps/mobile/apps/client/pubspec.yaml | 2 +- apps/mobile/apps/staff/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/mobile/apps/client/pubspec.yaml b/apps/mobile/apps/client/pubspec.yaml index c896944d..e59f8177 100644 --- a/apps/mobile/apps/client/pubspec.yaml +++ b/apps/mobile/apps/client/pubspec.yaml @@ -1,7 +1,7 @@ name: krowwithus_client description: "Krow Client Application" publish_to: "none" -version: 0.0.1-M3+5 +version: 0.0.1-M3+6 resolution: workspace environment: diff --git a/apps/mobile/apps/staff/pubspec.yaml b/apps/mobile/apps/staff/pubspec.yaml index 62c2ae21..5f76de72 100644 --- a/apps/mobile/apps/staff/pubspec.yaml +++ b/apps/mobile/apps/staff/pubspec.yaml @@ -1,7 +1,7 @@ name: krowwithus_staff description: "Krow Staff Application" publish_to: 'none' -version: 0.0.1-M3+3 +version: 0.0.1-M3+4 resolution: workspace environment: From ada3aa7ef3d9e4e25865671df27c606a7ad2e6e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Salazar?= <73718835+joshrs23@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:50:52 +0900 Subject: [PATCH 02/12] new instance for db validation dataconnect --- backend/dataconnect/dataconnect.dev.yaml | 13 ++ .../dataconnect/dataconnect.validation.yaml | 13 ++ makefiles/dataconnect.mk | 202 +++++++++++++++--- 3 files changed, 197 insertions(+), 31 deletions(-) create mode 100644 backend/dataconnect/dataconnect.dev.yaml create mode 100644 backend/dataconnect/dataconnect.validation.yaml diff --git a/backend/dataconnect/dataconnect.dev.yaml b/backend/dataconnect/dataconnect.dev.yaml new file mode 100644 index 00000000..39e01fdb --- /dev/null +++ b/backend/dataconnect/dataconnect.dev.yaml @@ -0,0 +1,13 @@ +specVersion: "v1" +serviceId: "krow-workforce-db" +location: "us-central1" +schema: + source: "./schema" + datasource: + postgresql: + database: "krow_db" + cloudSql: + instanceId: "krow-sql" + # schemaValidation: "STRICT" # STRICT mode makes Postgres schema match Data Connect exactly. + # schemaValidation: "COMPATIBLE" # COMPATIBLE mode makes Postgres schema compatible with Data Connect. +connectorDirs: ["./connector"] diff --git a/backend/dataconnect/dataconnect.validation.yaml b/backend/dataconnect/dataconnect.validation.yaml new file mode 100644 index 00000000..9e1775d6 --- /dev/null +++ b/backend/dataconnect/dataconnect.validation.yaml @@ -0,0 +1,13 @@ +specVersion: "v1" +serviceId: "krow-workforce-db-validation" +location: "us-central1" +schema: + source: "./schema" + datasource: + postgresql: + database: "krow_db" + cloudSql: + instanceId: "krow-sql-validation" + # schemaValidation: "STRICT" # STRICT mode makes Postgres schema match Data Connect exactly. + # schemaValidation: "COMPATIBLE" # COMPATIBLE mode makes Postgres schema compatible with Data Connect. +connectorDirs: ["./connector"] diff --git a/makefiles/dataconnect.mk b/makefiles/dataconnect.mk index ba7298ef..c2db1fd6 100644 --- a/makefiles/dataconnect.mk +++ b/makefiles/dataconnect.mk @@ -1,6 +1,47 @@ # --- Data Connect / Backend --- -.PHONY: dataconnect-enable-apis dataconnect-init dataconnect-deploy dataconnect-sql-migrate dataconnect-generate-sdk dataconnect-sync dataconnect-bootstrap-db check-gcloud-beta dataconnect-clean +# Usage examples: +# make dataconnect-sync DC_ENV=dev +# make dataconnect-seed DC_ENV=validation +# make dataconnect-clean DC_ENV=validation +# make dataconnect-generate-sdk DC_ENV=dev +# +DC_ENV ?= dev + +DC_SERVICE_DEV := krow-workforce-db +DC_SERVICE_VALIDATION := krow-workforce-db-validation + +ifeq ($(DC_ENV),dev) + DC_SERVICE := $(DC_SERVICE_DEV) +else ifeq ($(DC_ENV),validation) + DC_SERVICE := $(DC_SERVICE_VALIDATION) +else + $(error Invalid DC_ENV '$(DC_ENV)'. Use DC_ENV=dev or DC_ENV=validation) +endif + +.PHONY: dataconnect-enable-apis dataconnect-init dataconnect-deploy dataconnect-sql-migrate dataconnect-generate-sdk dataconnect-sync dataconnect-bootstrap-db check-gcloud-beta dataconnect-clean dataconnect-bootstrap-validation-db dataconnect-file dataconnect-file-validation dataconnect-file-dev dataconnect-seed dataconnect-test + +#creation dataconnect file +dataconnect-file: + @echo "--> Starting creation Firebase Data Connect schema file for service [$(DC_SERVICE)]..." + @test -f backend/dataconnect/dataconnect.$(DC_ENV).yaml || (echo "❌ Missing backend/dataconnect/dataconnect.$(DC_ENV).yaml" && exit 1) + @cp backend/dataconnect/dataconnect.$(DC_ENV).yaml backend/dataconnect/dataconnect.yaml + @echo "✅ Creation Data Connect file completed." + +#creation dev dataconnect file +dataconnect-file-dev: + @echo "--> Starting creation Firebase Data Connect schema file for service [$(DC_SERVICE)]..." + @test -f backend/dataconnect/dataconnect.dev.yaml || (echo "❌ Missing backend/dataconnect/dataconnect.dev.yaml" && exit 1) + @cp backend/dataconnect/dataconnect.dev.yaml backend/dataconnect/dataconnect.yaml + @echo "✅ Creation Data Connect file completed." + + +#creation validation dataconnect file +dataconnect-file-validation: + @echo "--> Starting creation Firebase Data Connect schema file for service [$(DC_SERVICE)]..." + @test -f backend/dataconnect/dataconnect.validation.yaml || (echo "❌ Missing backend/dataconnect/dataconnect.validation.yaml" && exit 1) + @cp backend/dataconnect/dataconnect.validation.yaml backend/dataconnect/dataconnect.yaml + @echo "✅ Creation Data Connect file completed." # Enable all required APIs for Firebase Data Connect + Cloud SQL dataconnect-enable-apis: @@ -14,63 +55,94 @@ dataconnect-enable-apis: @echo "✅ APIs enabled for project [$(GCP_PROJECT_ID)]." # Initialize Firebase Data Connect (interactive wizard). +# use only once per project dataconnect-init: @echo "--> Initializing Firebase Data Connect for alias [$(FIREBASE_ALIAS)] (project: $(GCP_PROJECT_ID))..." @firebase init dataconnect --project $(FIREBASE_ALIAS) @echo "✅ Data Connect initialization command executed. Follow the interactive steps in the CLI." # Deploy Data Connect schemas (GraphQL → Cloud SQL) -dataconnect-deploy: - @echo "--> Deploying Firebase Data Connect schemas to [$(ENV)] (project: $(FIREBASE_ALIAS))..." - @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) +dataconnect-deploy: dataconnect-file + @echo "--> Deploying Firebase Data Connect schemas to [$(ENV)] (service: $(DC_SERVICE)) (project: $(FIREBASE_ALIAS))..." + @firebase deploy --only dataconnect:$(DC_SERVICE) --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect deployment completed for [$(ENV)]." # Apply pending SQL migrations for Firebase Data Connect -dataconnect-sql-migrate: - @echo "--> Applying Firebase Data Connect SQL migrations to [$(ENV)] (project: $(FIREBASE_ALIAS))..." +dataconnect-sql-migrate: dataconnect-file + @echo "--> Applying Firebase Data Connect SQL migrations to [$(ENV)] (service: $(DC_SERVICE)) (project: $(FIREBASE_ALIAS))..." @firebase dataconnect:sql:migrate --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect SQL migration completed for [$(ENV)]." # Generate Data Connect client SDK for frontend-web and internal-api-harness -dataconnect-generate-sdk: +dataconnect-generate-sdk: dataconnect-file @echo "--> Generating Firebase Data Connect SDK for web frontend and API harness..." - @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) + @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect SDK generation completed for [$(ENV)]." # Unified backend schema update workflow (schema -> deploy -> SDK) -dataconnect-sync: - @echo "--> [1/3] Deploying Data Connect..." - @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) - @echo "--> [2/3] Applying SQL migrations..." - @firebase dataconnect:sql:migrate --project=$(FIREBASE_ALIAS) - @echo "--> [3/3] Regenerating SDK..." +dataconnect-sync: dataconnect-file + @echo "--> [1/3] Deploying Data Connect [$(DC_SERVICE)]..." + @firebase deploy --only dataconnect:$(DC_SERVICE) --project=$(FIREBASE_ALIAS) + @echo "--> [2/3] Applying SQL migrations [$(DC_SERVICE)]..." + @firebase dataconnect:sql:migrate $(DC_SERVICE) --project=$(FIREBASE_ALIAS) + @echo "--> [3/3] Regenerating SDK [$(DC_SERVICE)]..." @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) - @echo "✅ Data Connect SQL, deploy, and SDK generation completed for [$(ENV)]." + @echo "✅ Data Connect SQL, deploy, and SDK generation [$(ENV)]." # Execute seed in Firebase Data Connect -dataconnect-seed: - @echo "--> Exec seed in Firebase Data Connect..." - @firebase dataconnect:execute backend/dataconnect/functions/seed.gql --project=$(FIREBASE_ALIAS) +dataconnect-seed: dataconnect-file + @echo "--> Exec seed in Firebase Data Connect (service: $(DC_SERVICE))..." + @firebase dataconnect:execute backend/dataconnect/functions/seed.gql --project=$(FIREBASE_ALIAS) @echo "✅ Seed executed successfully." # Execute clean, to delete all the data in Firebase Data Connect -dataconnect-clean: - @echo "--> Exec clean all the data in Firebase Data Connect..." - @firebase dataconnect:execute backend/dataconnect/functions/clean.gql --project=$(FIREBASE_ALIAS) +dataconnect-clean: dataconnect-file + @echo "--> Exec clean all the data in Firebase Data Connect (service: $(DC_SERVICE))..." + @firebase dataconnect:execute backend/dataconnect/functions/clean.gql --project=$(FIREBASE_ALIAS) @echo "✅ Clean information executed successfully." # Run tests for Data Connect deployment and migrations -dataconnect-test: - @echo "--> Running Data Connect tests..." - @echo "--> [1/3] Deploying Data Connect..." - @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) --dry-run - @echo "--> [2/3] Applying SQL migrations..." +dataconnect-test: dataconnect-file + @echo "--> Running Data Connect tests (service: $(DC_SERVICE))..." + @echo "--> [1/2] Deploying Data Connect..." + @firebase deploy --only dataconnect:$(DC_SERVICE) --project=$(FIREBASE_ALIAS) --dry-run + @echo "--> [2/2] Applying SQL migrations..." @firebase dataconnect:sql:diff --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect tests completed." +dataconnect-backup-dev-to-validation: + @echo "🔍 Validating instances exist in [$(GCP_PROJECT_ID)]..." + @if ! gcloud sql instances describe krow-sql --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ + echo "❌ Dev instance 'krow-sql' not found in project $(GCP_PROJECT_ID)."; \ + exit 1; \ + fi + @if ! gcloud sql instances describe krow-sql-validation --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ + echo "❌ Validation instance 'krow-sql-validation' not found in project $(GCP_PROJECT_ID)."; \ + exit 1; \ + fi + @echo "✅ Instances found." + + @echo "🧰 Creating a backup on dev (krow-sql)..." + @gcloud sql backups create --instance=krow-sql --project=$(GCP_PROJECT_ID) >/dev/null + + @echo "🔎 Fetching latest backup ID..." + @LATEST_BACKUP_ID="$$(gcloud sql backups list --instance=krow-sql --project=$(GCP_PROJECT_ID) --sort-by=~endTime --limit=1 --format='value(id)')"; \ + if [ -z "$$LATEST_BACKUP_ID" ]; then \ + echo "❌ Could not find any backup ID for krow-sql."; \ + exit 1; \ + fi; \ + echo "✅ Latest backup ID: $$LATEST_BACKUP_ID"; \ + echo "⚠️ Restoring into validation..."; \ + gcloud sql backups restore $$LATEST_BACKUP_ID \ + --restore-instance=krow-sql-validation \ + --backup-instance=krow-sql \ + --project=$(GCP_PROJECT_ID) + + @echo "🎉 Done." + # ------------------------------------------------------------------- -# ONE-TIME FULL SETUP FOR CLOUD SQL + DATA CONNECT +# ONE-TIME FULL SETUP FOR CLOUD SQL + DATA CONNECT DEV # ------------------------------------------------------------------- # Check if gcloud and beta group are available @@ -85,7 +157,7 @@ check-gcloud-beta: } @echo "✅ gcloud CLI and 'gcloud beta' are available." -dataconnect-bootstrap-db: check-gcloud-beta +dataconnect-bootstrap-db: dataconnect-file-dev check-gcloud-beta @echo "🔍 Checking if Cloud SQL instance krow-sql already exists in [$(GCP_PROJECT_ID)]..." @if gcloud sql instances describe krow-sql --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ echo "⚠️ Cloud SQL instance 'krow-sql' already exists in project $(GCP_PROJECT_ID)."; \ @@ -112,7 +184,7 @@ dataconnect-bootstrap-db: check-gcloud-beta @echo "⚠️ Creating Firebase Data Connect service identity..." gcloud beta services identity create \ --service=firebasedataconnect.googleapis.com \ - --project=$(GCP_PROJECT_ID) + --project=$(GCP_PROJECT_ID) @echo "⚠️ Enabling IAM authentication on Cloud SQL instance krow-sql..." gcloud sql instances patch krow-sql \ @@ -124,9 +196,77 @@ dataconnect-bootstrap-db: check-gcloud-beta firebase dataconnect:sql:setup krow-workforce-db --project=$(FIREBASE_ALIAS) @echo "⚠️ Deploying initial Data Connect configuration..." - @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) + @firebase deploy --only dataconnect:$(DC_SERVICE_DEV) --project=$(FIREBASE_ALIAS) @echo "⚠️ Generating initial Data Connect SDK..." - @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) + @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) @echo "🎉 Cloud SQL + Data Connect bootstrap completed successfully!" + + +# ------------------------------------------------------------------- +# ONE-TIME FULL SETUP FOR CLOUD SQL + DATA CONNECT VALIDATEION +# ------------------------------------------------------------------- + +# Creates: krow-sql-validation + krow_db (inside it) + links service krow-workforce-db-validation +# Then clones data from krow-sql -> krow-sql-validation via backup/restore + +dataconnect-bootstrap-validation-database: dataconnect-file-validation + @echo "🔍 Checking if Cloud SQL instance krow-sql-validation already exists in [$(GCP_PROJECT_ID)]..." + @if gcloud sql instances describe krow-sql-validation --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ + echo "⚠️ Cloud SQL instance 'krow-sql-validation' already exists in project $(GCP_PROJECT_ID)."; \ + echo " If you need to recreate it, delete the instance manually first."; \ + exit 1; \ + fi + + @echo "⚠️ Creating Cloud SQL instance krow-sql-validation (tier: $(SQL_TIER))..." + gcloud sql instances create krow-sql-validation \ + --database-version=POSTGRES_15 \ + --tier=$(SQL_TIER) \ + --region=us-central1 \ + --storage-size=10 \ + --storage-auto-increase \ + --availability-type=zonal \ + --backup-start-time=03:00 \ + --project=$(GCP_PROJECT_ID) + + @echo "⚠️ Creating Cloud SQL database krow_db on krow-sql-validation..." + gcloud sql databases create krow_db \ + --instance=krow-sql-validation \ + --project=$(GCP_PROJECT_ID) + + @echo "⚠️ Enabling IAM authentication on Cloud SQL instance krow-sql-validation..." + gcloud sql instances patch krow-sql-validation \ + --project=$(GCP_PROJECT_ID) \ + --database-flags=cloudsql.iam_authentication=on \ + --quiet + + @echo "🔁 Creating a backup on dev instance (krow-sql) to clone data into validation..." + @echo " (Prereq: krow-sql must already exist and be stable.)" + gcloud sql backups create --instance=krow-sql --project=$(GCP_PROJECT_ID) + echo "✅ Backup creation started. Operation: $$BACKUP_OP" + + @echo "🔎 Fetching latest backup ID from krow-sql..." + @BACKUP_ID="$$(gcloud sql backups list --instance=krow-sql --project=$(GCP_PROJECT_ID) --limit=1 --sort-by=~endTime --format='value(id)')"; \ + if [ -z "$$BACKUP_ID" ]; then \ + echo "❌ Could not find a backup ID for krow-sql."; \ + exit 1; \ + fi; \ + echo "✅ Latest backup ID: $$BACKUP_ID"; \ + echo "⚠️ Restoring backup into krow-sql-validation..."; \ + gcloud sql backups restore $$BACKUP_ID \ + --restore-instance=krow-sql-validation \ + --backup-instance=krow-sql \ + --project=$(GCP_PROJECT_ID) + + @echo "⚠️ Linking Data Connect service (krow-workforce-db-validation) with Cloud SQL..." + @echo " When prompted, select instance: krow-sql-validation and database: krow_db" + firebase dataconnect:sql:setup krow-workforce-db-validation --project=$(FIREBASE_ALIAS) + + @echo "⚠️ Deploying Data Connect configuration ($(DC_SERVICE_VALIDATION))..." + @firebase deploy --only dataconnect:$(DC_SERVICE_VALIDATION) --project=$(FIREBASE_ALIAS) + + @echo "⚠️ Generating Data Connect SDK ($(DC_SERVICE))..." + @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) + + @echo "🎉 Validation Cloud SQL + Data Connect bootstrap completed successfully!" From eb149f680b1d0ef1deb8c68d292d475870b3012c Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Thu, 5 Feb 2026 00:18:34 -0500 Subject: [PATCH 03/12] Revert "Merge pull request #373 from Oloodi/368-sub-task-provision-and-copy-validation-database-instance" This reverts commit 8deb2931582d1fcc8f2b2a688f1085aca334f0db, reversing changes made to fbab4f729d24af4298dff54f7a8feaaf1fda4c27. --- .../presentation/pages/client_hubs_page.dart | 55 +---- .../settings_actions.dart | 2 +- .../navigation/home_navigator.dart | 6 +- .../presentation/pages/worker_home_page.dart | 3 +- .../blocs/shifts/shifts_bloc.dart | 70 +----- .../blocs/shifts/shifts_event.dart | 2 - .../blocs/shifts/shifts_state.dart | 5 - .../src/presentation/pages/shifts_page.dart | 25 +-- .../widgets/tabs/find_shifts_tab.dart | 6 - backend/dataconnect/dataconnect.dev.yaml | 13 -- .../dataconnect/dataconnect.validation.yaml | 13 -- backend/dataconnect/functions/seed.gql | 4 +- makefiles/dataconnect.mk | 202 +++--------------- makefiles/launchpad.mk | 4 +- 14 files changed, 49 insertions(+), 361 deletions(-) delete mode 100644 backend/dataconnect/dataconnect.dev.yaml delete mode 100644 backend/dataconnect/dataconnect.validation.yaml diff --git a/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/client_hubs_page.dart b/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/client_hubs_page.dart index aa3de3e2..85f60930 100644 --- a/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/client_hubs_page.dart +++ b/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/client_hubs_page.dart @@ -95,10 +95,10 @@ class ClientHubsPage extends StatelessWidget { ).add( ClientHubsIdentifyDialogToggled(hub: hub), ), - onDeletePressed: () => _confirmDeleteHub( - context, - hub, - ), + onDeletePressed: () => + BlocProvider.of( + context, + ).add(ClientHubsDeleteRequested(hub.id)), ), ), ], @@ -221,51 +221,4 @@ class ClientHubsPage extends StatelessWidget { ), ); } - - Future _confirmDeleteHub(BuildContext context, Hub hub) async { - final String hubName = hub.name.isEmpty ? 'this hub' : hub.name; - return showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext dialogContext) { - return AlertDialog( - title: const Text('Confirm Hub Deletion'), - content: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('Are you sure you want to delete "$hubName"?'), - const SizedBox(height: UiConstants.space2), - const Text('This action cannot be undone.'), - const SizedBox(height: UiConstants.space2), - Text( - 'Note that if there are any shifts/orders assigned to this hub we shouldn\'t be able to delete the hub.', - style: UiTypography.footnote1r.copyWith( - color: UiColors.textSecondary, - ), - ), - ], - ), - actions: [ - TextButton( - onPressed: () => Modular.to.pop(), - child: const Text('Cancel'), - ), - TextButton( - onPressed: () { - BlocProvider.of( - context, - ).add(ClientHubsDeleteRequested(hub.id)); - Modular.to.pop(); - }, - style: TextButton.styleFrom( - foregroundColor: UiColors.destructive, - ), - child: const Text('Delete'), - ), - ], - ); - }, - ); - } } diff --git a/apps/mobile/packages/features/client/settings/lib/src/presentation/widgets/client_settings_page/settings_actions.dart b/apps/mobile/packages/features/client/settings/lib/src/presentation/widgets/client_settings_page/settings_actions.dart index e044d1ec..e3e99090 100644 --- a/apps/mobile/packages/features/client/settings/lib/src/presentation/widgets/client_settings_page/settings_actions.dart +++ b/apps/mobile/packages/features/client/settings/lib/src/presentation/widgets/client_settings_page/settings_actions.dart @@ -83,7 +83,7 @@ class SettingsActions extends StatelessWidget { // Cancel button UiButton.secondary( text: t.common.cancel, - onPressed: () => Modular.to.pop(), + onPressed: () => Navigator.of(dialogContext).pop(), ), ], ), diff --git a/apps/mobile/packages/features/staff/home/lib/src/presentation/navigation/home_navigator.dart b/apps/mobile/packages/features/staff/home/lib/src/presentation/navigation/home_navigator.dart index cd9da6f6..9774cb07 100644 --- a/apps/mobile/packages/features/staff/home/lib/src/presentation/navigation/home_navigator.dart +++ b/apps/mobile/packages/features/staff/home/lib/src/presentation/navigation/home_navigator.dart @@ -31,11 +31,9 @@ extension HomeNavigator on IModularNavigator { /// Optionally provide a [tab] query param (e.g. `find`). void pushShifts({String? tab}) { if (tab == null) { - navigate('/worker-main/shifts'); + pushNamed('/worker-main/shifts'); } else { - navigate('/worker-main/shifts', arguments: { - 'initialTab': tab, - }); + pushNamed('/worker-main/shifts?tab=$tab'); } } diff --git a/apps/mobile/packages/features/staff/home/lib/src/presentation/pages/worker_home_page.dart b/apps/mobile/packages/features/staff/home/lib/src/presentation/pages/worker_home_page.dart index 777cbf14..a9b3f169 100644 --- a/apps/mobile/packages/features/staff/home/lib/src/presentation/pages/worker_home_page.dart +++ b/apps/mobile/packages/features/staff/home/lib/src/presentation/pages/worker_home_page.dart @@ -132,7 +132,8 @@ class WorkerHomePage extends StatelessWidget { EmptyStateWidget( message: emptyI18n.no_shifts_today, actionLink: emptyI18n.find_shifts_cta, - onAction: () => Modular.to.pushShifts(tab: 'find'), + onAction: () => + Modular.to.pushShifts(tab: 'find'), ) else Column( diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart index ff8dd4fd..40ab4f4d 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart @@ -31,7 +31,6 @@ class ShiftsBloc extends Bloc { on(_onLoadShifts); on(_onLoadHistoryShifts); on(_onLoadAvailableShifts); - on(_onLoadFindFirst); on(_onLoadShiftsForRange); on(_onFilterAvailableShifts); } @@ -63,7 +62,6 @@ class ShiftsBloc extends Bloc { availableLoaded: false, historyLoading: false, historyLoaded: false, - myShiftsLoaded: true, searchQuery: '', jobType: 'all', )); @@ -84,7 +82,6 @@ class ShiftsBloc extends Bloc { try { final historyResult = await getHistoryShifts(); emit(currentState.copyWith( - myShiftsLoaded: true, historyShifts: historyResult, historyLoading: false, historyLoaded: true, @@ -116,67 +113,6 @@ class ShiftsBloc extends Bloc { } } - Future _onLoadFindFirst( - LoadFindFirstEvent event, - Emitter emit, - ) async { - if (state is! ShiftsLoaded) { - emit(const ShiftsLoaded( - myShifts: [], - pendingShifts: [], - cancelledShifts: [], - availableShifts: [], - historyShifts: [], - availableLoading: false, - availableLoaded: false, - historyLoading: false, - historyLoaded: false, - myShiftsLoaded: false, - searchQuery: '', - jobType: 'all', - )); - } - - final currentState = - state is ShiftsLoaded ? state as ShiftsLoaded : null; - if (currentState != null && currentState.availableLoaded) return; - - if (currentState != null) { - emit(currentState.copyWith(availableLoading: true)); - } - - try { - final availableResult = - await getAvailableShifts(const GetAvailableShiftsArguments()); - final loadedState = state is ShiftsLoaded - ? state as ShiftsLoaded - : const ShiftsLoaded( - myShifts: [], - pendingShifts: [], - cancelledShifts: [], - availableShifts: [], - historyShifts: [], - availableLoading: true, - availableLoaded: false, - historyLoading: false, - historyLoaded: false, - myShiftsLoaded: false, - searchQuery: '', - jobType: 'all', - ); - emit(loadedState.copyWith( - availableShifts: _filterPastShifts(availableResult), - availableLoading: false, - availableLoaded: true, - )); - } catch (_) { - if (state is ShiftsLoaded) { - final current = state as ShiftsLoaded; - emit(current.copyWith(availableLoading: false)); - } - } - } - Future _onLoadShiftsForRange( LoadShiftsForRangeEvent event, Emitter emit, @@ -188,10 +124,7 @@ class ShiftsBloc extends Bloc { if (state is ShiftsLoaded) { final currentState = state as ShiftsLoaded; - emit(currentState.copyWith( - myShifts: myShiftsResult, - myShiftsLoaded: true, - )); + emit(currentState.copyWith(myShifts: myShiftsResult)); return; } @@ -205,7 +138,6 @@ class ShiftsBloc extends Bloc { availableLoaded: false, historyLoading: false, historyLoaded: false, - myShiftsLoaded: true, searchQuery: '', jobType: 'all', )); diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart index d25866e0..7822a249 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart @@ -14,8 +14,6 @@ class LoadHistoryShiftsEvent extends ShiftsEvent {} class LoadAvailableShiftsEvent extends ShiftsEvent {} -class LoadFindFirstEvent extends ShiftsEvent {} - class LoadShiftsForRangeEvent extends ShiftsEvent { final DateTime start; final DateTime end; diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_state.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_state.dart index d32e3fba..dc670b52 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_state.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_state.dart @@ -22,7 +22,6 @@ class ShiftsLoaded extends ShiftsState { final bool availableLoaded; final bool historyLoading; final bool historyLoaded; - final bool myShiftsLoaded; final String searchQuery; final String jobType; @@ -36,7 +35,6 @@ class ShiftsLoaded extends ShiftsState { required this.availableLoaded, required this.historyLoading, required this.historyLoaded, - required this.myShiftsLoaded, required this.searchQuery, required this.jobType, }); @@ -51,7 +49,6 @@ class ShiftsLoaded extends ShiftsState { bool? availableLoaded, bool? historyLoading, bool? historyLoaded, - bool? myShiftsLoaded, String? searchQuery, String? jobType, }) { @@ -65,7 +62,6 @@ class ShiftsLoaded extends ShiftsState { availableLoaded: availableLoaded ?? this.availableLoaded, historyLoading: historyLoading ?? this.historyLoading, historyLoaded: historyLoaded ?? this.historyLoaded, - myShiftsLoaded: myShiftsLoaded ?? this.myShiftsLoaded, searchQuery: searchQuery ?? this.searchQuery, jobType: jobType ?? this.jobType, ); @@ -82,7 +78,6 @@ class ShiftsLoaded extends ShiftsState { availableLoaded, historyLoading, historyLoaded, - myShiftsLoaded, searchQuery, jobType, ]; diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart index 3d86039d..f42e6d65 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart @@ -21,7 +21,6 @@ class ShiftsPage extends StatefulWidget { class _ShiftsPageState extends State { late String _activeTab; DateTime? _selectedDate; - bool _prioritizeFind = false; final ShiftsBloc _bloc = Modular.get(); @override @@ -29,22 +28,12 @@ class _ShiftsPageState extends State { super.initState(); _activeTab = widget.initialTab ?? 'myshifts'; _selectedDate = widget.selectedDate; - print('ShiftsPage init: initialTab=$_activeTab'); - _prioritizeFind = widget.initialTab == 'find'; - if (_prioritizeFind) { - _bloc.add(LoadFindFirstEvent()); - } else { - _bloc.add(LoadShiftsEvent()); - } + _bloc.add(LoadShiftsEvent()); if (_activeTab == 'history') { - print('ShiftsPage init: loading history tab'); _bloc.add(LoadHistoryShiftsEvent()); } if (_activeTab == 'find') { - print('ShiftsPage init: entering find tab (not loaded yet)'); - if (!_prioritizeFind) { - _bloc.add(LoadAvailableShiftsEvent()); - } + _bloc.add(LoadAvailableShiftsEvent()); } } @@ -54,7 +43,6 @@ class _ShiftsPageState extends State { if (widget.initialTab != null && widget.initialTab != _activeTab) { setState(() { _activeTab = widget.initialTab!; - _prioritizeFind = widget.initialTab == 'find'; }); } if (widget.selectedDate != null && widget.selectedDate != _selectedDate) { @@ -98,10 +86,6 @@ class _ShiftsPageState extends State { final bool historyLoaded = (state is ShiftsLoaded) ? state.historyLoaded : false; - final bool myShiftsLoaded = (state is ShiftsLoaded) - ? state.myShiftsLoaded - : false; - final bool blockTabsForFind = _prioritizeFind && !availableLoaded; // Note: "filteredJobs" logic moved to FindShiftsTab // Note: Calendar logic moved to MyShiftsTab @@ -140,8 +124,7 @@ class _ShiftsPageState extends State { "My Shifts", UiIcons.calendar, myShifts.length, - showCount: myShiftsLoaded, - enabled: !blockTabsForFind, + enabled: true, ), const SizedBox(width: 8), _buildTab( @@ -160,7 +143,7 @@ class _ShiftsPageState extends State { UiIcons.clock, historyShifts.length, showCount: historyLoaded, - enabled: !blockTabsForFind && baseLoaded, + enabled: baseLoaded, ), ], ), diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart index 4e914b84..3bb8c278 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart @@ -22,12 +22,6 @@ class _FindShiftsTabState extends State { String _searchQuery = ''; String _jobType = 'all'; - @override - void initState() { - super.initState(); - print('FindShiftsTab init: tab entered, data pending'); - } - Widget _buildFilterTab(String id, String label) { final isSelected = _jobType == id; return GestureDetector( diff --git a/backend/dataconnect/dataconnect.dev.yaml b/backend/dataconnect/dataconnect.dev.yaml deleted file mode 100644 index 39e01fdb..00000000 --- a/backend/dataconnect/dataconnect.dev.yaml +++ /dev/null @@ -1,13 +0,0 @@ -specVersion: "v1" -serviceId: "krow-workforce-db" -location: "us-central1" -schema: - source: "./schema" - datasource: - postgresql: - database: "krow_db" - cloudSql: - instanceId: "krow-sql" - # schemaValidation: "STRICT" # STRICT mode makes Postgres schema match Data Connect exactly. - # schemaValidation: "COMPATIBLE" # COMPATIBLE mode makes Postgres schema compatible with Data Connect. -connectorDirs: ["./connector"] diff --git a/backend/dataconnect/dataconnect.validation.yaml b/backend/dataconnect/dataconnect.validation.yaml deleted file mode 100644 index 9e1775d6..00000000 --- a/backend/dataconnect/dataconnect.validation.yaml +++ /dev/null @@ -1,13 +0,0 @@ -specVersion: "v1" -serviceId: "krow-workforce-db-validation" -location: "us-central1" -schema: - source: "./schema" - datasource: - postgresql: - database: "krow_db" - cloudSql: - instanceId: "krow-sql-validation" - # schemaValidation: "STRICT" # STRICT mode makes Postgres schema match Data Connect exactly. - # schemaValidation: "COMPATIBLE" # COMPATIBLE mode makes Postgres schema compatible with Data Connect. -connectorDirs: ["./connector"] diff --git a/backend/dataconnect/functions/seed.gql b/backend/dataconnect/functions/seed.gql index 073861ae..f59eda6f 100644 --- a/backend/dataconnect/functions/seed.gql +++ b/backend/dataconnect/functions/seed.gql @@ -5,7 +5,7 @@ mutation seedAll @transaction { data: { id: "dvpWnaBjT6UksS5lo04hfMTyq1q1" email: "legendary@krowd.com" - fullName: "Krow Payements" + fullName: "Krow" role: USER userRole: "BUSINESS" } @@ -26,7 +26,7 @@ mutation seedAll @transaction { id: "ef69e942-d6e5-48e5-a8bc-69d3faa63b2f" businessName: "Krow" userId: "dvpWnaBjT6UksS5lo04hfMTyq1q1" - contactName: "Krow Payements" + contactName: "Krow Ops" email: "legendary@krowd.com" phone: "+1-818-555-0148" address: "5000 San Jose Street, Granada Hills, CA, USA" diff --git a/makefiles/dataconnect.mk b/makefiles/dataconnect.mk index c2db1fd6..ba7298ef 100644 --- a/makefiles/dataconnect.mk +++ b/makefiles/dataconnect.mk @@ -1,47 +1,6 @@ # --- Data Connect / Backend --- -# Usage examples: -# make dataconnect-sync DC_ENV=dev -# make dataconnect-seed DC_ENV=validation -# make dataconnect-clean DC_ENV=validation -# make dataconnect-generate-sdk DC_ENV=dev -# -DC_ENV ?= dev - -DC_SERVICE_DEV := krow-workforce-db -DC_SERVICE_VALIDATION := krow-workforce-db-validation - -ifeq ($(DC_ENV),dev) - DC_SERVICE := $(DC_SERVICE_DEV) -else ifeq ($(DC_ENV),validation) - DC_SERVICE := $(DC_SERVICE_VALIDATION) -else - $(error Invalid DC_ENV '$(DC_ENV)'. Use DC_ENV=dev or DC_ENV=validation) -endif - -.PHONY: dataconnect-enable-apis dataconnect-init dataconnect-deploy dataconnect-sql-migrate dataconnect-generate-sdk dataconnect-sync dataconnect-bootstrap-db check-gcloud-beta dataconnect-clean dataconnect-bootstrap-validation-db dataconnect-file dataconnect-file-validation dataconnect-file-dev dataconnect-seed dataconnect-test - -#creation dataconnect file -dataconnect-file: - @echo "--> Starting creation Firebase Data Connect schema file for service [$(DC_SERVICE)]..." - @test -f backend/dataconnect/dataconnect.$(DC_ENV).yaml || (echo "❌ Missing backend/dataconnect/dataconnect.$(DC_ENV).yaml" && exit 1) - @cp backend/dataconnect/dataconnect.$(DC_ENV).yaml backend/dataconnect/dataconnect.yaml - @echo "✅ Creation Data Connect file completed." - -#creation dev dataconnect file -dataconnect-file-dev: - @echo "--> Starting creation Firebase Data Connect schema file for service [$(DC_SERVICE)]..." - @test -f backend/dataconnect/dataconnect.dev.yaml || (echo "❌ Missing backend/dataconnect/dataconnect.dev.yaml" && exit 1) - @cp backend/dataconnect/dataconnect.dev.yaml backend/dataconnect/dataconnect.yaml - @echo "✅ Creation Data Connect file completed." - - -#creation validation dataconnect file -dataconnect-file-validation: - @echo "--> Starting creation Firebase Data Connect schema file for service [$(DC_SERVICE)]..." - @test -f backend/dataconnect/dataconnect.validation.yaml || (echo "❌ Missing backend/dataconnect/dataconnect.validation.yaml" && exit 1) - @cp backend/dataconnect/dataconnect.validation.yaml backend/dataconnect/dataconnect.yaml - @echo "✅ Creation Data Connect file completed." +.PHONY: dataconnect-enable-apis dataconnect-init dataconnect-deploy dataconnect-sql-migrate dataconnect-generate-sdk dataconnect-sync dataconnect-bootstrap-db check-gcloud-beta dataconnect-clean # Enable all required APIs for Firebase Data Connect + Cloud SQL dataconnect-enable-apis: @@ -55,94 +14,63 @@ dataconnect-enable-apis: @echo "✅ APIs enabled for project [$(GCP_PROJECT_ID)]." # Initialize Firebase Data Connect (interactive wizard). -# use only once per project dataconnect-init: @echo "--> Initializing Firebase Data Connect for alias [$(FIREBASE_ALIAS)] (project: $(GCP_PROJECT_ID))..." @firebase init dataconnect --project $(FIREBASE_ALIAS) @echo "✅ Data Connect initialization command executed. Follow the interactive steps in the CLI." # Deploy Data Connect schemas (GraphQL → Cloud SQL) -dataconnect-deploy: dataconnect-file - @echo "--> Deploying Firebase Data Connect schemas to [$(ENV)] (service: $(DC_SERVICE)) (project: $(FIREBASE_ALIAS))..." - @firebase deploy --only dataconnect:$(DC_SERVICE) --project=$(FIREBASE_ALIAS) +dataconnect-deploy: + @echo "--> Deploying Firebase Data Connect schemas to [$(ENV)] (project: $(FIREBASE_ALIAS))..." + @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect deployment completed for [$(ENV)]." # Apply pending SQL migrations for Firebase Data Connect -dataconnect-sql-migrate: dataconnect-file - @echo "--> Applying Firebase Data Connect SQL migrations to [$(ENV)] (service: $(DC_SERVICE)) (project: $(FIREBASE_ALIAS))..." +dataconnect-sql-migrate: + @echo "--> Applying Firebase Data Connect SQL migrations to [$(ENV)] (project: $(FIREBASE_ALIAS))..." @firebase dataconnect:sql:migrate --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect SQL migration completed for [$(ENV)]." # Generate Data Connect client SDK for frontend-web and internal-api-harness -dataconnect-generate-sdk: dataconnect-file +dataconnect-generate-sdk: @echo "--> Generating Firebase Data Connect SDK for web frontend and API harness..." - @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) + @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect SDK generation completed for [$(ENV)]." # Unified backend schema update workflow (schema -> deploy -> SDK) -dataconnect-sync: dataconnect-file - @echo "--> [1/3] Deploying Data Connect [$(DC_SERVICE)]..." - @firebase deploy --only dataconnect:$(DC_SERVICE) --project=$(FIREBASE_ALIAS) - @echo "--> [2/3] Applying SQL migrations [$(DC_SERVICE)]..." - @firebase dataconnect:sql:migrate $(DC_SERVICE) --project=$(FIREBASE_ALIAS) - @echo "--> [3/3] Regenerating SDK [$(DC_SERVICE)]..." +dataconnect-sync: + @echo "--> [1/3] Deploying Data Connect..." + @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) + @echo "--> [2/3] Applying SQL migrations..." + @firebase dataconnect:sql:migrate --project=$(FIREBASE_ALIAS) + @echo "--> [3/3] Regenerating SDK..." @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) - @echo "✅ Data Connect SQL, deploy, and SDK generation [$(ENV)]." + @echo "✅ Data Connect SQL, deploy, and SDK generation completed for [$(ENV)]." # Execute seed in Firebase Data Connect -dataconnect-seed: dataconnect-file - @echo "--> Exec seed in Firebase Data Connect (service: $(DC_SERVICE))..." - @firebase dataconnect:execute backend/dataconnect/functions/seed.gql --project=$(FIREBASE_ALIAS) +dataconnect-seed: + @echo "--> Exec seed in Firebase Data Connect..." + @firebase dataconnect:execute backend/dataconnect/functions/seed.gql --project=$(FIREBASE_ALIAS) @echo "✅ Seed executed successfully." # Execute clean, to delete all the data in Firebase Data Connect -dataconnect-clean: dataconnect-file - @echo "--> Exec clean all the data in Firebase Data Connect (service: $(DC_SERVICE))..." - @firebase dataconnect:execute backend/dataconnect/functions/clean.gql --project=$(FIREBASE_ALIAS) +dataconnect-clean: + @echo "--> Exec clean all the data in Firebase Data Connect..." + @firebase dataconnect:execute backend/dataconnect/functions/clean.gql --project=$(FIREBASE_ALIAS) @echo "✅ Clean information executed successfully." # Run tests for Data Connect deployment and migrations -dataconnect-test: dataconnect-file - @echo "--> Running Data Connect tests (service: $(DC_SERVICE))..." - @echo "--> [1/2] Deploying Data Connect..." - @firebase deploy --only dataconnect:$(DC_SERVICE) --project=$(FIREBASE_ALIAS) --dry-run - @echo "--> [2/2] Applying SQL migrations..." +dataconnect-test: + @echo "--> Running Data Connect tests..." + @echo "--> [1/3] Deploying Data Connect..." + @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) --dry-run + @echo "--> [2/3] Applying SQL migrations..." @firebase dataconnect:sql:diff --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect tests completed." -dataconnect-backup-dev-to-validation: - @echo "🔍 Validating instances exist in [$(GCP_PROJECT_ID)]..." - @if ! gcloud sql instances describe krow-sql --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ - echo "❌ Dev instance 'krow-sql' not found in project $(GCP_PROJECT_ID)."; \ - exit 1; \ - fi - @if ! gcloud sql instances describe krow-sql-validation --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ - echo "❌ Validation instance 'krow-sql-validation' not found in project $(GCP_PROJECT_ID)."; \ - exit 1; \ - fi - @echo "✅ Instances found." - - @echo "🧰 Creating a backup on dev (krow-sql)..." - @gcloud sql backups create --instance=krow-sql --project=$(GCP_PROJECT_ID) >/dev/null - - @echo "🔎 Fetching latest backup ID..." - @LATEST_BACKUP_ID="$$(gcloud sql backups list --instance=krow-sql --project=$(GCP_PROJECT_ID) --sort-by=~endTime --limit=1 --format='value(id)')"; \ - if [ -z "$$LATEST_BACKUP_ID" ]; then \ - echo "❌ Could not find any backup ID for krow-sql."; \ - exit 1; \ - fi; \ - echo "✅ Latest backup ID: $$LATEST_BACKUP_ID"; \ - echo "⚠️ Restoring into validation..."; \ - gcloud sql backups restore $$LATEST_BACKUP_ID \ - --restore-instance=krow-sql-validation \ - --backup-instance=krow-sql \ - --project=$(GCP_PROJECT_ID) - - @echo "🎉 Done." - # ------------------------------------------------------------------- -# ONE-TIME FULL SETUP FOR CLOUD SQL + DATA CONNECT DEV +# ONE-TIME FULL SETUP FOR CLOUD SQL + DATA CONNECT # ------------------------------------------------------------------- # Check if gcloud and beta group are available @@ -157,7 +85,7 @@ check-gcloud-beta: } @echo "✅ gcloud CLI and 'gcloud beta' are available." -dataconnect-bootstrap-db: dataconnect-file-dev check-gcloud-beta +dataconnect-bootstrap-db: check-gcloud-beta @echo "🔍 Checking if Cloud SQL instance krow-sql already exists in [$(GCP_PROJECT_ID)]..." @if gcloud sql instances describe krow-sql --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ echo "⚠️ Cloud SQL instance 'krow-sql' already exists in project $(GCP_PROJECT_ID)."; \ @@ -184,7 +112,7 @@ dataconnect-bootstrap-db: dataconnect-file-dev check-gcloud-beta @echo "⚠️ Creating Firebase Data Connect service identity..." gcloud beta services identity create \ --service=firebasedataconnect.googleapis.com \ - --project=$(GCP_PROJECT_ID) + --project=$(GCP_PROJECT_ID) @echo "⚠️ Enabling IAM authentication on Cloud SQL instance krow-sql..." gcloud sql instances patch krow-sql \ @@ -196,77 +124,9 @@ dataconnect-bootstrap-db: dataconnect-file-dev check-gcloud-beta firebase dataconnect:sql:setup krow-workforce-db --project=$(FIREBASE_ALIAS) @echo "⚠️ Deploying initial Data Connect configuration..." - @firebase deploy --only dataconnect:$(DC_SERVICE_DEV) --project=$(FIREBASE_ALIAS) + @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) @echo "⚠️ Generating initial Data Connect SDK..." - @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) - - @echo "🎉 Cloud SQL + Data Connect bootstrap completed successfully!" - - -# ------------------------------------------------------------------- -# ONE-TIME FULL SETUP FOR CLOUD SQL + DATA CONNECT VALIDATEION -# ------------------------------------------------------------------- - -# Creates: krow-sql-validation + krow_db (inside it) + links service krow-workforce-db-validation -# Then clones data from krow-sql -> krow-sql-validation via backup/restore - -dataconnect-bootstrap-validation-database: dataconnect-file-validation - @echo "🔍 Checking if Cloud SQL instance krow-sql-validation already exists in [$(GCP_PROJECT_ID)]..." - @if gcloud sql instances describe krow-sql-validation --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ - echo "⚠️ Cloud SQL instance 'krow-sql-validation' already exists in project $(GCP_PROJECT_ID)."; \ - echo " If you need to recreate it, delete the instance manually first."; \ - exit 1; \ - fi - - @echo "⚠️ Creating Cloud SQL instance krow-sql-validation (tier: $(SQL_TIER))..." - gcloud sql instances create krow-sql-validation \ - --database-version=POSTGRES_15 \ - --tier=$(SQL_TIER) \ - --region=us-central1 \ - --storage-size=10 \ - --storage-auto-increase \ - --availability-type=zonal \ - --backup-start-time=03:00 \ - --project=$(GCP_PROJECT_ID) - - @echo "⚠️ Creating Cloud SQL database krow_db on krow-sql-validation..." - gcloud sql databases create krow_db \ - --instance=krow-sql-validation \ - --project=$(GCP_PROJECT_ID) - - @echo "⚠️ Enabling IAM authentication on Cloud SQL instance krow-sql-validation..." - gcloud sql instances patch krow-sql-validation \ - --project=$(GCP_PROJECT_ID) \ - --database-flags=cloudsql.iam_authentication=on \ - --quiet - - @echo "🔁 Creating a backup on dev instance (krow-sql) to clone data into validation..." - @echo " (Prereq: krow-sql must already exist and be stable.)" - gcloud sql backups create --instance=krow-sql --project=$(GCP_PROJECT_ID) - echo "✅ Backup creation started. Operation: $$BACKUP_OP" - - @echo "🔎 Fetching latest backup ID from krow-sql..." - @BACKUP_ID="$$(gcloud sql backups list --instance=krow-sql --project=$(GCP_PROJECT_ID) --limit=1 --sort-by=~endTime --format='value(id)')"; \ - if [ -z "$$BACKUP_ID" ]; then \ - echo "❌ Could not find a backup ID for krow-sql."; \ - exit 1; \ - fi; \ - echo "✅ Latest backup ID: $$BACKUP_ID"; \ - echo "⚠️ Restoring backup into krow-sql-validation..."; \ - gcloud sql backups restore $$BACKUP_ID \ - --restore-instance=krow-sql-validation \ - --backup-instance=krow-sql \ - --project=$(GCP_PROJECT_ID) - - @echo "⚠️ Linking Data Connect service (krow-workforce-db-validation) with Cloud SQL..." - @echo " When prompted, select instance: krow-sql-validation and database: krow_db" - firebase dataconnect:sql:setup krow-workforce-db-validation --project=$(FIREBASE_ALIAS) - - @echo "⚠️ Deploying Data Connect configuration ($(DC_SERVICE_VALIDATION))..." - @firebase deploy --only dataconnect:$(DC_SERVICE_VALIDATION) --project=$(FIREBASE_ALIAS) - - @echo "⚠️ Generating Data Connect SDK ($(DC_SERVICE))..." @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) - @echo "🎉 Validation Cloud SQL + Data Connect bootstrap completed successfully!" + @echo "🎉 Cloud SQL + Data Connect bootstrap completed successfully!" diff --git a/makefiles/launchpad.mk b/makefiles/launchpad.mk index 87050e19..8dbe860f 100644 --- a/makefiles/launchpad.mk +++ b/makefiles/launchpad.mk @@ -2,13 +2,13 @@ .PHONY: launchpad-dev deploy-launchpad-hosting -launchpad-dev: sync-prototypes +launchpad-dev: @echo "--> Starting local Launchpad server using Firebase Hosting emulator..." @echo " - Generating secure email hashes..." @node scripts/generate-allowed-hashes.js @firebase serve --only hosting:launchpad --project=$(FIREBASE_ALIAS) -deploy-launchpad-hosting: sync-prototypes +deploy-launchpad-hosting: @echo "--> Deploying Internal Launchpad to Firebase Hosting..." @echo " - Generating secure email hashes..." @node scripts/generate-allowed-hashes.js From 277b4b81caf5b584518ee16ccc5ebba840b1d151 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Thu, 5 Feb 2026 00:19:00 -0500 Subject: [PATCH 04/12] Reapply "Merge pull request #373 from Oloodi/368-sub-task-provision-and-copy-validation-database-instance" This reverts commit eb149f680b1d0ef1deb8c68d292d475870b3012c. --- .../presentation/pages/client_hubs_page.dart | 55 ++++- .../settings_actions.dart | 2 +- .../navigation/home_navigator.dart | 6 +- .../presentation/pages/worker_home_page.dart | 3 +- .../blocs/shifts/shifts_bloc.dart | 70 +++++- .../blocs/shifts/shifts_event.dart | 2 + .../blocs/shifts/shifts_state.dart | 5 + .../src/presentation/pages/shifts_page.dart | 25 ++- .../widgets/tabs/find_shifts_tab.dart | 6 + backend/dataconnect/dataconnect.dev.yaml | 13 ++ .../dataconnect/dataconnect.validation.yaml | 13 ++ backend/dataconnect/functions/seed.gql | 4 +- makefiles/dataconnect.mk | 202 +++++++++++++++--- makefiles/launchpad.mk | 4 +- 14 files changed, 361 insertions(+), 49 deletions(-) create mode 100644 backend/dataconnect/dataconnect.dev.yaml create mode 100644 backend/dataconnect/dataconnect.validation.yaml diff --git a/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/client_hubs_page.dart b/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/client_hubs_page.dart index 85f60930..aa3de3e2 100644 --- a/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/client_hubs_page.dart +++ b/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/client_hubs_page.dart @@ -95,10 +95,10 @@ class ClientHubsPage extends StatelessWidget { ).add( ClientHubsIdentifyDialogToggled(hub: hub), ), - onDeletePressed: () => - BlocProvider.of( - context, - ).add(ClientHubsDeleteRequested(hub.id)), + onDeletePressed: () => _confirmDeleteHub( + context, + hub, + ), ), ), ], @@ -221,4 +221,51 @@ class ClientHubsPage extends StatelessWidget { ), ); } + + Future _confirmDeleteHub(BuildContext context, Hub hub) async { + final String hubName = hub.name.isEmpty ? 'this hub' : hub.name; + return showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext dialogContext) { + return AlertDialog( + title: const Text('Confirm Hub Deletion'), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Are you sure you want to delete "$hubName"?'), + const SizedBox(height: UiConstants.space2), + const Text('This action cannot be undone.'), + const SizedBox(height: UiConstants.space2), + Text( + 'Note that if there are any shifts/orders assigned to this hub we shouldn\'t be able to delete the hub.', + style: UiTypography.footnote1r.copyWith( + color: UiColors.textSecondary, + ), + ), + ], + ), + actions: [ + TextButton( + onPressed: () => Modular.to.pop(), + child: const Text('Cancel'), + ), + TextButton( + onPressed: () { + BlocProvider.of( + context, + ).add(ClientHubsDeleteRequested(hub.id)); + Modular.to.pop(); + }, + style: TextButton.styleFrom( + foregroundColor: UiColors.destructive, + ), + child: const Text('Delete'), + ), + ], + ); + }, + ); + } } diff --git a/apps/mobile/packages/features/client/settings/lib/src/presentation/widgets/client_settings_page/settings_actions.dart b/apps/mobile/packages/features/client/settings/lib/src/presentation/widgets/client_settings_page/settings_actions.dart index e3e99090..e044d1ec 100644 --- a/apps/mobile/packages/features/client/settings/lib/src/presentation/widgets/client_settings_page/settings_actions.dart +++ b/apps/mobile/packages/features/client/settings/lib/src/presentation/widgets/client_settings_page/settings_actions.dart @@ -83,7 +83,7 @@ class SettingsActions extends StatelessWidget { // Cancel button UiButton.secondary( text: t.common.cancel, - onPressed: () => Navigator.of(dialogContext).pop(), + onPressed: () => Modular.to.pop(), ), ], ), diff --git a/apps/mobile/packages/features/staff/home/lib/src/presentation/navigation/home_navigator.dart b/apps/mobile/packages/features/staff/home/lib/src/presentation/navigation/home_navigator.dart index 9774cb07..cd9da6f6 100644 --- a/apps/mobile/packages/features/staff/home/lib/src/presentation/navigation/home_navigator.dart +++ b/apps/mobile/packages/features/staff/home/lib/src/presentation/navigation/home_navigator.dart @@ -31,9 +31,11 @@ extension HomeNavigator on IModularNavigator { /// Optionally provide a [tab] query param (e.g. `find`). void pushShifts({String? tab}) { if (tab == null) { - pushNamed('/worker-main/shifts'); + navigate('/worker-main/shifts'); } else { - pushNamed('/worker-main/shifts?tab=$tab'); + navigate('/worker-main/shifts', arguments: { + 'initialTab': tab, + }); } } diff --git a/apps/mobile/packages/features/staff/home/lib/src/presentation/pages/worker_home_page.dart b/apps/mobile/packages/features/staff/home/lib/src/presentation/pages/worker_home_page.dart index a9b3f169..777cbf14 100644 --- a/apps/mobile/packages/features/staff/home/lib/src/presentation/pages/worker_home_page.dart +++ b/apps/mobile/packages/features/staff/home/lib/src/presentation/pages/worker_home_page.dart @@ -132,8 +132,7 @@ class WorkerHomePage extends StatelessWidget { EmptyStateWidget( message: emptyI18n.no_shifts_today, actionLink: emptyI18n.find_shifts_cta, - onAction: () => - Modular.to.pushShifts(tab: 'find'), + onAction: () => Modular.to.pushShifts(tab: 'find'), ) else Column( diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart index 40ab4f4d..ff8dd4fd 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart @@ -31,6 +31,7 @@ class ShiftsBloc extends Bloc { on(_onLoadShifts); on(_onLoadHistoryShifts); on(_onLoadAvailableShifts); + on(_onLoadFindFirst); on(_onLoadShiftsForRange); on(_onFilterAvailableShifts); } @@ -62,6 +63,7 @@ class ShiftsBloc extends Bloc { availableLoaded: false, historyLoading: false, historyLoaded: false, + myShiftsLoaded: true, searchQuery: '', jobType: 'all', )); @@ -82,6 +84,7 @@ class ShiftsBloc extends Bloc { try { final historyResult = await getHistoryShifts(); emit(currentState.copyWith( + myShiftsLoaded: true, historyShifts: historyResult, historyLoading: false, historyLoaded: true, @@ -113,6 +116,67 @@ class ShiftsBloc extends Bloc { } } + Future _onLoadFindFirst( + LoadFindFirstEvent event, + Emitter emit, + ) async { + if (state is! ShiftsLoaded) { + emit(const ShiftsLoaded( + myShifts: [], + pendingShifts: [], + cancelledShifts: [], + availableShifts: [], + historyShifts: [], + availableLoading: false, + availableLoaded: false, + historyLoading: false, + historyLoaded: false, + myShiftsLoaded: false, + searchQuery: '', + jobType: 'all', + )); + } + + final currentState = + state is ShiftsLoaded ? state as ShiftsLoaded : null; + if (currentState != null && currentState.availableLoaded) return; + + if (currentState != null) { + emit(currentState.copyWith(availableLoading: true)); + } + + try { + final availableResult = + await getAvailableShifts(const GetAvailableShiftsArguments()); + final loadedState = state is ShiftsLoaded + ? state as ShiftsLoaded + : const ShiftsLoaded( + myShifts: [], + pendingShifts: [], + cancelledShifts: [], + availableShifts: [], + historyShifts: [], + availableLoading: true, + availableLoaded: false, + historyLoading: false, + historyLoaded: false, + myShiftsLoaded: false, + searchQuery: '', + jobType: 'all', + ); + emit(loadedState.copyWith( + availableShifts: _filterPastShifts(availableResult), + availableLoading: false, + availableLoaded: true, + )); + } catch (_) { + if (state is ShiftsLoaded) { + final current = state as ShiftsLoaded; + emit(current.copyWith(availableLoading: false)); + } + } + } + Future _onLoadShiftsForRange( LoadShiftsForRangeEvent event, Emitter emit, @@ -124,7 +188,10 @@ class ShiftsBloc extends Bloc { if (state is ShiftsLoaded) { final currentState = state as ShiftsLoaded; - emit(currentState.copyWith(myShifts: myShiftsResult)); + emit(currentState.copyWith( + myShifts: myShiftsResult, + myShiftsLoaded: true, + )); return; } @@ -138,6 +205,7 @@ class ShiftsBloc extends Bloc { availableLoaded: false, historyLoading: false, historyLoaded: false, + myShiftsLoaded: true, searchQuery: '', jobType: 'all', )); diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart index 7822a249..d25866e0 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_event.dart @@ -14,6 +14,8 @@ class LoadHistoryShiftsEvent extends ShiftsEvent {} class LoadAvailableShiftsEvent extends ShiftsEvent {} +class LoadFindFirstEvent extends ShiftsEvent {} + class LoadShiftsForRangeEvent extends ShiftsEvent { final DateTime start; final DateTime end; diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_state.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_state.dart index dc670b52..d32e3fba 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_state.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_state.dart @@ -22,6 +22,7 @@ class ShiftsLoaded extends ShiftsState { final bool availableLoaded; final bool historyLoading; final bool historyLoaded; + final bool myShiftsLoaded; final String searchQuery; final String jobType; @@ -35,6 +36,7 @@ class ShiftsLoaded extends ShiftsState { required this.availableLoaded, required this.historyLoading, required this.historyLoaded, + required this.myShiftsLoaded, required this.searchQuery, required this.jobType, }); @@ -49,6 +51,7 @@ class ShiftsLoaded extends ShiftsState { bool? availableLoaded, bool? historyLoading, bool? historyLoaded, + bool? myShiftsLoaded, String? searchQuery, String? jobType, }) { @@ -62,6 +65,7 @@ class ShiftsLoaded extends ShiftsState { availableLoaded: availableLoaded ?? this.availableLoaded, historyLoading: historyLoading ?? this.historyLoading, historyLoaded: historyLoaded ?? this.historyLoaded, + myShiftsLoaded: myShiftsLoaded ?? this.myShiftsLoaded, searchQuery: searchQuery ?? this.searchQuery, jobType: jobType ?? this.jobType, ); @@ -78,6 +82,7 @@ class ShiftsLoaded extends ShiftsState { availableLoaded, historyLoading, historyLoaded, + myShiftsLoaded, searchQuery, jobType, ]; diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart index f42e6d65..3d86039d 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shifts_page.dart @@ -21,6 +21,7 @@ class ShiftsPage extends StatefulWidget { class _ShiftsPageState extends State { late String _activeTab; DateTime? _selectedDate; + bool _prioritizeFind = false; final ShiftsBloc _bloc = Modular.get(); @override @@ -28,12 +29,22 @@ class _ShiftsPageState extends State { super.initState(); _activeTab = widget.initialTab ?? 'myshifts'; _selectedDate = widget.selectedDate; - _bloc.add(LoadShiftsEvent()); + print('ShiftsPage init: initialTab=$_activeTab'); + _prioritizeFind = widget.initialTab == 'find'; + if (_prioritizeFind) { + _bloc.add(LoadFindFirstEvent()); + } else { + _bloc.add(LoadShiftsEvent()); + } if (_activeTab == 'history') { + print('ShiftsPage init: loading history tab'); _bloc.add(LoadHistoryShiftsEvent()); } if (_activeTab == 'find') { - _bloc.add(LoadAvailableShiftsEvent()); + print('ShiftsPage init: entering find tab (not loaded yet)'); + if (!_prioritizeFind) { + _bloc.add(LoadAvailableShiftsEvent()); + } } } @@ -43,6 +54,7 @@ class _ShiftsPageState extends State { if (widget.initialTab != null && widget.initialTab != _activeTab) { setState(() { _activeTab = widget.initialTab!; + _prioritizeFind = widget.initialTab == 'find'; }); } if (widget.selectedDate != null && widget.selectedDate != _selectedDate) { @@ -86,6 +98,10 @@ class _ShiftsPageState extends State { final bool historyLoaded = (state is ShiftsLoaded) ? state.historyLoaded : false; + final bool myShiftsLoaded = (state is ShiftsLoaded) + ? state.myShiftsLoaded + : false; + final bool blockTabsForFind = _prioritizeFind && !availableLoaded; // Note: "filteredJobs" logic moved to FindShiftsTab // Note: Calendar logic moved to MyShiftsTab @@ -124,7 +140,8 @@ class _ShiftsPageState extends State { "My Shifts", UiIcons.calendar, myShifts.length, - enabled: true, + showCount: myShiftsLoaded, + enabled: !blockTabsForFind, ), const SizedBox(width: 8), _buildTab( @@ -143,7 +160,7 @@ class _ShiftsPageState extends State { UiIcons.clock, historyShifts.length, showCount: historyLoaded, - enabled: baseLoaded, + enabled: !blockTabsForFind && baseLoaded, ), ], ), diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart index 3bb8c278..4e914b84 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/widgets/tabs/find_shifts_tab.dart @@ -22,6 +22,12 @@ class _FindShiftsTabState extends State { String _searchQuery = ''; String _jobType = 'all'; + @override + void initState() { + super.initState(); + print('FindShiftsTab init: tab entered, data pending'); + } + Widget _buildFilterTab(String id, String label) { final isSelected = _jobType == id; return GestureDetector( diff --git a/backend/dataconnect/dataconnect.dev.yaml b/backend/dataconnect/dataconnect.dev.yaml new file mode 100644 index 00000000..39e01fdb --- /dev/null +++ b/backend/dataconnect/dataconnect.dev.yaml @@ -0,0 +1,13 @@ +specVersion: "v1" +serviceId: "krow-workforce-db" +location: "us-central1" +schema: + source: "./schema" + datasource: + postgresql: + database: "krow_db" + cloudSql: + instanceId: "krow-sql" + # schemaValidation: "STRICT" # STRICT mode makes Postgres schema match Data Connect exactly. + # schemaValidation: "COMPATIBLE" # COMPATIBLE mode makes Postgres schema compatible with Data Connect. +connectorDirs: ["./connector"] diff --git a/backend/dataconnect/dataconnect.validation.yaml b/backend/dataconnect/dataconnect.validation.yaml new file mode 100644 index 00000000..9e1775d6 --- /dev/null +++ b/backend/dataconnect/dataconnect.validation.yaml @@ -0,0 +1,13 @@ +specVersion: "v1" +serviceId: "krow-workforce-db-validation" +location: "us-central1" +schema: + source: "./schema" + datasource: + postgresql: + database: "krow_db" + cloudSql: + instanceId: "krow-sql-validation" + # schemaValidation: "STRICT" # STRICT mode makes Postgres schema match Data Connect exactly. + # schemaValidation: "COMPATIBLE" # COMPATIBLE mode makes Postgres schema compatible with Data Connect. +connectorDirs: ["./connector"] diff --git a/backend/dataconnect/functions/seed.gql b/backend/dataconnect/functions/seed.gql index f59eda6f..073861ae 100644 --- a/backend/dataconnect/functions/seed.gql +++ b/backend/dataconnect/functions/seed.gql @@ -5,7 +5,7 @@ mutation seedAll @transaction { data: { id: "dvpWnaBjT6UksS5lo04hfMTyq1q1" email: "legendary@krowd.com" - fullName: "Krow" + fullName: "Krow Payements" role: USER userRole: "BUSINESS" } @@ -26,7 +26,7 @@ mutation seedAll @transaction { id: "ef69e942-d6e5-48e5-a8bc-69d3faa63b2f" businessName: "Krow" userId: "dvpWnaBjT6UksS5lo04hfMTyq1q1" - contactName: "Krow Ops" + contactName: "Krow Payements" email: "legendary@krowd.com" phone: "+1-818-555-0148" address: "5000 San Jose Street, Granada Hills, CA, USA" diff --git a/makefiles/dataconnect.mk b/makefiles/dataconnect.mk index ba7298ef..c2db1fd6 100644 --- a/makefiles/dataconnect.mk +++ b/makefiles/dataconnect.mk @@ -1,6 +1,47 @@ # --- Data Connect / Backend --- -.PHONY: dataconnect-enable-apis dataconnect-init dataconnect-deploy dataconnect-sql-migrate dataconnect-generate-sdk dataconnect-sync dataconnect-bootstrap-db check-gcloud-beta dataconnect-clean +# Usage examples: +# make dataconnect-sync DC_ENV=dev +# make dataconnect-seed DC_ENV=validation +# make dataconnect-clean DC_ENV=validation +# make dataconnect-generate-sdk DC_ENV=dev +# +DC_ENV ?= dev + +DC_SERVICE_DEV := krow-workforce-db +DC_SERVICE_VALIDATION := krow-workforce-db-validation + +ifeq ($(DC_ENV),dev) + DC_SERVICE := $(DC_SERVICE_DEV) +else ifeq ($(DC_ENV),validation) + DC_SERVICE := $(DC_SERVICE_VALIDATION) +else + $(error Invalid DC_ENV '$(DC_ENV)'. Use DC_ENV=dev or DC_ENV=validation) +endif + +.PHONY: dataconnect-enable-apis dataconnect-init dataconnect-deploy dataconnect-sql-migrate dataconnect-generate-sdk dataconnect-sync dataconnect-bootstrap-db check-gcloud-beta dataconnect-clean dataconnect-bootstrap-validation-db dataconnect-file dataconnect-file-validation dataconnect-file-dev dataconnect-seed dataconnect-test + +#creation dataconnect file +dataconnect-file: + @echo "--> Starting creation Firebase Data Connect schema file for service [$(DC_SERVICE)]..." + @test -f backend/dataconnect/dataconnect.$(DC_ENV).yaml || (echo "❌ Missing backend/dataconnect/dataconnect.$(DC_ENV).yaml" && exit 1) + @cp backend/dataconnect/dataconnect.$(DC_ENV).yaml backend/dataconnect/dataconnect.yaml + @echo "✅ Creation Data Connect file completed." + +#creation dev dataconnect file +dataconnect-file-dev: + @echo "--> Starting creation Firebase Data Connect schema file for service [$(DC_SERVICE)]..." + @test -f backend/dataconnect/dataconnect.dev.yaml || (echo "❌ Missing backend/dataconnect/dataconnect.dev.yaml" && exit 1) + @cp backend/dataconnect/dataconnect.dev.yaml backend/dataconnect/dataconnect.yaml + @echo "✅ Creation Data Connect file completed." + + +#creation validation dataconnect file +dataconnect-file-validation: + @echo "--> Starting creation Firebase Data Connect schema file for service [$(DC_SERVICE)]..." + @test -f backend/dataconnect/dataconnect.validation.yaml || (echo "❌ Missing backend/dataconnect/dataconnect.validation.yaml" && exit 1) + @cp backend/dataconnect/dataconnect.validation.yaml backend/dataconnect/dataconnect.yaml + @echo "✅ Creation Data Connect file completed." # Enable all required APIs for Firebase Data Connect + Cloud SQL dataconnect-enable-apis: @@ -14,63 +55,94 @@ dataconnect-enable-apis: @echo "✅ APIs enabled for project [$(GCP_PROJECT_ID)]." # Initialize Firebase Data Connect (interactive wizard). +# use only once per project dataconnect-init: @echo "--> Initializing Firebase Data Connect for alias [$(FIREBASE_ALIAS)] (project: $(GCP_PROJECT_ID))..." @firebase init dataconnect --project $(FIREBASE_ALIAS) @echo "✅ Data Connect initialization command executed. Follow the interactive steps in the CLI." # Deploy Data Connect schemas (GraphQL → Cloud SQL) -dataconnect-deploy: - @echo "--> Deploying Firebase Data Connect schemas to [$(ENV)] (project: $(FIREBASE_ALIAS))..." - @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) +dataconnect-deploy: dataconnect-file + @echo "--> Deploying Firebase Data Connect schemas to [$(ENV)] (service: $(DC_SERVICE)) (project: $(FIREBASE_ALIAS))..." + @firebase deploy --only dataconnect:$(DC_SERVICE) --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect deployment completed for [$(ENV)]." # Apply pending SQL migrations for Firebase Data Connect -dataconnect-sql-migrate: - @echo "--> Applying Firebase Data Connect SQL migrations to [$(ENV)] (project: $(FIREBASE_ALIAS))..." +dataconnect-sql-migrate: dataconnect-file + @echo "--> Applying Firebase Data Connect SQL migrations to [$(ENV)] (service: $(DC_SERVICE)) (project: $(FIREBASE_ALIAS))..." @firebase dataconnect:sql:migrate --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect SQL migration completed for [$(ENV)]." # Generate Data Connect client SDK for frontend-web and internal-api-harness -dataconnect-generate-sdk: +dataconnect-generate-sdk: dataconnect-file @echo "--> Generating Firebase Data Connect SDK for web frontend and API harness..." - @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) + @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect SDK generation completed for [$(ENV)]." # Unified backend schema update workflow (schema -> deploy -> SDK) -dataconnect-sync: - @echo "--> [1/3] Deploying Data Connect..." - @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) - @echo "--> [2/3] Applying SQL migrations..." - @firebase dataconnect:sql:migrate --project=$(FIREBASE_ALIAS) - @echo "--> [3/3] Regenerating SDK..." +dataconnect-sync: dataconnect-file + @echo "--> [1/3] Deploying Data Connect [$(DC_SERVICE)]..." + @firebase deploy --only dataconnect:$(DC_SERVICE) --project=$(FIREBASE_ALIAS) + @echo "--> [2/3] Applying SQL migrations [$(DC_SERVICE)]..." + @firebase dataconnect:sql:migrate $(DC_SERVICE) --project=$(FIREBASE_ALIAS) + @echo "--> [3/3] Regenerating SDK [$(DC_SERVICE)]..." @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) - @echo "✅ Data Connect SQL, deploy, and SDK generation completed for [$(ENV)]." + @echo "✅ Data Connect SQL, deploy, and SDK generation [$(ENV)]." # Execute seed in Firebase Data Connect -dataconnect-seed: - @echo "--> Exec seed in Firebase Data Connect..." - @firebase dataconnect:execute backend/dataconnect/functions/seed.gql --project=$(FIREBASE_ALIAS) +dataconnect-seed: dataconnect-file + @echo "--> Exec seed in Firebase Data Connect (service: $(DC_SERVICE))..." + @firebase dataconnect:execute backend/dataconnect/functions/seed.gql --project=$(FIREBASE_ALIAS) @echo "✅ Seed executed successfully." # Execute clean, to delete all the data in Firebase Data Connect -dataconnect-clean: - @echo "--> Exec clean all the data in Firebase Data Connect..." - @firebase dataconnect:execute backend/dataconnect/functions/clean.gql --project=$(FIREBASE_ALIAS) +dataconnect-clean: dataconnect-file + @echo "--> Exec clean all the data in Firebase Data Connect (service: $(DC_SERVICE))..." + @firebase dataconnect:execute backend/dataconnect/functions/clean.gql --project=$(FIREBASE_ALIAS) @echo "✅ Clean information executed successfully." # Run tests for Data Connect deployment and migrations -dataconnect-test: - @echo "--> Running Data Connect tests..." - @echo "--> [1/3] Deploying Data Connect..." - @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) --dry-run - @echo "--> [2/3] Applying SQL migrations..." +dataconnect-test: dataconnect-file + @echo "--> Running Data Connect tests (service: $(DC_SERVICE))..." + @echo "--> [1/2] Deploying Data Connect..." + @firebase deploy --only dataconnect:$(DC_SERVICE) --project=$(FIREBASE_ALIAS) --dry-run + @echo "--> [2/2] Applying SQL migrations..." @firebase dataconnect:sql:diff --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect tests completed." +dataconnect-backup-dev-to-validation: + @echo "🔍 Validating instances exist in [$(GCP_PROJECT_ID)]..." + @if ! gcloud sql instances describe krow-sql --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ + echo "❌ Dev instance 'krow-sql' not found in project $(GCP_PROJECT_ID)."; \ + exit 1; \ + fi + @if ! gcloud sql instances describe krow-sql-validation --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ + echo "❌ Validation instance 'krow-sql-validation' not found in project $(GCP_PROJECT_ID)."; \ + exit 1; \ + fi + @echo "✅ Instances found." + + @echo "🧰 Creating a backup on dev (krow-sql)..." + @gcloud sql backups create --instance=krow-sql --project=$(GCP_PROJECT_ID) >/dev/null + + @echo "🔎 Fetching latest backup ID..." + @LATEST_BACKUP_ID="$$(gcloud sql backups list --instance=krow-sql --project=$(GCP_PROJECT_ID) --sort-by=~endTime --limit=1 --format='value(id)')"; \ + if [ -z "$$LATEST_BACKUP_ID" ]; then \ + echo "❌ Could not find any backup ID for krow-sql."; \ + exit 1; \ + fi; \ + echo "✅ Latest backup ID: $$LATEST_BACKUP_ID"; \ + echo "⚠️ Restoring into validation..."; \ + gcloud sql backups restore $$LATEST_BACKUP_ID \ + --restore-instance=krow-sql-validation \ + --backup-instance=krow-sql \ + --project=$(GCP_PROJECT_ID) + + @echo "🎉 Done." + # ------------------------------------------------------------------- -# ONE-TIME FULL SETUP FOR CLOUD SQL + DATA CONNECT +# ONE-TIME FULL SETUP FOR CLOUD SQL + DATA CONNECT DEV # ------------------------------------------------------------------- # Check if gcloud and beta group are available @@ -85,7 +157,7 @@ check-gcloud-beta: } @echo "✅ gcloud CLI and 'gcloud beta' are available." -dataconnect-bootstrap-db: check-gcloud-beta +dataconnect-bootstrap-db: dataconnect-file-dev check-gcloud-beta @echo "🔍 Checking if Cloud SQL instance krow-sql already exists in [$(GCP_PROJECT_ID)]..." @if gcloud sql instances describe krow-sql --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ echo "⚠️ Cloud SQL instance 'krow-sql' already exists in project $(GCP_PROJECT_ID)."; \ @@ -112,7 +184,7 @@ dataconnect-bootstrap-db: check-gcloud-beta @echo "⚠️ Creating Firebase Data Connect service identity..." gcloud beta services identity create \ --service=firebasedataconnect.googleapis.com \ - --project=$(GCP_PROJECT_ID) + --project=$(GCP_PROJECT_ID) @echo "⚠️ Enabling IAM authentication on Cloud SQL instance krow-sql..." gcloud sql instances patch krow-sql \ @@ -124,9 +196,77 @@ dataconnect-bootstrap-db: check-gcloud-beta firebase dataconnect:sql:setup krow-workforce-db --project=$(FIREBASE_ALIAS) @echo "⚠️ Deploying initial Data Connect configuration..." - @firebase deploy --only dataconnect --project=$(FIREBASE_ALIAS) + @firebase deploy --only dataconnect:$(DC_SERVICE_DEV) --project=$(FIREBASE_ALIAS) @echo "⚠️ Generating initial Data Connect SDK..." - @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) + @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) @echo "🎉 Cloud SQL + Data Connect bootstrap completed successfully!" + + +# ------------------------------------------------------------------- +# ONE-TIME FULL SETUP FOR CLOUD SQL + DATA CONNECT VALIDATEION +# ------------------------------------------------------------------- + +# Creates: krow-sql-validation + krow_db (inside it) + links service krow-workforce-db-validation +# Then clones data from krow-sql -> krow-sql-validation via backup/restore + +dataconnect-bootstrap-validation-database: dataconnect-file-validation + @echo "🔍 Checking if Cloud SQL instance krow-sql-validation already exists in [$(GCP_PROJECT_ID)]..." + @if gcloud sql instances describe krow-sql-validation --project=$(GCP_PROJECT_ID) >/dev/null 2>&1; then \ + echo "⚠️ Cloud SQL instance 'krow-sql-validation' already exists in project $(GCP_PROJECT_ID)."; \ + echo " If you need to recreate it, delete the instance manually first."; \ + exit 1; \ + fi + + @echo "⚠️ Creating Cloud SQL instance krow-sql-validation (tier: $(SQL_TIER))..." + gcloud sql instances create krow-sql-validation \ + --database-version=POSTGRES_15 \ + --tier=$(SQL_TIER) \ + --region=us-central1 \ + --storage-size=10 \ + --storage-auto-increase \ + --availability-type=zonal \ + --backup-start-time=03:00 \ + --project=$(GCP_PROJECT_ID) + + @echo "⚠️ Creating Cloud SQL database krow_db on krow-sql-validation..." + gcloud sql databases create krow_db \ + --instance=krow-sql-validation \ + --project=$(GCP_PROJECT_ID) + + @echo "⚠️ Enabling IAM authentication on Cloud SQL instance krow-sql-validation..." + gcloud sql instances patch krow-sql-validation \ + --project=$(GCP_PROJECT_ID) \ + --database-flags=cloudsql.iam_authentication=on \ + --quiet + + @echo "🔁 Creating a backup on dev instance (krow-sql) to clone data into validation..." + @echo " (Prereq: krow-sql must already exist and be stable.)" + gcloud sql backups create --instance=krow-sql --project=$(GCP_PROJECT_ID) + echo "✅ Backup creation started. Operation: $$BACKUP_OP" + + @echo "🔎 Fetching latest backup ID from krow-sql..." + @BACKUP_ID="$$(gcloud sql backups list --instance=krow-sql --project=$(GCP_PROJECT_ID) --limit=1 --sort-by=~endTime --format='value(id)')"; \ + if [ -z "$$BACKUP_ID" ]; then \ + echo "❌ Could not find a backup ID for krow-sql."; \ + exit 1; \ + fi; \ + echo "✅ Latest backup ID: $$BACKUP_ID"; \ + echo "⚠️ Restoring backup into krow-sql-validation..."; \ + gcloud sql backups restore $$BACKUP_ID \ + --restore-instance=krow-sql-validation \ + --backup-instance=krow-sql \ + --project=$(GCP_PROJECT_ID) + + @echo "⚠️ Linking Data Connect service (krow-workforce-db-validation) with Cloud SQL..." + @echo " When prompted, select instance: krow-sql-validation and database: krow_db" + firebase dataconnect:sql:setup krow-workforce-db-validation --project=$(FIREBASE_ALIAS) + + @echo "⚠️ Deploying Data Connect configuration ($(DC_SERVICE_VALIDATION))..." + @firebase deploy --only dataconnect:$(DC_SERVICE_VALIDATION) --project=$(FIREBASE_ALIAS) + + @echo "⚠️ Generating Data Connect SDK ($(DC_SERVICE))..." + @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) + + @echo "🎉 Validation Cloud SQL + Data Connect bootstrap completed successfully!" diff --git a/makefiles/launchpad.mk b/makefiles/launchpad.mk index 8dbe860f..87050e19 100644 --- a/makefiles/launchpad.mk +++ b/makefiles/launchpad.mk @@ -2,13 +2,13 @@ .PHONY: launchpad-dev deploy-launchpad-hosting -launchpad-dev: +launchpad-dev: sync-prototypes @echo "--> Starting local Launchpad server using Firebase Hosting emulator..." @echo " - Generating secure email hashes..." @node scripts/generate-allowed-hashes.js @firebase serve --only hosting:launchpad --project=$(FIREBASE_ALIAS) -deploy-launchpad-hosting: +deploy-launchpad-hosting: sync-prototypes @echo "--> Deploying Internal Launchpad to Firebase Hosting..." @echo " - Generating secure email hashes..." @node scripts/generate-allowed-hashes.js From e7c12245d0e647953af71a5fa43b5324b2468daa Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Thu, 5 Feb 2026 01:16:37 -0500 Subject: [PATCH 05/12] Update Data Connect configuration for validation environment --- backend/dataconnect/dataconnect.yaml | 4 ++-- makefiles/dataconnect.mk | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/backend/dataconnect/dataconnect.yaml b/backend/dataconnect/dataconnect.yaml index 39e01fdb..9e1775d6 100644 --- a/backend/dataconnect/dataconnect.yaml +++ b/backend/dataconnect/dataconnect.yaml @@ -1,5 +1,5 @@ specVersion: "v1" -serviceId: "krow-workforce-db" +serviceId: "krow-workforce-db-validation" location: "us-central1" schema: source: "./schema" @@ -7,7 +7,7 @@ schema: postgresql: database: "krow_db" cloudSql: - instanceId: "krow-sql" + instanceId: "krow-sql-validation" # schemaValidation: "STRICT" # STRICT mode makes Postgres schema match Data Connect exactly. # schemaValidation: "COMPATIBLE" # COMPATIBLE mode makes Postgres schema compatible with Data Connect. connectorDirs: ["./connector"] diff --git a/makefiles/dataconnect.mk b/makefiles/dataconnect.mk index c2db1fd6..5ec73a19 100644 --- a/makefiles/dataconnect.mk +++ b/makefiles/dataconnect.mk @@ -6,7 +6,7 @@ # make dataconnect-clean DC_ENV=validation # make dataconnect-generate-sdk DC_ENV=dev # -DC_ENV ?= dev +DC_ENV ?= validation DC_SERVICE_DEV := krow-workforce-db DC_SERVICE_VALIDATION := krow-workforce-db-validation @@ -74,17 +74,17 @@ dataconnect-sql-migrate: dataconnect-file @echo "✅ Data Connect SQL migration completed for [$(ENV)]." # Generate Data Connect client SDK for frontend-web and internal-api-harness -dataconnect-generate-sdk: dataconnect-file - @echo "--> Generating Firebase Data Connect SDK for web frontend and API harness..." - @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) - @echo "✅ Data Connect SDK generation completed for [$(ENV)]." +dataconnect-generate-sdk: dataconnect-file + @echo "--> Generating Firebase Data Connect SDK for [$(DC_SERVICE)]..." + @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) + @echo "✅ Data Connect SDK generation completed for [$(DC_ENV)]." # Unified backend schema update workflow (schema -> deploy -> SDK) dataconnect-sync: dataconnect-file @echo "--> [1/3] Deploying Data Connect [$(DC_SERVICE)]..." @firebase deploy --only dataconnect:$(DC_SERVICE) --project=$(FIREBASE_ALIAS) @echo "--> [2/3] Applying SQL migrations [$(DC_SERVICE)]..." - @firebase dataconnect:sql:migrate $(DC_SERVICE) --project=$(FIREBASE_ALIAS) + @firebase dataconnect:sql:migrate --project=$(FIREBASE_ALIAS) @echo "--> [3/3] Regenerating SDK [$(DC_SERVICE)]..." @firebase dataconnect:sdk:generate --project=$(FIREBASE_ALIAS) @echo "✅ Data Connect SQL, deploy, and SDK generation [$(ENV)]." @@ -95,7 +95,6 @@ dataconnect-seed: dataconnect-file @firebase dataconnect:execute backend/dataconnect/functions/seed.gql --project=$(FIREBASE_ALIAS) @echo "✅ Seed executed successfully." - # Execute clean, to delete all the data in Firebase Data Connect dataconnect-clean: dataconnect-file @echo "--> Exec clean all the data in Firebase Data Connect (service: $(DC_SERVICE))..." From 6dafb4c79819d1d324fa2c7540fad6fa11ac8e43 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Thu, 5 Feb 2026 01:19:31 -0500 Subject: [PATCH 06/12] Bump version to 0.0.1-M3+7 for client and 0.0.1-M3+5 for staff applications --- apps/mobile/apps/client/pubspec.yaml | 2 +- apps/mobile/apps/staff/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/mobile/apps/client/pubspec.yaml b/apps/mobile/apps/client/pubspec.yaml index e59f8177..68d1faff 100644 --- a/apps/mobile/apps/client/pubspec.yaml +++ b/apps/mobile/apps/client/pubspec.yaml @@ -1,7 +1,7 @@ name: krowwithus_client description: "Krow Client Application" publish_to: "none" -version: 0.0.1-M3+6 +version: 0.0.1-M3+7 resolution: workspace environment: diff --git a/apps/mobile/apps/staff/pubspec.yaml b/apps/mobile/apps/staff/pubspec.yaml index 5f76de72..51f1610a 100644 --- a/apps/mobile/apps/staff/pubspec.yaml +++ b/apps/mobile/apps/staff/pubspec.yaml @@ -1,7 +1,7 @@ name: krowwithus_staff description: "Krow Staff Application" publish_to: 'none' -version: 0.0.1-M3+4 +version: 0.0.1-M3+5 resolution: workspace environment: From 5d21069a49afe615dfbf33817882f90009ab4075 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Thu, 5 Feb 2026 13:48:20 -0500 Subject: [PATCH 07/12] Update versioning for client and staff applications to include specific identifiers for Iliana --- apps/mobile/apps/client/pubspec.yaml | 2 +- apps/mobile/apps/staff/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/mobile/apps/client/pubspec.yaml b/apps/mobile/apps/client/pubspec.yaml index 68d1faff..0dbee1b0 100644 --- a/apps/mobile/apps/client/pubspec.yaml +++ b/apps/mobile/apps/client/pubspec.yaml @@ -1,7 +1,7 @@ name: krowwithus_client description: "Krow Client Application" publish_to: "none" -version: 0.0.1-M3+7 +version: 0.0.1-M3+client+for+Iliana resolution: workspace environment: diff --git a/apps/mobile/apps/staff/pubspec.yaml b/apps/mobile/apps/staff/pubspec.yaml index 51f1610a..54773d19 100644 --- a/apps/mobile/apps/staff/pubspec.yaml +++ b/apps/mobile/apps/staff/pubspec.yaml @@ -1,7 +1,7 @@ name: krowwithus_staff description: "Krow Staff Application" publish_to: 'none' -version: 0.0.1-M3+5 +version: 0.0.1-M3+staff+for+Iliana resolution: workspace environment: From 831bfd2f64964f9ef3878bb6b007b86de07965f2 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Thu, 5 Feb 2026 14:06:20 -0500 Subject: [PATCH 08/12] Update versioning for client and staff applications to include specific identifiers for Iliana --- apps/mobile/apps/client/pubspec.yaml | 2 +- apps/mobile/apps/staff/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/mobile/apps/client/pubspec.yaml b/apps/mobile/apps/client/pubspec.yaml index 0dbee1b0..85dde1ec 100644 --- a/apps/mobile/apps/client/pubspec.yaml +++ b/apps/mobile/apps/client/pubspec.yaml @@ -1,7 +1,7 @@ name: krowwithus_client description: "Krow Client Application" publish_to: "none" -version: 0.0.1-M3+client+for+Iliana +version: 0.0.1-M3+iliana.client resolution: workspace environment: diff --git a/apps/mobile/apps/staff/pubspec.yaml b/apps/mobile/apps/staff/pubspec.yaml index 54773d19..8195d9c6 100644 --- a/apps/mobile/apps/staff/pubspec.yaml +++ b/apps/mobile/apps/staff/pubspec.yaml @@ -1,7 +1,7 @@ name: krowwithus_staff description: "Krow Staff Application" publish_to: 'none' -version: 0.0.1-M3+staff+for+Iliana +version: 0.0.1-M3+iliana.staff resolution: workspace environment: From f359c3c0d15fb0cd7e5ae5e1bd3c80c1e90673ee Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Thu, 5 Feb 2026 14:35:20 -0500 Subject: [PATCH 09/12] Update versioning for client and staff applications to standardize identifiers --- apps/mobile/apps/client/pubspec.yaml | 2 +- apps/mobile/apps/staff/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/mobile/apps/client/pubspec.yaml b/apps/mobile/apps/client/pubspec.yaml index 85dde1ec..101a2b77 100644 --- a/apps/mobile/apps/client/pubspec.yaml +++ b/apps/mobile/apps/client/pubspec.yaml @@ -1,7 +1,7 @@ name: krowwithus_client description: "Krow Client Application" publish_to: "none" -version: 0.0.1-M3+iliana.client +version: 0.0.1-IlianaClientM3 resolution: workspace environment: diff --git a/apps/mobile/apps/staff/pubspec.yaml b/apps/mobile/apps/staff/pubspec.yaml index 8195d9c6..8bc77687 100644 --- a/apps/mobile/apps/staff/pubspec.yaml +++ b/apps/mobile/apps/staff/pubspec.yaml @@ -1,7 +1,7 @@ name: krowwithus_staff description: "Krow Staff Application" publish_to: 'none' -version: 0.0.1-M3+iliana.staff +version: 0.0.1-IlianaStaffM3 resolution: workspace environment: From b0065068a4ed0265424fa67cb57a46e7285f71c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Salazar?= <73718835+joshrs23@users.noreply.github.com> Date: Fri, 6 Feb 2026 11:35:31 +0900 Subject: [PATCH 10/12] validations of connection to validation db --- .gitignore | 1 + apps/mobile/apps/client/lib/main.dart | 4 ++++ .../data/repositories_impl/auth_repository_impl.dart | 12 ++++++++++++ 3 files changed, 17 insertions(+) diff --git a/.gitignore b/.gitignore index 00f2c2ca..33036db1 100644 --- a/.gitignore +++ b/.gitignore @@ -142,6 +142,7 @@ build/ .firebase/ dataconnect/.dataconnect/ backend/dataconnect/.dataconnect/ +backend/dataconnect/dataconnect.yaml # Debug Logs (Recursive) **/firebase-debug.log diff --git a/apps/mobile/apps/client/lib/main.dart b/apps/mobile/apps/client/lib/main.dart index 362fe8b3..faa1ac8e 100644 --- a/apps/mobile/apps/client/lib/main.dart +++ b/apps/mobile/apps/client/lib/main.dart @@ -13,6 +13,7 @@ import 'package:client_create_order/client_create_order.dart' as client_create_order; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart'; +import 'package:krow_data_connect/krow_data_connect.dart' as dc; import 'package:krow_core/core.dart'; import 'firebase_options.dart'; @@ -21,6 +22,9 @@ void main() async { await Firebase.initializeApp( options: kIsWeb ? DefaultFirebaseOptions.currentPlatform : null, ); + if (kDebugMode) { + debugPrint('DataConnect config: ${dc.ExampleConnector.connectorConfig.toJson()}'); + } runApp(ModularApp(module: AppModule(), child: const AppWidget())); } diff --git a/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart b/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart index 87146306..8f546075 100644 --- a/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart +++ b/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart @@ -2,6 +2,7 @@ import 'dart:developer' as developer; import 'package:firebase_auth/firebase_auth.dart' as firebase; import 'package:firebase_data_connect/firebase_data_connect.dart'; +import 'package:flutter/foundation.dart'; import 'package:krow_data_connect/krow_data_connect.dart' as dc; import 'package:krow_domain/krow_domain.dart' show @@ -359,6 +360,17 @@ class AuthRepositoryImpl implements AuthRepositoryInterface { ? businessResponse.data.businesses.first : null; + if (kDebugMode) { + developer.log( + 'Client auth DataConnect: ${dc.ExampleConnector.connectorConfig.toJson()}', + name: 'AuthRepository', + ); + developer.log( + 'Client business session: userId=$firebaseUserId businessId=${business?.id} businessName=${business?.businessName} email=${business?.email}', + name: 'AuthRepository', + ); + } + dc.ClientSessionStore.instance.setSession( dc.ClientSession( user: domainUser, From aa2418b327ed73db7d7401f81b4426f54e732cf7 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Fri, 6 Feb 2026 00:29:04 -0500 Subject: [PATCH 11/12] Refactor import order and remove debug logging in authentication repository --- apps/mobile/apps/client/lib/main.dart | 23 ++++++++----------- .../auth_repository_impl.dart | 15 +----------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/apps/mobile/apps/client/lib/main.dart b/apps/mobile/apps/client/lib/main.dart index faa1ac8e..a557d8e8 100644 --- a/apps/mobile/apps/client/lib/main.dart +++ b/apps/mobile/apps/client/lib/main.dart @@ -1,20 +1,20 @@ +import 'package:client_authentication/client_authentication.dart' + as client_authentication; +import 'package:client_create_order/client_create_order.dart' + as client_create_order; +import 'package:client_hubs/client_hubs.dart' as client_hubs; +import 'package:client_main/client_main.dart' as client_main; +import 'package:client_settings/client_settings.dart' as client_settings; import 'package:core_localization/core_localization.dart' as core_localization; import 'package:design_system/design_system.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_modular/flutter_modular.dart'; -import 'package:client_authentication/client_authentication.dart' - as client_authentication; -import 'package:client_main/client_main.dart' as client_main; -import 'package:client_settings/client_settings.dart' as client_settings; -import 'package:client_hubs/client_hubs.dart' as client_hubs; -import 'package:client_create_order/client_create_order.dart' - as client_create_order; -import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/foundation.dart'; -import 'package:krow_data_connect/krow_data_connect.dart' as dc; import 'package:krow_core/core.dart'; + import 'firebase_options.dart'; void main() async { @@ -22,9 +22,6 @@ void main() async { await Firebase.initializeApp( options: kIsWeb ? DefaultFirebaseOptions.currentPlatform : null, ); - if (kDebugMode) { - debugPrint('DataConnect config: ${dc.ExampleConnector.connectorConfig.toJson()}'); - } runApp(ModularApp(module: AppModule(), child: const AppWidget())); } diff --git a/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart b/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart index 8f546075..f1ff2c80 100644 --- a/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart +++ b/apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart @@ -2,7 +2,6 @@ import 'dart:developer' as developer; import 'package:firebase_auth/firebase_auth.dart' as firebase; import 'package:firebase_data_connect/firebase_data_connect.dart'; -import 'package:flutter/foundation.dart'; import 'package:krow_data_connect/krow_data_connect.dart' as dc; import 'package:krow_domain/krow_domain.dart' show @@ -13,8 +12,7 @@ import 'package:krow_domain/krow_domain.dart' AccountExistsException, UserNotFoundException, UnauthorizedAppException, - PasswordMismatchException, - GoogleOnlyAccountException; + PasswordMismatchException; import 'package:krow_domain/krow_domain.dart' as domain; import '../../domain/repositories/auth_repository_interface.dart'; @@ -360,17 +358,6 @@ class AuthRepositoryImpl implements AuthRepositoryInterface { ? businessResponse.data.businesses.first : null; - if (kDebugMode) { - developer.log( - 'Client auth DataConnect: ${dc.ExampleConnector.connectorConfig.toJson()}', - name: 'AuthRepository', - ); - developer.log( - 'Client business session: userId=$firebaseUserId businessId=${business?.id} businessName=${business?.businessName} email=${business?.email}', - name: 'AuthRepository', - ); - } - dc.ClientSessionStore.instance.setSession( dc.ClientSession( user: domainUser, From d39fa6e6c33cdb93058a030c7b8846b6abc3afe7 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Fri, 6 Feb 2026 00:44:27 -0500 Subject: [PATCH 12/12] Update service IDs in dataconnect configuration for consistency --- backend/dataconnect/dataconnect.yaml | 4 ++-- makefiles/dataconnect.mk | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/dataconnect/dataconnect.yaml b/backend/dataconnect/dataconnect.yaml index 9e1775d6..39e01fdb 100644 --- a/backend/dataconnect/dataconnect.yaml +++ b/backend/dataconnect/dataconnect.yaml @@ -1,5 +1,5 @@ specVersion: "v1" -serviceId: "krow-workforce-db-validation" +serviceId: "krow-workforce-db" location: "us-central1" schema: source: "./schema" @@ -7,7 +7,7 @@ schema: postgresql: database: "krow_db" cloudSql: - instanceId: "krow-sql-validation" + instanceId: "krow-sql" # schemaValidation: "STRICT" # STRICT mode makes Postgres schema match Data Connect exactly. # schemaValidation: "COMPATIBLE" # COMPATIBLE mode makes Postgres schema compatible with Data Connect. connectorDirs: ["./connector"] diff --git a/makefiles/dataconnect.mk b/makefiles/dataconnect.mk index 5ec73a19..7285b997 100644 --- a/makefiles/dataconnect.mk +++ b/makefiles/dataconnect.mk @@ -6,7 +6,7 @@ # make dataconnect-clean DC_ENV=validation # make dataconnect-generate-sdk DC_ENV=dev # -DC_ENV ?= validation +DC_ENV ?= dev DC_SERVICE_DEV := krow-workforce-db DC_SERVICE_VALIDATION := krow-workforce-db-validation