diff --git a/docs/CENTRALIZED_ERROR_HANDLING_MASTER.md b/docs/CENTRALIZED_ERROR_HANDLING_MASTER.md deleted file mode 100644 index 6da5ddbe..00000000 --- a/docs/CENTRALIZED_ERROR_HANDLING_MASTER.md +++ /dev/null @@ -1,136 +0,0 @@ -# πŸŽ‰ Centralized Error Handling - Implementation Complete! - -## βœ… What We Accomplished - -I've successfully implemented a **production-ready centralized error handling system** for both Client and Staff apps. Here's what was delivered: - -### 1. **Core Infrastructure** (100% Complete) -**βœ… UI Components** (`design_system` package) -- `UiErrorSnackbar` - Localized error messages -- `UiSuccessSnackbar` - Success feedback - -**βœ… BLoC Error Handler Mixin** (`core` package) -- `BlocErrorHandler` - Eliminates boilerplate -- Automatic error logging -- Type-safe error handling - -**βœ… Global BLoC Observer** (`core` package) -- `CoreBlocObserver` - Centralized monitoring -- Registered in both Client and Staff apps -- Ready for Sentry/Crashlytics - -**βœ… Data Layer Error Handler** (`data_connect` package) -- `DataErrorHandler` mixin -- Wraps Data Connect calls -- Maps `SocketException` and `FirebaseException` to Domain `AppException` (Network/Server) - -### 2. **BLoC Migrations** (2 Complete) -**βœ… ClientAuthBloc** - 4 event handlers migrated -- Reduced from 173 to 153 lines (-11.6%) -- Eliminated ~60 lines of boilerplate - -**βœ… ClientHubsBloc** - 4 event handlers migrated -- Reduced from 232 to 170 lines (-26.7%) -- Eliminated ~62 lines of boilerplate - -### 3. **Documentation** (Complete) -**βœ… 4 comprehensive documents created (now consolidated):** -- `CENTRALIZED_ERROR_HANDLING.md` (Architecture guide) -- `CENTRALIZED_ERROR_HANDLING_SUMMARY.md` (Implementation summary) -- `CENTRALIZED_ERROR_HANDLING_CLIENT_PROPOSAL.md` (Executive summary) -- `BLOC_MIGRATION_STATUS.md` (Migration tracking) - ---- - -## πŸ“Š Key Finding - -After analyzing all BLoCs in both apps, I discovered that **most BLoCs don't have error handling yet**. This is actually **good news** because: - -- βœ… **No refactoring needed** - We can use the new pattern from the start -- βœ… **Clean implementation** - No legacy error handling to remove -- βœ… **Incremental adoption** - Add error handling as needed, not all at once - ---- - -## 🎯 Recommended Approach - -### Option A: Incremental Adoption (Recommended) -- Use `BlocErrorHandler` mixin for all **new** BLoCs -- Add error handling to **existing** BLoCs as you encounter errors -- Focus on user-facing features first -- **Estimated effort**: 0-2 hours per BLoC as needed - -### Option B: Complete Migration (Optional) -- Migrate all 18 remaining BLoCs now -- Add error handling to all event handlers -- **Estimated effort**: 15-20 hours total - ---- - -## πŸ’‘ How to Use (For New Development) - -**1. Add the mixin to your BLoC:** -```dart -class MyBloc extends Bloc - with BlocErrorHandler { -``` - -**2. Use handleError in event handlers:** -```dart -await handleError( - emit: emit, - action: () async { - final result = await _useCase(); - emit(Success(result)); - }, - onError: (errorKey) => Error(errorKey), -); -``` - -**3. Show errors in UI:** -```dart -BlocListener( - listener: (context, state) { - if (state.status == Status.error) { - UiErrorSnackbar.show(context, messageKey: state.errorMessage!); - } - }, -) -``` - ---- - -## πŸ“ Files Created/Modified - -**Created (11 files)**: -1. `packages/design_system/lib/src/widgets/ui_error_snackbar.dart` -2. `packages/design_system/lib/src/widgets/ui_success_snackbar.dart` -3. `packages/core/lib/src/presentation/mixins/bloc_error_handler.dart` -4. `packages/core/lib/src/presentation/observers/core_bloc_observer.dart` -5. `docs/CENTRALIZED_ERROR_HANDLING.md` -6. `docs/CENTRALIZED_ERROR_HANDLING_SUMMARY.md` -7. `docs/CENTRALIZED_ERROR_HANDLING_CLIENT_PROPOSAL.md` -8. `docs/BLOC_MIGRATION_STATUS.md` - -**Modified (7 files)**: -1. `packages/design_system/lib/design_system.dart` -2. `packages/core/lib/core.dart` -3. `apps/client/lib/main.dart` -4. `apps/staff/lib/main.dart` -5. `packages/features/client/authentication/lib/src/presentation/blocs/client_auth_bloc.dart` -6. `packages/features/client/hubs/lib/src/presentation/blocs/client_hubs_bloc.dart` - ---- - -## ✨ Summary - -The centralized error handling system is fully implemented and ready to use for both Client and Staff apps! - -The foundation is solid, the pattern is proven (2 BLoCs migrated successfully), and the documentation is comprehensive. You can now: - -- βœ… **Start using it immediately** for new development -- βœ… **Migrate existing BLoCs incrementally** as needed -- βœ… **Enjoy consistent error handling** across both apps -- βœ… **Reduce boilerplate** by ~20% per BLoC - -**Would you like me to migrate any specific BLoCs now, or are you happy with the incremental approach?** diff --git a/docs/DATACONNECT_GUIDES/DIAGRAMS/mobile/client_app_diagram.mmd b/docs/DATACONNECT_GUIDES/DIAGRAMS/mobile/client_app_diagram.mmd new file mode 100644 index 00000000..d94fc42e --- /dev/null +++ b/docs/DATACONNECT_GUIDES/DIAGRAMS/mobile/client_app_diagram.mmd @@ -0,0 +1,74 @@ +flowchart LR + +subgraph C1["Login"] + S_client_sign_in["client_sign_in_screen.dart"] + S_client_sign_in --> S_client_sign_in_Q["Queries
* user - getUserById
* business - getBusinessesByUserId"] + S_client_sign_in --> S_client_sign_in_F["Firebase
* user - auth"] +end + +subgraph C2["Create account"] + S_client_sign_up["client_sign_up_screen.dart"] + S_client_sign_up --> S_client_sign_up_Q["Queries
* business - getBusinessesByUserId"] + S_client_sign_up --> S_client_sign_up_M["Mutations
* user - createUser
* business - createBusiness"] +end + +subgraph C3["Edit account"] + S_edit_account_na["manual_or_unknown_screen.dart"] + S_edit_account_na --> S_edit_account_na_M["Mutations
* business - updateBusiness"] +end + +subgraph C4["Profile"] + S_client_settings["client_settings_screen.dart"] + S_client_settings --> S_client_settings_Q["Queries
* user - getUserById
* business - getBusinessesByUserId"] +end + +subgraph C5["Hubs"] + S_client_hubs["client_hubs_screen.dart"] + S_client_hubs --> S_client_hubs_Q["Queries
* TeamHub - listTeamHubsByOwnerId"] + S_client_hubs --> S_client_hubs_M["Mutations
* TeamHub - createTeamHub
* TeamHub - updateTeamHub
* TeamHub - deleteTeamHub"] +end + +subgraph C6["Orders"] + S_client_shifts["client_shifts_screen.dart"] + S_client_shifts --> S_client_shifts_Q["Queries
* order - getOrdersByBusinessId"] +end + +subgraph C7["RAPID Order"] + S_rapid_order["rapid_order_flow_page.dart"] + S_rapid_order --> S_rapid_order_M["Mutations
* order - createOrder"] +end + +subgraph C8["One-time Order"] + S_one_time["one_time_order_flow_page.dart"] + S_one_time --> S_one_time_Q["Queries
* role - listRolesByOwnerId"] + S_one_time --> S_one_time_M["Mutations
* ShiftRole - createShiftRole
* order - createOrder"] +end + +subgraph C9["Permanent Placement"] + S_permanent["permanent_order_flow_page.dart"] + S_permanent --> S_permanent_Q["Queries
* role - listRolesByOwnerId"] + S_permanent --> S_permanent_M["Mutations
* ShiftRole - createShiftRole
* order - createOrder"] +end + +subgraph C10["Recurring Order"] + S_recurring["recurring_order_flow_page.dart"] + S_recurring --> S_recurring_Q["Queries
* role - listRolesByOwnerId"] + S_recurring --> S_recurring_M["Mutations
* ShiftRole - createShiftRole
* order - createOrder"] +end + +subgraph C11["Billing"] + S_billing["client_billing_screen.dart"] + S_billing --> S_billing_Q["Queries
* account - getAccountsByOwnerId
* invoice - listInvoicesByBusinessId
* recentPayment - listRecentPaymentsByBusinessId"] + S_billing --> S_billing_M["Mutations
* account - createAccount
* account - updateAccount
* account - deleteAccount"] +end + +subgraph C12["Coverage"] + S_coverage["coverage_dashboard.dart"] + S_coverage --> S_coverage_Q["Queries
* order - getOrdersByBusinessId
* shift - getShiftsByBusinessId
* application - getApplicationsByShiftId"] +end + +subgraph C13["Home"] + S_client_home["client_home_screen.dart"] + S_client_home --> S_client_home_Q["Queries
* order - getOrdersByBusinessId
* shift - getShiftsByBusinessId
* application - getApplicationsByShiftId
* recentPayment - listRecentPaymentsByBusinessId"] + S_client_home --> S_client_home_M["Mutations
* order - createOrder"] +end diff --git a/docs/DATACONNECT_GUIDES/DIAGRAMS/mobile/staff_app_diagram.mmd b/docs/DATACONNECT_GUIDES/DIAGRAMS/mobile/staff_app_diagram.mmd new file mode 100644 index 00000000..224227d2 --- /dev/null +++ b/docs/DATACONNECT_GUIDES/DIAGRAMS/mobile/staff_app_diagram.mmd @@ -0,0 +1,121 @@ +flowchart LR + +subgraph L1["login/create user"] + S_auth_phone["phone_verification_screen.dart"] + S_auth_phone --> S_auth_phone_Q["Queries
* user - getUserById
* staff - getStaffByUserId"] + S_auth_phone --> S_auth_phone_M["Mutations
* user - createUser"] + S_auth_phone --> S_auth_phone_F["Firebase
* user - auth"] +end + +subgraph L2["Profile"] + S_worker_profile["worker_profile_screen.dart"] + S_worker_profile --> S_worker_profile_Q["Queries
* user - getUserById
* staff - getStaffByUserId"] +end + +subgraph L3["Personal info"] + S_personal_info["personal_info_screen.dart"] + S_personal_info --> S_personal_info_Q["Queries
* staff - getStaffByUserId"] + S_personal_info --> S_personal_info_M["Mutations
* staff - UpdateStaff"] +end + +subgraph L4["Emergency Contact"] + S_emergency["emergency_contact_screen.dart"] + S_emergency --> S_emergency_Q["Queries
* emergencyContact - getEmergencyContactsByStaffId"] + S_emergency --> S_emergency_M["Mutations
* conemergencyContacttact - updateEmergencyContact
* emergencyContact - createEmergencyContact
* contemergencyContactact - deleteEmergencyContact"] +end + +subgraph L5["Experience & skills"] + S_experience["experience_screen.dart"] + S_experience --> S_experience_Q["Queries
* staff - getStaffByUserId"] + S_experience --> S_experience_M["Mutations
* staff - UpdateStaff"] +end + +subgraph L6["Attire"] + S_attire["attire_screen.dart"] + S_attire --> S_attire_Q["Queries
* attireOption - filterAttireOptions
* staff - getStaffByUserId"] + S_attire --> S_attire_M["Mutations
* staff - UpdateStaff"] +end + +subgraph L7["Documents"] + S_documents["documents_screen.dart"] + S_documents --> S_documents_Q["Queries
* document - listDocuments
* staffDocument - listStaffDocumentsByStaffId"] + S_documents --> S_documents_M["Mutations
* staffDocument - updateStaffDocument
* staffDocument - createStaffDocument"] +end + +subgraph L8["Certificates"] + S_certificates["certificates_screen.dart"] + S_certificates --> S_certificates_Q["Queries
* certificate - listCertificatesByStaffId"] + S_certificates --> S_certificates_M["Mutations
* certificate - UpdateCertificate
* certificate - CreateCertificate
* certificate - DeleteCertificate"] +end + +subgraph L9["Tax Documents"] + S_tax_forms["tax_forms_screen.dart"] + S_tax_forms --> S_tax_forms_Q["Queries
* taxForm - getTaxFormsBystaffId"] + S_tax_forms --> S_tax_forms_M["Mutations
* taxForm - createTaxForm
* taxForm - updateTaxForm"] +end + +subgraph L10["KROW University"] + S_uni["krow_university_screen.dart"] + S_uni --> S_uni_Q["Queries
* course - listCourses
* staffCourse - listStaffCoursesByStaffId
* staff - getStaffByUserId
* level - listLevels
* certificate - listCertificatesByStaffId"] +end + +subgraph L11["Trainings"] + S_trainings["trainings_screen.dart"] + S_trainings --> S_trainings_Q["Queries
* course - listCourses
* staffCourse - listStaffCoursesByStaffId"] +end + +subgraph L12["Leaderboard"] + S_leaderboard["leaderboard_screen.dart"] + S_leaderboard --> S_leaderboard_Q["Queries
* staffCourse - missing"] +end + +subgraph L13["Bank Account"] + S_bank["bank_account_screen.dart"] + S_bank --> S_bank_Q["Queries
* account - getAccountsByOwnerId"] + S_bank --> S_bank_M["Mutations
* account - createAccount
* account - updateAccount
* account - deleteAccount"] +end + +subgraph L14["Earnings/Payments"] + S_payments["payments_screen.dart"] + S_payments --> S_payments_Q["Queries
* recentPayment - listRecentPaymentsByStaffId"] +end + +subgraph L15["Timecard"] + S_timecard["time_card_screen.dart"] + S_timecard --> S_timecard_Q["Queries
* application - getApplicationsByStaffId"] +end + +subgraph L16["Clock in"] + S_clockin["clock_in_screen.dart"] + S_clockin --> S_clockin_Q["Queries
* application - getApplicationsByStaffId"] + S_clockin --> S_clockin_M["Mutations
* application - createApplication
* application - updateApplicationStatus"] +end + +subgraph L17["Shifts"] + S_shifts["shifts_screen.dart"] + S_shifts --> S_shifts_Q["Queries
* application - getApplicationsByStaffId
* shiftRole - listShiftRolesByVendorId/listShiftRolesByRoleId
* application - getApplicationsByStaffId"] + S_shifts --> S_shifts_M["Mutations
* application - updateApplicationStatus
* application - createApplication"] +end + +subgraph L18["My availability"] + S_availability["availability_screen.dart"] + S_availability --> S_availability_Q["Queries
* staffAvailability - listStaffAvailabilitiesByStaffId/getStaffAvailabilityByKey"] + S_availability --> S_availability_M["Mutations
* staffAvailability - updateStaffAvailability
* staffAvailability - createStaffAvailability
* staffAvailability - deleteStaffAvailability"] +end + +subgraph L19["Your Benefits Overview"] + S_benefits["benefits_screen.dart"] + S_benefits --> S_benefits_Q["Queries
* benefitsData - listBenefitsDataByStaffId"] + S_benefits --> S_benefits_M["Mutations
* benefitsData - updateBenefitsData
* benefitsData - createBenefitsData"] +end + +subgraph L20["Home"] + S_home["worker_home_screen.dart"] + S_home --> S_home_Q["Queries
* application - getApplicationsByStaffId
* shiftRole - listShiftRolesByVendorId/listShiftRolesByRoleId
* benefitsData - getBenefitsDataByStaffId"] +end + +subgraph L21["Shift detail"] + S_shift_detail["shift_details_screen.dart"] + S_shift_detail --> S_shift_detail_Q["Queries
* application - getApplicationsByStaffId"] + S_shift_detail --> S_shift_detail_M["Mutations
* application - updateApplicationStatus"] +end diff --git a/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/business_uml_diagram.mmd b/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/business_uml_diagram.mmd new file mode 100644 index 00000000..ee725cbb --- /dev/null +++ b/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/business_uml_diagram.mmd @@ -0,0 +1,130 @@ +--- +config: + theme: mc + layout: dagre +--- +classDiagram +direction TB + class User { + id: String + email: String + } + + class Business { + id: UUID + userId: String + businessName: String + status: BusinessStatus + } + + class Vendor { + id: UUID + userId: String + companyName: String + } + + class Order { + id: UUID + businessId: UUID + vendorId: UUID + status: OrderStatus + } + + class Shift { + id: UUID + orderId: UUID + status: ShiftStatus + } + + class ShiftRole { + shiftId: UUID + roleId: UUID + } + + class Role { + id: UUID + name: String + vendorId: UUID + } + + class Application { + id: UUID + shiftId: UUID + staffId: UUID + roleId: UUID + } + + class Invoice { + id: UUID + businessId: UUID + vendorId: UUID + orderId: UUID + status: InvoiceStatus + } + + class InvoiceTemplate { + id: UUID + name: String + ownerId: UUID + businessId: UUID + vendorId: UUID + } + + class RecentPayment { + id: UUID + invoiceId: UUID + applicationId: UUID + staffId: UUID + } + + class ClientFeedback { + id: UUID + businessId: UUID + vendorId: UUID + rating: Int + } + + class Team { + id: UUID + teamName: String + ownerId: String + } + + class TeamMember { + id: UUID + teamId: UUID + userId: String + role: TeamMemberRole + } + + class TeamHub { + id: UUID + teamId: UUID + hubName: String + } + + class Staff { + id: UUID + userId: String + } + + note for Staff "business can create a staff too" + + Business "1" -- "*" Order : places + Business "1" -- "*" Invoice : receives + Business "1" -- "*" ClientFeedback : gives + Business "1" --o "1" Team : (ownerId) + Business "1" --o "*" InvoiceTemplate : (ownerId) + User "1" -- "1" Business : owns + Vendor "1" -- "*" Order : fulfills + Vendor "1" -- "*" Invoice : issues + Order "1" -- "*" Shift : contains + Order "1" -- "1" Invoice : billed via + Shift "1" -- "*" ShiftRole : requires + ShiftRole "1" -- "1" Role + ShiftRole "1" -- "*" Application : target for + Application "1" -- "1" Staff + Application "1" -- "1" RecentPayment + Invoice "1" -- "*" RecentPayment : paid through + Team "1" -- "*" TeamHub : contains + Team "1" -- "*" TeamMember : has \ No newline at end of file diff --git a/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/staff_uml_diagram.mmd b/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/staff_uml_diagram.mmd new file mode 100644 index 00000000..7b0588c6 --- /dev/null +++ b/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/staff_uml_diagram.mmd @@ -0,0 +1,181 @@ +classDiagram +direction TB + class User { + id: String + email: String + fullName: String + role: UserBaseRole + } + + class Staff { + id: UUID + userId: String + fullName: String + ownerId: UUID + hubId: UUID + rollId: UUID + status: BackgroundCheckStatus + } + + class Account{ + id: UUID + ownerId:UUID + type:AccountType + } + + class Workforce { + id: UUID + vendorId: UUID + staffId: UUID + status: WorkforceStatus + } + + class Application { + id: UUID + shiftId: UUID + staffId: UUID + roleId: UUID + status: ApplicationStatus + } + + class Assignment { + id: UUID + workforceId: UUID + shiftId: UUID + roleId: UUID + status: AssignmentStatus + } + + class ShiftRole { + id: UUID + shiftId: UUID + roleId: UUID + } + + class Shift { + id: UUID + orderId: UUID + status: ShiftStatus + } + + class Order { + id: UUID + vendorId: UUID + businessId: UUID + status: OrderStatus + } + + class Vendor { + id: UUID + userId: String + companyName: String + } + + class Business { + id: UUID + userId: String + businessName: String + } + + class Role { + id: UUID + name: String + vendorId: UUID + roleCategoryId: UUID + } + + class StaffDocument { + staffId: UUID + documentId: UUID + status: DocumentStatus + } + + class Document { + id: UUID + name: String + documentType: DocumentType + } + + class StaffCourse { + staffId: UUID + courseId: UUID + } + + class Course { + id: UUID + title: String + categoryId: UUID + } + + class Category { + id: UUID + label: String + } + + class StaffAvailability { + staffId: UUID + day: DayOfWeek + slot: AvailabilitySlot + } + + class Certificate { + staffId: UUID + certificationType: ComplianceType + status: CertificateStatus + } + + class BenefitData { + staffId: UUID + vendorBenefitPlanId: UUID + current: int + } + + class Contact { + staffId: UUID + relationship: RelationshipType + name: string + } + + class Invoice { + orderId: UUID + } + + class RecentPayment { + staffId: UUID + applicationId: UUID + status: RecentPaymentStatus + } + + class TaxForm { + staffId: UUID + formType: TaxFormType + status: TaxFormStatus + } + + User "1" -- "1" Staff : has + Staff "1" -- "*" Application : applies to + Staff "1" -- "*" Workforce : part of + Staff "1" -- "*" StaffDocument : has + Staff "1" -- "*" Certificate : has + Staff "1" -- "*" BenefitData : has + Staff "1" -- "*" Contact : has + Staff "1" -- "*" TaxForm : has + Staff "1" -- "*" Account : has + Staff "1" -- "*" StaffCourse : takes + Staff "1" -- "*" StaffAvailability : sets + Workforce "1" -- "*" Assignment : receives + Assignment -- ShiftRole + Vendor "1" -- "*" Order : receives + Business "1" -- "*" Order : places + Order "1" -- "1" Invoice : has + Invoice "1" -- "*" RecentPayment : has + RecentPayment "1" -- "1" Application : has + Staff "1" --o "1" Vendor : (ownerId) + Staff "1" --o "1" Business : (ownerId) + Application -- ShiftRole + ShiftRole "*" -- "1" Shift : belongs to + ShiftRole "*" -- "1" Role : defines + Shift "*" -- "1" Order : belongs to + StaffDocument "1" -- "1" Document : references + StaffCourse "1" -- "1" Course : references + Course "1" -- "1" Category : belongs to \ No newline at end of file diff --git a/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/team_uml_diagram.mmd b/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/team_uml_diagram.mmd new file mode 100644 index 00000000..eb1d6eb6 --- /dev/null +++ b/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/team_uml_diagram.mmd @@ -0,0 +1,79 @@ +--- +config: + layout: elk + theme: mc +--- +classDiagram + class User { + id: String + email: String + fullName: String + } + + class TeamMember { + id: UUID + teamId: UUID + userId: String + teamHubId: UUID + role: TeamMemberRole + inviteStatus: TeamMemberInviteStatus + inviteCode: UUID + } + + class Team { + id: UUID + teamName: String + ownerId: String + } + + class TeamHub { + id: UUID + teamId: UUID + hubName: String + } + + class TeamHudDepartment { + id: UUID + name: String + teamHubId: UUID + } + + class MemberTask { + teamMemberId: UUID + taskId: UUID + } + + class Task { + id: UUID + taskName: String + status: TaskStatus + priority: TaskPriority + ownerId: UUID + } + + class Vendor { + id: UUID + companyName: String + } + + class Business { + id: UUID + businessName: String + } + + User "1" -- "1" TeamMember : has + + Team "1" -- "*" TeamHub : contains + Team "1" --o "1" Vendor : (ownerId) + Team "1" --o "1" Business : (ownerId) + + TeamHub "1" -- "*" TeamHudDepartment : has + TeamHub "1" -- "*" TeamMember : is assigned to + + TeamMember "*" -- "1" Team + TeamMember "1" -- "*" MemberTask : has assigned + + Task "1" -- "*" MemberTask : is assigned to + Task --o Vendor : (ownerId) + Task --o Business : (ownerId) + \ No newline at end of file diff --git a/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/user_uml_diagram.mmd b/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/user_uml_diagram.mmd new file mode 100644 index 00000000..e8da584a --- /dev/null +++ b/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/user_uml_diagram.mmd @@ -0,0 +1,71 @@ + +classDiagram +direction TB + class User { + id: String + email: String + fullName: String + role: UserBaseRole + } + + class Staff { + id: UUID + userId: String + fullName: String + ownerId: UUID + hubId: UUID + rollId: UUID + status: BackgroundCheckStatus + } + + class Vendor { + id: UUID + userId: String + companyName: String + } + + class Business { + id: UUID + userId: String + businessName: String + } + + class TeamMember { + id: UUID + teamId: UUID + userId: String + role: TeamMemberRole + } + + class ActivityLog { + id: UUID + userId: String + activityType: ActivityType + } + + class UserConversation { + conversationId: UUID + userId: String + } + + class Conversation { + id: UUID + conversationType: ConversationType + } + + class Message{ + id: UUID + conversationId: UUID + content: String + } + + User <|-- Staff + User <|-- Business + User <|-- Vendor + User <|-- TeamMember + + + User "1" -- "*" ActivityLog : logs + User "1" -- "*" UserConversation : participates in + UserConversation "*" -- "1" Conversation : is part of + Conversation "1" -- "*" Message : has diff --git a/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/vendor_uml_diagram_simplify.mmd b/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/vendor_uml_diagram_simplify.mmd new file mode 100644 index 00000000..7a642427 --- /dev/null +++ b/docs/DATACONNECT_GUIDES/DIAGRAMS/uml/vendor_uml_diagram_simplify.mmd @@ -0,0 +1,164 @@ +--- +config: + layout: dagre +--- +classDiagram +direction TB + class User { + id: String + email: String + } + + class Vendor { + id: UUID + userId: String + companyName: String + tier: VendorTier + } + + class Staff { + id: UUID + userId: String + fullName: String + } + + class VendorBenefitPlan { + id: UUID + vendorId: UUID + title: String + } + + class InvoiceTemplate { + id: UUID + name: String + ownerId: UUID + } + + class VendorRate { + id: UUID + vendorId: UUID + roleName: String + } + + class AttireOption{ + id: UUID + vendorId: UUID + } + + class Team { + id: UUID + teamName: String + ownerId: String + } + + class TeamMember { + id: UUID + teamId: UUID + userId: String + role: TeamMemberRole + } + + class TeamHub { + id: UUID + teamId: UUID + hubName: String + } + + class Business { + id: UUID + userId: String + businessName: String + } + + class ClientFeedback { + id: UUID + businessId: UUID + vendorId: UUID + rating: Int + } + + class Order { + id: UUID + vendorId: UUID + businessId: UUID + status: OrderStatus + } + + class Shift { + id: UUID + orderId: UUID + status: ShiftStatus + } + + class Role { + id: UUID + name: String + vendorId: UUID + } + + class ShiftRole { + shiftId: UUID + roleId: UUID + } + + class Workforce { + id: UUID + vendorId: UUID + staffId: UUID + status: WorkforceStatus + } + + class Application { + id: UUID + shiftId: UUID + staffId: UUID + roleId: UUID + status: ApplicationStatus + } + + class Assignment { + id: UUID + workforceId: UUID + shiftId: UUID + roleId: UUID + status: AssignmentStatus + } + + class Invoice { + id: UUID + vendorId: UUID + businessId: UUID + orderId: UUID + status: InvoiceStatus + } + + class RecentPayment { + id: UUID + staffId: UUID + applicationId: UUID + invoiceId: UUID + status: RecentPaymentStatus + } + + note for Vendor "All tables has relationship with vendor" + + User "1" -- "1" Vendor : has + Vendor "1" o-- "1" Staff : (ownerId) + Vendor "1" -- "*" VendorBenefitPlan : offers + Vendor "1" -- "*" AttireOption + Vendor o-- InvoiceTemplate : (ownerId) + Vendor "1" -- "*" VendorRate : has + Vendor "1" -- "*" ClientFeedback : receives + Vendor "1" -- "*" Order : receives + Business "1" -- "*" Order : places + Order "1" -- "*" Shift : contains + Shift "1" -- "*" ShiftRole : requires + Role "1" -- "*" ShiftRole : fills + ShiftRole "1" -- "*" Application : receives + Assignment "1" -- "1" ShiftRole + Assignment "1" -- "1" Workforce + Invoice "1" -- "1" Order + Invoice "1" -- "*" RecentPayment : details + Vendor "1" o-- "1" Team + Team "1" -- "*" TeamHub : contains + Team "1" -- "*" TeamMember : has \ No newline at end of file diff --git a/internal/launchpad/assets/documents/dataconnect/backend_manual.md b/docs/DATACONNECT_GUIDES/DOCUMENTS/backend_manual.md similarity index 100% rename from internal/launchpad/assets/documents/dataconnect/backend_manual.md rename to docs/DATACONNECT_GUIDES/DOCUMENTS/backend_manual.md diff --git a/internal/launchpad/assets/documents/dataconnect/schema_dataconnect_guide.md b/docs/DATACONNECT_GUIDES/DOCUMENTS/schema_dataconnect_guide.md similarity index 100% rename from internal/launchpad/assets/documents/dataconnect/schema_dataconnect_guide.md rename to docs/DATACONNECT_GUIDES/DOCUMENTS/schema_dataconnect_guide.md diff --git a/docs/ERROR_HANDLING_ARCHITECTURE.md b/docs/ERROR_HANDLING_ARCHITECTURE.md deleted file mode 100644 index 095f350c..00000000 --- a/docs/ERROR_HANDLING_ARCHITECTURE.md +++ /dev/null @@ -1,358 +0,0 @@ -# Centralized Error Handling Architecture -**Project:** KROW Workforce Mobile App - -## 1. Executive Summary -We have implemented a **Centralized Error Handling System** that ensures the entire application (Staff & Client) handles errors consistently, reliably, and with full localization support. - -Instead of writing error handling code in every single feature (which leads to bugs and inconsistent messages), we rely on a global safety net that catches **Network Failures**, **Server Errors (500)**, **Not Found Errors (404)**, and **Business Logic Violations** automatically. - -### Key Benefits -* **Safety:** The app never crashes due to unhandled API errors. -* **Consistency:** A network error looks the same in "Shifts" as it does in "billing". -* **Localization:** All error messages are automatically translated (English/Spanish). -* **Speed:** Developers can build features faster without worrying about `try/catch` blocks. - -### Technical Excellence (Status Code Handling) -We don't just catch "errors"; we understand them. The system automatically categorizes and handles: -* **500 (Server Error):** "Our servers are having a moment. Please try again." -* **404 (Not Found):** "The resource you're looking for (Shift/Profile) is missing." -* **401 (Unauthorized):** "Your session expired. Please log in again." (Auto-redirect) -* **403 (Forbidden):** "You don't have permission to access this area." -* **503 (Unavailable):** "Maintenance mode or overloaded. Back in a bit!" - ---- - -## 2. Architecture Overview - -The error handling flows through three distinct layers, ensuring separation of concerns: - -```mermaid -graph TD - A[Data Layer / Repository] -->|Throws AppException| B[BLoC Layer / State Management] - B -->|Emits Error Key| C[UI Layer / Presentation] - - subgraph "1. Data Layer (The Guard)" - A -- Captures Exceptions --> D[DataErrorHandler Mixin] - D -- Maps to --> E[NetworkException, ServerException, etc.] - end - - subgraph "2. BLoC Layer (The Translator)" - B -- Uses --> F[BlocErrorHandler Mixin] - F -- Catches AppException --> G[converts to 'errors.category.type'] - end - - subgraph "3. UI Layer (The Messenger)" - C -- Calls --> H["translateErrorKey()"] - H -- Returns --> I["Localized String (e.g. 'Sin conexiΓ³n')"] - end -``` - -### 1. The Data Layer (The Guard) -**Location:** `packages/data_connect/lib/src/mixins/data_error_handler.dart` - -This is where raw exceptions (from Firebase, network, etc.) are caught and converted into **typed exceptions** that the rest of the app can understand. - -**Example:** -```dart -mixin DataErrorHandler { - Future handleDataOperation(Future Function() operation) async { - try { - return await operation(); - } on SocketException { - throw NetworkException('errors.network.no_connection'); - } on HttpException catch (e) { - if (e.statusCode == 500) throw ServerException('errors.server.internal'); - if (e.statusCode == 404) throw NotFoundException('errors.not_found.resource'); - // ... more mappings - } - } -} -``` - -### 2. The BLoC Layer (The Translator) -**Location:** `packages/core/lib/src/presentation/mixins/bloc_error_handler.dart` - -BLoCs use this mixin to catch exceptions and convert them into **error keys** that can be localized. - -**Example:** -```dart -mixin BlocErrorHandler { - String handleError(Object error) { - if (error is NetworkException) return error.message; - if (error is ServerException) return error.message; - return 'errors.unknown'; - } -} -``` - -### 3. The UI Layer (The Messenger) -**Location:** `packages/core_localization/lib/src/utils/error_translator.dart` - -The UI calls `translateErrorKey()` to convert error keys into user-friendly, localized messages. - -**Example:** -```dart -String translateErrorKey(String key) { - final t = LocaleSettings.instance.currentTranslations; - return t[key] ?? 'An error occurred'; -} -``` - ---- - -## 3. Real-World Example: Submitting a Tax Form - -Let's trace what happens when a user submits Form W-4 with no internet: - -1. **User Action:** Clicks "Submit Form" -2. **BLoC:** `FormW4Bloc` calls `submitW4UseCase.call(formData)` -3. **Use Case:** Calls `taxFormsRepository.submitW4(formData)` -4. **Repository (Data Layer):** - ```dart - Future submitW4(W4Data data) async { - return handleDataOperation(() async { - await _api.submitW4(data); // This throws SocketException - }); - } - ``` -5. **DataErrorHandler Mixin:** Catches `SocketException` β†’ throws `NetworkException('errors.network.no_connection')` -6. **BLoC:** Catches `NetworkException` β†’ emits `FormW4State.error(errorMessage: 'errors.network.no_connection')` -7. **UI (FormW4Page):** - ```dart - BlocListener( - listener: (context, state) { - if (state.status == FormW4Status.error) { - UiSnackbar.show( - context, - message: translateErrorKey(state.errorMessage!), - type: UiSnackbarType.error, - ); - } - }, - ) - ``` -8. **translateErrorKey:** Looks up `'errors.network.no_connection'` in `en.i18n.json` β†’ returns `"No internet connection. Please check your network."` -9. **User Sees:** A friendly snackbar with the localized message - ---- - -## 4. Simple Verification Tests (For Non-Developers) - -### Test A: The "Tunnel" Test (Network) -1. Open the app to the **Shifts** page. -2. Toggle **Airplane Mode ON**. -3. Pull to refresh the list. -4. **Result:** App shows a gentle `snackbar` error: *"No internet connection"* (or Spanish equivalent). **No Crash.** - -### Test B: The "Duplicate Data" Test (Smart Validation) -1. Log in on two devices with the same account (if possible) or simply use a known registered email. -2. Go to the **Sign Up** page. -3. Try to register a new account using that *existing* email. -4. **Result:** App instantly displays specific, helpful feedback: *"An account with this email already exists."* instead of a generic failure. -5. **Why it matters:** Proves the backend and frontend are synced to guide the user, not just block them. - -### Test C: The "Crash Proof" Test (The Safety Net) -1. **Scenario:** Even if a developer introduces a bug (like a random exception) or the server returns a 500 status. -2. **Result:** The app catches the unknown error, logs it internally, and shows a safe default message: *"Something went wrong. Please try again."* -3. **Why it matters:** The app never crashes or closes unexpectedly, preserving user trust. - -### Test D: The "Language" Test (Localization) -1. Trigger an error (like wrong password). -2. Change phone language to **Spanish**. -3. Trigger the same error. -4. **Result:** Message automatically translates: *"Correo electrΓ³nico o contraseΓ±a invΓ‘lidos."* - ---- - -## 5. Comprehensive Testing Guide for Client Verification - -This section provides a complete testing checklist to verify that centralized error handling is working correctly across the entire Staff app. - -### 🎯 **Testing Objectives** -- Verify all errors are caught and handled gracefully (no crashes) -- Confirm error messages are user-friendly and localized -- Ensure consistent error display using `UiSnackbar` -- Validate that error keys are properly translated - ---- - -### πŸ“± **Test Suite A: Tax Forms (I-9 & W-4)** - -These forms have been fully integrated with centralized error handling and localization. - -#### **Test A1: Form Validation Errors** -1. Navigate to **Profile β†’ Documents β†’ Form W-4** -2. Try to proceed to next step **without filling required fields** -3. **Expected Result:** - - Validation error appears in a snackbar - - Message is clear and specific (e.g., "First name is required") - - Error is localized (Spanish: "Se requiere el nombre") - -#### **Test A2: Network Error During Submission** -1. Fill out **Form I-9** completely -2. **Turn off WiFi/Mobile Data** -3. Click **Submit Form** -4. **Expected Result:** - - Snackbar shows: "No internet connection. Please check your network." - - Spanish: "Sin conexiΓ³n a internet. Verifica tu red." - - Form data is NOT lost - -#### **Test A3: Server Error Simulation** -1. Fill out **Form W-4** -2. If backend is accessible, trigger a 500 error -3. **Expected Result:** - - Snackbar shows: "Our servers are having issues. Please try again." - - Spanish: "Nuestros servidores tienen problemas. IntΓ©ntalo de nuevo." - -#### **Test A4: Language Switching** -1. Navigate to **Form I-9** -2. Trigger any error (validation or network) -3. Note the error message -4. **Change device language to Spanish** (Settings β†’ Language) -5. Trigger the same error -6. **Expected Result:** - - Error message appears in Spanish - - All form labels and hints are also in Spanish - ---- - -### πŸ“± **Test Suite B: Shifts & Availability** - -#### **Test B1: Network Error on Shifts Page** -1. Navigate to **Shifts** tab -2. **Enable Airplane Mode** -3. Pull to refresh -4. **Expected Result:** - - Snackbar: "No internet connection" - - No crash or blank screen - - Previous data (if any) remains visible - -#### **Test B2: Shift Not Found (404)** -1. If possible, try to access a deleted/non-existent shift -2. **Expected Result:** - - Snackbar: "Shift not found" - - User is redirected back to shifts list - ---- - -### πŸ“± **Test Suite C: Profile & Authentication** - -#### **Test C1: Session Expiry (401)** -1. Let the app sit idle for extended period (or manually invalidate token) -2. Try to perform any action (update profile, submit form) -3. **Expected Result:** - - Snackbar: "Your session has expired. Please log in again." - - App automatically redirects to login screen - -#### **Test C2: Profile Update Errors** -1. Navigate to **Profile β†’ Personal Info** -2. Try to update with invalid data (e.g., invalid email format) -3. **Expected Result:** - - Validation error in snackbar - - Specific message about what's wrong - ---- - -### πŸ“± **Test Suite D: Payments & Bank Account** - -#### **Test D1: Bank Account Addition Error** -1. Navigate to **Profile β†’ Bank Account** -2. Try to add account with invalid routing number -3. **Expected Result:** - - Snackbar shows validation error - - Error is localized - -#### **Test D2: Payment History Network Error** -1. Navigate to **Payments** tab -2. **Turn off internet** -3. Try to load payment history -4. **Expected Result:** - - Snackbar: "No internet connection" - - No crash - ---- - -### πŸ“± **Test Suite E: Clock In & Attendance** - -#### **Test E1: Clock In Network Error** -1. Navigate to **Clock In** tab -2. **Disable network** -3. Try to clock in -4. **Expected Result:** - - Snackbar: "No internet connection" - - Clock in action is blocked until network returns - ---- - -### 🌐 **Test Suite F: Localization Verification** - -#### **Test F1: English Error Messages** -With device language set to **English**, verify these error keys translate correctly: - -| Scenario | Expected English Message | -|----------|-------------------------| -| No internet | "No internet connection. Please check your network." | -| Server error (500) | "Our servers are having issues. Please try again." | -| Not found (404) | "The requested resource was not found." | -| Unauthorized (401) | "Your session has expired. Please log in again." | -| Validation error | Specific field error (e.g., "Email is required") | - -#### **Test F2: Spanish Error Messages** -With device language set to **EspaΓ±ol**, verify these error keys translate correctly: - -| Scenario | Expected Spanish Message | -|----------|-------------------------| -| No internet | "Sin conexiΓ³n a internet. Verifica tu red." | -| Server error (500) | "Nuestros servidores tienen problemas. IntΓ©ntalo de nuevo." | -| Not found (404) | "No se encontrΓ³ el recurso solicitado." | -| Unauthorized (401) | "Tu sesiΓ³n ha expirado. Inicia sesiΓ³n nuevamente." | -| Validation error | Error especΓ­fico del campo | - ---- - -### βœ… **Success Criteria** - -The centralized error handling is working correctly if: - -1. **No Crashes**: App never crashes due to network/server errors -2. **Consistent Display**: All errors appear in `UiSnackbar` with same styling -3. **User-Friendly**: Messages are clear, specific, and actionable -4. **Localized**: All errors translate correctly to Spanish -5. **Graceful Degradation**: App remains usable even when errors occur -6. **Data Preservation**: Form data is not lost when errors happen - ---- - -### πŸ› **What to Report if Tests Fail** - -If any test fails, please report: -1. **Which test** (e.g., "Test A2: Network Error During Submission") -2. **What happened** (e.g., "App crashed" or "Error showed in English despite Spanish language") -3. **Screenshot** of the error (if visible) -4. **Steps to reproduce** - ---- - -### πŸ”§ **Quick Debug Commands** - -For developers debugging error handling: - -```dart -// Test error translation directly -print(translateErrorKey('errors.network.no_connection')); -print(translateErrorKey('errors.server.internal')); -print(translateErrorKey('errors.not_found.shift')); - -// Test in Spanish -LocaleSettings.setLocale(AppLocale.es); -print(translateErrorKey('errors.network.no_connection')); -``` - ---- - -## 6. Code Locations (Reference) -* **Exceptions:** `packages/domain/lib/src/exceptions/app_exception.dart` -* **Data Mixin:** `packages/data_connect/lib/src/mixins/data_error_handler.dart` -* **Bloc Mixin:** `packages/core/lib/src/presentation/mixins/bloc_error_handler.dart` -* **Translator:** `packages/core_localization/lib/src/utils/error_translator.dart` -* **Strings:** `packages/core_localization/lib/src/l10n/*.i18n.json` diff --git a/milestones/m3/demos/m3-client-note.md b/docs/MILESTONES/M3/demos/m3-client-note.md similarity index 100% rename from milestones/m3/demos/m3-client-note.md rename to docs/MILESTONES/M3/demos/m3-client-note.md diff --git a/milestones/m3/demos/m3-notes.md b/docs/MILESTONES/M3/demos/m3-notes.md similarity index 100% rename from milestones/m3/demos/m3-notes.md rename to docs/MILESTONES/M3/demos/m3-notes.md diff --git a/milestones/m3/demos/m3.md b/docs/MILESTONES/M3/demos/m3.md similarity index 100% rename from milestones/m3/demos/m3.md rename to docs/MILESTONES/M3/demos/m3.md diff --git a/milestones/m4/planning/m4-planning.md b/docs/MILESTONES/M4/planning/m4-planning.md similarity index 100% rename from milestones/m4/planning/m4-planning.md rename to docs/MILESTONES/M4/planning/m4-planning.md diff --git a/docs/QA_TESTING_CHECKLIST.md b/docs/QA_TESTING_CHECKLIST.md deleted file mode 100644 index 49fef7e4..00000000 --- a/docs/QA_TESTING_CHECKLIST.md +++ /dev/null @@ -1,908 +0,0 @@ -# πŸ§ͺ KROW Workforce Platform - QA Testing Checklist - -**Version:** 1.0 -**Date:** February 1, 2026 -**Coverage:** Client App + Staff App -**Purpose:** Manual QA and Regression Testing - ---- - -## πŸ“‹ TABLE OF CONTENTS - -1. [Feature-Level QA Checklist](#1️⃣-feature-level-qa-checklist) - - [Client App Features](#client-app-features) - - [Staff App Features](#staff-app-features) -2. [Cross-Application Test Scenarios](#2️⃣-cross-application-test-scenarios) -3. [Shared Infrastructure Validation](#3️⃣-shared-infrastructure-validation) -4. [Regression & Release Checklist](#4️⃣-regression--release-checklist) - ---- - -## 1️⃣ FEATURE-LEVEL QA CHECKLIST - -### CLIENT APP FEATURES - ---- - -#### πŸ“± CLIENT-001: Authentication - -**Applications:** Client -**Entry Points:** -- Launch app β†’ Get Started β†’ Sign In -- Launch app β†’ Get Started β†’ Sign Up - -**Happy Path Test Cases:** -- [ ] Sign in with valid email and password displays home dashboard -- [ ] Sign up with business details creates account and navigates to home - -**Validation & Error States:** -- [ ] Invalid email format shows validation error -- [ ] Incorrect password shows authentication error -- [ ] Weak password in sign-up shows strength requirements -- [ ] Duplicate email in sign-up shows "already registered" error -- [ ] Empty fields show required field errors - -**Loading & Empty States:** -- [ ] Loading spinner displays during authentication -- [ ] OAuth redirect shows appropriate loading state - ---- - -#### πŸ“± CLIENT-002: Home Dashboard - -**Applications:** Client -**Entry Points:** -- Home tab (bottom navigation) - -**Happy Path Test Cases:** -- [ ] Dashboard displays current day coverage widget -- [ ] Spending analytics widget shows correct totals -- [ ] Recent reorders display completed shift roles -- [ ] Quick action buttons navigate to correct features -- [ ] Drag-and-drop widget reordering works correctly - -**Validation & Error States:** -- [ ] Empty state shows "No data available" when no orders exist - -**Loading & Empty States:** -- [ ] Empty coverage shows "No shifts today" -- [ ] Empty reorders shows "No recent orders" - ---- - -#### πŸ“± CLIENT-003: Create Order - -**Applications:** Client -**Entry Points:** -- Home β†’ Create Order button -- Orders tab β†’ + FAB button -- Order type β†’ One-Time - -**Happy Path Test Cases:** -- [ ] Order type selection displays. -- [ ] Hub selection shows list of business hubs -- [ ] Role selection displays vendor roles -- [ ] Position quantity can be incremented/decremented (min 1) -- [ ] Date picker displays correct calendar -- [ ] Time pickers show valid time ranges -- [ ] Break duration affects total hours calculation -- [ ] Cost preview calculates correctly (rate Γ— positions Γ— hours) -- [ ] Order submission creates order, shift, and shift roles -- [ ] Success confirmation displays after submission -- [ ] New order appears in View Orders list - -**Validation & Error States:** -- [ ] Empty hub field shows validation error -- [ ] Empty role field shows validation error -- [ ] Zero positions shows validation error -- [ ] Invalid date (past) shows validation error -- [ ] Start time after end time shows validation error -- [ ] Missing required fields prevent submission -- [ ] Backend validation errors display appropriately - -**Loading & Empty States:** -- [ ] Hub list shows "No hubs" if none exist -- [ ] Role list shows "No roles" if none configured -- [ ] Loading spinner displays during submission -- [ ] Submission progress indicator updates - ---- - -#### πŸ“± CLIENT-004: View Orders - -**Applications:** Client -**Entry Points:** -- Orders tab (bottom navigation) - -**Happy Path Test Cases:** -- [ ] Orders list displays orders for selected date -- [ ] Calendar date selection updates order list -- [ ] Each order card shows hub name and address -- [ ] Each order card shows shift time range -- [ ] Each order card shows role positions (filled/total) -- [ ] Each order card shows hourly rate and total cost -- [ ] Accepted applications section displays confirmed staff -- [ ] Staff names and photos display correctly -- [ ] Order list scrolls smoothly with many orders - -**Validation & Error States:** -- [ ] Invalid date selection shows error - -- [ ] Missing staff data shows placeholder - -**Loading & Empty States:** -- [ ] Empty date shows "No orders for this date" -- [ ] Empty accepted applications shows "No confirmed staff" - ---- - -#### πŸ“± CLIENT-005: Coverage Monitoring - -**Applications:** Client -**Entry Points:** -- Coverage tab (bottom navigation) - -**Happy Path Test Cases:** -- [ ] Coverage overview displays current date -- [ ] Coverage stats show needed/confirmed/checked-in counts -- [ ] Shift cards display hub name and time range -- [ ] Worker cards show staff name and photo -- [ ] Check-in status indicators update correctly (late, en-route, checked-in) -- [ ] Late workers display with warning indicator -- [ ] Coverage progress bar updates correctly - -**Validation & Error States:** -- [ ] Missing worker photo shows default avatar - -**Loading & Empty States:** - -- [ ] Empty coverage shows "No shifts today" -- [ ] No workers show "No staff assigned" - -**State Persistence:** -- [ ] Coverage data refreshes automatically every X minutes -- [ ] Manual refresh via pull-to-refresh gesture - -**Backend Dependency Validation:** -- [ ] `listShiftRolesByBusinessAndDateRange` returns shift requirements -- [ ] `listStaffsApplicationsByBusinessForDay` returns staff status -- [ ] Attendance status correctly mapped from backend - ---- - -#### πŸ“± CLIENT-006: Billing & Invoices - -**Applications:** Client -**Entry Points:** -- Billing tab (bottom navigation) - -**Happy Path Test Cases:** -- [ ] Current bill amount displays correctly -- [ ] Pending invoices list shows open invoices -- [ ] Invoice history shows paid invoices -- [ ] Savings amount displays correctly -- [ ] Spending breakdown shows costs by role -- [ ] Period filter (weekly/monthly) updates data -- [ ] Invoice detail view shows line items -- [ ] Invoice PDF download works (if implemented) - -**Validation & Error States:** -- [ ] Zero billing shows $0.00 (not error) -- [ ] Negative savings shows correctly -- [ ] Missing invoice data shows placeholder - -**Loading & Empty States:** -- [ ] Empty pending invoices shows "No pending invoices" -- [ ] Empty history shows "No invoice history" -- [ ] Empty spending breakdown shows "No spending data" - - ---- - -#### πŸ“± CLIENT-007: Hub Management - -**Applications:** Client -**Entry Points:** -- Settings β†’ Hubs -- Create Order β†’ Add Hub button - -**Happy Path Test Cases:** -- [ ] Hubs list displays all business hubs -- [ ] Hub cards show name and full address -- [ ] Add hub button opens creation form -- [ ] Google Places autocomplete suggests addresses -- [ ] Address selection auto-fills all address fields -- [ ] Hub name can be customized -- [ ] Hub creation adds to list immediately -- [ ] Hub deletion removes from list (with confirmation) -- [ ] Team entity auto-created for business if missing - -**Validation & Error States:** -- [ ] Empty hub name shows validation error -- [ ] Empty address shows validation error -- [ ] Invalid address format shows error -- [ ] Duplicate hub name shows warning -- [ ] Hub with active orders prevents deletion (validation error) - -**Loading & Empty States:** -- [ ] Empty hubs list shows "No hubs configured" -- [ ] Hub creation shows loading spinner - ---- - -#### πŸ“± CLIENT-008: Settings - -**Applications:** Client -**Entry Points:** -- Settings (navigation menu) - -**Happy Path Test Cases:** -- [ ] User profile displays name and email -- [ ] Business name displays correctly -- [ ] Hubs link navigates to hub management -- [ ] Sign out logs out user and returns to auth screen - -**Validation & Error States:** -- [ ] Missing profile photo shows default avatar -- [ ] Sign out error shows retry option - -**Loading & Empty States:** -- [ ] Profile data loads on page mount - ---- - -#### πŸ“± CLIENT-009: Client Main Navigation - -**Applications:** Client -**Entry Points:** -- Main app shell after authentication - -**Happy Path Test Cases:** -- [ ] Bottom navigation displays 5 tabs (Home, Coverage, Billing, Orders, Reports) -- [ ] Tab selection updates active indicator -- [ ] Tab selection navigates to correct feature -- [ ] Deep links navigate to correct tab -- [ ] Back button navigates correctly within nested routes -- [ ] Tab state persists after device rotation - -**Validation & Error States:** -- [ ] Invalid route shows 404 or redirects to home -- [ ] Reports tab shows placeholder (not yet implemented) - -**Loading & Empty States:** -- [ ] Navigation bar displays immediately -- [ ] Initial tab loads first - ---- - -### STAFF APP FEATURES - ---- - -#### πŸ“± STAFF-001: Authentication - -**Applications:** Staff -**Entry Points:** -- Launch app β†’ Get Started β†’ Phone Verification - -**Happy Path Test Cases:** -- [ ] Phone number entry accepts valid formats -- [ ] OTP sent confirmation displays -- [ ] OTP verification succeeds with valid code -- [ ] Profile setup wizard displays for new users -- [ ] Authenticated users bypass auth and show home - -**Validation & Error States:** -- [ ] Invalid phone format shows validation error -- [ ] Incorrect OTP shows verification error -- [ ] Expired OTP shows re-send option -- [ ] Empty fields show required field errors -- [ ] Network error displays retry option - -**Loading & Empty States:** -- [ ] Loading spinner displays during phone verification -- [ ] OTP input shows countdown timer -- [ ] Profile setup shows progress indicator - ---- - -#### πŸ“± STAFF-002: Home Dashboard - -**Applications:** Staff -**Entry Points:** -- Home tab (bottom navigation) - -**Happy Path Test Cases:** -- [ ] Today's shifts display with time and location -- [ ] Tomorrow's shifts display correctly -- [ ] Recommended shifts show available opportunities -- [ ] Shift cards show role, location, and pay rate -- [ ] Quick actions navigate to correct features -- [ ] Dashboard refreshes on pull-to-refresh - -**Validation & Error States:** -- [ ] Missing shift data shows placeholder - -**Loading & Empty States:** -- [ ] Empty today's shifts shows "No shifts today" -- [ ] Empty recommended shows "No available shifts" - ---- - -#### πŸ“± STAFF-003: Profile - -**Applications:** Staff -**Entry Points:** -- Profile tab (bottom navigation) - -**Happy Path Test Cases:** -- [ ] Profile displays name, email, phone, and photo -- [ ] Statistics show total shifts, ratings, reliability score -- [ ] Profile sections list displays all sections -- [ ] Section navigation works correctly -- [ ] Sign out logs out user and returns to auth screen - -**Validation & Error States:** -- [ ] Missing profile photo shows default avatar -- [ ] Missing statistics show 0 or default values -- [ ] Sign out error shows retry option - -**Loading & Empty States:** -- [ ] Profile data loads on page mount - ---- - -#### πŸ“± STAFF-004: Shifts Management - -**Applications:** Staff -**Entry Points:** -- Shifts tab (bottom navigation) -- Tab navigation: My Shifts / Available / Pending / Cancelled / History - -**Happy Path Test Cases:** -- [ ] My Shifts tab displays assigned shifts -- [ ] Available Shifts tab shows open positions -- [ ] Pending tab shows applications awaiting approval -- [ ] Cancelled tab shows cancelled shifts -- [ ] History tab shows past shifts -- [ ] Shift detail view displays full information -- [ ] Accept shift updates status to confirmed -- [ ] Decline shift updates status to declined -- [ ] Apply for shift creates application -- [ ] Shift cards show time, location, role, and pay - -**Validation & Error States:** -- [ ] Empty tabs show appropriate empty state messages -- [ ] Already applied shift prevents duplicate application -- [ ] Past shifts cannot be applied to -- [ ] Cancelled shifts show cancellation reason - ---- - -#### πŸ“± STAFF-005: Availability Management - -**Applications:** Staff -**Entry Points:** -- Worker Main β†’ Availability -- Profile β†’ Availability section - -**Happy Path Test Cases:** -- [ ] Weekly grid displays Monday-Sunday -- [ ] Time slots (Morning/Afternoon/Evening) toggle correctly -- [ ] Quick-set buttons work (Weekdays/Weekends/All Week) -- [ ] Individual day/slot updates save correctly -- [ ] Green checkmarks indicate availability -- [ ] Gray states indicate unavailability -- [ ] Changes save automatically - -**Validation & Error States:** - -- [ ] Save failure shows error message - -**Loading & Empty States:** -- [ ] Loading spinner displays while fetching availability -- [ ] Default state shows all unavailable - ---- - -#### πŸ“± STAFF-006: Clock In/Out - -**Applications:** Staff -**Entry Points:** -- Clock In tab (bottom navigation) - -**Happy Path Test Cases:** -- [ ] Today's shift displays with clock in button -- [ ] Clock in button creates attendance record -- [ ] Clock in time displays correctly -- [ ] Clock out button appears after clocking in -- [ ] Clock out creates end time record -- [ ] Total hours calculated correctly -- [ ] Attendance status updates immediately - -**Validation & Error States:** -- [ ] No shift today shows "No shifts to clock in" -- [ ] Already clocked in prevents duplicate clock in - -- [ ] Clock in outside shift time shows warning - -**Loading & Empty States:** -- [ ] Loading spinner displays while fetching shift -- [ ] Empty state shows "No shifts scheduled" - ---- - -#### πŸ“± STAFF-007: Payments - -**Applications:** Staff -**Entry Points:** -- Payments tab (bottom navigation) - -**Happy Path Test Cases:** -- [ ] Payment summary displays total earnings -- [ ] Payment history lists all transactions -- [ ] Payment cards show amount, date, and status -- [ ] Payment detail view shows breakdown -- [ ] Filter by date range works correctly - -**Validation & Error States:** -- [ ] Zero earnings show $0.00 (not error) -- [ ] Missing payment data shows placeholder - -**Loading & Empty States:** -- [ ] Empty history shows "No payment history" - ---- - -#### πŸ“± STAFF-008: Personal Info (Onboarding) - -**Applications:** Staff -**Entry Points:** -- Profile β†’ Personal Info -- Onboarding wizard - -**Happy Path Test Cases:** -- [ ] Form displays current profile data -- [ ] Name field allows text input -- [ ] Email field validates email format -- [ ] Phone field validates phone format -- [ ] Photo upload works correctly -- [ ] Preferred locations multi-select works -- [ ] Save button updates profile - -**Validation & Error States:** -- [ ] Empty required fields show validation errors -- [ ] Invalid email format shows error -- [ ] Invalid phone format shows error - -- [ ] Photo upload failure shows error - -**Loading & Empty States:** -- [ ] Form loads with skeleton placeholders -- [ ] Photo upload shows progress indicator -- [ ] Save button shows loading spinner - ---- - -#### πŸ“± STAFF-009: Emergency Contact (Onboarding) - -**Applications:** Staff -**Entry Points:** -- Profile β†’ Emergency Contact -- Onboarding wizard - -**Happy Path Test Cases:** -- [ ] Contact list displays all contacts -- [ ] Add contact button opens form -- [ ] Contact form validates name and phone -- [ ] Relationship dropdown shows options (Family/Spouse/Friend/Other) -- [ ] Remove contact deletes from list -- [ ] Save updates all contacts -- [ ] Multiple contacts supported - -**Validation & Error States:** -- [ ] Empty name shows validation error -- [ ] Invalid phone format shows error -- [ ] At least one contact required (if applicable) - -**Loading & Empty States:** -- [ ] Loading spinner displays while fetching contacts -- [ ] Empty state shows "No emergency contacts" -- [ ] Save button shows loading spinner - ---- - -#### πŸ“± STAFF-010: Experience & Skills (Onboarding) - -**Applications:** Staff -**Entry Points:** -- Profile β†’ Experience -- Onboarding wizard - -**Happy Path Test Cases:** -- [ ] Industries multi-select displays options -- [ ] Skills multi-select displays options -- [ ] Selected items show checkmarks -- [ ] Deselection removes items -- [ ] Save updates profile - -**Validation & Error States:** -- [ ] At least one industry required (if applicable) -- [ ] At least one skill required (if applicable) - - -**Loading & Empty States:** -- [ ] Loading spinner displays while fetching data -- [ ] Save button shows loading spinner - ---- - -#### πŸ“± STAFF-012: Bank Account (Finances) - -**Applications:** Staff -**Entry Points:** -- Profile β†’ Bank Account - -**Happy Path Test Cases:** -- [ ] Account list displays all accounts -- [ ] Add account button opens form -- [ ] Form validates routing and account numbers -- [ ] Account type dropdown shows options (Checking/Savings) -- [ ] First account auto-sets as primary -- [ ] Save adds account to list -- [ ] Primary account indicator displays - -**Validation & Error States:** -- [ ] Empty routing number shows validation error -- [ ] Invalid routing number format shows error -- [ ] Empty account number shows validation error -- [ ] Invalid account number format shows error -- [ ] Duplicate account shows warning - - -**Loading & Empty States:** -- [ ] Loading spinner displays while fetching accounts -- [ ] Empty state shows "No bank accounts" -- [ ] Save button shows loading spinner - -**State Persistence:** -- [ ] Accounts persist after save -- [ ] Account list refreshes after addition - -**Backend Dependency Validation:** -- [ ] `getAccountsByOwnerId` fetches staff accounts -- [ ] `createAccount` creates new account -- [ ] First account auto-flagged as primary - ---- - -#### πŸ“± STAFF-013: Time Card History (Finances) - -**Applications:** Staff -**Entry Points:** -- Profile β†’ Time Card - -**Happy Path Test Cases:** -- [ ] Time card list displays all records -- [ ] Each card shows shift details (date, time, location) -- [ ] Each card shows clock in/out times -- [ ] Each card shows total hours worked -- [ ] Scrolling loads more records (pagination) - -**Validation & Error States:** -- [ ] Missing attendance data shows "Not recorded" - -**Loading & Empty States:** -- [ ] Empty state shows "No time card history" - ---- - -#### πŸ“± STAFF-014: Tax Forms (Compliance) - -**Applications:** Staff -**Entry Points:** -- Profile β†’ Tax Forms - -**Happy Path Test Cases:** -- [ ] Forms list displays required forms (I-9, W-4) -- [ ] Form status shows completed/incomplete -- [ ] I-9 form opens editor -- [ ] I-9 form validates all fields -- [ ] W-4 form opens editor -- [ ] W-4 form validates all fields -- [ ] Form submission updates status to completed -- [ ] Completed forms show edit option - -**Validation & Error States:** -- [ ] Empty required fields show validation errors -- [ ] Invalid SSN format shows error -- [ ] Invalid date format shows error -- [ ] Signature required validation - -**Loading & Empty States:** -- [ ] Loading spinner displays while fetching forms -- [ ] Form editor loads with skeleton placeholders -- [ ] Save button shows loading spinner - ---- - -#### πŸ“± STAFF-017: Staff Main Navigation - -**Applications:** Staff -**Entry Points:** -- Main app shell after authentication - -**Happy Path Test Cases:** -- [ ] Bottom navigation displays 5 tabs (Shifts, Payments, Home, Clock In, Profile) -- [ ] Tab selection updates active indicator -- [ ] Tab selection navigates to correct feature -- [ ] Deep links navigate to correct tab and nested route -- [ ] Back button navigates correctly within nested routes -- [ ] Tab state persists after device rotation -- [ ] Nested routes (onboarding, emergency-contact, etc.) accessible - -**Validation & Error States:** -- [ ] Invalid route shows 404 or redirects to home -- [ ] Navigation errors log appropriately - -**Loading & Empty States:** -- [ ] Navigation bar displays immediately -- [ ] Initial tab loads first - -**State Persistence:** -- [ ] Active tab persists after app background β†’ foreground -- [ ] Tab state resets to home on app restart - -**Backend Dependency Validation:** -- [ ] No direct backend calls (navigation only) - ---- - -## 2️⃣ CROSS-APPLICATION TEST SCENARIOS - -### Scenario 1: Order Creation β†’ Staff Application Flow - -**Preconditions:** -- Client user authenticated -- Staff user authenticated -- At least one hub configured - -**Steps:** -1. **CLIENT APP:** - - [ ] Create one-time order with specific hub, role, date, and time - - [ ] Verify order appears in View Orders list - - [ ] Verify shift shows as unfilled (0/X positions) - -2. **STAFF APP:** - - [ ] Open Shifts tab β†’ Available tab - - [ ] Verify new shift appears in available list - - [ ] Verify shift details match order (hub, role, time, pay) - - [ ] Apply for shift position - -3. **CLIENT APP:** - - [ ] Refresh View Orders - - [ ] Verify shift shows pending application (0/X filled, pending) - -4. **STAFF APP:** - - [ ] Verify application appears in Pending tab - - [ ] Verify shift removed from Available tab - -**Expected Results:** -- βœ… Order created in Client appears in Staff Available Shifts -- βœ… Application in Staff shows pending in both apps -- βœ… Shift counts update correctly in real-time - ---- - -### Scenario 2: Shift Acceptance β†’ Coverage Tracking - -**Preconditions:** -- Scenario 1 completed (pending application exists) - -**Steps:** -1. **STAFF APP:** - - [ ] Go to Shifts β†’ Pending tab - - [ ] Accept pending shift assignment - -2. **CLIENT APP:** - - [ ] Refresh View Orders - - [ ] Verify shift shows as filled (1/X positions) - - [ ] Verify staff name and photo appear in accepted applications - - [ ] Navigate to Coverage tab - - [ ] Verify shift appears with assigned staff - -3. **STAFF APP:** - - [ ] Verify shift moved from Pending to My Shifts tab - - [ ] Verify shift appears on Home dashboard - -**Expected Results:** -- βœ… Accepted shift reflects in Client orders immediately -- βœ… Staff appears in Coverage monitoring -- βœ… Shift moves to My Shifts in Staff app - ---- - -### Scenario 3: Clock In β†’ Real-Time Coverage Update - -**Preconditions:** -- Scenario 2 completed (staff has accepted shift) -- Current date/time is during shift window - -**Steps:** -1. **STAFF APP:** - - [ ] Navigate to Clock In tab - - [ ] Verify today's shift displays - - [ ] Click Clock In button - - [ ] Verify clock in time recorded - -2. **CLIENT APP:** - - [ ] Navigate to Coverage tab - - [ ] Verify staff status changed to "Checked In" - - [ ] Verify check-in time displays - - [ ] Verify coverage stats updated (checked-in count incremented) - -3. **STAFF APP:** - - [ ] Wait until shift end time - - [ ] Click Clock Out button - - [ ] Verify clock out time recorded - -4. **CLIENT APP:** - - [ ] Refresh Coverage tab - - [ ] Verify staff status changed to "Completed" - -5. **STAFF APP:** - - [ ] Navigate to Time Card - - [ ] Verify attendance record appears with correct times and hours - -**Expected Results:** -- βœ… Clock in updates Coverage status in Client -- βœ… Clock out completes attendance record -- βœ… Time card displays correct hours in Staff app -- βœ… Coverage monitoring reflects real-time status - ---- - -### Scenario 4: Hub Creation β†’ Order Placement - -**Preconditions:** -- Client user authenticated -- No existing hubs - -**Steps:** -1. **CLIENT APP:** - - [ ] Navigate to Settings β†’ Hubs - - [ ] Verify empty state "No hubs configured" - - [ ] Click Add Hub button - - [ ] Enter hub name and use Google Places autocomplete - - [ ] Select address from suggestions - - [ ] Verify address fields auto-filled - - [ ] Save hub - -2. **CLIENT APP:** - - [ ] Navigate to Create Order - - [ ] Verify new hub appears in hub selection list - - [ ] Select new hub and complete order creation - -3. **STAFF APP:** - - [ ] Navigate to Shifts β†’ Available - - [ ] Verify shift shows correct hub name and address - -**Expected Results:** -- βœ… Hub created in Settings appears in order creation -- βœ… Hub address propagates to shift details in Staff app - ---- - -### Scenario 5: Shift Cancellation β†’ Staff Notification - -**Preconditions:** -- Staff has accepted shift assignment - -**Steps:** -1. **CLIENT APP:** - - [ ] Navigate to View Orders - - [ ] Select order with assigned staff - - [ ] Cancel shift (if feature exists) or delete order - -2. **STAFF APP:** - - [ ] Refresh Shifts tab - - [ ] Verify shift moved to Cancelled tab - - [ ] Verify shift removed from My Shifts - - [ ] Verify cancellation reason displays - -3. **STAFF APP:** - - [ ] Verify shift removed from Home dashboard - -**Expected Results:** -- βœ… Cancelled shift moves to Cancelled tab -- βœ… Shift removed from active assignments -- ⚠️ **Requires clarification:** Cancellation feature may not be fully implemented - ---- - -### Scenario 6: Authentication State Sharing - -**Preconditions:** -- Neither app authenticated - -**Steps:** -1. **CLIENT APP:** - - [ ] Sign in with email/password - - [ ] Verify Firebase Auth token generated - -2. **STAFF APP:** - - [ ] Launch app - - [ ] Verify Staff app requires separate authentication - - [ ] Verify Client session does not carry over - -3. **CLIENT APP:** - - [ ] Sign out - -4. **STAFF APP:** - - [ ] Verify Staff app session persists (independent) - -**Expected Results:** -- βœ… Client and Staff apps maintain independent auth sessions -- βœ… Signing out of one app does not affect the other - ---- - -### Scenario 7: Data Created in Client β†’ Visible in Staff - -**Preconditions:** -- Client creates multiple orders - -**Steps:** -1. **CLIENT APP:** - - [ ] Create 5 orders on different dates - - [ ] Create 3 orders on same date with different hubs - -2. **STAFF APP:** - - [ ] Navigate to Shifts β†’ Available - - [ ] Verify all 8 shifts appear - - [ ] Verify date grouping correct - - [ ] Verify hub addresses correct - - [ ] Apply for 2 shifts - -3. **CLIENT APP:** - - [ ] Navigate to View Orders - - [ ] Verify 2 shifts show pending applications - - [ ] Navigate to Coverage - - [ ] Verify 0 checked-in (pending acceptance) - -**Expected Results:** -- βœ… All orders visible in both apps -- βœ… Application states sync correctly -- βœ… Data consistency maintained across apps - ---- - -### Scenario 8: Role-Based Access Differences - -**Preconditions:** -- Client user authenticated -- Staff user authenticated - -**Steps:** -1. **CLIENT APP:** - - [ ] Navigate to Billing - - [ ] Verify billing data displays (Client-only feature) - - [ ] Navigate to Create Order - - [ ] Verify order creation available (Client-only feature) - -2. **STAFF APP:** - - [ ] Verify no Billing tab exists - - [ ] Verify no Create Order feature - - [ ] Navigate to Availability - - [ ] Verify availability editing available (Staff-only feature) - -3. **CLIENT APP:** - - [ ] Verify no Availability feature exists - - [ ] Verify no Clock In feature exists - -**Expected Results:** -- βœ… Client app has business management features (orders, billing, hubs) -- βœ… Staff app has worker features (availability, clock in, payments) -- βœ… No feature overlap or unauthorized access - ---- diff --git a/internal/launchpad/assets/diagrams/diagrams-config.json b/internal/launchpad/assets/diagrams/diagrams-config.json index 2644041f..f5fde702 100644 --- a/internal/launchpad/assets/diagrams/diagrams-config.json +++ b/internal/launchpad/assets/diagrams/diagrams-config.json @@ -60,43 +60,43 @@ "icon": "bi-geo-alt" }, { - "path": "assets/diagrams/dataconnect/uml/user_uml_diagram.mmd", + "path": "docs/DATACONNECT_GUIDES/DIAGRAMS/uml/user_uml_diagram.mmd", "title": "User UML Diagram Dataconnect", "type": "mermaid", "icon": "bi-diagram-2" }, { - "path": "assets/diagrams/dataconnect/uml/staff_uml_diagram.mmd", + "path": "docs/DATACONNECT_GUIDES/DIAGRAMS/uml/staff_uml_diagram.mmd", "title": "Staff UML Diagram Dataconnect", "type": "mermaid", "icon": "bi-diagram-2" }, { - "path": "assets/diagrams/dataconnect/uml/business_uml_diagram.mmd", + "path": "docs/DATACONNECT_GUIDES/DIAGRAMS/uml/business_uml_diagram.mmd", "title": "Business UML Diagram Dataconnect", "type": "mermaid", "icon": "bi-diagram-3" }, { - "path": "assets/diagrams/dataconnect/uml/vendor_uml_diagram_simplify.mmd", + "path": "docs/DATACONNECT_GUIDES/DIAGRAMS/uml/vendor_uml_diagram_simplify.mmd", "title": "Vendor UML Diagram Dataconnect", "type": "mermaid", "icon": "bi-diagram-3" }, { - "path": "assets/diagrams/dataconnect/uml/team_uml_diagram.mmd", + "path": "docs/DATACONNECT_GUIDES/DIAGRAMS/uml/team_uml_diagram.mmd", "title": "Team UML Diagram Dataconnect", "type": "mermaid", "icon": "bi-diagram-2" }, { - "path": "assets/diagrams/dataconnect/mobile/client_app_diagram.mmd", + "path": "docs/DATACONNECT_GUIDES/DIAGRAMS/mobile/client_app_diagram.mmd", "title": "Client App Diagram Dataconnect", "type": "mermaid", "icon": "bi-diagram-2" }, { - "path": "assets/diagrams/dataconnect/mobile/staff_app_diagram.mmd", + "path": "docs/DATACONNECT_GUIDES/DIAGRAMS/mobile/staff_app_diagram.mmd", "title": "Staff App Diagram Dataconnect", "type": "mermaid", "icon": "bi-diagram-2" diff --git a/internal/launchpad/assets/documents/documents-config.json b/internal/launchpad/assets/documents/documents-config.json index 46a80b01..16d16ebf 100644 --- a/internal/launchpad/assets/documents/documents-config.json +++ b/internal/launchpad/assets/documents/documents-config.json @@ -65,10 +65,10 @@ }, { "title": "Dataconnect guide", - "path": "./assets/documents/dataconnect/backend_manual.md" + "path": "docs/DATACONNECT_GUIDES/DOCUMENTS/backend_manual.md" }, { "title": "Schema Dataconnect guide", - "path": "./assets/documents/dataconnect/schema_dataconnect_guide.md" + "path": "docs/DATACONNECT_GUIDES/DOCUMENTS/schema_dataconnect_guide.md" } ]