A Laravel 12 + Livewire 3 + Filament 4 backend that powers a curated luxury wedding marketplace. The system lets administrators, agencies, and vendors collaborate on inquiries, bookings, and marketing assets while exposing a clean public explore page with real-time reactive filtering, AI-powered search, and a beautiful booking pipeline in INR.
The system has highly evolved, hitting Phase 3/4 of its development. Key new implementations include:
- AI Semantic Search: Livewire-powered queries routed via Google's Gemini to parse user intentions (e.g. "budget florists" ->
$max_price=30000) directly onto Postgres. - Strict Multitenancy Constraints: 3 explicitly partitioned Filament portals (
/admin,/vendor,/agency) with strictly enforced route blocking, role intercepts, and aGate::beforeintercept mechanism. - The Core Booking State Machine: A mathematically rigid framework controlling Deposits (
deposit_amount), Final Balances, and natively intercepting duplicated spam inquiries directly from the.blade/Livewire components. - Active Asynchronous Features: LocalStorage hydration allowing unregistered clients to 'heart' listings, caching them dynamically until they officially log in.
- Database Push Notifications: Zero-refresh Filament popup notifications triggering immediately when an Inquiry hits a new status.
- The Rupee / India Globalization: A massive system-wide find-and-replace upgrading the default currency strictly to INR (₹) across all queries, charts, and public dashboards.
For a deeply granular map of all underlying platform logic, refer to:
| Goal | Description |
|---|---|
| Centralize supply | Capture all agencies, vendors, services, and media in one authoritative database with soft-delete safety rails. |
| Empower operations | Provide Filament panels tailored for admins, agencies, and vendors, so each role can act on inquiries, availability, and promotions. |
| Feed the frontend | Deliver fast, Livewire-driven exploration endpoints with interactive AI Search and Booking Calendars. |
| Layer | Implementation | Reasoning |
|---|---|---|
| Framework | Laravel 12 (PHP 8.3) | Modern routing, queues, Eloquent ORM, first-class Sail support. |
| Admin UI | Filament 4 multi-panel (/admin, /agency, /vendor) with Filament Shield |
Accelerates CRUD, enforces role-aware permissions, gives widgets/dashboards out of the box. |
| Domain layer | app/Domain/* namespaces plus Eloquent models in app/Models |
Keeps business logic close to domain language while still leveraging Eloquent relations. |
| Database | PostgreSQL via Sail | Reliable relational storage with JSON support for flexible attributes. |
| Media | Spatie Laravel Media Library (media table) |
Unified handling for logos, banners, galleries; enforces single-file/logo collections. |
| APIs | Versioned read-only endpoints under routes/api.php (currently v1) |
Decouples public site needs from Filament; makes it easy to evolve versions later. |
| Auth | Panel auth for Providers/Admins, Native session auth for Clients; Sanctum-ready for API | Keeps backend secured via Shield while Clients enjoy seamless session-based dashboard access. |
| Area | Highlights | Key Files |
|---|---|---|
| Users & Roles | Soft-deletable users with dependency-aware deletion, role assignments, login tracking. Super admin gate intercept bypass logic for unconditional dashboard overrides. | app/Models/User.php, app/Filament/Resources/Users/Tables/UsersTable.php, app/Providers/AppServiceProvider.php |
| Agencies | Rich profile fields, media attachments, vendor relationships, rating metrics. | app/Models/Agency.php, app/Filament/Resources/Agencies/* |
| Vendors | Category + pricing info in INR, services, availability calendar, agency partnerships. | app/Models/Vendor.php, app/Filament/Resources/Vendors/* |
| Clients & Inquiries | Inquiry lifecycle (new → responded → booked), duplicate inquiry interception, urgency flags, follow-up tracking, database push notifications. | app/Models/Client.php, app/Models/Inquiry.php, app/Filament/Resources/Inquiries/* |
| Matching & Bookings | Morph relationships for packages, bookings, reviews, FAQs that attach to agencies or vendors. Full booking pipeline. | app/Models/Booking.php, app/Models/Package.php, etc. |
| AI Search & UX | Gemini-powered semantic search integration overriding standard keyword logic, real-time Livewire reactive pagination, LocalStorage saved listings. | app/Livewire/ExploreListings.php, resources/views/livewire/join-registry.blade.php |
| Professional Registry | Frontend vendor onboarding form (/join) transitioning into the Filament Professional Application Approval workflow. |
app/Filament/Resources/ProfessionalApplications/* |
- Users cover admins, agencies, vendors, and clients; role logic flows through Filament resources and policies.
- Super Admin Intercept: Configured
Gate::beforeintercept so those with thesuper_adminrole have automatic absolute bypass permissions on all models. - Soft deletes are enforced everywhere, with guardrails in
UsersTablethat hide delete buttons when dependencies exist and deliver persistent warnings before force deletes. - Spatie Media Library allows avatars/documents to attach just like vendor logos.
- Attributes (business name, slug, location, contact, specialties, years in business) live in
app/Models/Agency. - Relationships: vendors (approved/pending/rejected), inquiries, portfolio images, packages, reviews, FAQs, bookings, tags.
- Helpers such as
incrementViewsCount()andupdateRatingStats()keep dashboard metrics accurate. - Filament resources provide search, Trashed filters, toggled columns, and scoped delete/restore/force actions.
- Join Registry: Prospective professionals do not instantly become vendors. They enroll via the
/joinLivewire route to create aProfessionalApplication. - Admin Approval: Admins review
ProfessionalApplicationsinside Filament and trigger an Action mapping tooptions()approval hooks, converting them into active user records. - Vendors include pricing ranges (
min_price,max_price,price_unit) based globally around INR, service areas, social links, arbitrary JSONattributes. - Connected to categories, owning agencies, services, event types, tags, availability slots.
- Availability & Bookings:
isAvailableOn()natively prevents double-booking logic on the public UI Calendar view.
- Inquiries capture event metadata, budget, urgency, multiple note channels, and timestamps for response/follow-up/closure.
- Spam / Duplicate Block: Livewire inquiry modal checks for existing unresolved vendor-client pairs to prevent double-messaging.
- Convenience methods (
markAsResponded,recordFollowUp,close) prevent inconsistent status transitions. - Database Push Notifications: Emitted natively when Inquiry statuses transition so users get Filament UI alerts immediately.
- Services, packages, reviews, FAQs, and bookings rely on morph relationships so they can belong to either agencies or vendors.
- Tags offer cross-cutting categorization ("Luxury", "Destination", etc.).
- These abstractions keep the schema DRY yet flexible for future asset types.
registerMediaCollections()defines single-file vs. multi-file collections per model.- API resources expose
logo,banner,galleryURLs via Spatie helpers. - The
mediatable migration mirrors the official schema so conversions/responsive images can be enabled later without changes.
| Panel | Path | Purpose | Notable Logic |
|---|---|---|---|
| Admin | /admin |
Full CRUD across users, agencies, vendors, clients, inquiries, bookings. | Filament Shield permissions, soft-delete filters, dependency-aware deletes, dashboard widgets. |
| Agency | /agency |
Agency staff manage their vendors, respond to inquiries, maintain portfolios. | Custom AgencyPanelProvider scopes resources and branding. |
| Vendor | /vendor |
Vendors update profiles, services, availability, respond to leads. | Mirrors agency panel with vendor-specific navigation/resources. |
Why Filament?
- Rapid scaffolding with consistent UI components (tables, forms, infolists, dashboards).
- Built-in filters (search, column toggles, trashed) reduce bespoke UI work.
- Widgets put KPIs (e.g., inquiries per week) directly on panel dashboards.
Safety nets:
- Delete/force-delete actions only appear when the record lacks blocking dependencies (e.g., users tied to vendors/agencies).
- Confirmation copy explains consequences plainly and requires explicit admin confirmation.
Base URL: https://your-domain.test/api/v1
| Resource | Endpoint | Description |
|---|---|---|
| Agencies | GET /agencies |
Paginated list with filters (search, city, country, state, verified, featured, premium). |
| Agencies | GET /agencies/{slug} |
Single agency by slug; increments view count unless track_views=false. |
| Vendors | GET /vendors |
Paginated list; supports category + price filters, availability date, boolean flags. |
| Vendors | GET /vendors/{slug} |
Single vendor by slug; returns category, services, tags, media, stats. |
| Parameter | Applies to | Notes |
|---|---|---|
search |
Both | Fuzzy search across business name, description, city, country. |
city, state, country |
Both | Partial match filters for geo searches. |
verified, featured, premium |
Both | Accepts true/false; parsed into booleans. |
category_id |
Vendors | Exact match on the vendor's primary category. |
min_price, max_price |
Vendors | Numeric filters on price range columns. |
available_on |
Vendors | Y-m-d; ensures availability shows available/partially_booked. |
sort |
Both | Prefix with - for descending. Agencies: created_at, avg_rating, review_count, views_count. Vendors add min_price, max_price. |
page, per_page |
Both | Pagination (per_page capped at 50). |
track_views |
Detail endpoints | false skips the automatic view counter increment. |
GET /api/v1/agencies?city=Mumbai&verified=true&sort=-avg_rating
Accept: application/json{
"data": [
{
"id": 1,
"slug": "evergreen-events",
"business_name": "Evergreen Events",
"description": "Full-service planning studio...",
"location": {
"city": "Mumbai",
"country": "India"
},
"stats": {
"avg_rating": 4.9,
"review_count": 37,
"verified": true,
"featured": true,
"views_count": 1284
},
"media": {
"logo": "https://cdn.test/storage/.../logo.jpg",
"banner": "https://cdn.test/storage/.../banner.jpg",
"gallery": ["https://cdn.test/storage/.../gallery/1.jpg"]
}
}
],
"links": {
"first": "https://your-domain.test/api/v1/agencies?page=1"
},
"meta": {
"current_page": 1,
"per_page": 15,
"total": 1
}
}GET /api/v1/vendors/floral-boutique?track_views=false
Accept: application/json{
"data": {
"id": 5,
"slug": "floral-boutique",
"business_name": "The Floral Boutique",
"category": {
"id": 2,
"name": "Florist"
},
"pricing": {
"min_price": 50000,
"max_price": 300000,
"price_unit": "event"
},
"location": {
"city": "New Delhi",
"country": "India"
},
"services": [
{"id": 11, "name": "Premium Wedding Bouquet design", "price": 25000}
],
"media": {
"logo": "https://cdn.test/.../logo.png",
"gallery": ["https://cdn.test/.../1.png"]
},
"stats": {
"avg_rating": 4.8,
"review_count": 22,
"views_count": 194,
"verified": true
}
}
}- Lists return Laravel pagination payloads (
data,links,meta). - Resources expose nested dictionaries (
location,contact,social,stats,media) so the frontend can read structured data without extra transforms. - When relationships are eager loaded (
tags,services), the resources automatically append them. - All API routes share
throttle:120,1, limiting each IP to 120 requests/minute. Adjust inroutes/api.phpif traffic requires more headroom.
- Database: PostgreSQL via Sail. Run
./vendor/bin/sail artisan migrate --seedto bootstrap data. - Media: Stored via Spatie Media Library under
storage/app/public, exposed viapublic/storage. Collections includelogo,banner,gallery,portfolio,documents. - Caching: Not enabled yet, but architecture leaves room for query/response caching when the frontend traffic grows.
cp .env.example .env
./vendor/bin/sail up -d
./vendor/bin/sail composer install
./vendor/bin/sail artisan key:generate
./vendor/bin/sail artisan migrate --seedThis project is easiest to run on Windows through WSL2. The repo uses Laravel Sail, Bash-style scripts, and a Docker-based PostgreSQL stack, so running it inside Ubuntu on WSL avoids most Windows path and shell issues.
- Install WSL2 with Ubuntu 24.04 or 22.04.
- Install Docker Desktop and enable WSL Integration for the Ubuntu distro.
- Install Git inside WSL.
Store the repo somewhere under /home/<your-user> rather than under /mnt/c/... for better performance.
sudo apt update && sudo apt upgrade -y
sudo apt install -y git
cd ~
git clone <your-repository-url> wedding-platform
cd wedding-platform/wedding-platform-backendcp .env.example .envUpdate these values in .env before starting the containers:
APP_URL=http://localhost
DB_CONNECTION=pgsql
DB_HOST=pgsql
DB_PORT=5432
DB_DATABASE=wedding_platform
DB_USERNAME=sail
DB_PASSWORD=password
QUEUE_CONNECTION=database
CACHE_STORE=database
SESSION_DRIVER=database
APP_PORT=80
VITE_PORT=5173
FORWARD_DB_PORT=5432
FORWARD_REDIS_PORT=6379
FORWARD_MAILPIT_PORT=1025
FORWARD_MAILPIT_DASHBOARD_PORT=8025./vendor/bin/sail up -d
./vendor/bin/sail composer install
./vendor/bin/sail npm install./vendor/bin/sail artisan key:generate
./vendor/bin/sail artisan migrate --seed
./vendor/bin/sail artisan storage:linkKeep this running in a separate WSL terminal:
cd ~/wedding-platform/wedding-platform-backend
./vendor/bin/sail npm run dev- Main app / default URL:
http://localhost - Admin panel:
http://localhost/admin - Agency panel:
http://localhost/agency - Vendor panel:
http://localhost/vendor - Mailpit dashboard:
http://localhost:8025 - Vite dev server:
http://localhost:5173
./vendor/bin/sail artisan test
./vendor/bin/sail artisan migrate:fresh --seed
./vendor/bin/sail artisan optimize:clear
./vendor/bin/sail down- Run project commands from WSL Ubuntu, not PowerShell, for the smoothest experience.
- The helper script in switch-env.sh is a Bash script and should also be run from WSL.
- If port 80 is already in use on Windows, change
APP_PORTin.env, then reopen the app on that port. - If Docker volumes or file watching feel slow, confirm the repo is inside the WSL filesystem, not on the Windows drive.
- If Docker commands fail inside WSL, open Docker Desktop and verify Settings → Resources → WSL Integration is enabled for the distro.
Helpful commands:
./vendor/bin/sail artisan make:filament-resource Vendor– scaffold additional resources../vendor/bin/sail artisan migrate:fresh --seed– reset the DB while iterating quickly../vendor/bin/sail artisan storage:link– expose media assets.
The project includes a comprehensive test suite covering all core models and their relationships, business logic, and edge cases.
# Run all tests
./vendor/bin/sail artisan test
# Run with verbose output
./vendor/bin/sail artisan test --verbose
# Run specific test file
./vendor/bin/sail artisan test tests/Unit/Models/VendorTest.php
# Run tests with coverage (requires Xdebug)
./vendor/bin/sail artisan test --coverage| Test Suite | Tests | Description |
|---|---|---|
AgencyTest |
17 | Agency relationships, rating stats, view counts, subscriptions, soft deletes |
BookingTest |
20 | Booking lifecycle, payment tracking, status transitions, scopes |
ClientTest |
16 | Client profiles, wedding calculations, planning status, preferences |
InquiryTest |
19 | Inquiry lifecycle, status transitions, messaging, urgency flags |
MessageTest |
12 | Message delivery, read status, attachments, system messages |
UserTest |
12 | User types, relationships, soft deletes, authentication |
VendorTest |
19 | Vendor profiles, availability, pricing, agency relationships |
Total: 117 tests with 190+ assertions
| Check | Command |
|---|---|
| PHPUnit tests | ./vendor/bin/sail artisan test |
| Pint / code style | ./vendor/bin/sail pint |
| PHPStan (if enabled) | ./vendor/bin/sail vendor/bin/phpstan analyse |
| Static analysis / IDE helpers | ./vendor/bin/sail artisan ide-helper:generate |
Aim to keep builds green before merging; run relevant tests whenever you touch domain logic or Filament resources.
The project includes comprehensive seeders that populate the database with realistic Indian wedding platform demo data for development and showcasing.
# Seed demo data (safe to run multiple times - idempotent)
./vendor/bin/sail artisan db:seed
# Fresh database with demo data
./vendor/bin/sail artisan migrate:fresh --seed| Entity | Count | Description |
|---|---|---|
| Categories | 65 | Wedding service categories with hierarchical structure |
| Event Types | 16 | Indian wedding types (Hindu, Muslim, Sikh, Christian, etc.) |
| Users | 57 | 2 admins, 8 agency owners, 31 vendors, 15 clients |
| Agencies | 8 | Wedding planning agencies across major cities |
| Vendors | 20 | Photographers, caterers, decorators, venues, etc. |
| Clients | 15 | Couples with realistic wedding details and budgets |
| Inquiries | 54 | Realistic conversation threads |
| Bookings | 62 | Various statuses (pending, confirmed, completed) |
| Reviews | 8 | Realistic reviews with ratings |
| Messages | 143 | Inquiry conversation messages |
| Services | 71 | Vendor service offerings |
| Packages | 84 | Agency and vendor packages |
| Seeder | Purpose |
|---|---|
CategorySeeder |
Wedding vendor categories (Photography, Venues, Catering, etc.) |
EventTypeSeeder |
Indian wedding event types |
DemoUserSeeder |
Admin, agency, vendor, and client user accounts |
DemoAgencySeeder |
Wedding planning agencies with packages and FAQs |
DemoVendorSeeder |
Vendors with services, packages, and realistic profiles |
DemoClientSeeder |
Couples with wedding details, budgets, and preferences |
DemoInquirySeeder |
Inquiry conversations between clients and vendors/agencies |
DemoBookingSeeder |
Bookings with payment details and various statuses |
DemoReviewSeeder |
Reviews with ratings and detailed feedback |
All seeders are idempotent - they check for existing data before inserting, making them safe to run multiple times without creating duplicates.
- Configure DB (
DB_*), queue (QUEUE_CONNECTION), mail (MAIL_*), storage (FILESYSTEM_DISK=public) in.envacross environments. - Always run
./vendor/bin/sail artisan storage:linkafter provisioning so media URLs work. - Queues: inquiries, notifications, and media conversions can move to queues—set
QUEUE_CONNECTION=databaseby default. - Monitoring: Laravel
/uphealth route is enabled for uptime checks.
Now that Phase 3/4 has provided rigid multitenancy, a robust booking state machine, and AI semantic search, our upcoming milestones are:
- Payment Gateway Integration (Razorpay / Stripe) – Transitioning the booking pipeline's
deposit_amounttracking into real-world automated financial transactions for the Indian market. - WebSockets / Laravel Reverb – Elevating the new Database Push Notifications into fully real-time typed chat interfaces between clients, agencies, and vendors.
- Advanced AI Tooling – Expanding the Gemini model from backend search parsing to frontend utility (e.g., an AI-generated personalized wedding itinerary for logged-in clients).
- Caching & Performance (Redis) – Caching heavy Livewire rendering and database API queries for
VendorsandAgenciesto prepare for high-traffic scalability. - Authenticated REST API (Sanctum) & Headless Expansion – Issuing tokens so agencies and vendors can utilize endpoints directly, allowing for a decoupled mobile app layer down the road.