project_viewer.sh
user@portfolio:~$ cat yojahny-crm.project
Yojahny CRM

YOJAHNY CRM

Full-stack client relationship management system with gamified client portal, project lifecycle automation, and real-time status tracking

[STATUS] maintenance
[TYPE] web
[DATE] 01.15.2026

[TECH_STACK]

Laravel 12 Vue 3 Inertia.js PHP 8.4 MySQL Tailwind CSS 4 TypeScript DomPDF Pest Telegram Bot API
[MEDIA_GALLERY]
[5_IMAGES_LOADED]
[PROJECT_DETAILS]

Yojahny CRM

A comprehensive client relationship management system built to streamline my freelance business operations, featuring a sophisticated multi-stage project workflow, automated notifications, and a uniquely gamified client portal that transforms the typical project tracking experience into an engaging journey. The system manages the complete project lifecycle from proposal creation through final payment, with real-time status synchronization between admin and client interfaces.

Key Features

  • Gamified Client Portal (“Quest Map”) - Designed an innovative client-facing interface that presents project stages as an interactive journey with animated unlock sequences, progress visualization, and stage-specific content panels. Clients track their project through four stages (Proposal, Progress, Review, Invoice) with contextual tooltips, real-time polling updates, and a polished dark theme with glass-morphism effects.

  • Nine-Stage Project Lifecycle Engine - Implemented a robust state machine managing projects through Draft, Proposal Sent, Accepted, In Progress, Staging Review, Staging Approved, Production Ready, Delivered, and Paid states. Each transition enforces business rules, triggers appropriate notifications, and updates the UI accordingly, preventing invalid state changes through Enum-based validation.

  • Automated Multi-Channel Notifications - Built a comprehensive notification system that automatically alerts clients via email at key milestones (proposal ready, work started, staging deployed, project complete). Admin receives Telegram notifications for time-sensitive events like proposal acceptance, with notification logging for audit trails and retry capabilities.

  • Dynamic Pricing with Discounts & Services - Created a flexible pricing engine supporting percentage and fixed-amount discounts that stack sequentially, free service bundles, and optional add-on services with conditional pricing (e.g., “free when purchased with X”). The system calculates discounted totals, total savings, and monthly recurring costs in real-time.

  • PDF Generation for Proposals & Invoices - Integrated DomPDF to generate professional PDF documents for proposals (including task breakdowns, applied discounts, and selected services) and invoices, downloadable by both admin and portal-authenticated clients with proper access controls.

  • Task Management with Drag-and-Drop Reordering - Implemented project-level task management with position-based ordering, status toggling (complete/incomplete), and progress percentage calculation. Tasks display in both admin views and the client portal’s “Work in Progress” stage.

  • Secure Portal Access via Signed URLs - Engineered a code-based portal authentication system where clients enter a 12-character alphanumeric code to receive time-limited signed URLs. Rate limiting (3 attempts per 15 minutes) protects against brute force, with comprehensive access logging tracking IP addresses, success/failure states, and failure reasons.

  • Developer Notes & Project Artifacts - Added internal documentation features allowing developers to attach notes and upload artifacts (mockups, specifications, deliverables) to projects, with secure file storage and portal-accessible downloads for approved artifacts.

Technical Implementation

Architecture & Stack

The application is built on Laravel 12 with Inertia.js v2, providing a true SPA experience while maintaining Laravel’s powerful backend capabilities. Vue 3 powers the reactive frontend with TypeScript for type safety, while Tailwind CSS 4 delivers a consistent, responsive design system. The architecture follows Laravel’s directory conventions with a clean separation between Admin and Portal domains.

The database schema is normalized with proper foreign key constraints across 15+ tables including projects, clients, tasks, invoices, discounts, free_services, optional_services, and junction tables for many-to-many relationships. Eloquent models leverage accessors, scopes, and eager loading to prevent N+1 queries while providing a clean API for complex calculations like discounted_cost and monthly_recurring_cost.

Portal Stage State Machine

The client portal’s stage logic is implemented through a composable-based architecture in Vue. The usePortalStages composable maps the nine-step backend ProjectStatus enum to four client-visible stages, computing which stages are unlocked, current, and complete based on the project’s status:

// Stage unlock logic maps backend statuses to portal stages
proposal: ['draft', 'proposal_sent', 'accepted', ...],
progress: ['accepted', 'in_progress', ...],
review: ['staging_review', 'staging_approved', 'production_ready', ...],
invoice: ['delivered', 'paid']

The useUnlockAnimation composable tracks which stages have been viewed (persisted in localStorage per portal code), triggering celebratory unlock animations only for newly-unlocked stages. This creates a delightful experience when clients first see their project progress to a new phase.

Real-Time Updates with Polling

Rather than implementing WebSockets for this use case, the portal uses Inertia’s polling capabilities via a custom usePortalPolling composable that refreshes page props every 60 seconds. This ensures clients see updated task progress, status changes, and new invoices without manual refresh, while keeping infrastructure simple and costs low.

Notification Architecture

The notification system is built on Laravel’s native notification infrastructure with custom channels:

  • Email Channel: Uses Laravel’s Mailable classes with Blade templates for professional, branded emails to clients
  • Telegram Channel: Custom TelegramService sends formatted messages to admin for urgent events (proposal accepted, payment received)
  • Notification Logging: All outgoing notifications are logged to notification_logs table with project association, recipient, channel, status, and payload for debugging and audit purposes

Failed notifications can be retried from the admin interface, which re-dispatches the original notification class with preserved context.

PDF Generation Service

The PdfService handles all PDF generation through a clean interface, loading project relationships and calculating display values before passing to Blade templates. Proposals include:

  • Client information and project details
  • Task breakdown with estimated hours
  • Free services included
  • Applied discounts with calculated savings
  • Selected optional services with conditional pricing
  • Final pricing summary with acceptance date stamp

Invoices are simpler but follow the same pattern, pulling project and client data for a complete billing document.

Security Implementation

The portal implements defense-in-depth security:

  1. Portal Code Generation: 12-character alphanumeric codes with ambiguous characters (0, O, I, 1, L) replaced to prevent confusion
  2. Signed URLs: Laravel’s temporarySignedRoute with 30-day expiration prevents URL sharing/guessing
  3. Rate Limiting: IP-based rate limiting (3 attempts per 15 minutes) with automatic lockout messaging
  4. Access Logging: Every portal access attempt is logged with IP, code entered, success/failure, and failure reason
  5. Invoice Scoping: Portal invoice downloads validate that the requested invoice belongs to the portal’s project

Frontend Component Architecture

The admin interface uses a component library built on Radix Vue primitives (via shadcn-vue), providing accessible, keyboard-navigable UI components. Key patterns include:

  • AdminLayout: Sidebar navigation with collapsible sections, user menu, and breadcrumb system
  • PortalLayout: Minimal chrome with animated gradient background for the client portal
  • Form Components: Reusable input components with validation error display using Inertia’s form helpers
  • Status Badges: Dynamic color-coded badges computed from Enum values on the backend

The portal’s QuestMap component is the most complex, managing:

  • Responsive layouts (desktop: horizontal path, tablet: 2x2 grid, mobile: vertical timeline)
  • Stage card interactions with unlock states and tooltips
  • Stage content panels with contextual components (ProposalStage, WIPStage, ReviewStage, InvoiceStage)
  • Smooth animations via Motion.js with prefers-reduced-motion support

Business Impact & Use Cases

Streamlined Client Communication

Before this CRM, project updates required manual emails at each milestone, often leading to missed communications or confused clients. The automated notification system ensures clients receive timely, professional updates at every stage transition, while the portal provides self-service access to project status, reducing “where’s my project?” inquiries.

Professional Proposal Presentation

The portal transforms proposals from static documents into interactive experiences. Clients can review project scope, see exactly what’s included, understand discount savings, and make acceptance decisions all within a branded, professional interface. PDF generation provides downloadable records for client accounting departments that require traditional documentation.

Project Status Visibility

The gamified portal design encourages client engagement with their project status. Rather than checking a boring dashboard, clients enjoy seeing their “quest” progress, creating positive associations with project updates. The visual stage progression makes it immediately clear where their project stands without reading detailed status text.

Invoicing Integration

Projects flow naturally into invoicing, with invoice creation pre-populated from project data. Payment status tracking closes the loop, automatically transitioning projects to “Paid” status when invoices are marked paid, completing the lifecycle and moving the project into read-only archival mode in the portal.

Development & Testing

Test-Driven Development with Pest

The project follows TDD practices with Pest v4, featuring comprehensive Feature tests covering:

  • Portal code validation and rate limiting
  • Project status transitions and business rules
  • Invoice creation and PDF generation
  • Notification dispatch and logging
  • Authentication and authorization flows

Tests use Laravel’s RefreshDatabase trait with factories that generate realistic test data, including project states at various lifecycle stages.

Code Quality & Standards

PHP code follows PSR-12 standards enforced by Laravel Pint, with strict types enabled. The frontend uses ESLint and Prettier for consistent formatting. TypeScript provides compile-time type checking for Vue components, catching errors before runtime.

Deployment Considerations

The application is designed for standard LEMP stack deployment with Laravel Sail available for development. Environment-based configuration handles differences between development and production, including notification channels (Telegram only in production), PDF rendering settings, and signed URL domains.


Built with Laravel 12 and Vue 3 to transform freelance project management into a delightful experience for both developer and client.

EOF: Data loaded