Skip to content

Customer User Creation Guide

To login to the customer portal, you need customer users in the database.

To login to the customer portal, you need customer users in the database. Here are your options:


Option 1: Use the Test User Creation Script (Easiest) ⭐

Section titled “Option 1: Use the Test User Creation Script (Easiest) ⭐”
Terminal window
python scripts/create_test_auth_users.py

This automatically creates three test users:

PortalUsernamePasswordRoleDashboard
Customercustomer1password123Customer (role_id=2)/customer/dashboard
Operationsoperations1password123Operations (role_id=1)/operations/dashboard
Adminadmin1password123Admin (role_id=3)/admin/dashboard
Terminal window
# Create test users
python scripts/create_test_auth_users.py
# Start the application
python main.py --port 5002
# Open in browser
# http://localhost:5002/login
# Login with: customer1 / password123

Expected output from script:

✓ Created customer user: customer1 (password: password123)
✓ Created operations user: operations1 (password: password123)
✓ Created admin user: admin1 (password: password123)
✓ All test users created/verified successfully!
Test Credentials:
==================================================
Customer Portal:
Username: customer1
Password: password123
Role: Customer (role_id=2)
Portal: /customer/dashboard
Operations Portal:
Username: operations1
Password: password123
Role: Operations (role_id=1)
Portal: /operations/dashboard
Admin Portal:
Username: admin1
Password: password123
Role: Admin (role_id=3)
Portal: /admin/dashboard
==================================================

Option 2: Check Existing Users in Database

Section titled “Option 2: Check Existing Users in Database”

If users might already exist, check what customer users you have:

-- Find all customer users
SELECT id, username, email, role_id, is_active
FROM users
WHERE role_id = 2;

Use any of those users to login with their username and password.


Terminal window
python -c "from werkzeug.security import generate_password_hash; print(generate_password_hash('password123'))"

This outputs something like: $2b$12$1234567890abcdefghij...

Copy the hash.

INSERT INTO users (username, email, password, role_id, is_active)
VALUES (
'mycustomer',
'mycustomer@example.com',
'PASTE_THE_HASH_HERE',
2,
TRUE
);

Replace PASTE_THE_HASH_HERE with the actual hash from Step 1.

SELECT * FROM users WHERE username = 'mycustomer';

Should show:

  • role_id = 2
  • is_active = TRUE
  • password = the hash you pasted
  • Username: mycustomer
  • Password: password123 (the plain text password, not the hash)

Terminal window
python main.py --port 5002

Console should show:

Customer Portal registered successfully
Auth Blueprint registered successfully
Running on http://localhost:5002

Open in your browser:

http://localhost:5002/

This redirects to:

http://localhost:5002/login

Fill in the login form:

  • Username: customer1
  • Password: password123

Click the login button.

5. Should Be Redirected to Customer Dashboard

Section titled “5. Should Be Redirected to Customer Dashboard”

You should see:

http://localhost:5002/customer/dashboard

With the page title: Customer Dashboard


Once logged in as a customer:

  • http://localhost:5002/customer/dashboard - Customer dashboard
  • http://localhost:5002/customer/shipments - View shipments
  • http://localhost:5002/customer/quotes - View quotes
  • http://localhost:5002/customer/bookings - View bookings
  • http://localhost:5002/customer/request-quote - Request new quote
  • http://localhost:5002/customer/book-shipment - Book shipment
  • All other customer portal routes

If you try to access operations portal:

http://localhost:5002/operations/dashboard

You’ll get:

  • Error message: “You don’t have permission to access the customer portal”
  • Redirected to: /operations/dashboard

This is expected behavior! Customer users are restricted to the customer portal.


If you need multiple customer users:

Option A: Modify and Run Script Multiple Times

Section titled “Option A: Modify and Run Script Multiple Times”

Edit scripts/create_test_auth_users.py to change usernames, then run it again.

-- Customer 1
INSERT INTO users (username, email, password, role_id, is_active)
VALUES (
'acme_corp',
'acme@example.com',
'$2b$12$1234567890abcdefghij...',
2,
TRUE
);
-- Customer 2
INSERT INTO users (username, email, password, role_id, is_active)
VALUES (
'logistics_co',
'logistics@example.com',
'$2b$12$1234567890abcdefghij...',
2,
TRUE
);
-- Customer 3
INSERT INTO users (username, email, password, role_id, is_active)
VALUES (
'shipping_plus',
'shipping@example.com',
'$2b$12$1234567890abcdefghij...',
2,
TRUE
);

Remember: The password hash must match the plain text password you want to use.


Symptom: Login page shows error “Invalid username or password”

Solutions:

  1. Check username spelling: SELECT username FROM users;
  2. Verify role_id is 2: SELECT role_id FROM users WHERE username='customer1';
  3. Check user is active: SELECT is_active FROM users WHERE username='customer1';
  4. Try creating user again with script: python scripts/create_test_auth_users.py

Symptom: Login as customer1 but redirects to /operations/dashboard

Solution: Check the user’s role_id:

SELECT username, role_id FROM users WHERE username='customer1';

Should show role_id = 2. If it shows 1, this user is for operations, not customer.

Symptom: “Your account is inactive. Please contact administrator.”

Solution: Check and fix user status:

UPDATE users SET is_active = TRUE WHERE username = 'customer1';

Symptom: 404 when trying to access /customer/dashboard

Solution: Make sure application was restarted after creating users:

Terminal window
python main.py --port 5002

Check console for: Customer Portal registered successfully


role_idPortalPurposeDashboard
1OperationsFreight operations staff/operations/dashboard
2CustomerCustomer portal users/customer/dashboard
3AdminAdministrative users/admin/dashboard
4DriverDriver portal users/driver/dashboard
5WarehouseWarehouse staff/warehouse/dashboard

  • QUICK_START_CUSTOMER_PORTAL.md - Quick reference guide
  • CUSTOMER_PORTAL_AUTH_IMPLEMENTATION.md - Technical implementation details
  • IMPLEMENTATION_COMPLETE.md - Architecture and design decisions
  • AGENTS.md - Project overview and conventions

Q: Can I change the password for customer1? A: Yes, use the script or SQL UPDATE statement:

UPDATE users SET password = '$2b$12$...' WHERE username = 'customer1';

Q: Can multiple customers share one user account? A: Yes, but it’s not recommended. Each customer should have their own user account for audit trails and permissions.

Q: What if I forgot the password? A: Reset it by generating a new hash:

from werkzeug.security import generate_password_hash
print(generate_password_hash('newpassword'))

Then update in database:

UPDATE users SET password = 'NEW_HASH' WHERE username = 'customer1';

Q: How do I delete a customer user? A: Soft delete (deactivate):

UPDATE users SET is_active = FALSE WHERE username = 'customer1';

Or hard delete (not recommended):

DELETE FROM users WHERE username = 'customer1';

Q: Can customer users access the API? A: Yes, the user authentication works for both web routes and API endpoints.


After creating the customer1 user, you can seed sample bookings (connotes) and quotes for testing the customer portal features.

Terminal window
# From the project root directory
psql "postgresql://postgres.ostyrjgufbzfjieahqkm:H^BG%2HtXRgR@aws-1-ap-northeast-2.pooler.supabase.com:6543/postgres" -f migrations/seed_customer_portal_test_data.sql

The script automatically:

  1. Finds the customer1 user by username
  2. Links them to an existing customer record (or creates one if needed)
  3. Creates 7 test connotes (bookings) with various statuses
  4. Creates 7 test quotes with various statuses
Connote #StatusRouteAmount
CN-TEST-001DraftSydney, NSW → Melbourne, VIC$450.00
CN-TEST-002ConfirmedMelbourne, VIC → Brisbane, QLD$825.50
CN-TEST-003In TransitAdelaide, SA → Perth, WA$1,250.00
CN-TEST-004DeliveredHobart, TAS → Sydney, NSW$550.75
CN-TEST-005CancelledDarwin, NT → Cairns, QLD$380.00
CN-TEST-006PendingSydney, NSW → Adelaide, SA$675.00
CN-TEST-007AllocatedBrisbane, QLD → Melbourne, VIC$925.00
Quote #StatusRouteServiceWeightAmount
QT-TEST-001QUOTEDSydney, NSW → Melbourne, VICStandard100 kg$300.00
QT-TEST-002APPROVEDMelbourne, VIC → Brisbane, QLDExpress200 kg$550.00
QT-TEST-003PENDINGBrisbane, QLD → Sydney, NSWEconomy300 kg$800.00
QT-TEST-004EXPIREDPerth, WA → Darwin, NTStandard400 kg$1,050.00
QT-TEST-005REJECTEDAdelaide, SA → Hobart, TASExpress500 kg$1,300.00
QT-TEST-006QUOTEDParramatta, NSW → Geelong, VICStandard150 kg$450.00
QT-TEST-007APPROVEDGold Coast, QLD → Penrith, NSWExpress250 kg$700.00

After running the seed script, verify the data:

-- Check connotes for customer1
SELECT c.connote_number, c.status, c.total_amount,
pa.suburb as pickup, da.suburb as delivery
FROM connotes c
LEFT JOIN connote_addresses pa ON c.id = pa.connote_id AND pa.address_type = 'pickup'
LEFT JOIN connote_addresses da ON c.id = da.connote_id AND da.address_type = 'delivery'
WHERE c.customer_id = (
SELECT cu.id FROM customers cu
JOIN users u ON cu.email = u.email
WHERE u.username = 'customer1'
)
ORDER BY c.connote_number;
-- Check quotes for customer1
SELECT quote_reference, status, origin_suburb, destination_suburb, total_amount
FROM unified_quotes
WHERE customer_id = (
SELECT cu.id FROM customers cu
JOIN users u ON cu.email = u.email
WHERE u.username = 'customer1'
)
ORDER BY quote_reference;
  1. Login as customer1 / password123
  2. Navigate to My Bookings (/customer/bookings) - Should see 7 connotes
  3. Navigate to My Quotes (/customer/quotes) - Should see 7 quotes
  4. Use the status filters to test filtering by Draft, Confirmed, Completed, etc.

The seed script uses ON CONFLICT DO NOTHING clauses, so it’s safe to run multiple times. Existing records will be skipped, and only missing records will be created.

To completely reset and recreate test data:

-- Delete existing test connotes and quotes
DELETE FROM connote_addresses WHERE connote_id IN (
SELECT id FROM connotes WHERE connote_number LIKE 'CN-TEST-%'
);
DELETE FROM connotes WHERE connote_number LIKE 'CN-TEST-%';
DELETE FROM unified_quotes WHERE quote_reference LIKE 'QT-TEST-%';

Then run the seed script again.


  1. ✅ Create customer users (this guide)
  2. ✅ Login to customer portal
  3. ✅ Seed test data for customer1
  4. → Test bookings list and quotes list
  5. → Create new bookings via the booking form
  6. → Verify customer-specific data filtering works

Last Updated: 2025-02-04 Status: Ready for Production Difficulty: Easy Time to Complete: 5 minutes