ovenzeze / nimship-admin-nuxt

https://nimship-admin-v0.vercel.app
0 stars 0 forks source link

Driver Registration/Edit Form - Requirements, Technical Design, and Test Plan #8

Open ovenzeze opened 2 months ago

ovenzeze commented 2 months ago

Driver Registration/Edit Form

[Previous content remains unchanged]

Approval Status

Next Steps

  1. PM to complete and submit product requirements for review
  2. Once requirements are approved, Tech Lead to complete and submit technical design for review
  3. Once technical design is approved, QA Lead to complete and submit test plan for review
  4. ✅ All sections are approved, development can begin

Development Plan

  1. Set up project structure and install necessary dependencies
  2. Implement base components (BaseInput, BaseSelect, BaseDatePicker, SensitiveInput, AddressInput)
  3. Create DriverForm component
  4. Implement useDriverForm composable
  5. Set up Pinia store for driver management
  6. Integrate with Supabase for data persistence
  7. Implement form validation
  8. Add responsive design and accessibility features
  9. Conduct unit and integration tests
  10. Perform end-to-end testing
  11. Address any issues found during testing
  12. Conduct final review and prepare for deployment

Current Tasks

Team members can assign themselves to tasks and update their status as they progress.

ovenzeze commented 2 months ago

Product Requirements Approved 😯

ovenzeze commented 2 months ago

Test Plan

1. Unit Tests

1.1 Component Tests

1.2 Composable Tests

1.3 Store Tests

2. Integration Tests

2.1 Form Interaction Tests

2.2 API Integration Tests

3. End-to-End Tests

3.1 User Flow Tests

3.2 Error Handling and Edge Cases

4. Performance Tests

5. Compatibility Tests

6. Accessibility Tests

7. Security Tests

8. Usability Tests

Test Execution Plan

  1. Set up automated unit and integration tests using Jest and Vue Test Utils
  2. Implement end-to-end tests using Playwright
  3. Use test/runtest.py for running the test suite:
    • Full test suite: python runtest.py
    • Specific tests: python runtest.py test_driver_form test_api_integration
  4. Integrate tests into CI/CD pipeline for automatic execution on each commit
  5. Conduct manual testing for usability and final verification

Test Environment

Reporting

Exit Criteria

Approval Status

Next Steps

  1. PM to complete and submit product requirements for review
  2. Once requirements are approved, Tech Lead to complete and submit technical design for review
  3. Once technical design is approved, QA Lead to complete and submit test plan for review
  4. After all sections are approved, development can begin

Note: Each section should be reviewed and approved by the appropriate stakeholders before moving to the next stage. Use comments for discussions and updates.

ovenzeze commented 2 months ago

Technical Design: Driver Registration/Edit Form

Overview

The Driver Registration/Edit Form is a crucial component of our system, allowing new drivers to register and existing drivers to update their information. This form should be user-friendly, secure, and compliant with all relevant regulations.

This technical design outlines the implementation approach for the Driver Registration/Edit Form, based on the product requirements. We will use Vue 3 with Composition API, Nuxt 3 for server-side rendering, and Supabase for backend integration.

Component Structure

State Management

Form Implementation

<!-- DriverForm.vue -->
<template>
  <form @submit.prevent="handleSubmit" class="space-y-6">
    <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
      <BaseInput v-model="form.first_name" label="First Name" name="first_name" :rules="{ required: true }" />
      <BaseInput v-model="form.last_name" label="Last Name" name="last_name" :rules="{ required: true }" />
      <BaseDatePicker v-model="form.date_of_birth" label="Date of Birth" name="date_of_birth" :rules="{ required: true }" />
      <BaseSelect v-model="form.warehouse" label="Warehouse" name="warehouse" :options="warehouseOptions" :rules="{ required: true }" />
      <BaseInput v-model="form.phone" label="Phone" name="phone" type="tel" :rules="{ required: true, regex: /^\+?[1-9]\d{1,14}$/ }" />
      <BaseInput v-model="form.email" label="Email" name="email" type="email" :rules="{ email: true }" />
      <BaseInput v-model="form.driver_license_no" label="Driver's License Number" name="driver_license_no" :rules="{ required: true }" />
      <SensitiveInput v-model="form.social_security_no" label="Social Security Number" name="social_security_no" :rules="{ required: true }" />
      <BaseInput v-model="form.routing_number" label="Routing Number" name="routing_number" :rules="{ regex: /^\d{9}$/ }" />
      <SensitiveInput v-model="form.account_number" label="Account Number" name="account_number" />
      <BaseInput v-model="form.zelle" label="Zelle" name="zelle" />
      <BaseDatePicker v-model="form.enroll_time" label="Enroll Time" name="enroll_time" :disabled="!isAdmin" />
      <BaseSelect v-model="form.status" label="Status" name="status" :options="statusOptions" :rules="{ required: true }" />
      <BaseSelect v-model="form.team_name" label="Team Name" name="team_name" :options="teamOptions" :rules="{ required: true }" />
      <BaseSelect v-model="form.driver_type" label="Driver Type" name="driver_type" :options="driverTypeOptions" :rules="{ required: true }" />
      <BaseInput v-model="form.commisson_rate" label="Commission Rate" name="commisson_rate" type="number" :rules="{ required: true, min: 0, max: 100 }" />
      <AddressInput v-model="form.address" />
      <BaseDatePicker v-model="form.dl_expired_time" label="Driver's License Expiration Date" name="dl_expired_time" :rules="{ required: true }" />
    </div>
    <Button type="submit" :disabled="!isFormValid">{{ isEditMode ? 'Update' : 'Register' }}</Button>
  </form>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { useForm } from 'vee-validate'
import { Button } from '@/components/ui/button'
import BaseInput from '@/components/BaseInput.vue'
import BaseSelect from '@/components/BaseSelect.vue'
import BaseDatePicker from '@/components/BaseDatePicker.vue'
import SensitiveInput from '@/components/SensitiveInput.vue'
import AddressInput from '@/components/AddressInput.vue'
import { useDriverForm } from '@/composables/useDriverForm'
import type { HaulblazeContact } from '@/types'

const props = defineProps<{
  initialData?: Partial<HaulblazeContact>
  isEditMode: boolean
}>()

const { form, isFormValid, handleSubmit, warehouseOptions, statusOptions, teamOptions, driverTypeOptions } = useDriverForm(props.initialData)

const isAdmin = computed(() => {
  // Logic to determine if current user is admin
})
</script>

Composables

// useDriverForm.ts
import { ref } from 'vue'
import { useForm } from 'vee-validate'
import type { HaulblazeContact } from '@/types'
import { useDriverStore } from '@/stores/driver'

export function useDriverForm(initialData?: Partial<HaulblazeContact>) {
  const driverStore = useDriverStore()

  const form = ref<HaulblazeContact>({
    first_name: '',
    last_name: '',
    date_of_birth: null,
    warehouse: null,
    phone: '',
    email: null,
    driver_license_no: '',
    social_security_no: '',
    routing_number: null,
    account_number: null,
    zelle: null,
    enroll_time: new Date(),
    status: 'Onboarding',
    team_name: null,
    driver_type: 'HAULER',
    commisson_rate: 0,
    mail_street: null,
    mail_city: null,
    mail_state: null,
    mail_zip: null,
    dl_expired_time: null,
    ...initialData
  })

  const { handleSubmit, isSubmitting, errors } = useForm({
    validationSchema: {
      // Define validation schema here
    }
  })

  const submitForm = handleSubmit(async (values) => {
    try {
      await driverStore.submitDriverInfo(values)
      // Handle successful submission
    } catch (error) {
      // Handle submission error
    }
  })

  // Fetch options for select fields
  const warehouseOptions = computed(() => driverStore.warehouseOptions)
  const statusOptions = computed(() => driverStore.statusOptions)
  const teamOptions = computed(() => driverStore.teamOptions)
  const driverTypeOptions = computed(() => driverStore.driverTypeOptions)

  return {
    form,
    isFormValid: computed(() => Object.keys(errors.value).length === 0),
    handleSubmit: submitForm,
    warehouseOptions,
    statusOptions,
    teamOptions,
    driverTypeOptions
  }
}

Store

// stores/driver.ts
import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { HaulblazeContact } from '@/types'
import { submitDriverInfo } from '@/api/driver'

export const useDriverStore = defineStore('driver', () => {
  const warehouseOptions = ref([])
  const statusOptions = ref([])
  const teamOptions = ref([])
  const driverTypeOptions = ref([])

  async function fetchOptions() {
    // Fetch options from API
  }

  async function submitDriverInfo(data: HaulblazeContact) {
    return await submitDriverInfo(data)
  }

  return {
    warehouseOptions,
    statusOptions,
    teamOptions,
    driverTypeOptions,
    fetchOptions,
    submitDriverInfo
  }
})

API Integration

// api/driver.ts
import { supabase } from '@/lib/supabaseClient'
import type { HaulblazeContact } from '@/types'

export async function submitDriverInfo(data: HaulblazeContact) {
  const { data: result, error } = await supabase
    .from('haulblaze_contact')
    .upsert(data)
    .select()

  if (error) throw error
  return result
}

Key Features

Detailed Requirements

1. Form Fields

The form should include the following fields based on the haulblaze_contact table structure:

2. Functionality

3. User Experience

Performance Optimizations

Accessibility

Responsive Design

Error Handling

4. Security and Compliance

5. Integration

Non-functional Requirements