A web application for digitizing and automating the approval workflow for concept papers with budget allocation. Built with Laravel 12, Inertia.js, and React.
- Public Landing Page: Informative homepage showcasing system features, workflow process, and user roles
- Enhanced User Registration: Capture academic information including school year and student number
- Comprehensive User Guide: In-app documentation with role-specific guides and FAQs
- Role-Based Access Control: Seven distinct user roles (Requisitioner, SPS, VP Acad, Senior VP, Auditor, Accounting, Admin)
- 10-Stage Approval Workflow: Automated routing through predefined approval stages
- Email Notifications: Automated notifications for stage assignments, overdue tasks, completions, and returns
- Deadline Tracking: Automatic deadline calculation and overdue alerts
- Audit Trail: Complete history of all actions taken on concept papers
- File Attachments: PDF upload support for concept papers and supporting documents
- Admin Dashboard: User management and comprehensive reporting
- Responsive Design: Works on desktop, tablet, and mobile devices
- PHP 8.2 or higher
- Composer
- Node.js 18+ and npm
- SQLite (development) or MySQL/PostgreSQL (production)
- Clone the repository
git clone <repository-url>
cd concept-paper-tracker- Install PHP dependencies
composer install- Install JavaScript dependencies
npm install- Set up environment
cp .env.example .env
php artisan key:generate- Configure database
The application uses SQLite by default for development. The database file will be created automatically.
For production, update the .env file with your database credentials:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=concept_paper_tracker
DB_USERNAME=your_username
DB_PASSWORD=your_password- Run migrations and seeders
php artisan migrate --seedThis will create the database tables and seed test users with all roles.
- Build frontend assets
npm run buildFor development with hot reload:
npm run dev- Start the queue worker
Email notifications and background jobs (document conversion, deadline checks) are processed asynchronously via queue:
php artisan queue:workFor development, you can use the dev script which runs the server, queue worker, and Vite concurrently:
composer dev- Start the scheduler (optional for development)
The system includes scheduled tasks that run hourly:
- Check for reached deadlines and send notifications
- Check for overdue workflow stages
To enable scheduled tasks in development:
php artisan schedule:workOr add to your crontab for production (see Production Deployment section).
- Start the development server
php artisan serveVisit http://localhost:8000 in your browser.
The application features a public landing page that serves as the entry point for new users.
- Unauthenticated users: Visiting the root URL (
/) displays the landing page - Authenticated users: Automatically redirected to the dashboard
The landing page includes:
- Hero Section: System title, tagline, and call-to-action buttons
- Features Section: Key capabilities displayed in a grid layout
- Workflow Section: Visual representation of the 9-step approval process
- Roles Section: Description of all six user roles
- Use Cases Section: Example scenarios demonstrating system benefits
- CTA Section: Final call-to-action encouraging registration
- Footer: Links and contact information
To customize the landing page content:
- Edit the Landing component:
resources/js/Pages/Landing.jsx - Modify sub-components: Located in
resources/js/Pages/Landing/directoryHeroSection.jsx- Hero banner and main CTAFeaturesSection.jsx- Feature cardsWorkflowSection.jsx- Workflow visualizationRolesSection.jsx- User role descriptionsUseCasesSection.jsx- Example use casesCTASection.jsx- Final call-to-actionFooter.jsx- Footer content
- Update styling: Modify Tailwind CSS classes in component files
- Change workflow data: Edit
config/workflow.phpfor workflow stage information
- Icons: Uses Heroicons (included via
@heroicons/react) - Styling: Tailwind CSS with custom gradient backgrounds
- Responsive: Mobile-first design with breakpoints for tablet and desktop
The registration form captures additional academic information:
- School Year (optional): Academic year designation (e.g., "2024-2025", "1st Year", "2nd Year")
- Student Number (optional, requisitioner role only): Unique student identifier
- Department (required): User's department or organizational unit
- School Year: Maximum 50 characters, free-form text
- Student Number: Maximum 50 characters, must be unique across all users
- Department: Required for all users
During registration, users can select from the following roles:
- Requisitioner: Submit and track concept papers
- SPS: School Principal/Supervisor - Initial review
- VP Acad: Vice President for Academic Affairs - Academic review
- Auditor: Audit review and countersigning
- Accounting: Voucher and cheque preparation
Note: Admin role can only be assigned by existing administrators.
After running the seeders, you can log in with these test accounts:
| Role | Password | School Year | Student Number | |
|---|---|---|---|---|
| Requisitioner | requisitioner@example.com | password | 2024-2025 | 2024-00001 |
| SPS | sps@example.com | password | N/A | N/A |
| VP Acad | vp_acad@example.com | password | N/A | N/A |
| Auditor | auditor@example.com | password | N/A | N/A |
| Accounting | accounting@example.com | password | N/A | N/A |
| Admin | admin@example.com | password | N/A | N/A |
By default, emails are logged to storage/logs/laravel.log. No additional configuration needed!
For testing email delivery, use Mailtrap:
- Sign up for a free account
- Get your SMTP credentials
- Update
.env:
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your-username
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tlsFor production, use a professional email service (Mailgun, SendGrid, Amazon SES, etc.).
See docs/MAIL_SETUP.md for detailed configuration instructions.
Test all notification types:
php artisan notification:test allTest specific notification:
php artisan notification:test assigned
php artisan notification:test overdue
php artisan notification:test completed
php artisan notification:test returnedThe users table includes the following fields:
| Field | Type | Description | Required | Unique |
|---|---|---|---|---|
| id | bigint | Primary key | Yes | Yes |
| name | varchar(255) | Full name | Yes | No |
| varchar(255) | Email address | Yes | Yes | |
| password | varchar(255) | Hashed password | Yes | No |
| role | varchar(50) | User role (requisitioner, sps, vp_acad, etc.) | Yes | No |
| department | varchar(255) | Department or organizational unit | Yes | No |
| school_year | varchar(50) | Academic year (e.g., "2024-2025", "1st Year") | No | No |
| student_number | varchar(50) | Unique student identifier | No | Yes |
| is_active | boolean | Account active status | Yes | No |
| created_at | timestamp | Account creation timestamp | Yes | No |
| updated_at | timestamp | Last update timestamp | Yes | No |
Users can view and edit their academic information through:
- Profile Page:
/profile- View and edit school year and student number - Admin Interface: Administrators can manage all user fields including academic information
Administrators have additional capabilities:
- View school year and student number in user list
- Filter users by school year
- Edit academic information for any user
- Export user data including academic fields
The system implements a 10-stage sequential approval process:
- SPS Review (1 day) - School Principal/Supervisor
- VP Acad Review (3 days) - Vice President for Academic Affairs
- Auditing Review (3 days) - Auditor
- Senior VP Approval (2 days) - Senior Vice President
- Acad Copy Distribution (1 day) - VP Acad
- Auditing Copy Distribution (1 day) - Auditor
- Voucher Preparation (1 day) - Accounting
- Audit & Countersign (1 day) - Auditor
- Cheque Preparation (4 days) - Accounting
- Budget Release (1 day) - Accounting
The system uses Laravel's queue system for asynchronous processing and scheduled tasks for automated monitoring.
The following jobs are processed asynchronously:
-
ConvertDocumentJob - Converts Word documents to PDF for in-browser preview
- Runs when a Word document is uploaded
- Uses PHPWord and dompdf libraries
- Implements retry logic with exponential backoff (3 attempts)
-
SendDeadlineNotificationJob - Sends email notifications when deadlines are reached
- Dispatched by CheckDeadlinesJob
- Notifies requisitioner and current stage assignee
- Includes concept paper details and current status
-
SendApprovalNotificationJob - Sends email notifications when papers are fully approved
- Dispatched when all workflow stages complete
- Notifies requisitioner and administrators
- Includes processing time summary
-
CheckOverdueStages - Identifies and notifies about overdue workflow stages
- Scheduled to run hourly
- Sends notifications for stages exceeding their max_days limit
-
CheckDeadlinesJob - Identifies concept papers that have reached their deadline
- Scheduled to run hourly
- Uses caching to ensure single notification per paper
- Dispatches SendDeadlineNotificationJob for each reached deadline
The system automatically schedules the following tasks (configured in routes/console.php):
// Runs every hour
Schedule::job(new CheckOverdueStages)->hourly();
Schedule::job(new CheckDeadlinesJob)->hourly();Development:
# Start queue worker
php artisan queue:work
# Start scheduler (for hourly tasks)
php artisan schedule:work
# Or use the combined dev script
composer devProduction:
Configure Supervisor for queue workers and add cron job for scheduler (see Production Deployment section).
# View queue status
php artisan queue:monitor
# View failed jobs
php artisan queue:failed
# Retry failed jobs
php artisan queue:retry all
# Clear all failed jobs
php artisan queue:flushQueue configuration is in config/queue.php:
- Default connection:
database(suitable for small to medium applications) - Retry attempts: 3 with exponential backoff
- Timeout: 90 seconds
- For production with high volume, consider switching to Redis
The application includes a comprehensive in-app user guide accessible to all authenticated users.
- Click "User Guide" in the main navigation menu
- Or visit
/user-guidewhen logged in
- Getting Started: System overview, login process, and navigation
- Requisitioner Guide: Submitting and tracking concept papers
- Approver Guide: Reviewing, approving, and returning papers
- Administrator Guide: User management, reports, and troubleshooting
- Workflow Process: Complete 10-stage workflow documentation
- FAQ: Frequently asked questions and support information
User guide content is stored as Markdown files in resources/docs/user-guide/:
resources/docs/user-guide/
├── getting-started.md
├── requisitioner.md
├── approver.md
├── admin.md
├── workflow.md
└── faq.md
To update guide content:
- Edit Markdown files: Modify the
.mdfiles inresources/docs/user-guide/ - Use standard Markdown: Supports headings, lists, code blocks, tables, and links
- Add images: Place images in
public/images/user-guide/and reference with relative paths - Test rendering: View changes in the application after saving
To add a new section to the user guide:
- Create Markdown file: Add new
.mdfile inresources/docs/user-guide/ - Update controller: Edit
app/Http/Controllers/UserGuideController.php- Add section to
getSections()method - Include title, icon, and subsections
- Add section to
- Add route (if needed): Update
routes/web.phpfor custom routes - Update navigation: Section will automatically appear in the table of contents
The user guide uses Tailwind Typography plugin for consistent markdown rendering:
- Headings are automatically styled with proper hierarchy
- Code blocks include syntax highlighting
- Tables are responsive and styled
- Lists have proper spacing and indentation
Follow these steps to update user guide content:
- Locate the file: Navigate to
resources/docs/user-guide/ - Edit the Markdown file: Open the relevant
.mdfile in your editor - Make changes: Update content using standard Markdown syntax
- Add images (if needed):
- Place images in
public/images/user-guide/ - Reference in Markdown:

- Place images in
- Save the file: Changes are immediately available (no build required)
- Test in browser: Log in and navigate to the user guide to verify changes
- Commit changes: Add to version control with descriptive commit message
Best Practices:
- Keep content clear and concise
- Use headings to organize content hierarchically
- Include code examples where applicable
- Add screenshots for complex UI interactions
- Update the FAQ section with common user questions
- Review content for accuracy after system updates
Content Review Schedule:
- Review all guide sections quarterly
- Update immediately after major feature releases
- Incorporate user feedback and common support questions
- Keep screenshots current with UI changes
- System Documentation - Complete technical documentation including database schema, API endpoints, and architecture
- Dependencies Guide - Detailed information about external dependencies (PHPWord, Fabric.js, PDF.js) and their configuration
- Queue and Scheduler Setup - Comprehensive guide for setting up and managing background jobs and scheduled tasks
- Customization Guide - Guide for customizing landing page, user registration, user guide, and styling
- Email Setup Guide - Detailed mail configuration instructions
- Email Notifications - Complete notification system documentation
- User Guide - In-app comprehensive user documentation (requires login)
php artisan testThe project follows Laravel coding standards. Format code using:
./vendor/bin/pintMonitor queue:
php artisan queue:monitorView failed jobs:
php artisan queue:failedRetry failed jobs:
php artisan queue:retry all- Set
APP_ENV=productionandAPP_DEBUG=false - Configure production database
- Set up SMTP email service
- Configure queue worker with Supervisor
- Set up scheduled tasks for overdue checking
Create /etc/supervisor/conf.d/concept-paper-tracker.conf:
[program:concept-paper-tracker-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /path/to/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/path/to/storage/logs/worker.log
stopwaitsecs=3600Add to crontab:
* * * * * cd /path/to/project && php artisan schedule:run >> /dev/null 2>&1- Ensure queue worker is running:
php artisan queue:work - Check failed jobs:
php artisan queue:failed - Verify mail configuration in
.env - Check logs:
storage/logs/laravel.log
- Restart queue worker:
php artisan queue:restart - Clear failed jobs:
php artisan queue:flush - Check database connection
chmod -R 775 storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cacheThis project is proprietary software. All rights reserved.
For issues and questions, please contact the development team.