Chippie End-to-End Testing Guide
A comprehensive guide for QA testers to understand and test all features of the Chippie quote and invoice management system.
Table of Contents
1. System Overview 2. Getting Started 3. Core Business Workflow 4. User Authentication 5. Client Management 6. Quote Management 7. Job Management 8. Invoice Management 9. Team Management 10. Settings & Configuration 11. Map & Calendar Views 12. Public/Email Pages 13. Admin Panel 14. API Endpoints 15. Edge Cases & Error Scenarios 16. Status Workflow Reference
System Overview
Chippie is a multi-tenant quote and invoice management system for service businesses. Each business has isolated data using PostgreSQL schema-based multi-tenancy.
Key Entities
- Clients: Customer contact information and address
- Quotes: Price proposals sent to clients
- Jobs: Work to be performed (created when quote accepted)
- Invoices: Payment requests (created when quote accepted)
Core Workflow
Client → Quote (pending/quoted) → Accept → Job (in_progress) + Invoice (draft)
↓ ↓ completed pending (after job completion) ↓ paid
Getting Started
Test Credentials
- Email:
first@last.com - Password:
fourfour
Application URL
- Development:
http://localhost:8080 - Production: Configured domain
First Login Experience
1. Navigate to /auth/login 2. Enter credentials 3. If user has businesses: redirected to dashboard 4. If user has no businesses: redirected to /auth/business-setup
Core Business Workflow
Complete Quote-to-Payment Workflow
Test Scenario: Full lifecycle from client creation to paid invoice
1. Create Client
- Navigate to
/clients
- Click "Add Client"
- Enter: First Name, Last Name (required), Phone, Email, Address
- Submit → Client appears in list
2. Create Quote
- From client list: Click client dropdown → "New Quote"
- OR: Navigate to
/quotes→ "Add Quote"
- Enter description (required)
- Enter amount (optional - creates enquiry if omitted)
- Submit → Quote appears in Quotes list
3. Accept Quote
- Find quote in list (status: quoted or pending_quote)
- Click "Accept" button
- System automatically creates:
- Job with status
in_progress
- Invoice with status
draft
- Quote status changes to
accepted
4. Complete Job
- Navigate to
/jobs
- Find job (status: in_progress)
- Click "Complete" button
- Job status →
completed
- Invoice status →
pending(automatic)
5. Mark Invoice Paid
- Navigate to
/invoices
- Find invoice (status: pending)
- Click "Mark Paid" button
- Invoice status →
paid
Expected Outcome: Complete audit trail from client to paid invoice.
User Authentication
Routes
| Route | Method | Description |
|---|---|---|
/auth/login |
GET/POST | Login page and handler |
/auth/register |
GET/POST | User registration |
/auth/business-setup |
GET/POST | Create new business (after registration) |
/auth/business-join |
GET/POST | Join existing business |
/auth/logout |
GET/POST | End session |
/auth/forgot-password |
GET/POST | Request password reset |
/auth/reset-password |
GET/POST | Complete password reset |
/auth/verify-email |
GET | Email verification via token |
/auth/google/login |
GET | Google OAuth login |
/auth/google/register |
GET | Google OAuth registration |
/auth/pending-invitations |
GET | View pending team invitations |
Test Scenarios
TC-AUTH-001: Successful Login 1. Navigate to /auth/login 2. Enter valid email and password 3. Click "Login" 4. Expected: Redirect to dashboard, success flash message
TC-AUTH-002: Failed Login (Wrong Password) 1. Navigate to /auth/login 2. Enter valid email, wrong password 3. Click "Login" 4. Expected: Error message, stay on login page
TC-AUTH-003: Registration Flow 1. Navigate to /auth/register 2. Enter: Email, Password, Confirm Password 3. Submit 4. Expected: Redirect to /auth/business-setup 5. Create business OR join existing 6. Expected: Redirect to dashboard
TC-AUTH-004: Password Reset 1. Navigate to /auth/forgot-password 2. Enter registered email 3. Check email for reset link 4. Click link → /auth/reset-password?token=... 5. Enter new password 6. Expected: Success message, redirect to login
TC-AUTH-005: Session Expiry 1. Login successfully 2. Wait for session timeout (or clear cookies) 3. Try to access /dashboard 4. Expected: Redirect to login page
Client Management
Routes
| Route | Method | Description |
|---|---|---|
/clients |
GET | List all clients |
/add_client |
POST | Create new client |
/client/update/<id> |
POST | Update client details |
/client/delete-info/<id> |
GET | Pre-delete info (shows dependencies) |
/client/delete/<id> |
POST | Delete client |
/client/<id>/edit-modal |
GET | Load edit form modal |
/client/<id> |
GET | Client details page |
Fields
| Field | Required | Validation |
|---|---|---|
| first_name | Yes | Non-empty string |
| last_name | Yes | Non-empty string |
| No | Valid email format, unique | |
| phone | No | String |
| street | No | Address component |
| city | No | Address component |
| state | No | Address component |
| postcode | No | Address component |
| address_input | No | Free-form address (preserved as typed) |
Test Scenarios
TC-CLIENT-001: Create Client (Minimal) 1. Navigate to /clients 2. Click "Add Client" 3. Enter only First Name and Last Name 4. Submit 5. Expected: Client created, appears in list
TC-CLIENT-002: Create Client (Full) 1. Navigate to /clients 2. Click "Add Client" 3. Fill all fields including address 4. Submit 5. Expected: Client created with all details saved
TC-CLIENT-003: Edit Client 1. Find existing client in list 2. Click edit icon 3. Modify fields 4. Submit 5. Expected: Changes saved, list updated
TC-CLIENT-004: Delete Client (No Dependencies) 1. Create new client with no quotes/jobs/invoices 2. Click delete 3. Confirm deletion 4. Expected: Client removed from list
TC-CLIENT-005: Delete Client (With Dependencies) 1. Find client with existing quotes 2. Click delete 3. Expected: Warning modal shows dependent records 4. Confirm deletes client AND all related records
TC-CLIENT-006: Duplicate Email Prevention 1. Create client with email "test@example.com" 2. Try to create another client with same email 3. Expected: Validation error "Email already exists"
Quote Management
Routes
| Route | Method | Description |
|---|---|---|
/quotes |
GET | List all quotes by status |
/add_quote |
POST | Create quote for existing client |
/add_quote_with_client |
POST | Create quote + new client together |
/add_enquiry_with_client |
POST | Create enquiry (no price) + new client |
/accept_quote/<id> |
POST | Accept quote → create job + invoice |
/quote/add_price/<id> |
POST | Add price to pending_quote |
/quote/set_status/<id>/<status> |
POST | Change quote status |
/quote/update/<id> |
POST | Update quote details |
/quote/revert/<id> |
POST | Revert to quoted status |
/quote/archive/<id> |
POST | Archive quote |
/quote/delete/<id> |
POST | Delete quote |
/quote/<id>/pdf |
GET | Generate/download PDF |
/quote/<id>/preview-image |
GET | Generate JPEG preview |
/quote/<id>/email-data |
GET | Get email composition data |
/quote/<id>/send-email |
POST | Send via Brevo API |
/quote/<id>/edit-modal |
GET | Load edit form |
/quote/<id>/related-records |
GET | View related jobs/invoices |
Quote Statuses
| Status | Description | Next Actions |
|---|---|---|
pending_quote |
Enquiry without price | Add price, Cancel |
quoted |
Has price, ready for acceptance | Accept, Cancel, Update |
accepted |
Accepted by client | Archive (notes only editable) |
cancelled |
Rejected/cancelled | Revert, Archive |
archived |
Hidden from active list | None |
Fields
| Field | Required | Notes |
|---|---|---|
| client_id | Yes | Must exist in current business |
| description | Yes | What the quote is for |
| amount | No | Creates pending_quote if omitted |
| notes | No | Internal notes (not on PDF) |
Test Scenarios
TC-QUOTE-001: Create Quote with Amount 1. Navigate to /quotes 2. Click "Add Quote" 3. Select existing client 4. Enter description and amount 5. Submit 6. Expected: Quote created with status quoted
TC-QUOTE-002: Create Enquiry (No Price) 1. Navigate to /quotes 2. Click "Add Enquiry" 3. Select client or create new 4. Enter description only (no amount) 5. Submit 6. Expected: Quote created with status pending_quote
TC-QUOTE-003: Add Price to Enquiry 1. Find quote with status pending_quote 2. Click "Add Price" 3. Enter amount 4. Submit 5. Expected: Status changes to quoted
TC-QUOTE-004: Accept Quote 1. Find quote with status quoted 2. Click "Accept" 3. Expected:
- Quote status →
accepted
- New Job created (status:
in_progress)
- New Invoice created (status:
draft)
- Redirect to dashboard
TC-QUOTE-005: Update Pending/Quoted Quote 1. Find quote with status pending_quote or quoted 2. Click edit 3. Change description, amount, notes 4. Submit 5. Expected: All fields updated
TC-QUOTE-006: Update Accepted Quote (Notes Only) 1. Find quote with status accepted 2. Click edit 3. Try to change description or amount 4. Expected: Only notes field is editable
TC-QUOTE-007: Revert Cancelled Quote 1. Find quote with status cancelled 2. Click "Revert" 3. Expected: Status changes to quoted
TC-QUOTE-008: Archive Quote 1. Find quote with status accepted or cancelled 2. Click "Archive" 3. Expected: Quote hidden from main list
TC-QUOTE-009: Generate Quote PDF 1. Find any quote 2. Click "PDF" button 3. Expected: PDF opens/downloads with quote details
TC-QUOTE-010: Send Quote Email 1. Find quote with client email 2. Click "Send Email" 3. Expected: Email sent (if Brevo configured) or mailto link opens
TC-QUOTE-011: Create Quote with New Client 1. Navigate to /quotes 2. Click "Add Quote + New Client" 3. Fill client details and quote details 4. Submit 5. Expected: Both client and quote created atomically
TC-QUOTE-012: Delete Quote with Dependencies 1. Accept a quote (creates job + invoice) 2. Try to delete the quote 3. Expected: Warning shows related job/invoice 4. Confirm → Quote, Job, and Invoice all deleted
Job Management
Routes
| Route | Method | Description |
|---|---|---|
/jobs |
GET | List all jobs |
/job/complete/<id> |
POST | Mark job as completed |
/job/set_status/<id>/<status> |
POST | Change job status |
/job/revert/<id> |
POST | Revert to in_progress |
/job/update/<id> |
POST | Update job details |
/job/archive/<id> |
POST | Archive job |
/job/delete-info/<id> |
GET | Pre-delete info |
/job/delete/<id> |
POST | Delete job |
Job Statuses
| Status | Description | Next Actions |
|---|---|---|
in_progress |
Work is ongoing | Complete, Cancel, On Hold |
completed |
Work finished | Archive, Revert |
cancelled |
Job cancelled | Archive, Revert |
on_hold |
Job paused | Resume (set back to in_progress) |
archived |
Hidden from active list | None |
Test Scenarios
TC-JOB-001: Complete Job 1. Find job with status in_progress 2. Click "Complete" 3. Expected:
- Job status →
completed
- Related invoice status →
pending(from draft)
TC-JOB-002: Put Job On Hold 1. Find job with status in_progress 2. Change status to on_hold 3. Expected: Job status updated, visible in jobs list
TC-JOB-003: Revert Completed Job 1. Find job with status completed 2. Click "Revert" 3. Expected: Status → in_progress
TC-JOB-004: Update Job Notes 1. Find any job 2. Click edit 3. Update notes 4. Expected: Notes saved (synced to related quote)
TC-JOB-005: Archive Job 1. Find job with status completed or cancelled 2. Click "Archive" 3. Expected: Job hidden from main list
TC-JOB-006: Cannot Archive Active Job 1. Find job with status in_progress 2. Try to archive 3. Expected: Error - can only archive completed/cancelled
Invoice Management
Routes
| Route | Method | Description |
|---|---|---|
/invoices |
GET | List invoices (excludes draft/cancelled/archived) |
/payment-summary |
GET | Payment analytics page |
/invoice/update/<id> |
POST | Update invoice details |
/invoice/set_status/<id>/<status> |
POST | Change status |
/invoice/revert/<id> |
POST | Revert to pending |
/invoice/archive/<id> |
POST | Archive invoice |
/invoice/delete-info/<id> |
GET | Pre-delete info |
/invoice/delete/<id> |
POST | Delete invoice |
/invoice/<id>/pdf |
GET | Generate/download PDF |
/invoice/<id>/preview-image |
GET | Generate JPEG preview |
/invoice/<id>/email-data |
GET | Get email composition data |
/invoice/<id>/send-email |
POST | Send via Brevo API |
/invoice/<id>/edit-modal |
GET | Load edit form |
Invoice Statuses
| Status | Description | Next Actions |
|---|---|---|
draft |
Created with quote acceptance, hidden | (auto-transitions on job complete) |
pending |
Ready for payment | Mark paid, Cancel |
unpaid |
Explicitly marked unpaid | Mark paid |
paid |
Payment received | Archive |
overdue |
Past due date | Mark paid, Cancel |
cancelled |
Invoice cancelled | Revert |
archived |
Hidden but preserved | None |
Test Scenarios
TC-INV-001: Invoice Auto-Created on Quote Accept 1. Accept a quote 2. Navigate to /invoices 3. Expected: Invoice exists but may be hidden (draft status) 4. Complete the related job 5. Expected: Invoice now visible (pending status)
TC-INV-002: Mark Invoice Paid 1. Find invoice with status pending 2. Click "Mark Paid" 3. Expected: Status → paid
TC-INV-003: Revert Paid Invoice 1. Find invoice with status paid 2. Click "Revert" 3. Expected: Status → pending
TC-INV-004: Archive Paid Invoice 1. Find invoice with status paid 2. Click "Archive" 3. Expected: Invoice hidden from list
TC-INV-005: Cannot Archive Unpaid Invoice 1. Find invoice with status pending 2. Try to archive 3. Expected: Error - can only archive paid invoices
TC-INV-006: Update Invoice Amount 1. Find any invoice 2. Click edit 3. Change amount 4. Expected: Amount updated
TC-INV-007: Generate Invoice PDF 1. Find any invoice 2. Click "PDF" button 3. Expected: PDF opens/downloads with invoice details
TC-INV-008: Payment Summary Page 1. Navigate to /payment-summary 2. Expected: Shows totals for paid, pending, overdue 3. Expected: Collection rate percentage displayed
Team Management
Routes
| Route | Method | Description |
|---|---|---|
/team or /team/manage |
GET | Team dashboard |
/team/invite |
GET/POST | Invite form and handler |
/team/join-requests |
GET | View join requests |
/team/join-requests/<id>/approve |
POST | Approve join request |
/team/join-requests/<id>/reject |
POST | Reject join request |
Roles
| Role | Description |
|---|---|
manager |
Full access to all features |
member |
Standard access |
Test Scenarios
TC-TEAM-001: Invite Team Member 1. Navigate to /team 2. Click "Invite Member" 3. Enter email and select role 4. Submit 5. Expected: Invitation sent, shows in pending list
TC-TEAM-002: Accept Invitation 1. Receive invitation email 2. Click invitation link 3. Register/login 4. Expected: Added to business team
TC-TEAM-003: Join Request (Public Business) 1. Enable business discovery in settings 2. Another user searches for business 3. User requests to join 4. Manager sees request in /team/join-requests 5. Approve → User added to team
TC-TEAM-004: Reject Join Request 1. Have pending join request 2. Click "Reject" 3. Expected: Request removed, user not added
Settings & Configuration
Routes
| Route | Method | Description |
|---|---|---|
/settings |
GET | Settings page |
/settings/update |
POST | Update settings (form) |
/settings/update-ajax |
POST | Update settings (AJAX) |
/settings/delete-business |
POST | Delete entire business |
/theme/change |
POST | Change color theme |
Settings Sections
Business Profile
- Business name
- Logo/branding
- Contact information
- Address
Invoice Settings
- Invoice numbering format
- Payment terms text
- Default due date offset
- Tax/fees configuration
Quote Settings
- Default quote template
- Expiry period
- Terms and conditions
Custom Status Management
- Create custom status categories
- Add custom statuses within categories
- Set default statuses
- Reorder statuses
Test Scenarios
TC-SET-001: Update Business Name 1. Navigate to /settings 2. Change business name 3. Save 4. Expected: Name updated throughout app
TC-SET-002: Configure Payment Terms 1. Navigate to /settings 2. Update payment terms text 3. Save 4. Expected: Appears on generated invoices
TC-SET-003: Change Theme 1. Navigate to /settings 2. Select different theme 3. Expected: UI colors change immediately
TC-SET-004: Create Custom Status 1. Navigate to /settings → Status Management 2. Create new status category 3. Add custom status to category 4. Expected: New status available when changing entity status
TC-SET-005: Delete Business 1. Navigate to /settings 2. Click "Delete Business" 3. Confirm deletion 4. Expected: All business data removed, redirected to business setup
Map & Calendar Views
Map View (/map)
Displays clients, jobs, and quotes on an interactive map.
Features
- Color-coded markers (Blue: clients, Green: jobs, Purple: quotes)
- Clickable popups with entity details
- Filter by entity type and status
Test Scenarios
TC-MAP-001: View Clients on Map 1. Create client with address 2. Navigate to /map 3. Expected: Client marker appears at address location
TC-MAP-002: Filter Map 1. Navigate to /map 2. Toggle filters (clients, jobs, quotes) 3. Expected: Only selected types visible
Calendar View (/calendar)
Schedule management with optional Google Calendar sync.
Features
- Full calendar interface
- Event CRUD operations
- Link events to quotes/jobs
Test Scenarios
TC-CAL-001: Create Calendar Event 1. Navigate to /calendar 2. Click on date 3. Enter event details 4. Save 5. Expected: Event appears on calendar
TC-CAL-002: Link Event to Job 1. Create event for a job 2. Click event 3. Expected: Link to job details available
Public/Email Pages
These pages are accessible without authentication via secure tokens.
Routes
| Route | Description |
|---|---|
/quotes/accept/<token> |
Accept quote via email link |
/quotes/decline/<token> |
Decline quote via email link |
/quotes/view/<token> |
View quote (read-only) |
/quotes/pdf/<token> |
Download quote PDF |
/invoices/pay/<token> |
Invoice payment page |
/invoices/view/<token> |
View invoice (read-only) |
/invoices/pdf/<token> |
Download invoice PDF |
Email Tracking
| Route | Description |
|---|---|
/email/tracking/pixel/<id> |
Track email opens |
/email/tracking/click/<id> |
Track link clicks |
/email/analytics |
View email analytics |
Test Scenarios
TC-EMAIL-001: Accept Quote via Email 1. Send quote email to client 2. Client clicks "Accept" link 3. Expected: Quote accepted, success page shown 4. Verify: Job and Invoice created
TC-EMAIL-002: Decline Quote via Email 1. Send quote email to client 2. Client clicks "Decline" link 3. Expected: Quote cancelled, thank you page shown
TC-EMAIL-003: View Quote without Auth 1. Get quote view token URL 2. Open in incognito browser 3. Expected: Quote details displayed (read-only)
TC-EMAIL-004: Already Accepted Quote 1. Accept quote 2. Click accept link again 3. Expected: "Already accepted" message, not error
TC-EMAIL-005: Invoice Payment Page 1. Send invoice email 2. Client clicks "Pay" link 3. Expected: Invoice details with payment instructions
Admin Panel
Accessible only to admin users (configured via ADMIN_EMAIL env var).
Routes
| Route | Description |
|---|---|
/admin/dashboard |
Admin overview |
/admin/users |
User management |
/admin/users/<id> |
User details |
/admin/businesses |
Business management |
/admin/businesses/<id> |
Business details |
/admin/database |
Database management |
/admin/database/schemas |
View all schemas |
/admin/database/migrations |
Migration status |
/admin/database/drift |
Schema drift detection |
/admin/audit-logs |
System audit logs |
/admin/activity-logs |
Activity logs |
/admin/backup |
Backup management |
/admin/settings |
System settings |
Test Scenarios
TC-ADMIN-001: Admin Login 1. Login with admin email 2. Expected: Redirect to admin dashboard (not business dashboard)
TC-ADMIN-002: View All Users 1. Navigate to /admin/users 2. Expected: List of all users across all businesses
TC-ADMIN-003: Disable User 1. Find user in admin panel 2. Click "Disable" 3. Expected: User cannot login
TC-ADMIN-004: View Business Database 1. Navigate to /admin/businesses/<id>/database 2. Expected: Database schema info for that business
TC-ADMIN-005: Check Migration Status 1. Navigate to /admin/database/migrations 2. Expected: Shows applied/pending migrations per schema
API Endpoints
Authentication
# Login (get JWT token)
curl -X POST http://localhost:8080/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"email": "first@last.com", "password": "fourfour"}'
Use token in subsequent requests
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8080/api/clients
Core Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/clients |
GET | List clients |
/api/clients |
POST | Create client |
/api/clients/<id> |
GET/PUT/DELETE | CRUD operations |
/api/quotes |
GET | List quotes |
/api/quotes |
POST | Create quote |
/api/quotes/<id> |
GET/PUT | Quote operations |
/api/quotes/<id>/accept |
POST | Accept quote |
/api/jobs |
GET | List jobs |
/api/jobs/<id> |
GET/PUT | Job operations |
/api/jobs/<id>/complete |
POST | Complete job |
/api/invoices |
GET | List invoices |
/api/invoices/<id> |
GET/PUT | Invoice operations |
/api/invoices/<id>/mark-paid |
POST | Mark paid |
/api/dashboard/stats |
GET | Dashboard metrics |
Test Scenarios
TC-API-001: API Authentication 1. POST to /api/v1/auth/login with credentials 2. Expected: JWT token returned 3. Use token in Authorization header 4. Expected: API calls succeed
TC-API-002: Create Client via API 1. POST to /api/clients with client data 2. Expected: 201 Created, client data returned
TC-API-003: Unauthorized Access 1. Call API endpoint without token 2. Expected: 401 Unauthorized
Edge Cases & Error Scenarios
Multi-Tenant Isolation
TC-MT-001: Cross-Business Data Access 1. Login as User A (Business X) 2. Try to access Client from Business Y via direct URL 3. Expected: 404 Not Found or 403 Forbidden
TC-MT-002: Business Switching 1. User belongs to multiple businesses 2. Switch to different business 3. Expected: Only see data from selected business
Quote Acceptance Edge Cases
TC-EDGE-001: Accept Already Accepted Quote 1. Accept a quote 2. Try to accept again (via URL or API) 3. Expected: Error "Quote is not in quoted status"
TC-EDGE-002: Accept Cancelled Quote 1. Cancel a quote 2. Try to accept (via direct POST) 3. Expected: Error, no job/invoice created
TC-EDGE-003: Concurrent Quote Acceptance 1. Open same quote in two browser tabs 2. Click Accept in both simultaneously 3. Expected: One succeeds, one fails gracefully
Deletion Constraints
TC-EDGE-004: Delete Client with Active Quotes 1. Create client with pending quote 2. Try to delete client 3. Expected: Warning shows dependent records
TC-EDGE-005: Delete Quote with Job/Invoice 1. Accept quote (creates job + invoice) 2. Delete quote 3. Expected: Cascade deletes job and invoice too
Form Validation
TC-EDGE-006: Create Client Missing Required Fields 1. Try to create client without first_name 2. Expected: Validation error
TC-EDGE-007: Create Quote with Negative Amount 1. Enter negative amount in quote form 2. Expected: Validation error
TC-EDGE-008: Duplicate Client Email 1. Create client with email 2. Create another with same email 3. Expected: Validation error
Status Workflow Reference
Quote Status Flow
┌─────────────┐
│pending_quote│ (no price) └──────┬──────┘ │ add price ▼ ┌─────────────────────────────────────────┐ │ quoted │ │ (ready for acceptance) │ └─────────┬─────────────────────┬─────────┘ │ accept │ cancel ▼ ▼ ┌──────────┐ ┌───────────┐ │ accepted │ │ cancelled │ └────┬─────┘ └─────┬─────┘ │ archive │ archive ▼ ▼ ┌──────────┐ ┌───────────┐ │ archived │ │ archived │ └──────────┘ └───────────┘
Job Status Flow
┌─────────────┐
│ in_progress │ (created on quote accept) └──────┬──────┘ │ ├─── complete ────▶ ┌───────────┐ │ │ completed │──▶ archive ──▶ archived │ └───────────┘ │ │ │ │ revert │ ▼ │ ┌───────────┐ │ │in_progress│ │ └───────────┘ │ ├─── cancel ──────▶ ┌───────────┐ │ │ cancelled │──▶ archive ──▶ archived │ └───────────┘ │ └─── on_hold ─────▶ ┌───────────┐ │ on_hold │ └───────────┘
Invoice Status Flow
┌─────────┐
│ draft │ (created on quote accept, hidden) └────┬────┘ │ (auto on job complete) ▼ ┌─────────┐ │ pending │ └────┬────┘ │ ├─── mark paid ────▶ ┌──────┐ │ │ paid │──▶ archive ──▶ archived │ └──────┘ │ │ │ │ revert │ ▼ │ ┌─────────┐ │ │ pending │ │ └─────────┘ │ └─── cancel ───────▶ ┌───────────┐ │ cancelled │ └───────────┘
Testing Checklist Summary
Core Workflow
- Create client → Create quote → Accept → Complete job → Mark paid
- Enquiry workflow (no price) → Add price → Accept
Authentication
- Login/logout
- Registration → Business setup
- Password reset
- Session handling
CRUD Operations
- Client: Create, Read, Update, Delete
- Quote: Create, Read, Update, Delete, Accept, Archive
- Job: Read, Update, Complete, Archive
- Invoice: Read, Update, Mark Paid, Archive
Business Rules
- Quote acceptance creates job + invoice
- Job completion triggers invoice pending status
- Accepted quotes have locked description/amount
- Delete cascades work correctly
Multi-Tenant
- Data isolation between businesses
- Business switching works correctly
- Cannot access other business data
API
- JWT authentication
- All CRUD endpoints
- Proper error responses
Edge Cases
- Concurrent operations
- Invalid status transitions
- Missing required fields
- Duplicate prevention
Reporting Issues
When reporting bugs, include: 1. Steps to reproduce (exact clicks/actions) 2. Expected result 3. Actual result 4. Screenshots (if UI issue) 5. Browser/device information 6. Request ID (from error page if available) 7. Console errors (if any)