← Work

Apr 2024 – Aug 2024 · 4 months

Job Fair Registration Platform

I built the user authentication system, registration flows, and survey analytics for a job fair platform serving both job seekers and employers.

27
commits
10%
of codebase
4
months
15
migrations
LaravelPHPLivewireMySQLBladeSMS Integration

Overview

A job fair registration platform for connecting job seekers with employers at physical job fair events. I owned the authentication system, user/company registration flows, profile management, survey feedback collection, and password security enhancements. The platform supports both individual job seekers and company accounts with distinct registration processes.

What I Built

Authentication & Registration System (Apr – May 2024)

  • Dual authentication for job seekers (users) and employers (companies)
  • Multi-step company registration wizard using Livewire Wizard
  • User registration with SMS verification code
  • Forgot password / reset password flow with token-based verification
  • Login CAPTCHA integration for bot prevention
  • 15-second rate limiting on SMS verification code requests

Profile Management (May 2024)

  • Job seeker profile editing with image upload preview and deletion
  • Company profile editing with multi-step form (basic info, description, contact)
  • City and zone selection for company locations
  • Real-time form validation using Livewire

Survey Feedback System (May 2024)

  • Company feedback form with satisfaction ratings
  • Job seeker feedback collection
  • Survey statistics dashboard for both user types
  • "Other desired services" free-text field for additional feedback

Password Security Enhancement (Jul – Aug 2024)

  • Password history tracking to prevent reuse
  • last_password_changed_at timestamp for both users and companies
  • Account disable/enable functionality in admin backend
  • Reset password token expiration management
  • Strengthened forgot password validation logic

Architecture Decisions

Separate Users and Companies Tables Rather than using a single users table with role flags, I created distinct users (job seekers) and companies (employers) tables. Each has its own authentication guard, profile fields, and registration flow. This separation made sense because the two user types have fundamentally different data models: job seekers have resumes while companies have booth numbers, VAT numbers, and contact persons.

Password History Table for Security Compliance Added password_histories table to track previous passwords. When users reset their password, the system checks against recent entries to prevent reuse. Combined with last_password_changed_at column, this enables password rotation policies if required by enterprise clients.

VAT Number Changed from Integer to String Original migration defined vat_number as integer, but Taiwan VAT numbers can have leading zeros. Created migration to change both vat_number and booth_number to string type, preserving data integrity.

Key Bug Fix: Profile Photo Not Saving to Database

Problem: Users could upload profile photos and see the preview, but after saving, the photo wasn't persisted. The image file was uploaded to storage but the database path field remained null.

Fix: Traced the issue to the controller not passing the uploaded file path to the model's update method. Added the photo path to the fillable attributes and ensured the controller included it in the save operation.

Other Contributions

  • Removed ImageMagick dependencies in favor of Intervention Image
  • Backend admin fields for user and company account management
  • Account activation/deactivation toggle in admin panel
  • Notification system integration for SMS alerts
  • Survey completion page styling improvements

Reflection

This project taught me the importance of thinking through authentication architecture upfront. The decision to separate users and companies into distinct tables was made early, and it paid off as each user type evolved with different requirements. However, the password security features came as a late addition after the initial launch—I would have designed the password history tracking from the start if security requirements had been clearer during planning.