Merge remote-tracking branch 'origin/dev' into recreate_validation
This commit is contained in:
@@ -41,6 +41,11 @@ class ClientPaths {
|
|||||||
/// This serves as the entry point for unauthenticated users.
|
/// This serves as the entry point for unauthenticated users.
|
||||||
static const String root = '/';
|
static const String root = '/';
|
||||||
|
|
||||||
|
/// Get Started page (relative path within auth module).
|
||||||
|
///
|
||||||
|
/// The landing page for unauthenticated users, offering login/signup options.
|
||||||
|
static const String getStarted = '/get-started';
|
||||||
|
|
||||||
/// Sign-in page where existing clients can log into their account.
|
/// Sign-in page where existing clients can log into their account.
|
||||||
///
|
///
|
||||||
/// Supports email/password and social authentication.
|
/// Supports email/password and social authentication.
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ class StaffPaths {
|
|||||||
/// This serves as the entry point for unauthenticated staff members.
|
/// This serves as the entry point for unauthenticated staff members.
|
||||||
static const String root = '/';
|
static const String root = '/';
|
||||||
|
|
||||||
|
/// Get Started page (relative path within auth module).
|
||||||
|
///
|
||||||
|
/// The landing page for unauthenticated users, offering login/signup options.
|
||||||
|
static const String getStarted = '/get-started';
|
||||||
|
|
||||||
/// Phone verification page (relative path within auth module).
|
/// Phone verification page (relative path within auth module).
|
||||||
///
|
///
|
||||||
/// Used for both login and signup flows to verify phone numbers via OTP.
|
/// Used for both login and signup flows to verify phone numbers via OTP.
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import 'package:flutter_modular/flutter_modular.dart';
|
import 'package:flutter_modular/flutter_modular.dart';
|
||||||
|
import 'services/data_connect_service.dart';
|
||||||
|
|
||||||
/// A module that provides Data Connect dependencies.
|
/// A module that provides Data Connect dependencies.
|
||||||
class DataConnectModule extends Module {
|
class DataConnectModule extends Module {
|
||||||
@override
|
@override
|
||||||
void exportedBinds(Injector i) {
|
void exportedBinds(Injector i) {
|
||||||
// No mock bindings anymore.
|
i.addInstance<DataConnectService>(DataConnectService.instance);
|
||||||
// Real repositories are instantiated in their feature modules.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import 'src/domain/usecases/sign_in_with_social_use_case.dart';
|
|||||||
import 'src/domain/usecases/sign_out_use_case.dart';
|
import 'src/domain/usecases/sign_out_use_case.dart';
|
||||||
import 'src/domain/usecases/sign_up_with_email_use_case.dart';
|
import 'src/domain/usecases/sign_up_with_email_use_case.dart';
|
||||||
import 'src/presentation/blocs/client_auth_bloc.dart';
|
import 'src/presentation/blocs/client_auth_bloc.dart';
|
||||||
|
import 'src/presentation/pages/client_intro_page.dart';
|
||||||
import 'src/presentation/pages/client_get_started_page.dart';
|
import 'src/presentation/pages/client_get_started_page.dart';
|
||||||
import 'src/presentation/pages/client_sign_in_page.dart';
|
import 'src/presentation/pages/client_sign_in_page.dart';
|
||||||
import 'src/presentation/pages/client_sign_up_page.dart';
|
import 'src/presentation/pages/client_sign_up_page.dart';
|
||||||
@@ -54,7 +55,8 @@ class ClientAuthenticationModule extends Module {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void routes(RouteManager r) {
|
void routes(RouteManager r) {
|
||||||
r.child(ClientPaths.root, child: (_) => const ClientGetStartedPage());
|
r.child(ClientPaths.root, child: (_) => const ClientIntroPage());
|
||||||
|
r.child(ClientPaths.getStarted, child: (_) => const ClientGetStartedPage());
|
||||||
r.child(ClientPaths.signIn, child: (_) => const ClientSignInPage());
|
r.child(ClientPaths.signIn, child: (_) => const ClientSignInPage());
|
||||||
r.child(ClientPaths.signUp, child: (_) => const ClientSignUpPage());
|
r.child(ClientPaths.signUp, child: (_) => const ClientSignUpPage());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -414,4 +414,26 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
|
|||||||
|
|
||||||
return domainUser;
|
return domainUser;
|
||||||
}
|
}
|
||||||
|
@override
|
||||||
|
Future<domain.User?> restoreSession() async {
|
||||||
|
final firebase.User? firebaseUser = _service.auth.currentUser;
|
||||||
|
if (firebaseUser == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await _getUserProfile(
|
||||||
|
firebaseUserId: firebaseUser.uid,
|
||||||
|
fallbackEmail: firebaseUser.email,
|
||||||
|
requireBusinessRole: true,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
// If the user is not found or other permanent errors, we should probably sign out
|
||||||
|
if (e is UserNotFoundException || e is UnauthorizedAppException) {
|
||||||
|
await _service.auth.signOut();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,4 +34,7 @@ abstract class AuthRepositoryInterface {
|
|||||||
|
|
||||||
/// Terminates the current user session and clears authentication tokens.
|
/// Terminates the current user session and clears authentication tokens.
|
||||||
Future<void> signOut();
|
Future<void> signOut();
|
||||||
|
|
||||||
|
/// Restores the session if a user is already logged in.
|
||||||
|
Future<User?> restoreSession();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:client_authentication/src/domain/repositories/auth_repository_interface.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_modular/flutter_modular.dart';
|
||||||
|
import 'package:krow_core/core.dart';
|
||||||
|
|
||||||
|
class ClientIntroPage extends StatefulWidget {
|
||||||
|
const ClientIntroPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ClientIntroPage> createState() => _ClientIntroPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ClientIntroPageState extends State<ClientIntroPage> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_checkSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _checkSession() async {
|
||||||
|
// Check session immediately without artificial delay
|
||||||
|
if (!mounted) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final AuthRepositoryInterface authRepo = Modular.get<AuthRepositoryInterface>();
|
||||||
|
// Add a timeout to prevent infinite loading
|
||||||
|
final user = await authRepo.restoreSession().timeout(
|
||||||
|
const Duration(seconds: 5),
|
||||||
|
onTimeout: () {
|
||||||
|
throw TimeoutException('Session restore timed out');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
if (user != null) {
|
||||||
|
Modular.to.navigate(ClientPaths.home);
|
||||||
|
} else {
|
||||||
|
Modular.to.navigate(ClientPaths.getStarted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('ClientIntroPage: Session check error: $e');
|
||||||
|
if (mounted) {
|
||||||
|
Modular.to.navigate(ClientPaths.getStarted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
|
body: Center(
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/logo-blue.png',
|
||||||
|
package: 'design_system',
|
||||||
|
width: 120,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -257,4 +257,77 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
|
|||||||
);
|
);
|
||||||
return domainUser;
|
return domainUser;
|
||||||
}
|
}
|
||||||
|
@override
|
||||||
|
Future<domain.User?> restoreSession() async {
|
||||||
|
final User? firebaseUser = _service.auth.currentUser;
|
||||||
|
if (firebaseUser == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. Fetch User
|
||||||
|
final QueryResult<GetUserByIdData, GetUserByIdVariables> response =
|
||||||
|
await _service.run(() => _service.connector
|
||||||
|
.getUserById(
|
||||||
|
id: firebaseUser.uid,
|
||||||
|
)
|
||||||
|
.execute());
|
||||||
|
final GetUserByIdUser? user = response.data.user;
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Check Role
|
||||||
|
if (user.userRole != 'STAFF' && user.userRole != 'BOTH') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Fetch Staff Profile
|
||||||
|
final QueryResult<GetStaffByUserIdData, GetStaffByUserIdVariables>
|
||||||
|
staffResponse = await _service.run(() => _service.connector
|
||||||
|
.getStaffByUserId(
|
||||||
|
userId: firebaseUser.uid,
|
||||||
|
)
|
||||||
|
.execute());
|
||||||
|
|
||||||
|
if (staffResponse.data.staffs.isEmpty) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final GetStaffByUserIdStaffs staffRecord = staffResponse.data.staffs.first;
|
||||||
|
|
||||||
|
// 4. Populate Session
|
||||||
|
final domain.User domainUser = domain.User(
|
||||||
|
id: firebaseUser.uid,
|
||||||
|
email: user.email ?? '',
|
||||||
|
phone: firebaseUser.phoneNumber,
|
||||||
|
role: user.role.stringValue,
|
||||||
|
);
|
||||||
|
|
||||||
|
final domain.Staff domainStaff = domain.Staff(
|
||||||
|
id: staffRecord.id,
|
||||||
|
authProviderId: staffRecord.userId,
|
||||||
|
name: staffRecord.fullName,
|
||||||
|
email: staffRecord.email ?? '',
|
||||||
|
phone: staffRecord.phone,
|
||||||
|
status: domain.StaffStatus.completedProfile,
|
||||||
|
address: staffRecord.addres,
|
||||||
|
avatar: staffRecord.photoUrl,
|
||||||
|
);
|
||||||
|
|
||||||
|
StaffSessionStore.instance.setSession(
|
||||||
|
StaffSession(
|
||||||
|
user: domainUser,
|
||||||
|
staff: domainStaff,
|
||||||
|
ownerId: staffRecord.ownerId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return domainUser;
|
||||||
|
} catch (e) {
|
||||||
|
// If restoration fails (network, etc), we rethrow to let UI handle it.
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,5 +20,7 @@ abstract interface class AuthRepositoryInterface {
|
|||||||
|
|
||||||
/// Signs out the current user.
|
/// Signs out the current user.
|
||||||
Future<void> signOut();
|
Future<void> signOut();
|
||||||
// Future<Staff?> getStaffProfile(String userId); // Could be moved to a separate repository if needed, but useful here for routing logic.
|
|
||||||
|
/// Restores the session if a user is already logged in.
|
||||||
|
Future<User?> restoreSession();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_modular/flutter_modular.dart';
|
||||||
|
import 'package:krow_core/core.dart';
|
||||||
|
import 'package:staff_authentication/src/domain/repositories/auth_repository_interface.dart';
|
||||||
|
|
||||||
|
class IntroPage extends StatefulWidget {
|
||||||
|
const IntroPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<IntroPage> createState() => _IntroPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _IntroPageState extends State<IntroPage> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_checkSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _checkSession() async {
|
||||||
|
// Check session immediately without artificial delay
|
||||||
|
if (!mounted) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final AuthRepositoryInterface authRepo = Modular.get<AuthRepositoryInterface>();
|
||||||
|
// Add a timeout to prevent infinite loading
|
||||||
|
final user = await authRepo.restoreSession().timeout(
|
||||||
|
const Duration(seconds: 5),
|
||||||
|
onTimeout: () {
|
||||||
|
// If it takes too long, navigate to Get Started.
|
||||||
|
// This handles poor network conditions gracefully.
|
||||||
|
throw TimeoutException('Session restore timed out');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
if (user != null) {
|
||||||
|
Modular.to.navigate(StaffPaths.home);
|
||||||
|
} else {
|
||||||
|
Modular.to.navigate(StaffPaths.getStarted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('IntroPage: Session check error: $e');
|
||||||
|
if (mounted) {
|
||||||
|
Modular.to.navigate(StaffPaths.getStarted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
|
body: Center(
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/logo-yellow.png',
|
||||||
|
package: 'design_system',
|
||||||
|
width: 120,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ import 'package:staff_authentication/src/data/repositories_impl/place_repository
|
|||||||
import 'package:staff_authentication/src/domain/usecases/search_cities_usecase.dart';
|
import 'package:staff_authentication/src/domain/usecases/search_cities_usecase.dart';
|
||||||
import 'package:staff_authentication/src/presentation/blocs/auth_bloc.dart';
|
import 'package:staff_authentication/src/presentation/blocs/auth_bloc.dart';
|
||||||
import 'package:staff_authentication/src/presentation/blocs/profile_setup/profile_setup_bloc.dart';
|
import 'package:staff_authentication/src/presentation/blocs/profile_setup/profile_setup_bloc.dart';
|
||||||
|
import 'package:staff_authentication/src/presentation/pages/intro_page.dart';
|
||||||
import 'package:staff_authentication/src/presentation/pages/get_started_page.dart';
|
import 'package:staff_authentication/src/presentation/pages/get_started_page.dart';
|
||||||
import 'package:staff_authentication/src/presentation/pages/phone_verification_page.dart';
|
import 'package:staff_authentication/src/presentation/pages/phone_verification_page.dart';
|
||||||
import 'package:staff_authentication/src/presentation/pages/profile_setup_page.dart';
|
import 'package:staff_authentication/src/presentation/pages/profile_setup_page.dart';
|
||||||
@@ -54,7 +55,8 @@ class StaffAuthenticationModule extends Module {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void routes(RouteManager r) {
|
void routes(RouteManager r) {
|
||||||
r.child(StaffPaths.root, child: (_) => const GetStartedPage());
|
r.child(StaffPaths.root, child: (_) => const IntroPage());
|
||||||
|
r.child(StaffPaths.getStarted, child: (_) => const GetStartedPage());
|
||||||
r.child(
|
r.child(
|
||||||
StaffPaths.phoneVerification,
|
StaffPaths.phoneVerification,
|
||||||
child: (BuildContext context) {
|
child: (BuildContext context) {
|
||||||
|
|||||||
@@ -186,10 +186,20 @@ class ShiftsRepositoryImpl
|
|||||||
final fdc.QueryResult<dc.ListShiftRolesByVendorIdData, dc.ListShiftRolesByVendorIdVariables> result = await _service.executeProtected(() => _service.connector
|
final fdc.QueryResult<dc.ListShiftRolesByVendorIdData, dc.ListShiftRolesByVendorIdVariables> result = await _service.executeProtected(() => _service.connector
|
||||||
.listShiftRolesByVendorId(vendorId: vendorId)
|
.listShiftRolesByVendorId(vendorId: vendorId)
|
||||||
.execute());
|
.execute());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
final allShiftRoles = result.data.shiftRoles;
|
final allShiftRoles = result.data.shiftRoles;
|
||||||
|
|
||||||
|
// Fetch my applications to filter out already booked shifts
|
||||||
|
final List<Shift> myShifts = await _fetchApplications();
|
||||||
|
final Set<String> myShiftIds = myShifts.map((s) => s.id).toSet();
|
||||||
|
|
||||||
final List<Shift> mappedShifts = [];
|
final List<Shift> mappedShifts = [];
|
||||||
for (final sr in allShiftRoles) {
|
for (final sr in allShiftRoles) {
|
||||||
|
// Skip if I have already applied/booked this shift
|
||||||
|
if (myShiftIds.contains(sr.shiftId)) continue;
|
||||||
|
|
||||||
|
|
||||||
final DateTime? shiftDate = _service.toDateTime(sr.shift.date);
|
final DateTime? shiftDate = _service.toDateTime(sr.shift.date);
|
||||||
final startDt = _service.toDateTime(sr.startTime);
|
final startDt = _service.toDateTime(sr.startTime);
|
||||||
|
|||||||
@@ -141,10 +141,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.1"
|
||||||
charcode:
|
charcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -741,14 +741,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.5"
|
version: "1.0.5"
|
||||||
js:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: js
|
|
||||||
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.7.2"
|
|
||||||
json_annotation:
|
json_annotation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -817,18 +809,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.17"
|
version: "0.12.18"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.1"
|
version: "0.13.0"
|
||||||
melos:
|
melos:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@@ -1326,26 +1318,26 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test
|
name: test
|
||||||
sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7"
|
sha256: "54c516bbb7cee2754d327ad4fca637f78abfc3cbcc5ace83b3eda117e42cd71a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.26.3"
|
version: "1.29.0"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.7"
|
version: "0.7.9"
|
||||||
test_core:
|
test_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_core
|
name: test_core
|
||||||
sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0"
|
sha256: "394f07d21f0f2255ec9e3989f21e54d3c7dc0e6e9dbce160e5a9c1a6be0e2943"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.12"
|
version: "0.6.15"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -247,6 +247,7 @@ query listShiftRolesByShiftIdAndTimeRange(
|
|||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
query listShiftRolesByVendorId(
|
query listShiftRolesByVendorId(
|
||||||
$vendorId: UUID!
|
$vendorId: UUID!
|
||||||
|
|
||||||
$offset: Int
|
$offset: Int
|
||||||
$limit: Int
|
$limit: Int
|
||||||
) @auth(level: USER) {
|
) @auth(level: USER) {
|
||||||
@@ -313,6 +314,7 @@ query listShiftRolesByVendorId(
|
|||||||
vendor { id companyName }
|
vendor { id companyName }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,4 +33,6 @@ type ShiftRole @table(name: "shift_roles", key: ["shiftId", "roleId"]) {
|
|||||||
|
|
||||||
createdAt: Timestamp @default(expr: "request.time")
|
createdAt: Timestamp @default(expr: "request.time")
|
||||||
updatedAt: Timestamp @default(expr: "request.time")
|
updatedAt: Timestamp @default(expr: "request.time")
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -303,14 +303,19 @@ const dataconnectEntityConfig = {
|
|||||||
Order:{
|
Order:{
|
||||||
list: 'listOrder',
|
list: 'listOrder',
|
||||||
get: 'getOrderById',
|
get: 'getOrderById',
|
||||||
create: 'UpdateOrder',
|
create: 'createOrder',
|
||||||
update: 'updateEnterprise',
|
update: 'updateOrder',
|
||||||
delete: 'deleteEnterprise',
|
delete: 'deleteOrder',
|
||||||
filter: 'filterOrder',
|
filter: 'filterOrder',
|
||||||
},
|
},
|
||||||
|
|
||||||
Shift:{
|
Shift:{
|
||||||
|
list: 'listShifts',
|
||||||
|
get: 'getShiftById',
|
||||||
|
create: 'createShift',
|
||||||
|
update: 'updateShift',
|
||||||
|
delete: 'deleteShift',
|
||||||
|
filter: 'filterShifts',
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user