+ );
+}
\ No newline at end of file
diff --git a/Front-end/src/pages/Venues.jsx b/Front-end/src/pages/Venues.jsx
new file mode 100644
index 000000000..4ee3384fd
--- /dev/null
+++ b/Front-end/src/pages/Venues.jsx
@@ -0,0 +1,232 @@
+import { useState, useEffect, useRef } from "react";
+import { useSearchParams } from "react-router-dom";
+import VenueCard from "../components/VenueCard";
+import SearchBar from "../components/SearchBar";
+import { venues } from "../services/Data";
+
+const TYPES = ["All", "Wedding", "Party", "Corporate", "Outdoor", "Birthday", "Reception"];
+const SORT_OPTIONS = ["Recommended", "Price: Low to High", "Price: High to Low", "Top Rated"];
+const AMENITIES = ["AC", "Parking", "Catering", "DJ", "Garden", "Bar", "WiFi", "Stage"];
+
+export default function Venues() {
+ const [searchParams] = useSearchParams();
+ const [filtered, setFiltered] = useState(venues);
+ const [activeType, setActiveType] = useState("All");
+ const [sortBy, setSortBy] = useState("Recommended");
+ const [maxPrice, setMaxPrice] = useState(200000);
+ const [selectedAmenities, setSelectedAmenities] = useState([]);
+ const [showSidebar, setShowSidebar] = useState(false);
+ const sidebarRef = useRef(null);
+
+ // Read URL params on mount
+ useEffect(() => {
+ const type = searchParams.get("type");
+ const q = searchParams.get("q");
+ if (type && type !== "all") {
+ const cap = type.charAt(0).toUpperCase() + type.slice(1);
+ setActiveType(cap);
+ }
+ }, [searchParams]);
+
+ // Apply filters
+ useEffect(() => {
+ let result = [...venues];
+ const q = searchParams.get("q");
+
+ if (activeType !== "All") result = result.filter(v => v.type.toLowerCase() === activeType.toLowerCase());
+ if (q) result = result.filter(v =>
+ v.name.toLowerCase().includes(q.toLowerCase()) ||
+ v.location.toLowerCase().includes(q.toLowerCase()) ||
+ v.city.toLowerCase().includes(q.toLowerCase())
+ );
+ result = result.filter(v => v.price <= maxPrice);
+ if (selectedAmenities.length > 0) {
+ result = result.filter(v => selectedAmenities.every(a => v.amenities?.includes(a)));
+ }
+ if (sortBy === "Price: Low to High") result.sort((a, b) => a.price - b.price);
+ else if (sortBy === "Price: High to Low") result.sort((a, b) => b.price - a.price);
+ else if (sortBy === "Top Rated") result.sort((a, b) => b.rating - a.rating);
+
+ setFiltered(result);
+ }, [activeType, sortBy, maxPrice, selectedAmenities, searchParams]);
+
+ const toggleAmenity = (a) => {
+ setSelectedAmenities(prev => prev.includes(a) ? prev.filter(x => x !== a) : [...prev, a]);
+ };
+
+ const clearAll = () => {
+ setActiveType("All");
+ setMaxPrice(200000);
+ setSelectedAmenities([]);
+ setSortBy("Recommended");
+ };
+
+ const activeFilterCount = [
+ activeType !== "All" ? 1 : 0,
+ maxPrice < 200000 ? 1 : 0,
+ selectedAmenities.length,
+ ].reduce((a, b) => a + b, 0);
+
+ return (
+
+ {/* Hero */}
+
+
Find Your Venue
+
Explore {venues.length}+ verified venues across India
+
+
+
+ {/* ── Inline Top Filter Bar ── */}
+
+
+
+ {/* Type Pills */}
+
+ {TYPES.map(t => (
+ setActiveType(t)}
+ >
+ {t}
+
+ ))}
+
+
+ {/* Divider */}
+
+
+ {/* Sort */}
+
setSortBy(e.target.value)}
+ >
+ {SORT_OPTIONS.map(o => {o} )}
+
+
+ {/* Price quick filter */}
+
+ Max ₹{(maxPrice / 1000).toFixed(0)}K
+ setMaxPrice(Number(e.target.value))}
+ className="price-quick-range"
+ />
+
+
+ {/* More Filters (opens sidebar) */}
+
setShowSidebar(s => !s)}
+ >
+ ⚙ Filters {activeFilterCount > 0 && {activeFilterCount} }
+
+
+ {/* Clear */}
+ {activeFilterCount > 0 && (
+
✕ Clear
+ )}
+
+
+
+ {/* Active filter chips */}
+ {(activeType !== "All" || selectedAmenities.length > 0 || maxPrice < 200000) && (
+
+ {activeType !== "All" && (
+ {activeType} setActiveType("All")}>✕
+ )}
+ {maxPrice < 200000 && (
+ ≤ ₹{(maxPrice/1000).toFixed(0)}K setMaxPrice(200000)}>✕
+ )}
+ {selectedAmenities.map(a => (
+ {a} toggleAmenity(a)}>✕
+ ))}
+
+ )}
+
+
+ {/* ── Slide-in Sidebar ── */}
+
+
+
More Filters
+ setShowSidebar(false)}>✕
+
+
+
+ Event Type
+ {TYPES.map(t => (
+ setActiveType(t)}
+ >
+ {t}
+
+ ))}
+
+
+
+
Max Budget
+
₹{maxPrice.toLocaleString()}
+
setMaxPrice(Number(e.target.value))}
+ className="range-input"
+ />
+
₹20K ₹2L
+
+
+
+
Amenities
+
+ {AMENITIES.map(a => (
+
+ toggleAmenity(a)}
+ />
+ {a}
+
+ ))}
+
+
+
+
+ Clear All
+ setShowSidebar(false)}>
+ Show {filtered.length} Results
+
+
+
+
+ {/* Overlay */}
+ {showSidebar &&
setShowSidebar(false)} />}
+
+ {/* ── Main Results ── */}
+
+
+ {filtered.length} venues found
+ {activeType !== "All" && ` for "${activeType}"`}
+
+
+ {filtered.length > 0 ? (
+
+ {filtered.map(v => )}
+
+ ) : (
+
+
😔
+
No venues found
+
Try adjusting your filters or search query
+
Clear Filters
+
+ )}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/Front-end/src/routes/AppRoutes.jsx b/Front-end/src/routes/AppRoutes.jsx
new file mode 100644
index 000000000..ba1711569
--- /dev/null
+++ b/Front-end/src/routes/AppRoutes.jsx
@@ -0,0 +1,24 @@
+import { Routes, Route } from "react-router-dom";
+import Home from "../pages/Home";
+import Venues from "../pages/Venues";
+import VenueDetails from "../pages/VenueDetails";
+import Login from "../pages/Login";
+import Register from "../pages/Register";
+import Booking from "../pages/Booking";
+import Admin from "../pages/Admin";
+import VenuePanel from "../pages/VenuePanel";
+
+export default function AppRoutes() {
+ return (
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+ );
+}
\ No newline at end of file
diff --git a/Front-end/src/services/Data.js b/Front-end/src/services/Data.js
new file mode 100644
index 000000000..a35ae447d
--- /dev/null
+++ b/Front-end/src/services/Data.js
@@ -0,0 +1,58 @@
+export const venues = [
+ // WEDDING
+ { id: 1, name: "The Grand Palace Banquet", type: "Wedding", city: "Bengaluru", location: "Indiranagar", capacity: "500 guests", price: 85000, rating: 4.8, reviews: 124, featured: true, image: "https://images.unsplash.com/photo-1519167758481-83f550bb49b3?w=600&q=80", amenities: ["AC", "Parking", "Catering", "DJ", "Decor", "Bridal Room"], description: "A luxurious banquet hall with elegant interiors, perfect for grand weddings and receptions.", images: ["https://images.unsplash.com/photo-1519167758481-83f550bb49b3?w=800&q=80","https://images.unsplash.com/photo-1464366400600-7168b8af9bc3?w=800&q=80"] },
+ { id: 4, name: "The Heritage Hall", type: "Wedding", city: "Delhi", location: "Connaught Place", capacity: "800 guests", price: 120000, rating: 4.9, reviews: 312, featured: true, image: "https://images.unsplash.com/photo-1510076857177-7470076d4098?w=600&q=80", amenities: ["AC", "Valet Parking", "Catering", "Bridal Room", "Stage", "Decor"], description: "A heritage property with timeless elegance hosting Delhi's most prestigious weddings.", images: ["https://images.unsplash.com/photo-1510076857177-7470076d4098?w=800&q=80"] },
+ { id: 6, name: "Pearl Banquet & Lawn", type: "Wedding", city: "Bengaluru", location: "Koramangala", capacity: "400 guests", price: 72000, rating: 4.6, reviews: 158, featured: false, image: "https://images.unsplash.com/photo-1511795409834-ef04bbd61622?w=600&q=80", amenities: ["Indoor + Lawn", "AC", "Catering", "DJ", "Parking", "Decor"], description: "An exquisite combination of indoor hall and outdoor lawn for your dream wedding.", images: ["https://images.unsplash.com/photo-1511795409834-ef04bbd61622?w=600&q=80"] },
+ { id: 7, name: "Royal Mahal Banquet", type: "Wedding", city: "Jaipur", location: "MI Road", capacity: "600 guests", price: 95000, rating: 4.7, reviews: 201, featured: false, image: "https://images.unsplash.com/photo-1519225421980-715cb0215aed?w=600&q=80", amenities: ["AC", "Parking", "Catering", "Stage", "Decor", "Bridal Room"], description: "Royal Rajasthani architecture meets modern luxury for an unforgettable wedding.", images: ["https://images.unsplash.com/photo-1519225421980-715cb0215aed?w=600&q=80"] },
+ { id: 8, name: "Lotus Terrace Weddings", type: "Wedding", city: "Mumbai", location: "Juhu", capacity: "350 guests", price: 110000, rating: 4.8, reviews: 175, featured: false, image: "https://images.unsplash.com/photo-1465495976277-4387d4b0b4c6?w=600&q=80", amenities: ["Sea View", "AC", "Catering", "DJ", "Valet Parking"], description: "Beachside wedding venue with stunning sea views and world-class catering.", images: ["https://images.unsplash.com/photo-1465495976277-4387d4b0b4c6?w=800&q=80"] },
+ { id: 9, name: "Bliss Convention Hall", type: "Wedding", city: "Chennai", location: "Anna Nagar", capacity: "700 guests", price: 78000, rating: 4.5, reviews: 143, featured: false, image: "https://images.unsplash.com/photo-1501281668745-f7f57925c3b4?w=600&q=80", amenities: ["AC", "Parking", "Catering", "Stage", "Decor"], description: "Chennai's most loved wedding hall with traditional decor and modern amenities.", images: ["https://images.unsplash.com/photo-1501281668745-f7f57925c3b4?w=800&q=80"] },
+ { id: 10, name: "Monarch Garden Estate", type: "Wedding", city: "Pune", location: "Baner", capacity: "450 guests", price: 68000, rating: 4.6, reviews: 112, featured: false, image: "https://images.unsplash.com/photo-1537633552985-df8429e8048b?w=600&q=80", amenities: ["Garden", "AC", "Catering", "DJ", "Parking"], description: "Lush garden estate perfect for intimate yet grand wedding celebrations.", images: ["https://images.unsplash.com/photo-1537633552985-df8429e8048b?w=800&q=80"] },
+
+ // PARTY
+ { id: 3, name: "Sky Lounge Events", type: "Party", city: "Mumbai", location: "Bandra", capacity: "200 guests", price: 55000, rating: 4.7, reviews: 203, featured: true, image: "https://images.unsplash.com/photo-1530103862676-de8c9debad1d?w=600&q=80", amenities: ["Rooftop", "Bar", "DJ", "AC", "Valet Parking"], description: "Mumbai's premier rooftop party venue with stunning skyline views.", images: ["https://images.unsplash.com/photo-1530103862676-de8c9debad1d?w=800&q=80"] },
+ { id: 11, name: "Neon Club & Party Hall", type: "Party", city: "Bengaluru", location: "Whitefield", capacity: "150 guests", price: 40000, rating: 4.5, reviews: 189, featured: false, image: "https://images.unsplash.com/photo-1547153760-18fc86324498?w=600&q=80", amenities: ["DJ", "Bar", "AC", "Dance Floor", "LED Lights"], description: "Electric party venue with pro DJ setup and vibrant lighting for unforgettable nights.", images: ["https://images.unsplash.com/photo-1547153760-18fc86324498?w=800&q=80"] },
+ { id: 12, name: "Breeze Poolside Venue", type: "Party", city: "Hyderabad", location: "Gachibowli", capacity: "120 guests", price: 45000, rating: 4.6, reviews: 97, featured: false, image: "https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=600&q=80", amenities: ["Pool", "Bar", "DJ", "Catering", "Parking"], description: "Stunning poolside venue for birthday parties and celebrations.", images: ["https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=800&q=80"] },
+ { id: 13, name: "The Loft Party Space", type: "Party", city: "Delhi", location: "Hauz Khas", capacity: "100 guests", price: 35000, rating: 4.4, reviews: 134, featured: false, image: "https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=600&q=80", amenities: ["DJ", "Bar", "Rooftop", "AC", "Decor"], description: "Trendy loft-style party space in the heart of Delhi's most vibrant neighborhood.", images: ["https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=800&q=80"] },
+ { id: 14, name: "Fiesta Banquet Hall", type: "Party", city: "Pune", location: "Kothrud", capacity: "250 guests", price: 50000, rating: 4.5, reviews: 88, featured: false, image: "https://images.unsplash.com/photo-1528605248644-14dd04022da1?w=600&q=80", amenities: ["AC", "DJ", "Catering", "Decor", "Parking"], description: "Spacious banquet hall built for lively parties and grand birthday celebrations.", images: ["https://images.unsplash.com/photo-1528605248644-14dd04022da1?w=800&q=80"] },
+ { id: 15, name: "Terrace 360 Events", type: "Party", city: "Chennai", location: "OMR", capacity: "180 guests", price: 42000, rating: 4.7, reviews: 115, featured: false, image: "https://images.unsplash.com/photo-1496337589254-7e19d01cec44?w=600&q=80", amenities: ["Rooftop", "DJ", "Bar", "AC", "Catering"], description: "360-degree city view rooftop perfect for parties and private events.", images: ["https://images.unsplash.com/photo-1496337589254-7e19d01cec44?w=800&q=80"] },
+
+ // CORPORATE
+ { id: 5, name: "TechPark Convention Center", type: "Corporate", city: "Hyderabad", location: "HITEC City", capacity: "1000 guests", price: 95000, rating: 4.5, reviews: 67, featured: true, image: "https://images.unsplash.com/photo-1587825140708-dfaf72ae4b04?w=600&q=80", amenities: ["AC", "AV Equipment", "WiFi", "Catering", "Parking", "Stage"], description: "A modern convention center for large-scale corporate events and conferences.", images: ["https://images.unsplash.com/photo-1587825140708-dfaf72ae4b04?w=800&q=80"] },
+ { id: 16, name: "Pinnacle Business Hub", type: "Corporate", city: "Bengaluru", location: "MG Road", capacity: "300 guests", price: 70000, rating: 4.6, reviews: 52, featured: false, image: "https://images.unsplash.com/photo-1515187029135-18ee286d815b?w=600&q=80", amenities: ["AC", "WiFi", "AV Setup", "Catering", "Parking"], description: "Premium corporate venue with cutting-edge AV tech for product launches and AGMs.", images: ["https://images.unsplash.com/photo-1515187029135-18ee286d815b?w=800&q=80"] },
+ { id: 17, name: "Skyline Conference Center", type: "Corporate", city: "Mumbai", location: "BKC", capacity: "500 guests", price: 115000, rating: 4.8, reviews: 78, featured: false, image: "https://images.unsplash.com/photo-1497366216548-37526070297c?w=600&q=80", amenities: ["AC", "WiFi", "Stage", "AV Equipment", "Catering", "Valet"], description: "BKC's most sought-after corporate events space with panoramic city views.", images: ["https://images.unsplash.com/photo-1497366216548-37526070297c?w=800&q=80"] },
+ { id: 18, name: "InnoSpace Events", type: "Corporate", city: "Delhi", location: "Aerocity", capacity: "200 guests", price: 60000, rating: 4.4, reviews: 43, featured: false, image: "https://images.unsplash.com/photo-1542744173-8e7e53415bb0?w=600&q=80", amenities: ["AC", "WiFi", "Projector", "Catering", "Parking"], description: "Modern event space near the airport, ideal for corporate off-sites and seminars.", images: ["https://images.unsplash.com/photo-1542744173-8e7e53415bb0?w=800&q=80"] },
+ { id: 19, name: "Metro Grand Auditorium", type: "Corporate", city: "Pune", location: "Hinjewadi", capacity: "800 guests", price: 85000, rating: 4.5, reviews: 61, featured: false, image: "https://images.unsplash.com/photo-1505373877841-8d25f7d46678?w=600&q=80", amenities: ["AC", "Stage", "AV Equipment", "WiFi", "Catering", "Parking"], description: "Massive auditorium-style venue perfect for large corporate gatherings.", images: ["https://images.unsplash.com/photo-1505373877841-8d25f7d46678?w=800&q=80"] },
+ { id: 20, name: "Catalyst Events Space", type: "Corporate", city: "Chennai", location: "Guindy", capacity: "150 guests", price: 48000, rating: 4.3, reviews: 39, featured: false, image: "https://images.unsplash.com/photo-1511578314322-379afb476865?w=600&q=80", amenities: ["AC", "WiFi", "AV Setup", "Catering"], description: "Compact and efficient corporate space for workshops, townhalls and team events.", images: ["https://images.unsplash.com/photo-1511578314322-379afb476865?w=800&q=80"] },
+
+ // OUTDOOR
+ { id: 2, name: "Serene Garden Villa", type: "Outdoor", city: "Bengaluru", location: "Whitefield", capacity: "300 guests", price: 65000, rating: 4.6, reviews: 89, featured: true, image: "https://images.unsplash.com/photo-1464366400600-7168b8af9bc3?w=600&q=80", amenities: ["Open Air", "Garden", "Parking", "Catering", "Decor"], description: "Beautiful outdoor garden venue surrounded by lush greenery.", images: ["https://images.unsplash.com/photo-1464366400600-7168b8af9bc3?w=800&q=80"] },
+ { id: 21, name: "Sunset Farmhouse", type: "Outdoor", city: "Jaipur", location: "Amer Road", capacity: "400 guests", price: 58000, rating: 4.7, reviews: 104, featured: false, image: "https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?w=600&q=80", amenities: ["Farm", "Open Air", "Catering", "Parking", "Decor"], description: "Rustic farmhouse with open lawns and golden-hour views for magical celebrations.", images: ["https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?w=800&q=80"] },
+ { id: 22, name: "Riverside Lawn & Resort", type: "Outdoor", city: "Pune", location: "Mulshi", capacity: "250 guests", price: 52000, rating: 4.5, reviews: 76, featured: false, image: "https://images.unsplash.com/photo-1504214208698-ea1916a2195a?w=600&q=80", amenities: ["Riverside", "Open Air", "Catering", "Parking", "Swimming Pool"], description: "Scenic riverside resort with lush lawns perfect for outdoor celebrations.", images: ["https://images.unsplash.com/photo-1504214208698-ea1916a2195a?w=800&q=80"] },
+ { id: 23, name: "Green Acres Event Park", type: "Outdoor", city: "Hyderabad", location: "Shamshabad", capacity: "600 guests", price: 62000, rating: 4.4, reviews: 91, featured: false, image: "https://images.unsplash.com/photo-1519225421980-715cb0215aed?w=600&q=80", amenities: ["Open Air", "Garden", "Stage", "Catering", "Parking"], description: "Vast open-air event park with manicured gardens and stage facilities.", images: ["https://images.unsplash.com/photo-1519225421980-715cb0215aed?w=800&q=80"] },
+ { id: 24, name: "Palm Grove Venue", type: "Outdoor", city: "Chennai", location: "ECR", capacity: "200 guests", price: 45000, rating: 4.6, reviews: 68, featured: false, image: "https://images.unsplash.com/photo-1470229722913-7c0e2dbbafd3?w=600&q=80", amenities: ["Beach Nearby", "Open Air", "Catering", "Parking"], description: "Tropical outdoor venue near the beach with swaying palms and ocean breeze.", images: ["https://images.unsplash.com/photo-1470229722913-7c0e2dbbafd3?w=800&q=80"] },
+
+ // BIRTHDAY
+ { id: 25, name: "Confetti Party Studio", type: "Birthday", city: "Bengaluru", location: "HSR Layout", capacity: "80 guests", price: 22000, rating: 4.8, reviews: 245, featured: false, image: "https://images.unsplash.com/photo-1530103862676-de8c9debad1d?w=600&q=80", amenities: ["Decor", "DJ", "AC", "Catering", "Photo Booth"], description: "Vibrant and colorful party studio perfect for birthday bashes big and small.", images: ["https://images.unsplash.com/photo-1530103862676-de8c9debad1d?w=800&q=80"] },
+ { id: 26, name: "Kids Wonder Party Hall", type: "Birthday", city: "Mumbai", location: "Andheri", capacity: "60 guests", price: 18000, rating: 4.7, reviews: 312, featured: false, image: "https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=600&q=80", amenities: ["Play Area", "AC", "Catering", "Decor", "Games"], description: "Magical themed party hall with play zones for kids' birthdays.", images: ["https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=800&q=80"] },
+ { id: 27, name: "The Bash Lounge", type: "Birthday", city: "Delhi", location: "Vasant Kunj", capacity: "120 guests", price: 32000, rating: 4.6, reviews: 178, featured: false, image: "https://images.unsplash.com/photo-1496337589254-7e19d01cec44?w=600&q=80", amenities: ["DJ", "Bar", "AC", "Decor", "Catering"], description: "Trendy lounge-style venue for adult birthdays and milestone celebrations.", images: ["https://images.unsplash.com/photo-1496337589254-7e19d01cec44?w=800&q=80"] },
+ { id: 28, name: "Celebration Corner", type: "Birthday", city: "Hyderabad", location: "Madhapur", capacity: "100 guests", price: 25000, rating: 4.5, reviews: 143, featured: false, image: "https://images.unsplash.com/photo-1527529482837-4698179dc6ce?w=600&q=80", amenities: ["Decor", "DJ", "AC", "Catering", "Parking"], description: "Cozy and beautifully decorated birthday venue for all age groups.", images: ["https://images.unsplash.com/photo-1527529482837-4698179dc6ce?w=800&q=80"] },
+ { id: 29, name: "Star Night Party Hall", type: "Birthday", city: "Pune", location: "Wakad", capacity: "90 guests", price: 20000, rating: 4.4, reviews: 98, featured: false, image: "https://images.unsplash.com/photo-1519671482749-fd09be7ccebf?w=600&q=80", amenities: ["LED Decor", "DJ", "AC", "Catering"], description: "Glittering star-themed party hall for unforgettable birthday nights.", images: ["https://images.unsplash.com/photo-1519671482749-fd09be7ccebf?w=800&q=80"] },
+ { id: 30, name: "Pixel Arcade Party", type: "Birthday", city: "Chennai", location: "T Nagar", capacity: "70 guests", price: 16000, rating: 4.6, reviews: 167, featured: false, image: "https://images.unsplash.com/photo-1575783970733-1aaedde1db74?w=600&q=80", amenities: ["Gaming Zone", "AC", "Catering", "DJ", "Decor"], description: "Gaming-themed birthday venue with arcade games and fun activities.", images: ["https://images.unsplash.com/photo-1575783970733-1aaedde1db74?w=800&q=80"] },
+
+ // RECEPTION
+ { id: 31, name: "Elysian Reception Hall", type: "Reception", city: "Bengaluru", location: "Jayanagar", capacity: "500 guests", price: 90000, rating: 4.8, reviews: 132, featured: false, image: "https://images.unsplash.com/photo-1478146059778-26ca6e370071?w=600&q=80", amenities: ["AC", "Stage", "Catering", "DJ", "Valet Parking", "Decor"], description: "Grand reception hall with golden chandeliers and impeccable service.", images: ["https://images.unsplash.com/photo-1478146059778-26ca6e370071?w=800&q=80"] },
+ { id: 32, name: "The Golden Ballroom", type: "Reception", city: "Mumbai", location: "Worli", capacity: "700 guests", price: 130000, rating: 4.9, reviews: 221, featured: false, image: "https://images.unsplash.com/photo-1519167758481-83f550bb49b3?w=600&q=80", amenities: ["AC", "Ballroom", "Catering", "DJ", "Valet", "Bar"], description: "Mumbai's most glamorous ballroom for the grandest reception celebrations.", images: ["https://images.unsplash.com/photo-1519167758481-83f550bb49b3?w=800&q=80"] },
+ { id: 33, name: "Sapphire Banquet", type: "Reception", city: "Delhi", location: "Dwarka", capacity: "400 guests", price: 75000, rating: 4.6, reviews: 156, featured: false, image: "https://images.unsplash.com/photo-1510076857177-7470076d4098?w=600&q=80", amenities: ["AC", "Stage", "Catering", "DJ", "Parking", "Decor"], description: "Elegant sapphire-themed banquet hall for elegant receptions.", images: ["https://images.unsplash.com/photo-1510076857177-7470076d4098?w=800&q=80"] },
+ { id: 34, name: "Ivory Palace Events", type: "Reception", city: "Hyderabad", location: "Banjara Hills", capacity: "600 guests", price: 105000, rating: 4.7, reviews: 189, featured: false, image: "https://images.unsplash.com/photo-1465495976277-4387d4b0b4c6?w=600&q=80", amenities: ["AC", "Ballroom", "Stage", "Catering", "Valet", "Decor"], description: "Palatial reception venue with ivory-white interiors and royal grandeur.", images: ["https://images.unsplash.com/photo-1465495976277-4387d4b0b4c6?w=800&q=80"] },
+ { id: 35, name: "Magnolia Event Center", type: "Reception", city: "Pune", location: "Aundh", capacity: "350 guests", price: 68000, rating: 4.5, reviews: 114, featured: false, image: "https://images.unsplash.com/photo-1501281668745-f7f57925c3b4?w=600&q=80", amenities: ["AC", "Stage", "Catering", "DJ", "Parking"], description: "Warm and welcoming reception hall with floral decor and excellent catering.", images: ["https://images.unsplash.com/photo-1501281668745-f7f57925c3b4?w=800&q=80"] },
+ { id: 36, name: "Crimson Hall", type: "Reception", city: "Chennai", location: "Velachery", capacity: "450 guests", price: 72000, rating: 4.6, reviews: 137, featured: false, image: "https://images.unsplash.com/photo-1537633552985-df8429e8048b?w=600&q=80", amenities: ["AC", "Stage", "Catering", "DJ", "Valet", "Decor"], description: "Vibrant crimson-themed reception hall for celebrations full of color.", images: ["https://images.unsplash.com/photo-1537633552985-df8429e8048b?w=800&q=80"] },
+];
+
+export const eventCategories = [
+ { id: "wedding", label: "Wedding", icon: "💍", count: 128 },
+ { id: "party", label: "Party", icon: "🎉", count: 95 },
+ { id: "corporate", label: "Corporate", icon: "🏢", count: 72 },
+ { id: "outdoor", label: "Outdoor", icon: "🌿", count: 43 },
+ { id: "birthday", label: "Birthday", icon: "🎂", count: 87 },
+ { id: "reception", label: "Reception", icon: "🥂", count: 64 },
+];
\ No newline at end of file
diff --git a/Front-end/src/services/api.js b/Front-end/src/services/api.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/Front-end/vite.config.js b/Front-end/vite.config.js
new file mode 100644
index 000000000..3e34260e6
--- /dev/null
+++ b/Front-end/vite.config.js
@@ -0,0 +1,6 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+export default defineConfig({
+ plugins: [react()],
+})
\ No newline at end of file
diff --git a/backend/.gitattributes b/backend/.gitattributes
new file mode 100644
index 000000000..3b41682ac
--- /dev/null
+++ b/backend/.gitattributes
@@ -0,0 +1,2 @@
+/mvnw text eol=lf
+*.cmd text eol=crlf
diff --git a/backend/.gitignore b/backend/.gitignore
new file mode 100644
index 000000000..a80d47bcb
--- /dev/null
+++ b/backend/.gitignore
@@ -0,0 +1,34 @@
+HELP.md
+target/
+.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+.idea/
\ No newline at end of file
diff --git a/backend/.mvn/wrapper/maven-wrapper.properties b/backend/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 000000000..216df0589
--- /dev/null
+++ b/backend/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,3 @@
+wrapperVersion=3.3.4
+distributionType=only-script
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.16/apache-maven-3.9.16-bin.zip
diff --git a/backend/mvnw b/backend/mvnw
new file mode 100644
index 000000000..bd8896bf2
--- /dev/null
+++ b/backend/mvnw
@@ -0,0 +1,295 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.3.4
+#
+# Optional ENV vars
+# -----------------
+# JAVA_HOME - location of a JDK home dir, required when download maven via java source
+# MVNW_REPOURL - repo url base for downloading maven distribution
+# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
+# ----------------------------------------------------------------------------
+
+set -euf
+[ "${MVNW_VERBOSE-}" != debug ] || set -x
+
+# OS specific support.
+native_path() { printf %s\\n "$1"; }
+case "$(uname)" in
+CYGWIN* | MINGW*)
+ [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
+ native_path() { cygpath --path --windows "$1"; }
+ ;;
+esac
+
+# set JAVACMD and JAVACCMD
+set_java_home() {
+ # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
+ if [ -n "${JAVA_HOME-}" ]; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ]; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACCMD="$JAVA_HOME/jre/sh/javac"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ JAVACCMD="$JAVA_HOME/bin/javac"
+
+ if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
+ echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
+ echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
+ return 1
+ fi
+ fi
+ else
+ JAVACMD="$(
+ 'set' +e
+ 'unset' -f command 2>/dev/null
+ 'command' -v java
+ )" || :
+ JAVACCMD="$(
+ 'set' +e
+ 'unset' -f command 2>/dev/null
+ 'command' -v javac
+ )" || :
+
+ if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
+ echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
+ return 1
+ fi
+ fi
+}
+
+# hash string like Java String::hashCode
+hash_string() {
+ str="${1:-}" h=0
+ while [ -n "$str" ]; do
+ char="${str%"${str#?}"}"
+ h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
+ str="${str#?}"
+ done
+ printf %x\\n $h
+}
+
+verbose() { :; }
+[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
+
+die() {
+ printf %s\\n "$1" >&2
+ exit 1
+}
+
+trim() {
+ # MWRAPPER-139:
+ # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
+ # Needed for removing poorly interpreted newline sequences when running in more
+ # exotic environments such as mingw bash on Windows.
+ printf "%s" "${1}" | tr -d '[:space:]'
+}
+
+scriptDir="$(dirname "$0")"
+scriptName="$(basename "$0")"
+
+# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
+while IFS="=" read -r key value; do
+ case "${key-}" in
+ distributionUrl) distributionUrl=$(trim "${value-}") ;;
+ distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
+ esac
+done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
+[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
+
+case "${distributionUrl##*/}" in
+maven-mvnd-*bin.*)
+ MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
+ case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
+ *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
+ :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
+ :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
+ :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
+ *)
+ echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
+ distributionPlatform=linux-amd64
+ ;;
+ esac
+ distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
+ ;;
+maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
+*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
+esac
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-
,maven-mvnd--}/
+[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
+distributionUrlName="${distributionUrl##*/}"
+distributionUrlNameMain="${distributionUrlName%.*}"
+distributionUrlNameMain="${distributionUrlNameMain%-bin}"
+MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
+MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
+
+exec_maven() {
+ unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
+ exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
+}
+
+if [ -d "$MAVEN_HOME" ]; then
+ verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+ exec_maven "$@"
+fi
+
+case "${distributionUrl-}" in
+*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
+*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
+esac
+
+# prepare tmp dir
+if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
+ clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
+ trap clean HUP INT TERM EXIT
+else
+ die "cannot create temp dir"
+fi
+
+mkdir -p -- "${MAVEN_HOME%/*}"
+
+# Download and Install Apache Maven
+verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+verbose "Downloading from: $distributionUrl"
+verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+# select .zip or .tar.gz
+if ! command -v unzip >/dev/null; then
+ distributionUrl="${distributionUrl%.zip}.tar.gz"
+ distributionUrlName="${distributionUrl##*/}"
+fi
+
+# verbose opt
+__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
+[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
+
+# normalize http auth
+case "${MVNW_PASSWORD:+has-password}" in
+'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+esac
+
+if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
+ verbose "Found wget ... using wget"
+ wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
+elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
+ verbose "Found curl ... using curl"
+ curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
+elif set_java_home; then
+ verbose "Falling back to use Java to download"
+ javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
+ targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
+ cat >"$javaSource" <<-END
+ public class Downloader extends java.net.Authenticator
+ {
+ protected java.net.PasswordAuthentication getPasswordAuthentication()
+ {
+ return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
+ }
+ public static void main( String[] args ) throws Exception
+ {
+ setDefault( new Downloader() );
+ java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
+ }
+ }
+ END
+ # For Cygwin/MinGW, switch paths to Windows format before running javac and java
+ verbose " - Compiling Downloader.java ..."
+ "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
+ verbose " - Running Downloader.java ..."
+ "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
+fi
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+if [ -n "${distributionSha256Sum-}" ]; then
+ distributionSha256Result=false
+ if [ "$MVN_CMD" = mvnd.sh ]; then
+ echo "Checksum validation is not supported for maven-mvnd." >&2
+ echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+ exit 1
+ elif command -v sha256sum >/dev/null; then
+ if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then
+ distributionSha256Result=true
+ fi
+ elif command -v shasum >/dev/null; then
+ if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
+ distributionSha256Result=true
+ fi
+ else
+ echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
+ echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+ exit 1
+ fi
+ if [ $distributionSha256Result = false ]; then
+ echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
+ echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
+ exit 1
+ fi
+fi
+
+# unzip and move
+if command -v unzip >/dev/null; then
+ unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
+else
+ tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
+fi
+
+# Find the actual extracted directory name (handles snapshots where filename != directory name)
+actualDistributionDir=""
+
+# First try the expected directory name (for regular distributions)
+if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
+ if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
+ actualDistributionDir="$distributionUrlNameMain"
+ fi
+fi
+
+# If not found, search for any directory with the Maven executable (for snapshots)
+if [ -z "$actualDistributionDir" ]; then
+ # enable globbing to iterate over items
+ set +f
+ for dir in "$TMP_DOWNLOAD_DIR"/*; do
+ if [ -d "$dir" ]; then
+ if [ -f "$dir/bin/$MVN_CMD" ]; then
+ actualDistributionDir="$(basename "$dir")"
+ break
+ fi
+ fi
+ done
+ set -f
+fi
+
+if [ -z "$actualDistributionDir" ]; then
+ verbose "Contents of $TMP_DOWNLOAD_DIR:"
+ verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
+ die "Could not find Maven distribution directory in extracted archive"
+fi
+
+verbose "Found extracted Maven distribution directory: $actualDistributionDir"
+printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
+mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
+
+clean || :
+exec_maven "$@"
diff --git a/backend/mvnw.cmd b/backend/mvnw.cmd
new file mode 100644
index 000000000..92450f932
--- /dev/null
+++ b/backend/mvnw.cmd
@@ -0,0 +1,189 @@
+<# : batch portion
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.3.4
+@REM
+@REM Optional ENV vars
+@REM MVNW_REPOURL - repo url base for downloading maven distribution
+@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
+@REM ----------------------------------------------------------------------------
+
+@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
+@SET __MVNW_CMD__=
+@SET __MVNW_ERROR__=
+@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
+@SET PSModulePath=
+@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
+ IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
+)
+@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
+@SET __MVNW_PSMODULEP_SAVE=
+@SET __MVNW_ARG0_NAME__=
+@SET MVNW_USERNAME=
+@SET MVNW_PASSWORD=
+@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
+@echo Cannot start maven from wrapper >&2 && exit /b 1
+@GOTO :EOF
+: end batch / begin powershell #>
+
+$ErrorActionPreference = "Stop"
+if ($env:MVNW_VERBOSE -eq "true") {
+ $VerbosePreference = "Continue"
+}
+
+# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
+$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
+if (!$distributionUrl) {
+ Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
+}
+
+switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
+ "maven-mvnd-*" {
+ $USE_MVND = $true
+ $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
+ $MVN_CMD = "mvnd.cmd"
+ break
+ }
+ default {
+ $USE_MVND = $false
+ $MVN_CMD = $script -replace '^mvnw','mvn'
+ break
+ }
+}
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/
+if ($env:MVNW_REPOURL) {
+ $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" }
+ $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')"
+}
+$distributionUrlName = $distributionUrl -replace '^.*/',''
+$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
+
+$MAVEN_M2_PATH = "$HOME/.m2"
+if ($env:MAVEN_USER_HOME) {
+ $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
+}
+
+if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
+ New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
+}
+
+$MAVEN_WRAPPER_DISTS = $null
+if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
+ $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
+} else {
+ $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
+}
+
+$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
+$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
+$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
+
+if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
+ Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+ Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
+ exit $?
+}
+
+if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
+ Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
+}
+
+# prepare tmp dir
+$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
+$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
+$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
+trap {
+ if ($TMP_DOWNLOAD_DIR.Exists) {
+ try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+ catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+ }
+}
+
+New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
+
+# Download and Install Apache Maven
+Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+Write-Verbose "Downloading from: $distributionUrl"
+Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+$webclient = New-Object System.Net.WebClient
+if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
+ $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
+}
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
+if ($distributionSha256Sum) {
+ if ($USE_MVND) {
+ Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
+ }
+ Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
+ if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
+ Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
+ }
+}
+
+# unzip and move
+Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
+
+# Find the actual extracted directory name (handles snapshots where filename != directory name)
+$actualDistributionDir = ""
+
+# First try the expected directory name (for regular distributions)
+$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
+$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
+if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
+ $actualDistributionDir = $distributionUrlNameMain
+}
+
+# If not found, search for any directory with the Maven executable (for snapshots)
+if (!$actualDistributionDir) {
+ Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
+ $testPath = Join-Path $_.FullName "bin/$MVN_CMD"
+ if (Test-Path -Path $testPath -PathType Leaf) {
+ $actualDistributionDir = $_.Name
+ }
+ }
+}
+
+if (!$actualDistributionDir) {
+ Write-Error "Could not find Maven distribution directory in extracted archive"
+}
+
+Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
+Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null
+try {
+ Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
+} catch {
+ if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
+ Write-Error "fail to move MAVEN_HOME"
+ }
+} finally {
+ try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+ catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+}
+
+Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
diff --git a/backend/pom.xml b/backend/pom.xml
new file mode 100644
index 000000000..25a142438
--- /dev/null
+++ b/backend/pom.xml
@@ -0,0 +1,164 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.5.14
+
+
+ com.bookmyvenue
+ backend
+ 0.0.1-SNAPSHOT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 21
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.postgresql
+ postgresql
+ runtime
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+
+
+ org.mapstruct
+ mapstruct
+ 1.5.5.Final
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-ui
+ 2.8.9
+
+
+
+
+ com.auth0
+ java-jwt
+ 4.5.2
+ compile
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ default-compile
+ compile
+
+ compile
+
+
+
+
+ org.projectlombok
+ lombok
+
+
+ org.mapstruct
+ mapstruct-processor
+ 1.5.5.Final
+
+
+
+
+
+ default-testCompile
+ test-compile
+
+ testCompile
+
+
+
+
+ org.projectlombok
+ lombok
+
+
+ org.mapstruct
+ mapstruct-processor
+ 1.5.5.Final
+
+
+
+
+
+
+
+
+
+
diff --git a/backend/src/main/java/com/bookmyvenue/backend/BackendApplication.java b/backend/src/main/java/com/bookmyvenue/backend/BackendApplication.java
new file mode 100644
index 000000000..b74b600a1
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/BackendApplication.java
@@ -0,0 +1,13 @@
+package com.bookmyvenue.backend;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class BackendApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(BackendApplication.class, args);
+ }
+
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/config/SecurityConfiguration.java b/backend/src/main/java/com/bookmyvenue/backend/config/SecurityConfiguration.java
new file mode 100644
index 000000000..846cdfc48
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/config/SecurityConfiguration.java
@@ -0,0 +1,77 @@
+package com.bookmyvenue.backend.config;
+
+import com.bookmyvenue.backend.service.CustomUserDetailsService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+@Configuration
+@EnableWebSecurity
+@RequiredArgsConstructor
+public class SecurityConfiguration {
+
+ private final JwtAuthenticationFilter jwtAuthenticationFilter;
+ private final CustomUserDetailsService customUserDetailsService;
+
+ @Bean
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+
+ http.csrf(csrf->csrf.disable());
+
+ http.sessionManagement(session->
+ session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
+
+ http.authorizeHttpRequests(authorize->
+ authorize
+ .requestMatchers(
+ "/error",
+ "/swagger-ui/**",
+ "/swagger-ui.html",
+ "/api-docs/**",
+ "/api-docs"
+ ).permitAll()
+ .requestMatchers("/api/auth/**")
+ .permitAll()
+
+ .anyRequest().authenticated()
+ );
+
+ http.authenticationProvider(authenticationProvider());
+
+ http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
+
+ return http.build();
+ }
+
+ @Bean
+ public AuthenticationProvider authenticationProvider(){
+
+ DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
+ authenticationProvider.setUserDetailsService(customUserDetailsService);
+ authenticationProvider.setPasswordEncoder(passwordEncoder());
+
+ return authenticationProvider;
+ }
+
+ @Bean
+ public AuthenticationManager authenticationManager(
+ AuthenticationConfiguration authenticationConfiguration)
+ throws Exception {
+ return authenticationConfiguration.getAuthenticationManager();
+
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/config/SwaggerConfiguration.java b/backend/src/main/java/com/bookmyvenue/backend/config/SwaggerConfiguration.java
new file mode 100644
index 000000000..a80b097ab
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/config/SwaggerConfiguration.java
@@ -0,0 +1,43 @@
+package com.bookmyvenue.backend.config;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.info.Contact;
+import io.swagger.v3.oas.models.info.License;
+import io.swagger.v3.oas.models.security.SecurityRequirement;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import io.swagger.v3.oas.models.servers.Server;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class SwaggerConfiguration {
+
+ @Bean
+ public OpenAPI customOpenAPI() {
+ final String securityScheme = "BearerAuth";
+ return new OpenAPI()
+ .addServersItem(new Server()
+ .url("http://localhost:8080")
+ .description("Local Development Server"))
+ .addSecurityItem(new SecurityRequirement().addList(securityScheme))
+ .components(new Components()
+ .addSecuritySchemes(securityScheme,new SecurityScheme()
+ .type(SecurityScheme.Type.HTTP)
+ .scheme("bearer")
+ .bearerFormat("JWT")))
+ .info(new Info()
+ .title("BookMyVenue API")
+ .version("1.0.0")
+ .description("Comprehensive API documentation for BookMyVenue backend application. " +
+ "This API provides endpoints for managing venue categories, bookings, and related operations.")
+ .contact(new Contact()
+ .name("BookMyVenue Team")
+ .email("support@bookmyvenue.com")
+ .url("https://www.bookmyvenue.com"))
+ .license(new License()
+ .name("Apache 2.0")
+ .url("https://www.apache.org/licenses/LICENSE-2.0.html")));
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/AdminDashboardController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/AdminDashboardController.java
new file mode 100644
index 000000000..3f48c5418
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/AdminDashboardController.java
@@ -0,0 +1,4 @@
+package com.bookmyvenue.backend.controller;
+
+public class AdminDashboardController {
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/AdminRequestController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/AdminRequestController.java
new file mode 100644
index 000000000..43f97f527
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/AdminRequestController.java
@@ -0,0 +1,83 @@
+package com.bookmyvenue.backend.controller;
+import com.bookmyvenue.backend.dto.adminDashboard.AdminRequestResponse;
+import com.bookmyvenue.backend.dto.adminDashboard.AdminRequestSearchRequest;
+import com.bookmyvenue.backend.service.AdminRequestService;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/admin/requests")
+@RequiredArgsConstructor
+@Tag(name = "Admin Requests")
+public class AdminRequestController {
+
+ private final
+ AdminRequestService adminRequestService;
+
+ @GetMapping
+ public ResponseEntity<
+ List>
+ getAllRequests() {
+
+ return ResponseEntity.ok(
+ adminRequestService
+ .getAllRequests());
+ }
+
+ @GetMapping("/{venueId}")
+ public ResponseEntity<
+ AdminRequestResponse>
+ getRequestDetails(
+ @PathVariable Long venueId) {
+
+ return ResponseEntity.ok(
+ adminRequestService
+ .getRequestDetails(
+ venueId));
+ }
+
+ @PostMapping("/search")
+ public ResponseEntity<
+ List>
+ searchRequests(
+ @RequestBody
+ AdminRequestSearchRequest request) {
+
+ return ResponseEntity.ok(
+ adminRequestService
+ .searchRequests(
+ request));
+ }
+
+ @PatchMapping("/{venueId}/approve")
+ public ResponseEntity<
+ AdminRequestResponse>
+ approveRequest(
+ @PathVariable Long venueId,
+ @RequestParam String remarks) {
+
+ return ResponseEntity.ok(
+ adminRequestService
+ .approveRequest(
+ venueId,
+ remarks));
+ }
+
+ @PatchMapping("/{venueId}/reject")
+ public ResponseEntity<
+ AdminRequestResponse>
+ rejectRequest(
+ @PathVariable Long venueId,
+ @RequestParam String remarks) {
+
+ return ResponseEntity.ok(
+ adminRequestService
+ .rejectRequest(
+ venueId,
+ remarks));
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/AdminUserController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/AdminUserController.java
new file mode 100644
index 000000000..462ce85b7
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/AdminUserController.java
@@ -0,0 +1,67 @@
+package com.bookmyvenue.backend.controller;
+
+import com.bookmyvenue.backend.dto.adminDashboard.AdminUserResponse;
+import com.bookmyvenue.backend.service.AdminUserService;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/admin/users")
+@RequiredArgsConstructor
+@Tag(name = "Admin User Management")
+public class AdminUserController {
+
+ private final AdminUserService adminUserService;
+
+ @GetMapping
+ public ResponseEntity>
+ getAllUsers() {
+
+ return ResponseEntity.ok(
+ adminUserService.getAllUsers());
+ }
+
+ @GetMapping("/{userId}")
+ public ResponseEntity
+ getUserById(
+ @PathVariable Long userId) {
+
+ return ResponseEntity.ok(
+ adminUserService
+ .getUserById(userId));
+ }
+
+ @GetMapping("/search")
+ public ResponseEntity>
+ searchUsers(
+ @RequestParam String keyword) {
+
+ return ResponseEntity.ok(
+ adminUserService
+ .searchUsers(keyword));
+ }
+
+ @PatchMapping("/{userId}/suspend")
+ public ResponseEntity
+ suspendUser(
+ @PathVariable Long userId) {
+
+ return ResponseEntity.ok(
+ adminUserService
+ .suspendUser(userId));
+ }
+
+ @PatchMapping("/{userId}/activate")
+ public ResponseEntity
+ activateUser(
+ @PathVariable Long userId) {
+
+ return ResponseEntity.ok(
+ adminUserService
+ .activateUser(userId));
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/AdminVenueOwnerController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/AdminVenueOwnerController.java
new file mode 100644
index 000000000..2519e596a
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/AdminVenueOwnerController.java
@@ -0,0 +1,66 @@
+package com.bookmyvenue.backend.controller;
+
+import com.bookmyvenue.backend.dto.adminDashboard.AdminVenueOwnerResponse;
+import com.bookmyvenue.backend.dto.adminDashboard.AdminVenueOwnerSearchRequest;
+import com.bookmyvenue.backend.service.AdminVenueOwnerService;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/admin/venue-owners")
+@RequiredArgsConstructor
+@Tag(name = "Admin Venue Owner Management")
+public class AdminVenueOwnerController {
+
+ private final
+ AdminVenueOwnerService service;
+
+ @GetMapping
+ public ResponseEntity>
+ getAllVenueOwners() {
+
+ return ResponseEntity.ok(
+ service.getAllVenueOwners());
+ }
+
+ @GetMapping("/{ownerId}")
+ public ResponseEntity
+ getVenueOwnerById(
+ @PathVariable Long ownerId) {
+
+ return ResponseEntity.ok(
+ service.getVenueOwnerById(ownerId));
+ }
+
+ @PostMapping("/search")
+ public ResponseEntity>
+ searchVenueOwners(
+ @RequestBody
+ AdminVenueOwnerSearchRequest request) {
+
+ return ResponseEntity.ok(
+ service.searchVenueOwners(request));
+ }
+
+ @PatchMapping("/{ownerId}/verify")
+ public ResponseEntity
+ verifyVenueOwner(
+ @PathVariable Long ownerId) {
+
+ return ResponseEntity.ok(
+ service.verifyVenueOwner(ownerId));
+ }
+
+ @PatchMapping("/{ownerId}/suspend")
+ public ResponseEntity
+ suspendVenueOwner(
+ @PathVariable Long ownerId) {
+
+ return ResponseEntity.ok(
+ service.suspendVenueOwner(ownerId));
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/AmenityController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/AmenityController.java
new file mode 100644
index 000000000..8012d8ff9
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/AmenityController.java
@@ -0,0 +1,132 @@
+package com.bookmyvenue.backend.controller;
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityRequest;
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityResponse;
+import com.bookmyvenue.backend.service.AmenityService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/amenities")
+@RequiredArgsConstructor
+@Tag(name = "Amenities", description = "APIs for managing amenities")
+public class AmenityController {
+
+ private final AmenityService amenityService;
+
+ @PostMapping
+ @Operation(
+ summary = "Create Amenity",
+ description = "Creates a new amenity"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "201",
+ description = "Amenity created successfully",
+ content = @Content(
+ mediaType = "application/json",
+ schema = @Schema(implementation = AmenityResponse.class))),
+ @ApiResponse(responseCode = "400",
+ description = "Invalid request")
+ })
+ public ResponseEntity createAmenity(
+ @Valid
+ @RequestBody AmenityRequest request) {
+
+ return ResponseEntity.status(HttpStatus.CREATED)
+ .body(amenityService.createAmenity(request));
+ }
+
+ @GetMapping("/{id}")
+ @Operation(
+ summary = "Get Amenity By ID",
+ description = "Retrieves an amenity by its ID"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200",
+ description = "Amenity found",
+ content = @Content(
+ mediaType = "application/json",
+ schema = @Schema(implementation = AmenityResponse.class))),
+ @ApiResponse(responseCode = "404",
+ description = "Amenity not found")
+ })
+ public ResponseEntity getAmenityById(
+ @Parameter(description = "Amenity ID", required = true)
+ @PathVariable Long id) {
+
+ return ResponseEntity.ok(
+ amenityService.getAmenityById(id));
+ }
+
+ @GetMapping
+ @Operation(
+ summary = "Get All Amenities",
+ description = "Retrieves all amenities"
+ )
+ @ApiResponse(responseCode = "200",
+ description = "List of amenities",
+ content = @Content(
+ mediaType = "application/json",
+ schema = @Schema(implementation = AmenityResponse.class)))
+ public ResponseEntity> getAllAmenities() {
+
+ return ResponseEntity.ok(
+ amenityService.getAllAmenities());
+ }
+
+ @PutMapping("/{id}")
+ @Operation(
+ summary = "Update Amenity",
+ description = "Updates an existing amenity"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200",
+ description = "Amenity updated successfully",
+ content = @Content(
+ mediaType = "application/json",
+ schema = @Schema(implementation = AmenityResponse.class))),
+ @ApiResponse(responseCode = "404",
+ description = "Amenity not found"),
+ @ApiResponse(responseCode = "400",
+ description = "Invalid request")
+ })
+ public ResponseEntity updateAmenity(
+ @Parameter(description = "Amenity ID", required = true)
+ @PathVariable Long id,
+ @Valid
+ @RequestBody AmenityRequest request) {
+
+ return ResponseEntity.ok(
+ amenityService.updateAmenity(id, request));
+ }
+
+ @DeleteMapping("/{id}")
+ @Operation(
+ summary = "Delete Amenity",
+ description = "Deletes an amenity by ID"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "204",
+ description = "Amenity deleted successfully"),
+ @ApiResponse(responseCode = "404",
+ description = "Amenity not found")
+ })
+ public ResponseEntity deleteAmenity(
+ @Parameter(description = "Amenity ID", required = true)
+ @PathVariable Long id) {
+
+ amenityService.deleteAmenity(id);
+
+ return ResponseEntity.noContent().build();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/AuthenticationController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/AuthenticationController.java
new file mode 100644
index 000000000..d7dd760ee
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/AuthenticationController.java
@@ -0,0 +1,36 @@
+package com.bookmyvenue.backend.controller;
+import com.bookmyvenue.backend.dto.authentication.LoginRequest;
+import com.bookmyvenue.backend.dto.authentication.LoginResponse;
+import com.bookmyvenue.backend.dto.authentication.RegisterRequest;
+import com.bookmyvenue.backend.dto.authentication.RegisterResponse;
+import com.bookmyvenue.backend.service.AuthenticationService;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/api/auth")
+@RequiredArgsConstructor
+public class AuthenticationController {
+
+ private final AuthenticationService authenticationService;
+
+ @PostMapping("/register")
+ public ResponseEntity register(
+ @Valid @RequestBody RegisterRequest registerRequest){
+
+ RegisterResponse registerResponse = authenticationService.register(registerRequest);
+
+ return ResponseEntity.status(HttpStatus.CREATED).body(registerResponse);
+
+ }
+
+ @PostMapping("/login")
+ public ResponseEntity login(
+ @Valid @RequestBody LoginRequest loginRequest){
+ LoginResponse loginResponse = authenticationService.login(loginRequest);
+ return ResponseEntity.status(HttpStatus.OK).body(loginResponse);
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/BookingController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/BookingController.java
new file mode 100644
index 000000000..178953e0b
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/BookingController.java
@@ -0,0 +1,106 @@
+package com.bookmyvenue.backend.controller;
+import com.bookmyvenue.backend.dto.Book.BookingRequest;
+import com.bookmyvenue.backend.dto.Book.BookingResponse;
+import com.bookmyvenue.backend.dto.Book.BookingStatusRequest;
+import com.bookmyvenue.backend.service.BookingService;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import java.util.List;
+
+@RestController
+ @RequestMapping("/api/bookings")
+ @RequiredArgsConstructor
+ @Tag(name = "Booking Management")
+ public class BookingController {
+
+ private final BookingService bookingService;
+
+ @PostMapping
+ public ResponseEntity
+ createBooking(
+ @RequestBody
+ BookingRequest request) {
+
+ return ResponseEntity.ok(
+ bookingService.createBooking(
+ request));
+ }
+
+ @GetMapping("/{bookingId}")
+ public ResponseEntity
+ getBooking(
+ @PathVariable Long bookingId) {
+
+ return ResponseEntity.ok(
+ bookingService.getBookingById(
+ bookingId));
+ }
+
+ @GetMapping
+ public ResponseEntity>
+ getAllBookings() {
+
+ return ResponseEntity.ok(
+ bookingService.getAllBookings());
+ }
+
+ @GetMapping("/user/{userId}")
+ public ResponseEntity>
+ getBookingsByUser(
+ @PathVariable Long userId) {
+
+ return ResponseEntity.ok(
+ bookingService.getBookingsByUser(
+ userId));
+ }
+
+ @GetMapping("/owner/{ownerId}")
+ public ResponseEntity>
+ getBookingsByOwner(
+ @PathVariable Long ownerId) {
+
+ return ResponseEntity.ok(
+ bookingService.getBookingsByOwner(
+ ownerId));
+ }
+
+ @PatchMapping("/{bookingId}/status")
+ public ResponseEntity
+ updateStatus(
+ @PathVariable Long bookingId,
+ @RequestBody
+ BookingStatusRequest request) {
+
+ return ResponseEntity.ok(
+ bookingService
+ .updateBookingStatus(
+ bookingId,
+ request));
+ }
+
+ @PutMapping("/{bookingId}/cancel")
+ public ResponseEntity
+ cancelBooking(
+ @PathVariable Long bookingId) {
+
+ bookingService.cancelBooking(
+ bookingId);
+
+ return ResponseEntity.noContent()
+ .build();
+ }
+
+ @PostMapping("/search")
+ public ResponseEntity>
+ searchBookings(
+ @RequestBody
+ BookingRequest request) {
+
+ return ResponseEntity.ok(
+ bookingService.searchBookings(
+ request));
+ }
+ }
+
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/PaymentController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/PaymentController.java
new file mode 100644
index 000000000..f09e4b42f
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/PaymentController.java
@@ -0,0 +1,48 @@
+package com.bookmyvenue.backend.controller;
+
+import com.bookmyvenue.backend.dto.payment.PaymentRequestDTO;
+import com.bookmyvenue.backend.dto.payment.PaymentResponseDTO;
+import com.bookmyvenue.backend.dto.payment.PaymentUpdateDTO;
+import com.bookmyvenue.backend.service.PaymentService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/payments")
+@RequiredArgsConstructor
+public class PaymentController {
+
+ private final PaymentService paymentService;
+
+ @PostMapping
+ public ResponseEntity createPayment(
+ @RequestBody PaymentRequestDTO request) {
+ return ResponseEntity.ok(paymentService.createPayment(request));
+ }
+
+ @GetMapping("/{id}")
+ public ResponseEntity getById(@PathVariable Long id) {
+ return ResponseEntity.ok(paymentService.getPaymentById(id));
+ }
+
+ @GetMapping("/booking/{bookingId}")
+ public ResponseEntity> getByBooking(@PathVariable Long bookingId) {
+ return ResponseEntity.ok(paymentService.getPaymentsByBookingId(bookingId));
+ }
+
+ @PutMapping("/{id}")
+ public ResponseEntity update(
+ @PathVariable Long id,
+ @RequestBody PaymentUpdateDTO request) {
+ return ResponseEntity.ok(paymentService.updatePayment(id, request));
+ }
+
+ @DeleteMapping("/{id}")
+ public ResponseEntity delete(@PathVariable Long id) {
+ paymentService.deletePayment(id);
+ return ResponseEntity.noContent().build();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/VenueAvailabilityController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/VenueAvailabilityController.java
new file mode 100644
index 000000000..6c061e2c9
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/VenueAvailabilityController.java
@@ -0,0 +1,78 @@
+package com.bookmyvenue.backend.controller;
+import com.bookmyvenue.backend.dto.venuAvailability.VenueAvailabilityRequest;
+import com.bookmyvenue.backend.dto.venuAvailability.VenueAvailabilityResponse;
+import com.bookmyvenue.backend.service.VenueAvailabilityService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/availability")
+@RequiredArgsConstructor
+@Tag(name = "Venue Availability")
+public class VenueAvailabilityController {
+
+ private final VenueAvailabilityService service;
+
+ @Operation(summary = "Create availability")
+ @PostMapping
+ public ResponseEntity
+ create(
+ @RequestBody
+ VenueAvailabilityRequest request) {
+
+ return ResponseEntity.ok(
+ service.create(request));
+ }
+
+ @Operation(summary = "Get availability by ID")
+ @GetMapping("/{id}")
+ public ResponseEntity
+ getById(@PathVariable Long id) {
+
+ return ResponseEntity.ok(
+ service.getById(id));
+ }
+
+ @Operation(summary = "Get all availability")
+ @GetMapping
+ public ResponseEntity>
+ getAll() {
+
+ return ResponseEntity.ok(
+ service.getAll());
+ }
+
+ @Operation(summary = "Get availability by venue")
+ @GetMapping("/venue/{venueId}")
+ public ResponseEntity>
+ getByVenueId(
+ @PathVariable Long venueId) {
+
+ return ResponseEntity.ok(
+ service.getByVenueId(venueId));
+ }
+
+ @Operation(summary = "Update availability")
+ @PutMapping("/{id}")
+ public ResponseEntity
+ update(
+ @PathVariable Long id,
+ @RequestBody VenueAvailabilityRequest request) {
+
+ return ResponseEntity.ok(
+ service.update(id, request));
+ }
+
+ @Operation(summary = "Delete availability")
+ @DeleteMapping("/{id}")
+ public ResponseEntity delete(
+ @PathVariable Long id) {
+
+ service.delete(id);
+ return ResponseEntity.noContent().build();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/VenueController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/VenueController.java
new file mode 100644
index 000000000..3ec489494
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/VenueController.java
@@ -0,0 +1,76 @@
+package com.bookmyvenue.backend.controller;
+
+import com.bookmyvenue.backend.dto.Venue.VenueRequest;
+import com.bookmyvenue.backend.dto.Venue.VenueResponse;
+import com.bookmyvenue.backend.service.VenueService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/venues")
+@RequiredArgsConstructor
+@Tag(name = "Venue Management")
+public class VenueController {
+
+ private final VenueService venueService;
+
+ @PostMapping
+ @Operation(summary = "Create Venue")
+ public ResponseEntity
+ createVenue(
+ @Valid
+ @RequestBody VenueRequest request) {
+
+ return ResponseEntity.ok(
+ venueService.createVenue(request));
+ }
+
+ @GetMapping("/{venueId}")
+ @Operation(summary = "Get Venue By Id")
+ public ResponseEntity
+ getVenue(
+ @PathVariable Long venueId) {
+
+ return ResponseEntity.ok(
+ venueService.getVenueById(
+ venueId));
+ }
+
+ @GetMapping
+ @Operation(summary = "Get All Venues")
+ public ResponseEntity>
+ getAllVenues() {
+
+ return ResponseEntity.ok(
+ venueService.getAllVenues());
+ }
+
+ @PutMapping("/{venueId}")
+ @Operation(summary = "Update Venue")
+ public ResponseEntity
+ updateVenue(
+ @PathVariable Long venueId,
+ @RequestBody VenueRequest request) {
+
+ return ResponseEntity.ok(
+ venueService.updateVenue(
+ venueId,
+ request));
+ }
+
+ @DeleteMapping("/{venueId}")
+ @Operation(summary = "Delete Venue")
+ public ResponseEntity
+ deleteVenue(
+ @PathVariable Long venueId) {
+
+ venueService.deleteVenue(venueId);
+
+ return ResponseEntity.noContent().build();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/VenueDocumentController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/VenueDocumentController.java
new file mode 100644
index 000000000..bc9ebbc4f
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/VenueDocumentController.java
@@ -0,0 +1,165 @@
+package com.bookmyvenue.backend.controller;
+
+import com.bookmyvenue.backend.dto.venueDocument.VenueDocumentRequest;
+import com.bookmyvenue.backend.dto.venueDocument.VenueDocumentResponse;
+import com.bookmyvenue.backend.service.VenueDocumentService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/venue-documents")
+@RequiredArgsConstructor
+@Tag(name = "Venue Documents", description = "APIs for managing venue documents")
+public class VenueDocumentController {
+
+ private final VenueDocumentService service;
+
+ @PostMapping
+ @Operation(
+ summary = "Create venue document",
+ description = "Creates a new document for a venue"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(
+ responseCode = "200",
+ description = "Document created successfully",
+ content = @Content(
+ mediaType = "application/json",
+ schema = @Schema(implementation = VenueDocumentResponse.class)
+ )
+ ),
+ @ApiResponse(responseCode = "400", description = "Invalid request"),
+ @ApiResponse(responseCode = "404", description = "Venue not found")
+ })
+
+ public ResponseEntity create(
+ @Valid @RequestBody VenueDocumentRequest request) {
+
+ return ResponseEntity.ok(
+ service.createDocument(request)
+
+ );
+ }
+
+ @GetMapping("/{id}")
+ @Operation(
+ summary = "Get document by ID",
+ description = "Retrieves a venue document by its ID"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(
+ responseCode = "200",
+ description = "Document found",
+ content = @Content(
+ mediaType = "application/json",
+ schema = @Schema(implementation = VenueDocumentResponse.class)
+ )
+ ),
+ @ApiResponse(responseCode = "404", description = "Document not found")
+ })
+ public ResponseEntity getById(
+ @Parameter(description = "Document ID", required = true)
+ @PathVariable Long id) {
+
+ return ResponseEntity.ok(
+ service.getDocumentById(id));
+
+
+ }
+
+ @GetMapping
+ @Operation(
+ summary = "Get all documents",
+ description = "Retrieves all venue documents"
+ )
+ @ApiResponse(
+ responseCode = "200",
+ description = "Documents retrieved successfully"
+ )
+ public ResponseEntity> getAll() {
+
+ return ResponseEntity.ok(service.getAllDocuments());
+
+
+ }
+
+ @GetMapping("/venue/{venueId}")
+ @Operation(
+ summary = "Get documents by venue",
+ description = "Retrieves all documents associated with a specific venue"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(
+ responseCode = "200",
+ description = "Documents retrieved successfully"
+ ),
+ @ApiResponse(responseCode = "404", description = "Venue not found")
+ })
+ public ResponseEntity> getByVenue(
+ @Parameter(description = "Venue ID", required = true)
+ @PathVariable Long venueId) {
+
+ return ResponseEntity.ok(
+ service.getDocumentsByVenue(venueId));
+
+
+ }
+
+ @PutMapping("/{id}")
+ @Operation(
+ summary = "Update venue document",
+ description = "Updates an existing venue document"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(
+ responseCode = "200",
+ description = "Document updated successfully",
+ content = @Content(
+ mediaType = "application/json",
+ schema = @Schema(implementation = VenueDocumentResponse.class)
+ )
+ ),
+ @ApiResponse(responseCode = "404", description = "Document not found"),
+ @ApiResponse(responseCode = "400", description = "Invalid request")
+ })
+ public ResponseEntity update(
+ @Parameter(description = "Document ID", required = true)
+ @PathVariable Long id,
+ @Valid @RequestBody VenueDocumentRequest request) {
+
+ return ResponseEntity.ok(
+ service.updateDocument(id, request));
+ }
+
+
+ @DeleteMapping("/{id}")
+ @Operation(
+ summary = "Delete venue document",
+ description = "Deletes a venue document by its ID"
+ )
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "204", description = "Document deleted successfully"),
+ @ApiResponse(responseCode = "404", description = "Document not found")
+ })
+
+public ResponseEntity delete(
+ @Parameter(description = "Document ID", required = true)
+ @PathVariable Long id) {
+
+ service.deleteDocument(id);
+
+ return ResponseEntity.noContent().build();
+}
+
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/controller/VenuePhotoController.java b/backend/src/main/java/com/bookmyvenue/backend/controller/VenuePhotoController.java
new file mode 100644
index 000000000..a87b6ef4c
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/controller/VenuePhotoController.java
@@ -0,0 +1,73 @@
+package com.bookmyvenue.backend.controller;
+import com.bookmyvenue.backend.dto.venuePhoto.VenuePhotoRequest;
+import com.bookmyvenue.backend.dto.venuePhoto.VenuePhotoResponse;
+import com.bookmyvenue.backend.service.VenuePhotoService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/venue-photos")
+@RequiredArgsConstructor
+@Tag(name = "Venue Photo API",
+ description = "CRUD operations for Venue Photos")
+public class VenuePhotoController {
+
+ private final VenuePhotoService venuePhotoService;
+
+ @PostMapping
+ @Operation(summary = "Create venue photo")
+ public ResponseEntity create(
+ @Valid @RequestBody VenuePhotoRequest request) {
+
+ return new ResponseEntity<>(
+ venuePhotoService.create(request),
+ HttpStatus.CREATED);
+ }
+
+ @GetMapping("/{photoId}")
+ @Operation(summary = "Get venue photo by ID")
+ public ResponseEntity getById(
+ @PathVariable Long photoId) {
+
+ return ResponseEntity.ok(
+ venuePhotoService.getById(photoId));
+ }
+
+ @GetMapping("/venue/{venueId}")
+ @Operation(summary = "Get all photos by venue ID")
+ public ResponseEntity> getAllPhotoByVenueId(
+ @PathVariable Long venueId) {
+
+ return ResponseEntity.ok(
+ venuePhotoService.getAllPhotoByVenueId(venueId)
+ );
+
+ }
+
+ @PutMapping("/{photoId}")
+ @Operation(summary = "Update venue photo")
+ public ResponseEntity update(
+ @PathVariable Long photoId,
+ @Valid @RequestBody VenuePhotoRequest request) {
+
+ return ResponseEntity.ok(
+ venuePhotoService.update(photoId, request));
+ }
+
+ @DeleteMapping("/{photoId}")
+ @Operation(summary = "Delete venue photo")
+ public ResponseEntity delete(
+ @PathVariable Long photoId) {
+
+ venuePhotoService.delete(photoId);
+
+ return ResponseEntity.noContent().build();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/Book/BookingRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/Book/BookingRequest.java
new file mode 100644
index 000000000..ca747938a
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/Book/BookingRequest.java
@@ -0,0 +1,27 @@
+package com.bookmyvenue.backend.dto.Book;
+
+import com.bookmyvenue.backend.enums.BookingStatus;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+@Data
+public class BookingRequest {
+ private Long venueId;
+
+ private Long userId;
+
+ private LocalDate bookingDate;
+
+ private LocalTime startTime;
+
+ private LocalTime endTime;
+
+ private Integer guestCount;
+
+ private String remarks;
+
+ private BookingStatus bookingStatus;
+
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/Book/BookingResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/Book/BookingResponse.java
new file mode 100644
index 000000000..ed46b7a37
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/Book/BookingResponse.java
@@ -0,0 +1,43 @@
+package com.bookmyvenue.backend.dto.Book;
+
+
+import com.bookmyvenue.backend.enums.BookingStatus;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+
+@Data
+public class BookingResponse {
+
+ private Long bookingId;
+
+ private Long venueId;
+
+ private String venueName;
+
+ private Long userId;
+
+ private String userName;
+
+ private LocalDate bookingDate;
+
+ private LocalTime startTime;
+
+ private LocalTime endTime;
+
+ private Integer guestCount;
+
+ private BigDecimal totalAmount;
+
+ private BigDecimal advanceAmount;
+
+ private BookingStatus bookingStatus;
+
+ private String remarks;
+
+ private LocalDateTime createdAt;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/Book/BookingStatusRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/Book/BookingStatusRequest.java
new file mode 100644
index 000000000..47b0bf82e
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/Book/BookingStatusRequest.java
@@ -0,0 +1,18 @@
+package com.bookmyvenue.backend.dto.Book;
+
+import com.bookmyvenue.backend.enums.BookingStatus;
+import lombok.Data;
+
+@Data
+public class BookingStatusRequest {
+
+ private String remarks;
+
+ private Long updatedBy;
+
+ private BookingStatus bookingStatus;
+
+ private String cancellationReason;
+
+ private String cancelledBy;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueRequest.java
new file mode 100644
index 000000000..576eab946
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueRequest.java
@@ -0,0 +1,64 @@
+package com.bookmyvenue.backend.dto.Venue;
+
+import com.bookmyvenue.backend.enums.EventType;
+import com.bookmyvenue.backend.enums.PricingType;
+import jakarta.validation.constraints.*;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Set;
+
+@Data
+public class VenueRequest {
+
+ @NotNull
+ private Long ownerUserId;
+
+ @NotBlank
+ private String venueName;
+
+ @NotBlank
+ private String addressLine1;
+
+ private String addressLine2;
+
+ @NotBlank
+ private String city;
+
+ @NotBlank
+ private String district;
+
+ @NotBlank
+ private String state;
+
+ @NotBlank
+ private String country;
+
+ private String pincode;
+
+ private BigDecimal latitude;
+
+ private BigDecimal longitude;
+
+ @NotNull
+ private Integer capacity;
+
+ @NotNull
+ private PricingType pricingType;
+
+ @NotNull
+ private BigDecimal basePrice;
+
+ private BigDecimal advancePercentage;
+
+ private String contactName;
+
+ private String contactEmail;
+
+ private Set amenityIds;
+
+ private Set supportedEventTypes;
+
+ @NotNull
+ private Long createdBy;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueResponse.java
new file mode 100644
index 000000000..406ae2843
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueResponse.java
@@ -0,0 +1,65 @@
+package com.bookmyvenue.backend.dto.Venue;
+
+import com.bookmyvenue.backend.enums.PricingType;
+import com.bookmyvenue.backend.enums.VenueStatus;
+import lombok.Builder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Set;
+
+@Data
+@Builder
+public class VenueResponse {
+
+ private Long venueId;
+
+ private Long ownerUserId;
+
+ private String ownerName;
+
+ private String venueName;
+
+ private String addressLine1;
+
+ private String addressLine2;
+
+ private String city;
+
+ private String district;
+
+ private String state;
+
+ private String country;
+
+ private String pincode;
+
+ private BigDecimal latitude;
+
+ private BigDecimal longitude;
+
+ private Integer capacity;
+
+ private PricingType pricingType;
+
+ private BigDecimal basePrice;
+
+ private BigDecimal advancePercentage;
+
+ private VenueStatus status;
+
+ private String approvalRemarks;
+
+ private String contactName;
+
+ private String contactEmail;
+
+ private Set amenities;
+
+ private Set categories;
+
+ private LocalDateTime createdAt;
+
+ private LocalDateTime updatedAt;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueSearchRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueSearchRequest.java
new file mode 100644
index 000000000..3326ee501
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueSearchRequest.java
@@ -0,0 +1,31 @@
+package com.bookmyvenue.backend.dto.Venue;
+
+import com.bookmyvenue.backend.enums.EventType;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Set;
+
+@Data
+public class VenueSearchRequest {
+
+ private BigDecimal minPrice;
+
+ private BigDecimal maxPrice;
+
+ private Integer capacity;
+
+ private LocalDate availableDate;
+
+ private String city;
+
+ private EventType eventType;
+
+ private Integer guestCount;
+
+ private BigDecimal maxRate;
+
+ private List amenityIds;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueStatusRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueStatusRequest.java
new file mode 100644
index 000000000..86f0bea04
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/Venue/VenueStatusRequest.java
@@ -0,0 +1,9 @@
+package com.bookmyvenue.backend.dto.Venue;
+
+import com.bookmyvenue.backend.enums.VenueStatus;
+import lombok.Data;
+
+@Data
+public class VenueStatusRequest {
+ private VenueStatus status;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminRequestResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminRequestResponse.java
new file mode 100644
index 000000000..f35fc3e23
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminRequestResponse.java
@@ -0,0 +1,28 @@
+package com.bookmyvenue.backend.dto.adminDashboard;
+
+import com.bookmyvenue.backend.enums.VenueStatus;
+import lombok.Builder;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@Builder
+public class AdminRequestResponse {
+
+ private Long venueId;
+
+ private String venueName;
+
+ private Long ownerId;
+
+ private String ownerName;
+
+ private String requestType;
+
+ private VenueStatus status;
+
+ private LocalDateTime requestDate;
+
+ private String approvalRemarks;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminRequestSearchRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminRequestSearchRequest.java
new file mode 100644
index 000000000..51626755b
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminRequestSearchRequest.java
@@ -0,0 +1,14 @@
+package com.bookmyvenue.backend.dto.adminDashboard;
+
+import com.bookmyvenue.backend.enums.VenueStatus;
+import lombok.Data;
+
+@Data
+public class AdminRequestSearchRequest {
+
+ private String venueName;
+
+ private VenueStatus status;
+
+ private Long ownerId;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminUserResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminUserResponse.java
new file mode 100644
index 000000000..8299001e4
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminUserResponse.java
@@ -0,0 +1,23 @@
+package com.bookmyvenue.backend.dto.adminDashboard;
+
+import com.bookmyvenue.backend.enums.UserStatus;
+import lombok.Builder;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+@Builder
+@Data
+public class AdminUserResponse {
+
+ private Long userId;
+
+ private String fullName;
+
+ private String email;
+
+ private UserStatus status;
+
+ private LocalDateTime createdAt;
+
+ private Long totalBookings;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminVenueOwnerResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminVenueOwnerResponse.java
new file mode 100644
index 000000000..25611192b
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminVenueOwnerResponse.java
@@ -0,0 +1,28 @@
+package com.bookmyvenue.backend.dto.adminDashboard;
+
+import com.bookmyvenue.backend.enums.UserStatus;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class AdminVenueOwnerResponse {
+
+ private Long ownerId;
+
+ private String ownerName;
+
+ private String email;
+
+ private Long totalVenues;
+
+ private BigDecimal revenue;
+
+ private UserStatus status;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminVenueOwnerSearchRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminVenueOwnerSearchRequest.java
new file mode 100644
index 000000000..245c17745
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/adminDashboard/AdminVenueOwnerSearchRequest.java
@@ -0,0 +1,14 @@
+package com.bookmyvenue.backend.dto.adminDashboard;
+
+import com.bookmyvenue.backend.enums.UserStatus;
+import lombok.Data;
+
+@Data
+public class AdminVenueOwnerSearchRequest {
+
+ private String name;
+
+ private String email;
+
+ private UserStatus status;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/LoginRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/LoginRequest.java
new file mode 100644
index 000000000..253c1d814
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/LoginRequest.java
@@ -0,0 +1,13 @@
+package com.bookmyvenue.backend.dto.authentication;
+
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+@Data
+public class LoginRequest {
+
+ @NotBlank(message = "Registered Email/Phone Number is required")
+ private String userName;
+ @NotBlank(message = "Password is required")
+ private String password;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/LoginResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/LoginResponse.java
new file mode 100644
index 000000000..0d094e28b
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/LoginResponse.java
@@ -0,0 +1,17 @@
+package com.bookmyvenue.backend.dto.authentication;
+
+import com.bookmyvenue.backend.enums.UserRole;
+import lombok.Data;
+
+@Data
+public class LoginResponse {
+
+ private long userId;
+ private String firstName;
+ private String email;
+ private String phone;
+ private String city;
+ private UserRole role;
+ private String message;
+ private String token;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/RegisterRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/RegisterRequest.java
new file mode 100644
index 000000000..395afd336
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/RegisterRequest.java
@@ -0,0 +1,32 @@
+package com.bookmyvenue.backend.dto.authentication;
+
+import com.bookmyvenue.backend.enums.UserRole;
+import jakarta.validation.constraints.*;
+import lombok.Data;
+
+@Data
+public class RegisterRequest {
+
+ @NotBlank (message = "First name is required")
+ private String firstName;
+
+ private String lastName;
+
+ @NotBlank(message = "Phone number is required")
+ @Pattern(
+ regexp = "^[6-9][0-9]{9}$",
+ message = "Phone Number must be a valid 10 digit Indian Mobile Number"
+ )
+ private String phone;
+
+ @NotBlank (message = "Password is required")
+ @Size(min = 8, max = 30, message = "Password must be between 8 and 30 characters")
+ private String password;
+
+ @NotBlank(message = "Email ID is required")
+ @Email(message = "Invalid Email format")
+ private String email;
+
+ @NotNull(message = "Role is required")
+ private UserRole role;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/RegisterResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/RegisterResponse.java
new file mode 100644
index 000000000..bd353fd48
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/authentication/RegisterResponse.java
@@ -0,0 +1,15 @@
+package com.bookmyvenue.backend.dto.authentication;
+
+import com.bookmyvenue.backend.enums.UserRole;
+import lombok.Data;
+
+@Data
+public class RegisterResponse {
+
+ private String firstName;
+ private String lastName;
+ private String email;
+ private long userId;
+ private UserRole role;
+ private String message;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/common/ErrorResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/common/ErrorResponse.java
new file mode 100644
index 000000000..dc240332b
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/common/ErrorResponse.java
@@ -0,0 +1,19 @@
+package com.bookmyvenue.backend.dto.common;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ErrorResponse {
+
+ private LocalDateTime timestamp;
+ private int status;
+ private List errors;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/payment/PaymentRequestDTO.java b/backend/src/main/java/com/bookmyvenue/backend/dto/payment/PaymentRequestDTO.java
new file mode 100644
index 000000000..8f798f061
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/payment/PaymentRequestDTO.java
@@ -0,0 +1,19 @@
+package com.bookmyvenue.backend.dto.payment;
+
+import com.bookmyvenue.backend.enums.PaymentType;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+public class PaymentRequestDTO {
+
+ private Long bookingId;
+
+ private PaymentType paymentType;
+
+ private BigDecimal amount;
+
+ private LocalDateTime paymentDueDate;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/payment/PaymentResponseDTO.java b/backend/src/main/java/com/bookmyvenue/backend/dto/payment/PaymentResponseDTO.java
new file mode 100644
index 000000000..0c225eece
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/payment/PaymentResponseDTO.java
@@ -0,0 +1,35 @@
+package com.bookmyvenue.backend.dto.payment;
+
+import com.bookmyvenue.backend.enums.PaymentStatus;
+import com.bookmyvenue.backend.enums.PaymentType;
+import com.bookmyvenue.backend.enums.RefundStatus;
+import lombok.Builder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@Builder
+public class PaymentResponseDTO {
+
+ private Long paymentId;
+
+ private Long bookingId;
+
+ private PaymentType paymentType;
+
+ private BigDecimal amount;
+
+ private BigDecimal refundAmount;
+
+ private PaymentStatus paymentStatus;
+
+ private RefundStatus refundStatus;
+
+ private String razorOrderId;
+
+ private String razorPaymentId;
+
+ private LocalDateTime paidAt;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/payment/PaymentUpdateDTO.java b/backend/src/main/java/com/bookmyvenue/backend/dto/payment/PaymentUpdateDTO.java
new file mode 100644
index 000000000..3c303f949
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/payment/PaymentUpdateDTO.java
@@ -0,0 +1,15 @@
+package com.bookmyvenue.backend.dto.payment;
+
+import com.bookmyvenue.backend.enums.PaymentStatus;
+import com.bookmyvenue.backend.enums.RefundStatus;
+import lombok.Data;
+
+@Data
+public class PaymentUpdateDTO {
+
+ private PaymentStatus paymentStatus;
+
+ private RefundStatus refundStatus;
+
+ private String razorPaymentId;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/review/ReviewRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/review/ReviewRequest.java
new file mode 100644
index 000000000..bcea0bc3b
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/review/ReviewRequest.java
@@ -0,0 +1,13 @@
+package com.bookmyvenue.backend.dto.review;
+
+import lombok.Data;
+
+@Data
+public class ReviewRequest {
+
+ private Long venueId;
+
+ private Integer rating;
+
+ private String comment;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/review/ReviewResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/review/ReviewResponse.java
new file mode 100644
index 000000000..eeba81d51
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/review/ReviewResponse.java
@@ -0,0 +1,27 @@
+package com.bookmyvenue.backend.dto.review;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@Builder
+public class ReviewResponse {
+
+ private Long reviewId;
+
+ private Long venueId;
+
+ private String venueName;
+
+ private Long userId;
+
+ private String userName;
+
+ private Integer rating;
+
+ private String comment;
+
+ private LocalDateTime reviewDate;
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/venuAvailability/VenueAvailabilityRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/venuAvailability/VenueAvailabilityRequest.java
new file mode 100644
index 000000000..54df8e21b
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/venuAvailability/VenueAvailabilityRequest.java
@@ -0,0 +1,25 @@
+package com.bookmyvenue.backend.dto.venuAvailability;
+
+import com.bookmyvenue.backend.enums.AvailabilityStatus;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+@Data
+public class VenueAvailabilityRequest {
+
+ private Long venueId;
+
+ private LocalDate availableDate;
+
+ private LocalTime startTime;
+
+ private LocalTime endTime;
+
+ private AvailabilityStatus availabilityStatus;
+
+ private String reason;
+
+ private Long createdBy;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/venuAvailability/VenueAvailabilityResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/venuAvailability/VenueAvailabilityResponse.java
new file mode 100644
index 000000000..08d1deb27
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/venuAvailability/VenueAvailabilityResponse.java
@@ -0,0 +1,32 @@
+package com.bookmyvenue.backend.dto.venuAvailability;
+
+import com.bookmyvenue.backend.enums.AvailabilityStatus;
+import lombok.Builder;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+@Data
+@Builder
+public class VenueAvailabilityResponse {
+
+ private Long availabilityId;
+
+ private Long venueId;
+
+ private LocalDate availableDate;
+
+ private LocalTime startTime;
+
+ private LocalTime endTime;
+
+ private AvailabilityStatus availabilityStatus;
+
+ private String reason;
+
+ private LocalDateTime createdAt;
+
+ private LocalDateTime updatedAt;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/venueAmenity/AmenityRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/venueAmenity/AmenityRequest.java
new file mode 100644
index 000000000..0d261ab0e
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/venueAmenity/AmenityRequest.java
@@ -0,0 +1,13 @@
+package com.bookmyvenue.backend.dto.venueAmenity;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class AmenityRequest {
+
+ private String amenityName;
+ private String description;
+ private Boolean isActive;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/venueAmenity/AmenityResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/venueAmenity/AmenityResponse.java
new file mode 100644
index 000000000..fe72b35ee
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/venueAmenity/AmenityResponse.java
@@ -0,0 +1,22 @@
+package com.bookmyvenue.backend.dto.venueAmenity;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@Builder
+public class AmenityResponse {
+
+ private Long amenityId;
+ private String amenityName;
+ private String description;
+ private Boolean isActive;
+
+ private LocalDateTime createdAt;
+ private LocalDateTime updatedAt;
+
+ private Long createdBy;
+ private Long updatedBy;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/venueDocument/VenueDocumentRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/venueDocument/VenueDocumentRequest.java
new file mode 100644
index 000000000..f6fa76fff
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/venueDocument/VenueDocumentRequest.java
@@ -0,0 +1,31 @@
+package com.bookmyvenue.backend.dto.venueDocument;
+
+import com.bookmyvenue.backend.enums.DocumentStatus;
+import com.bookmyvenue.backend.enums.DocumentType;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.*;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class VenueDocumentRequest {
+
+ @NotNull
+ private Long venueId;
+
+ @NotNull
+ private DocumentType documentType;
+
+ @NotBlank
+ private String documentName;
+
+ @NotBlank
+ private String documentUrl;
+
+ private DocumentStatus documentStatus;
+
+ private String remarks;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/venueDocument/VenueDocumentResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/venueDocument/VenueDocumentResponse.java
new file mode 100644
index 000000000..29e7d4d83
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/venueDocument/VenueDocumentResponse.java
@@ -0,0 +1,39 @@
+package com.bookmyvenue.backend.dto.venueDocument;
+
+import com.bookmyvenue.backend.enums.DocumentStatus;
+import com.bookmyvenue.backend.enums.DocumentType;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class VenueDocumentResponse {
+
+ private Long documentId;
+
+ private Long venueId;
+
+ private String venueName;
+
+ private DocumentType documentType;
+
+ private String documentName;
+
+ private String documentUrl;
+
+ private DocumentStatus documentStatus;
+
+ private String remarks;
+
+ private Long createdBy;
+
+ private Long updatedBy;
+
+ private LocalDateTime createdAt;
+
+ private LocalDateTime updatedAt;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/venueOwnerDashboard/OwnerDashboardResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/venueOwnerDashboard/OwnerDashboardResponse.java
new file mode 100644
index 000000000..f7a822e9e
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/venueOwnerDashboard/OwnerDashboardResponse.java
@@ -0,0 +1,26 @@
+package com.bookmyvenue.backend.dto.venueOwnerDashboard;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+@Builder
+public class OwnerDashboardResponse {
+
+ private Long activeVenues;
+
+ private Long totalVenues;
+
+ private Long totalBookings;
+
+ private BigDecimal revenueEarned;
+
+ private Double averageRating;
+
+ private List recentBookings;
+
+ private List venues;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/venueOwnerDashboard/OwnerVenueDto.java b/backend/src/main/java/com/bookmyvenue/backend/dto/venueOwnerDashboard/OwnerVenueDto.java
new file mode 100644
index 000000000..79d3d0b4b
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/venueOwnerDashboard/OwnerVenueDto.java
@@ -0,0 +1,20 @@
+package com.bookmyvenue.backend.dto.venueOwnerDashboard;
+
+import com.bookmyvenue.backend.enums.VenueStatus;
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class OwnerVenueDto {
+
+ private Long venueId;
+
+ private String venueName;
+
+ private String city;
+
+ private VenueStatus status;
+
+ private Long bookingCount;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/venueOwnerDashboard/RecentBookingDto.java b/backend/src/main/java/com/bookmyvenue/backend/dto/venueOwnerDashboard/RecentBookingDto.java
new file mode 100644
index 000000000..8d4023ff7
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/venueOwnerDashboard/RecentBookingDto.java
@@ -0,0 +1,23 @@
+package com.bookmyvenue.backend.dto.venueOwnerDashboard;
+
+import com.bookmyvenue.backend.enums.BookingStatus;
+import lombok.Builder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+@Data
+@Builder
+public class RecentBookingDto {
+
+ private String guestName;
+
+ private String venueName;
+
+ private LocalDate bookingDate;
+
+ private BigDecimal amount;
+
+ private BookingStatus status;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/venuePhoto/VenuePhotoRequest.java b/backend/src/main/java/com/bookmyvenue/backend/dto/venuePhoto/VenuePhotoRequest.java
new file mode 100644
index 000000000..3cfacc0a2
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/venuePhoto/VenuePhotoRequest.java
@@ -0,0 +1,21 @@
+package com.bookmyvenue.backend.dto.venuePhoto;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class VenuePhotoRequest {
+
+ @NotNull
+ private Long venueId;
+
+ private Boolean isPrimary;
+
+ private Integer displayOrder;
+
+ private String photoUrl;
+ @NotNull
+ private Long createdBy;
+
+ private Long updatedBy;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/dto/venuePhoto/VenuePhotoResponse.java b/backend/src/main/java/com/bookmyvenue/backend/dto/venuePhoto/VenuePhotoResponse.java
new file mode 100644
index 000000000..ab00ebfbd
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/dto/venuePhoto/VenuePhotoResponse.java
@@ -0,0 +1,29 @@
+package com.bookmyvenue.backend.dto.venuePhoto;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@Builder
+public class VenuePhotoResponse {
+
+ private Long photoId;
+
+ private Long venueId;
+
+ private Boolean isPrimary;
+
+ private Integer displayOrder;
+
+ private String photoUrl;
+
+ private LocalDateTime createdAt;
+
+ private LocalDateTime updatedAt;
+
+ private Long createdBy;
+
+ private Long updatedBy;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/entity/Amenity.java b/backend/src/main/java/com/bookmyvenue/backend/entity/Amenity.java
new file mode 100644
index 000000000..4c880c497
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/entity/Amenity.java
@@ -0,0 +1,62 @@
+package com.bookmyvenue.backend.entity;
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.time.LocalDateTime;
+import java.util.Set;
+
+@Entity
+@Table(name = "amenity")
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class Amenity {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "amenity_id")
+ private Long amenityId;
+
+ @Column(name = "amenity_name",nullable = false,unique = true, length = 255)
+ private String amenityName;
+
+ @Column(name = "description",columnDefinition = "TEXT")
+ private String description;
+
+ @Column(name = "is_active",nullable = false)
+ private Boolean isActive=true;
+
+ @ManyToMany(mappedBy = "amenities")
+ private Set venues;
+
+ @Column(name = "created_at", nullable = false, updatable = false)
+ private LocalDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+
+ @Column(name = "created_by", nullable = false, updatable = false)
+ private Long createdBy;
+
+ @Column(name = "updated_by",nullable = false)
+ private Long updatedBy;
+
+ @PrePersist
+ protected void prePersist() {
+ createdAt = LocalDateTime.now();
+ updatedAt = LocalDateTime.now();
+ if(this.isActive==null)
+ {
+ this.isActive=true;
+ }
+
+ }
+
+ @PreUpdate
+ protected void preUpdate() {
+ updatedAt = LocalDateTime.now();
+ }
+
+
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/entity/Booking.java b/backend/src/main/java/com/bookmyvenue/backend/entity/Booking.java
new file mode 100644
index 000000000..d0dc9aadb
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/entity/Booking.java
@@ -0,0 +1,165 @@
+package com.bookmyvenue.backend.entity;
+import com.bookmyvenue.backend.enums.BookingStatus;
+import com.bookmyvenue.backend.enums.BookingType;
+import com.fasterxml.jackson.annotation.JsonManagedReference;
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.List;
+
+@Entity
+@Table(name = "booking")
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class Booking {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "booking_id")
+ private Long bookingId;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "venue_id", nullable = false)
+ private Venue venue;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "user_id", nullable = false)
+ private Users user;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "booking_type", nullable = false, length = 30)
+ private BookingType bookingType;
+
+ @Column(name = "venue_date", nullable = false)
+ private LocalDate eventDate;
+
+ @Column(name = "start_time")
+ private LocalTime startTime;
+
+ @Column(name = "end_time")
+ private LocalTime endTime;
+
+ @Column(name = "guest_count", nullable = false)
+ private Integer guestCount;
+
+ // Financial Summary
+
+ @Column(name = "total_amount",
+ nullable = false,
+ precision = 12,
+ scale = 2)
+ private BigDecimal totalAmount;
+
+ @Builder.Default
+ @Column(name = "paid_amount",
+ nullable = false,
+ precision = 12,
+ scale = 2)
+ private BigDecimal paidAmount = BigDecimal.ZERO;
+
+ @Column(name = "balance_amount",
+ nullable = false,
+ precision = 12,
+ scale = 2)
+ private BigDecimal balanceAmount;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "booking_status",
+ nullable = false,
+ length = 30)
+ private BookingStatus bookingStatus =
+ BookingStatus.PENDING_PAYMENT;
+
+ @JsonManagedReference
+ @Builder.Default
+ @OneToMany(
+ mappedBy = "booking",
+ cascade = CascadeType.ALL,
+ orphanRemoval = false)
+ private List payments =
+ new ArrayList<>();
+
+ @Column(name = "cancellation_reason", length = 500)
+ private String cancellationReason;
+
+ @Column(name = "cancellation_at")
+ private LocalDateTime cancellationAt;
+
+ @Column(name = "cancelled_by", length = 100)
+ private String cancelledBy;
+
+ @Column(name = "created_at",
+ nullable = false,
+ updatable = false)
+ private LocalDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+
+ @Column(name = "created_by",
+ updatable = false)
+ private Long createdBy;
+
+ @Column(name = "updated_by")
+ private Long updatedBy;
+
+ public void addPayment(Payment payment) {
+ payments.add(payment);
+ payment.setBooking(this);
+ }
+
+ public void removePayment(Payment payment) {
+ payments.remove(payment);
+ payment.setBooking(null);
+ }
+
+ public void updatePaymentSummary() {
+
+ BigDecimal totalPaid = payments.stream()
+ .filter(payment ->
+ payment.getPaymentStatus().name()
+ .equals("SUCCESS"))
+ .map(Payment::getAmount)
+ .reduce(
+ BigDecimal.ZERO,
+ BigDecimal::add);
+
+ this.paidAmount = totalPaid;
+ this.balanceAmount =
+ this.totalAmount.subtract(totalPaid);
+ }
+
+ @PrePersist
+ protected void prePersist() {
+
+ createdAt = LocalDateTime.now();
+ updatedAt = LocalDateTime.now();
+
+ if (paidAmount == null) {
+ paidAmount = BigDecimal.ZERO;
+ }
+
+ if (totalAmount != null) {
+ balanceAmount =
+ totalAmount.subtract(paidAmount);
+ }
+
+ if (bookingStatus == null) {
+ bookingStatus =
+ BookingStatus.PENDING_PAYMENT;
+ }
+ }
+
+ @PreUpdate
+ protected void preUpdate() {
+ updatedAt = LocalDateTime.now();
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/entity/Payment.java b/backend/src/main/java/com/bookmyvenue/backend/entity/Payment.java
new file mode 100644
index 000000000..2f2161902
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/entity/Payment.java
@@ -0,0 +1,114 @@
+package com.bookmyvenue.backend.entity;
+import com.bookmyvenue.backend.enums.PaymentStatus;
+import com.bookmyvenue.backend.enums.PaymentType;
+import com.bookmyvenue.backend.enums.RefundStatus;
+import com.fasterxml.jackson.annotation.JsonBackReference;
+import jakarta.persistence.*;
+import lombok.*;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "payment")
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class Payment {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "payment_id")
+ private Long paymentId;
+
+ @JsonBackReference
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "booking_id", nullable = false)
+ private Booking booking;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "payment_type",
+ nullable = false,
+ length = 30)
+ private PaymentType paymentType;
+
+ // Amount of THIS payment transaction
+ @Column(name = "amount",
+ nullable = false,
+ precision = 12,
+ scale = 2)
+ private BigDecimal amount;
+
+ @Column(name = "payment_due_date")
+ private LocalDateTime paymentDueDate;
+
+ @Column(name = "refund_amount",
+ precision = 12,
+ scale = 2)
+ private BigDecimal refundAmount = BigDecimal.ZERO;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "payment_status",
+ nullable = false,
+ length = 30)
+ private PaymentStatus paymentStatus = PaymentStatus.PENDING;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "refund_status",
+ nullable = false,
+ length = 30)
+ private RefundStatus refundStatus = RefundStatus.REFUND_PENDING;
+
+ @Column(name = "razorpay_order_id",
+ unique = true,
+ length = 100)
+ private String razorOrderId;
+
+ @Column(name = "razorpay_payment_id",
+ length = 100)
+ private String razorPaymentId;
+
+ @Column(name = "paid_at")
+ private LocalDateTime paidAt;
+
+ @Column(name = "created_at",
+ nullable = false,
+ updatable = false)
+ private LocalDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+
+ @Column(name = "created_by",
+ updatable = false)
+ private Long createdBy;
+
+ @Column(name = "updated_by")
+ private Long updatedBy;
+
+ @PrePersist
+ protected void prePersist() {
+
+ createdAt = LocalDateTime.now();
+ updatedAt = LocalDateTime.now();
+
+ if (refundAmount == null) {
+ refundAmount = BigDecimal.ZERO;
+ }
+
+ if (paymentStatus == null) {
+ paymentStatus = PaymentStatus.PENDING;
+ }
+
+ if (refundStatus == null) {
+ refundStatus = RefundStatus.REFUND_PENDING;
+ }
+ }
+
+ @PreUpdate
+ protected void preUpdate() {
+ updatedAt = LocalDateTime.now();
+ }
+}
+
diff --git a/backend/src/main/java/com/bookmyvenue/backend/entity/Review.java b/backend/src/main/java/com/bookmyvenue/backend/entity/Review.java
new file mode 100644
index 000000000..3cdf29314
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/entity/Review.java
@@ -0,0 +1,56 @@
+package com.bookmyvenue.backend.entity;
+
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "review")
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class Review {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "review_id")
+ private Long reviewId;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "venue_id", nullable = false)
+ private Venue venue;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "user_id", nullable = false)
+ private Users user;
+
+ @Column(name = "rating", nullable = false)
+ private Integer rating; // 1-5
+
+ @Column(name = "comment", length = 1000)
+ private String comment;
+
+ @Column(name = "review_date")
+ private LocalDateTime reviewDate;
+
+ @Column(name = "created_at", nullable = false)
+ private LocalDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+
+ @PrePersist
+ public void prePersist() {
+ this.reviewDate = LocalDateTime.now();
+ this.createdAt = LocalDateTime.now();
+ this.updatedAt = LocalDateTime.now();
+ }
+
+ @PreUpdate
+ public void preUpdate() {
+ this.updatedAt = LocalDateTime.now();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/entity/Users.java b/backend/src/main/java/com/bookmyvenue/backend/entity/Users.java
new file mode 100644
index 000000000..1e4b97b5a
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/entity/Users.java
@@ -0,0 +1,87 @@
+package com.bookmyvenue.backend.entity;
+
+import com.bookmyvenue.backend.enums.UserRole;
+import com.bookmyvenue.backend.enums.UserStatus;
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "users")
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class Users {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "user_id")
+ private Long userId;
+
+ @Column(name = "first_name",nullable = false,length = 100)
+ private String firstName;
+
+ @Column(name = "last_name",length = 100)
+ private String lastName;
+
+ @Column(name="email",nullable = false, unique = true,length = 150)
+ private String email;
+
+ @Column(name="phone",nullable = false, unique = true,length = 20)
+ private String phone;
+
+ @Column(name="password_hash",nullable = false,length = 255)
+ private String passwordHash;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name="role",nullable = false,length = 30)
+ private UserRole role;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name="status",nullable = false,length = 30)
+ private UserStatus status =UserStatus.ACTIVE;
+
+ @Column(name = "created_at", nullable = false, updatable = false)
+ private LocalDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+
+ @Column(name = "created_by", updatable = false)
+ private Long createdBy;
+
+ @Column(name = "updated_by")
+ private Long updatedBy;
+
+ @Column(name = "address_line1")
+ private String addressLine1;
+
+ @Column(name = "address_line2")
+ private String addressLine2;
+
+ @Column(name = "city")
+ private String city;
+
+ @Column(name = "district")
+ private String district;
+
+ @Column(name = "state")
+ private String state;
+
+ @Column(name = "pin_code")
+ private String pinCode;
+
+ @PrePersist
+ protected void prePersist() {
+ createdAt = LocalDateTime.now();
+ updatedAt = LocalDateTime.now();
+ }
+
+ @PreUpdate
+ protected void preUpdate() {
+ updatedAt = LocalDateTime.now();
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/entity/Venue.java b/backend/src/main/java/com/bookmyvenue/backend/entity/Venue.java
new file mode 100644
index 000000000..0dfb56a5d
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/entity/Venue.java
@@ -0,0 +1,138 @@
+package com.bookmyvenue.backend.entity;
+import com.bookmyvenue.backend.enums.EventType;
+import com.bookmyvenue.backend.enums.PricingType;
+import com.bookmyvenue.backend.enums.VenueStatus;
+import jakarta.persistence.*;
+import lombok.*;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Set;
+
+@Entity
+@Table(name = "venue")
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class Venue {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "venue_id")
+ private Long venueId;
+
+ @ManyToOne(optional = false)
+ @JoinColumn(name = "owner_user_id", nullable = false)
+ private Users ownerUser;
+
+ @Column(name = "venue_name",nullable = false,length = 255)
+ private String venueName;
+
+
+ @Column(name = "address_line1",nullable = false,length = 255)
+ private String addressLine1;
+
+ @Column(name = "address_line2",length = 255)
+ private String addressLine2;
+
+ @Column(name = "city",nullable = false,length = 100)
+ private String city;
+
+ @Column(name = "district",nullable = false,length = 255)
+ private String district;
+
+ @Column(name = "state",nullable = false,length = 100)
+ private String state;
+
+ @Column(name = "country",nullable = false,length = 100)
+ private String country;
+
+ @Column(name = "pincode",length =20)
+ private String pincode;
+
+ @Column(name = "latitude",precision=11,scale=8)
+ private BigDecimal latitude;
+
+ @Column(name = "longitude",precision=11,scale=8)
+ private BigDecimal longitude;
+
+ @Column(name = "capacity",nullable = false)
+ private Integer capacity;
+
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "pricing_type", nullable = false)
+ private PricingType pricingType;
+
+ @Column(name = "base_price",nullable=false,precision=12,scale=2)
+ private BigDecimal basePrice;
+
+ @Column(name = "advance_percentage",precision=12,scale=2)
+ private BigDecimal advancePercentage;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "status", nullable = false)
+ private VenueStatus status = VenueStatus.PENDING_APPROVAL;
+
+ @Column(name = "approval_remarks",columnDefinition = "TEXT")
+ private String approvalRemarks;
+
+ @Column(name = "contact_name",length = 150)
+ private String contactName;
+
+ @Column(name = "contact_email",length = 150)
+ private String contactEmail;
+
+ @ManyToMany
+ @JoinTable(
+ name="venue_amenity",
+ joinColumns =@JoinColumn(name="venue_id"),
+ inverseJoinColumns = @JoinColumn(name = "amenity_id")
+
+ )
+private Set amenities;
+
+ @ElementCollection(fetch = FetchType.LAZY)
+ @CollectionTable(
+ name = "venue_event_types",
+ joinColumns = @JoinColumn(name = "venue_id")
+ )
+ @Column(name = "event_type")
+ @Enumerated(EnumType.STRING)
+ private Set supportedEventTypes;
+
+ @OneToMany(mappedBy="venue",
+ cascade=CascadeType.ALL,
+ orphanRemoval = true)
+ private List venuePhotos;
+
+ @Column(name = "created_at", nullable = false, updatable = false)
+ private LocalDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+
+ @Column(name = "created_by", nullable = false, updatable = false)
+ private Long createdBy;
+
+ @Column(name = "updated_by",nullable = false)
+ private Long updatedBy;
+
+ @PrePersist
+ protected void prePersist() {
+ createdAt = LocalDateTime.now();
+ updatedAt = LocalDateTime.now();
+ if(this.status==null)
+ {
+ this.status=VenueStatus.PENDING_APPROVAL;
+ }
+ }
+
+ @PreUpdate
+ protected void preUpdate() {
+ updatedAt = LocalDateTime.now();
+ }
+
+
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/entity/VenueAvailability.java b/backend/src/main/java/com/bookmyvenue/backend/entity/VenueAvailability.java
new file mode 100644
index 000000000..dbbe7851a
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/entity/VenueAvailability.java
@@ -0,0 +1,66 @@
+package com.bookmyvenue.backend.entity;
+import com.bookmyvenue.backend.enums.AvailabilityStatus;
+import jakarta.persistence.*;
+import lombok.*;
+import java.time.LocalDateTime;
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+@Entity
+@Table(name = "venue_availability")
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class VenueAvailability {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "availability_id")
+ private Long availabilityId;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "venue_id", nullable = false)
+ private Venue venue;
+
+ @Column(name = "available_date", nullable = false)
+ private LocalDate availableDate;
+
+ @Column(name = "start_time", nullable = false)
+ private LocalTime startTime;
+
+ @Column(name = "end_time", nullable = false)
+ private LocalTime endTime;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "availability_status", nullable = false)
+ private AvailabilityStatus availabilityStatus;
+
+ @Column(name = "reason", length = 500)
+ private String reason;
+
+ @Column(name = "created_at", nullable = false, updatable = false)
+ private LocalDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+
+ @Column(name = "created_by", nullable = false, updatable = false)
+ private Long createdBy;
+
+ @Column(name = "updated_by",nullable = false)
+ private Long updatedBy;
+
+ @PrePersist
+ public void prePersist() {
+ this.createdAt = LocalDateTime.now();
+ this.updatedAt = LocalDateTime.now();
+ }
+
+ @PreUpdate
+ public void preUpdate() {
+ this.updatedAt = LocalDateTime.now();
+ }
+
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/entity/VenueDocument.java b/backend/src/main/java/com/bookmyvenue/backend/entity/VenueDocument.java
new file mode 100644
index 000000000..174d876da
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/entity/VenueDocument.java
@@ -0,0 +1,72 @@
+package com.bookmyvenue.backend.entity;
+
+import com.bookmyvenue.backend.enums.DocumentStatus;
+import com.bookmyvenue.backend.enums.DocumentType;
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "venue_document")
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class VenueDocument {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "document_id")
+ private Long documentId;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "venue_id", nullable = false)
+ private Venue venue;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "document_type", nullable = false)
+ private DocumentType documentType;
+
+ @Column(name = "document_name", nullable = false, length = 255)
+ private String documentName;
+
+ @Column(name = "document_url", nullable = false, length = 1000)
+ private String documentUrl;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "document_status", nullable = false)
+ private DocumentStatus documentStatus;
+
+ @Column(name = "created_by", nullable = false, updatable = false)
+ private Long createdBy;
+
+ @Column(name = "updated_by",nullable = false)
+ private Long updatedBy;
+
+
+ @Column(name = "remarks", length = 500)
+ private String remarks;
+
+ @Column(name = "created_at", nullable = false, updatable = false)
+ private LocalDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+
+ @PrePersist
+ public void prePersist() {
+ this.createdAt = LocalDateTime.now();
+ this.updatedAt = LocalDateTime.now();
+ if(this.documentStatus==null)
+ {
+ this.documentStatus=DocumentStatus.PENDING;
+ }
+ }
+
+ @PreUpdate
+ public void preUpdate() {
+ this.updatedAt = LocalDateTime.now();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/entity/VenuePhoto.java b/backend/src/main/java/com/bookmyvenue/backend/entity/VenuePhoto.java
new file mode 100644
index 000000000..091f98a30
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/entity/VenuePhoto.java
@@ -0,0 +1,68 @@
+package com.bookmyvenue.backend.entity;
+import jakarta.persistence.*;
+import lombok.*;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "venuePhoto")
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class VenuePhoto {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "photo_id")
+ private Long photoId;
+
+ @ManyToOne(fetch=FetchType.LAZY)
+ @JoinColumn(name = "venue_id", nullable = false)
+ private Venue venue;
+
+ @Column(name = "is_primary",nullable = false)
+ private Boolean isPrimary=false;
+
+ @Column(name = "photo_url", nullable = false)
+ private String photoUrl;
+
+// @Lob
+// @Column(name = "image_data")
+// private byte[] imageData;
+
+ @Column(name = "display_Order")
+ private Integer displayOrder=1;
+
+ @Column(name = "created_at", nullable = false, updatable = false)
+ private LocalDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+
+ @Column(name = "created_by", nullable = false, updatable = false)
+ private Long createdBy;
+
+ @Column(name = "updated_by",nullable = false)
+ private Long updatedBy;
+
+
+ @PrePersist
+ protected void prePersist() {
+ createdAt = LocalDateTime.now();
+ updatedAt = LocalDateTime.now();
+ if(this.isPrimary==null)
+ {
+ this.isPrimary=false;
+ }
+ if(this.displayOrder==null)
+ {
+ this.displayOrder=1;
+ }
+ }
+
+ @PreUpdate
+ protected void preUpdate() {
+ updatedAt = LocalDateTime.now();
+ }
+
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/AvailabilityStatus.java b/backend/src/main/java/com/bookmyvenue/backend/enums/AvailabilityStatus.java
new file mode 100644
index 000000000..b1bfb8c22
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/AvailabilityStatus.java
@@ -0,0 +1,9 @@
+package com.bookmyvenue.backend.enums;
+
+public enum AvailabilityStatus {
+
+ AVAILABLE,
+ BLOCKED,
+ BOOKED
+
+ }
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/BookingStatus.java b/backend/src/main/java/com/bookmyvenue/backend/enums/BookingStatus.java
new file mode 100644
index 000000000..bf7f720a7
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/BookingStatus.java
@@ -0,0 +1,9 @@
+package com.bookmyvenue.backend.enums;
+
+public enum BookingStatus {
+ PENDING_PAYMENT,
+ CONFIRMED,
+ REJECTED,
+ CANCELLED,
+ COMPLETED
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/BookingType.java b/backend/src/main/java/com/bookmyvenue/backend/enums/BookingType.java
new file mode 100644
index 000000000..75fb0ef8a
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/BookingType.java
@@ -0,0 +1,6 @@
+package com.bookmyvenue.backend.enums;
+
+public enum BookingType {
+ FULL_DAY,
+ HOURLY
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/DocumentStatus.java b/backend/src/main/java/com/bookmyvenue/backend/enums/DocumentStatus.java
new file mode 100644
index 000000000..4f102af02
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/DocumentStatus.java
@@ -0,0 +1,8 @@
+package com.bookmyvenue.backend.enums;
+
+public enum DocumentStatus {
+ PENDING,
+ APPROVED,
+ REJECTED,
+ EXPIRED
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/DocumentType.java b/backend/src/main/java/com/bookmyvenue/backend/enums/DocumentType.java
new file mode 100644
index 000000000..a3ef0ab21
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/DocumentType.java
@@ -0,0 +1,13 @@
+package com.bookmyvenue.backend.enums;
+
+public enum DocumentType {
+ OWNERSHIP_PROOF,
+ BUSINESS_LICENSE,
+ TAX_CERTIFICATE,
+ GST_CERTIFICATE,
+ FLOOR_PLAN,
+ VENUE_IMAGE,
+ ID_PROOF,
+ ADDRESS_PROOF,
+ OTHER
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/EventType.java b/backend/src/main/java/com/bookmyvenue/backend/enums/EventType.java
new file mode 100644
index 000000000..e3a9d6f30
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/EventType.java
@@ -0,0 +1,10 @@
+package com.bookmyvenue.backend.enums;
+
+public enum EventType {
+ WEDDING,
+ CORPORATE,
+ BIRTHDAY,
+ RECEPTION,
+ PARTY,
+ OUTDOOR
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/PaymentStatus.java b/backend/src/main/java/com/bookmyvenue/backend/enums/PaymentStatus.java
new file mode 100644
index 000000000..7a957a8dd
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/PaymentStatus.java
@@ -0,0 +1,9 @@
+package com.bookmyvenue.backend.enums;
+
+public enum PaymentStatus {
+ PENDING,
+ SUCCESS,
+ FAILED,
+ PARTIAL
+
+ }
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/PaymentType.java b/backend/src/main/java/com/bookmyvenue/backend/enums/PaymentType.java
new file mode 100644
index 000000000..9fd74c1e0
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/PaymentType.java
@@ -0,0 +1,7 @@
+package com.bookmyvenue.backend.enums;
+
+public enum PaymentType {
+ PARTIAL_PAYMENT,
+ FULL_PAYMENT
+
+ }
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/PricingType.java b/backend/src/main/java/com/bookmyvenue/backend/enums/PricingType.java
new file mode 100644
index 000000000..75f017662
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/PricingType.java
@@ -0,0 +1,6 @@
+package com.bookmyvenue.backend.enums;
+
+public enum PricingType {
+ FULL_DAY,
+ HOURLY
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/RefundStatus.java b/backend/src/main/java/com/bookmyvenue/backend/enums/RefundStatus.java
new file mode 100644
index 000000000..f7891d215
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/RefundStatus.java
@@ -0,0 +1,7 @@
+package com.bookmyvenue.backend.enums;
+
+public enum RefundStatus {
+ REFUND_PENDING,
+ REFUND_COMPLETED
+
+ }
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/UserRole.java b/backend/src/main/java/com/bookmyvenue/backend/enums/UserRole.java
new file mode 100644
index 000000000..974ff0333
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/UserRole.java
@@ -0,0 +1,7 @@
+package com.bookmyvenue.backend.enums;
+
+public enum UserRole {
+ ADMIN,
+ VENUE_OWNER,
+ END_USER
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/UserStatus.java b/backend/src/main/java/com/bookmyvenue/backend/enums/UserStatus.java
new file mode 100644
index 000000000..ad336de4e
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/UserStatus.java
@@ -0,0 +1,7 @@
+package com.bookmyvenue.backend.enums;
+
+public enum UserStatus {
+ ACTIVE,
+ SUSPENDED,
+ BLOCKED
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/enums/VenueStatus.java b/backend/src/main/java/com/bookmyvenue/backend/enums/VenueStatus.java
new file mode 100644
index 000000000..6fc76db17
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/enums/VenueStatus.java
@@ -0,0 +1,9 @@
+package com.bookmyvenue.backend.enums;
+
+public enum VenueStatus {
+ PENDING_APPROVAL,
+ APPROVED,
+ REJECTED,
+ SUSPENDED
+
+ }
diff --git a/backend/src/main/java/com/bookmyvenue/backend/exception/BadRequestException.java b/backend/src/main/java/com/bookmyvenue/backend/exception/BadRequestException.java
new file mode 100644
index 000000000..f6db6e541
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/exception/BadRequestException.java
@@ -0,0 +1,10 @@
+package com.bookmyvenue.backend.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+public class BadRequestException extends RuntimeException {
+ public BadRequestException(String message) {
+ super(message);
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/exception/DuplicateResourceException.java b/backend/src/main/java/com/bookmyvenue/backend/exception/DuplicateResourceException.java
new file mode 100644
index 000000000..69ca5f928
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/exception/DuplicateResourceException.java
@@ -0,0 +1,10 @@
+package com.bookmyvenue.backend.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+public class DuplicateResourceException extends RuntimeException {
+ public DuplicateResourceException(String message) {
+ super(message);
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/exception/GlobalExceptionHandler.java b/backend/src/main/java/com/bookmyvenue/backend/exception/GlobalExceptionHandler.java
new file mode 100644
index 000000000..66e6135bc
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/exception/GlobalExceptionHandler.java
@@ -0,0 +1,71 @@
+package com.bookmyvenue.backend.exception;
+
+import com.bookmyvenue.backend.dto.common.ErrorResponse;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(BadRequestException.class)
+ public ResponseEntity handleBadRequestException(BadRequestException ex) {
+ ErrorResponse errorResponse = new ErrorResponse(
+ LocalDateTime.now(),
+ HttpStatus.BAD_REQUEST.value(),
+ List.of(ex.getMessage())
+ );
+
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST)
+ .body(errorResponse);
+ }
+
+ @ExceptionHandler(DuplicateResourceException.class)
+ public ResponseEntity handleDuplicateResourceException(DuplicateResourceException ex) {
+ ErrorResponse errorResponse = new ErrorResponse(
+ LocalDateTime.now(),
+ HttpStatus.CONFLICT.value(),
+ List.of(ex.getMessage())
+ );
+
+ return ResponseEntity.status(HttpStatus.CONFLICT)
+ .body(errorResponse);
+ }
+
+ @ExceptionHandler(ResourceNotFoundException.class)
+ public ResponseEntity handleResourceNotFoundException(ResourceNotFoundException ex) {
+ ErrorResponse errorResponse = new ErrorResponse(
+ LocalDateTime.now(),
+ HttpStatus.NOT_FOUND.value(),
+ List.of(ex.getMessage())
+ );
+
+ return ResponseEntity.status(HttpStatus.NOT_FOUND)
+ .body(errorResponse);
+ }
+
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
+
+ List errors = ex.getBindingResult()
+ .getFieldErrors()
+ .stream()
+ .map(FieldError::getDefaultMessage)
+ .toList();
+
+ ErrorResponse errorResponse = new ErrorResponse(
+ LocalDateTime.now(),
+ HttpStatus.BAD_REQUEST.value(),
+ errors
+ );
+
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST)
+ .body(errorResponse);
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/exception/ResourceNotFoundException.java b/backend/src/main/java/com/bookmyvenue/backend/exception/ResourceNotFoundException.java
new file mode 100644
index 000000000..59ce2384c
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/exception/ResourceNotFoundException.java
@@ -0,0 +1,15 @@
+package com.bookmyvenue.backend.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+public class ResourceNotFoundException extends RuntimeException {
+
+ public ResourceNotFoundException(String message) {
+ super(message);
+ }
+
+ public ResourceNotFoundException(String resource, Long id) {
+ super(resource + " not found with id " + id);
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/exception/SlotAlreadyBookedException.java b/backend/src/main/java/com/bookmyvenue/backend/exception/SlotAlreadyBookedException.java
new file mode 100644
index 000000000..b2122ffe0
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/exception/SlotAlreadyBookedException.java
@@ -0,0 +1,10 @@
+package com.bookmyvenue.backend.exception;
+
+public class SlotAlreadyBookedException
+ extends RuntimeException {
+
+ public SlotAlreadyBookedException(
+ String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/feature2.txt b/backend/src/main/java/com/bookmyvenue/backend/feature2.txt
new file mode 100644
index 000000000..c136b5f64
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/feature2.txt
@@ -0,0 +1,180 @@
+AuthController->Register, Login, Refresh Token
+UserController->User profile management
+VenueController->Venue CRUD
+VenueAvailabilityController->Availability management
+VenuePhotoController->Venue photo upload/manage
+VenueDocumentController->Venue document upload/manage
+AmenityController->Amenity CRUD
+VenueCategoryController->Venue category CRUD
+BookingController->Booking CRUD
+PaymentController->Payment processing
+********************************************
+
+AdminVenueController-> Approve/Reject venues
+AdminUserController-> Suspend/Delete users
+AdminDashboardController-> Statistics & analytics
+
+********************************************
+ReviewController-> Venue reviews and ratings
+NotificationController-> Notifications
+RefundController-> Refund management
+
+
+********************************************
+1. User Module
+Authentication
+Sign Up
+Login
+Google Login (optional)
+********************************************
+Venue Discovery
+Search nearby venues
+Filter by:
+Venue type
+Price
+Capacity
+Date
+********************************************
+Venue Details
+View photos
+View amenities
+Check availability
+View pricing
+********************************************
+Booking
+Create booking
+Make payment
+View booking history
+Cancel booking
+Request refund
+********************************************
+Suggested APIs
+POST /api/auth/register
+POST /api/auth/login
+
+GET /api/venues
+GET /api/venues/{id}
+
+POST /api/bookings
+
+GET /api/bookings/user/{userId}
+
+POST /api/payments
+
+PUT /api/bookings/{id}/cancel
+********************************************
+2. Venue Owner Module
+Owner Authentication
+Register as owner
+Login
+********************************************
+Venue Management
+Create venue
+Upload photos
+Upload documents
+Update venue details
+Update pricing
+Update availability
+********************************************
+Booking Management
+View incoming bookings
+Accept booking
+Reject booking
+********************************************
+Analytics
+Occupancy rate
+Booking statistics
+Revenue statistics
+********************************************
+Suggested APIs
+POST /api/venues
+
+PUT /api/venues/{id}
+
+POST /api/venue-photos
+
+POST /api/venue-documents
+
+POST /api/availability
+
+PUT /api/availability/{id}
+
+GET /api/bookings/owner/{ownerId}
+
+PATCH /api/bookings/{id}/accept
+
+PATCH /api/bookings/{id}/reject
+3. Admin Module
+********************************************
+User Management
+View users
+Suspend users
+Delete users
+********************************************
+Venue Approval
+Review venue
+Approve venue
+Reject venue
+********************************************
+Platform Monitoring
+View all bookings
+View all venues
+View all payments
+********************************************
+Analytics Dashboard
+Total Users
+Total Venues
+Total Bookings
+Total Revenue
+Suggested APIs
+GET /api/admin/users
+
+PATCH /api/admin/users/{id}/suspend
+
+DELETE /api/admin/users/{id}
+
+GET /api/admin/venues/pending
+
+PATCH /api/admin/venues/{id}/approve
+
+PATCH /api/admin/venues/{id}/reject
+
+GET /api/admin/bookings
+
+GET /api/admin/payments
+
+GET /api/admin/dashboard
+********************************************
+Recommended Database Tables
+
+Based on your current entities and this workflow, the core tables should be:
+
+users
+roles
+user_roles
+
+venue
+venue_category
+venue_category_map
+
+amenity
+venue_amenity
+
+venue_photo
+venue_document
+venue_availability
+
+booking
+payment
+refund
+
+review
+notification
+
+audit_log
+
+
+
+
+
+
diff --git a/backend/src/main/java/com/bookmyvenue/backend/features.txt b/backend/src/main/java/com/bookmyvenue/backend/features.txt
new file mode 100644
index 000000000..e12f1959e
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/features.txt
@@ -0,0 +1,495 @@
+
+
+
+
+1. Database Connection Pooling
+Use:
+HikariCP (default in Spring Boot)
+Benefits:
+Reuses database connections
+Reduces connection creation overhead
+Improves response time
+
+************************************************
+2. Asynchronous Processing
+Use:
+Java
+@Async
+public void sendEmail() {
+ // Long-running task
+}
+Benefits:
+User doesn't wait for email, report generation, etc.
+Faster API responses
+********************************************
+3. Message Queues
+Use:
+Apache Kafka
+RabbitMQ
+Benefits:
+Decouples components
+Handles spikes in traffic
+Improves reliability
+Example:
+Plain text
+Order Service
+ ↓
+Message Queue
+ ↓
+Email Processing
+***************************************
+4. Database Optimization
+Techniques:
+Proper indexing
+Query tuning
+Pagination
+Example:
+SQL
+CREATE INDEX idx_customer_email
+ON customer(email);
+Can reduce query time dramatically.
+***************************************
+5. Read Replicas
+Plain text
+Application
+ ↓
+Primary DB (Writes)
+ ↓
+Read Replica (Reads)
+Benefits:
+Reduces load on the main database
+Improves read performance
+***************************************
+6. Batch Processing
+Use:
+Spring Batch
+Instead of:
+Java
+for(100000 records)
+ save();
+Process records in chunks.
+Benefits:
+Better memory usage
+Faster bulk operations
+***************************************
+7. API Rate Limiting
+Prevent abuse using:
+Redis-based counters
+Libraries such as Bucket4j
+Example:
+100 requests per minute per user
+***************************************
+8. Compression
+Enable GZIP:
+Properties
+server.compression.enabled=true
+Benefits:
+Smaller responses
+Faster network transfers
+***************************************
+9. Monitoring & Observability
+Use:
+Spring Boot Actuator
+Prometheus
+Grafana
+Monitor:
+Response times
+Memory usage
+Database calls
+Error rates
+***************************************
+10. JVM Tuning
+Tune:
+Heap size
+Garbage collection
+Example:
+Bash
+-Xms2g -Xmx4g
+Benefits:
+Better memory management
+Fewer GC pauses
+***************************************
+11. Scheduled Jobs
+Use:
+Java
+@Scheduled(cron = "0 0 * * * *")
+For:
+Cleanup jobs
+Report generation
+Cache refresh
+***************************************
+12. Search Engine Integration
+For large datasets, use:
+Elasticsearch
+Instead of complex database searches.
+Benefits:
+Fast full-text search
+Better user experience
+**************************************
+
+13. Caching (You already mentioned)
+
+Use cache for:
+
+Venue details
+Venue availability
+Amenities list
+Venue categories
+City/state lookup data
+@Cacheable(value = "venues", key = "#venueId")
+public VenueResponseDto getVenue(Long venueId) {
+ return venueRepository.findById(venueId);
+}
+***************************************
+14. Pagination
+
+Never return all venues at once.
+
+Bad
+List findAll();
+Good
+Page findAll(Pageable pageable);
+
+Controller:
+
+@GetMapping
+public Page getAllVenues(
+ @RequestParam(defaultValue = "0") int page,
+ @RequestParam(defaultValue = "10") int size) {
+
+ return venueService.getAllVenues(page, size);
+}
+
+Benefits:
+
+Faster API response
+Reduced memory usage
+******************************************************************************
+15. Database Indexing
+
+For frequently searched columns.
+
+CREATE INDEX idx_venue_city ON venue(city);
+
+CREATE INDEX idx_venue_status ON venue(status);
+
+CREATE INDEX idx_booking_date ON booking(event_date);
+
+Useful for:
+
+City search
+Venue status
+Availability lookup
+Booking dates
+******************************************************************************
+16. DTO Layer
+
+Avoid exposing entities.
+
+Request DTO
+public class CreateVenueRequest {
+ private String venueName;
+ private Integer capacity;
+}
+Response DTO
+public class VenueResponse {
+ private Long venueId;
+ private String venueName;
+}
+
+Benefits:
+
+Better security
+API versioning
+Cleaner responses
+******************************************************************************
+17. MapStruct
+
+Avoid manual mapping.
+
+@Mapper(componentModel = "spring")
+public interface VenueMapper {
+
+ Venue toEntity(CreateVenueRequest dto);
+
+ VenueResponse toDto(Venue venue);
+}
+
+Benefits:
+
+Less boilerplate
+Faster than reflection-based mappers
+******************************************************************************
+18. Global Exception Handling
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(ResourceNotFoundException.class)
+ public ResponseEntity handleNotFound(
+ ResourceNotFoundException ex) {
+
+ return ResponseEntity.status(404)
+ .body(new ApiResponse(ex.getMessage()));
+ }
+}
+
+Benefits:
+
+Consistent error responses
+
+******************************************************************************
+18. Auditing
+
+Track who created/updated records.
+
+@EntityListeners(AuditingEntityListener.class)
+
+Base entity:
+
+@CreatedDate
+private LocalDateTime createdAt;
+
+@LastModifiedDate
+private LocalDateTime updatedAt;
+
+Useful for:
+
+Venue
+Booking
+Documents
+Availability
+******************************************************************************
+19. Soft Delete
+
+Instead of deleting data.
+
+private Boolean deleted = false;
+
+Query:
+
+WHERE deleted = false
+
+Benefits:
+
+Recover records
+Audit history
+*********************************************************************************************************************
+20. API Documentation
+
+Use Swagger/OpenAPI.
+
+springdoc-openapi
+
+Access:
+
+/swagger-ui.html
+
+Benefits:
+
+Easy testing
+Frontend integration
+*********************************************************************************************************************
+21. Validation
+@NotBlank
+private String venueName;
+
+@Min(1)
+private Integer capacity;
+
+Controller:
+
+@PostMapping
+public VenueResponse create(
+ @Valid @RequestBody CreateVenueRequest request) {
+}
+*********************************************************************************************************************
+22. Security
+
+Use JWT Authentication.
+
+Roles:
+
+ADMIN
+OWNER
+CUSTOMER
+
+Example:
+
+@PreAuthorize("hasRole('ADMIN')")
+*********************************************************************************************************************
+23. File Storage
+
+For venue documents.
+
+Instead of storing files in DB:
+
+Store:
+
+AWS S3
+Azure Blob Storage
+Local storage (development)
+
+Store only URL in database.
+
+document_url
+*********************************************************************************************************************
+24. Asynchronous Processing
+
+For email/SMS notifications.
+
+@Async
+public void sendBookingEmail() {
+}
+
+Benefits:
+
+Faster API responses
+*********************************************************************************************************************
+25. Database Connection Pooling
+
+Use HikariCP.
+
+spring.datasource.hikari.maximum-pool-size=20
+spring.datasource.hikari.minimum-idle=5
+
+Benefits:
+
+Better DB performance
+*********************************************************************************************************************
+26. Logging
+
+Use SLF4J.
+
+private static final Logger log =
+ LoggerFactory.getLogger(VenueService.class);
+log.info("Venue created: {}", venueId);
+*********************************************************************************************************************
+27. Monitoring
+
+Add Spring Boot Actuator.
+
+Dependency:
+
+spring-boot-starter-actuator
+
+Endpoints:
+
+/actuator/health
+/actuator/metrics
+
+Useful for production monitoring.
+*********************************************************************************************************************
+28. Search & Filtering
+
+Instead of:
+
+GET /venues
+
+Support:
+
+GET /venues?
+city=Kochi&
+capacity=500&
+priceMin=10000&
+priceMax=50000
+
+Use JPA Specifications.
+******************************************************************************
+29. Optimistic Locking
+
+Prevent concurrent updates.
+
+@Version
+private Long version;
+
+Useful when two admins edit the same venue.
+******************************************************************************
+30. Flyway Database Migration
+
+Instead of manually creating tables.
+
+V1__create_user_table.sql
+V2__create_venue_table.sql
+V3__create_booking_table.sql
+
+Benefits:
+
+Version-controlled database
+*********************************************************************************************************************
+31. API Response Standardization
+{
+ "success": true,
+ "message": "Venue created successfully",
+ "data": {}
+}
+
+Using your existing:
+
+ApiResponseWrapper
+*********************************************************************************************************************
+32. Rate Limiting
+
+Prevent abuse.
+
+Libraries:
+
+Bucket4j
+Resilience4j
+
+Example:
+
+100 requests/minute
+
+per user/IP.
+*********************************************************************************************************************
+33. Redis Session Storage
+
+If multiple application instances are added later.
+
+Store:
+
+JWT blacklist
+OTP
+Session data
+Cache
+
+Using Redis.
+*********************************************************************************************************************
+34. Notification Module
+
+Send:
+
+Booking confirmation
+Venue approval
+Venue rejection
+Payment success
+
+Through:
+
+Email
+SMS
+Push notifications
+*********************************************************************************************************************
+35. Event-Driven Design Inside Monolith
+
+Instead of tightly coupling services:
+
+applicationEventPublisher.publishEvent(
+ new VenueCreatedEvent(venueId));
+
+Listener:
+
+@EventListener
+public void handleVenueCreated(
+ VenueCreatedEvent event) {
+}
+
+Benefits:
+
+Easier future migration to microservices
+*********************************************************************************************************************
+36. API Versioning
+/api/v1/venues
+/api/v2/venues
+
+Useful when APIs evolve.
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/mapper/AmenityMapper.java b/backend/src/main/java/com/bookmyvenue/backend/mapper/AmenityMapper.java
new file mode 100644
index 000000000..02c6c4ad1
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/mapper/AmenityMapper.java
@@ -0,0 +1,14 @@
+package com.bookmyvenue.backend.mapper;
+
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityRequest;
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityResponse;
+import com.bookmyvenue.backend.entity.Amenity;
+import org.mapstruct.Mapper;
+
+@Mapper(componentModel = "spring")
+public interface AmenityMapper {
+
+ Amenity toEntity(AmenityRequest request );
+
+ AmenityResponse toResponse(Amenity response);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/mapper/BookingMapper.java b/backend/src/main/java/com/bookmyvenue/backend/mapper/BookingMapper.java
new file mode 100644
index 000000000..a8b0d3b19
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/mapper/BookingMapper.java
@@ -0,0 +1,17 @@
+package com.bookmyvenue.backend.mapper;
+
+import com.bookmyvenue.backend.dto.Book.BookingRequest;
+import com.bookmyvenue.backend.dto.Book.BookingResponse;
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityRequest;
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityResponse;
+import com.bookmyvenue.backend.entity.Amenity;
+import com.bookmyvenue.backend.entity.Booking;
+import org.mapstruct.Mapper;
+
+@Mapper(componentModel = "spring")
+public interface BookingMapper {
+
+ Booking toEntity(BookingRequest request );
+
+ BookingResponse toResponse(Booking booking);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/mapper/PaymentMapper.java b/backend/src/main/java/com/bookmyvenue/backend/mapper/PaymentMapper.java
new file mode 100644
index 000000000..0b49ba964
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/mapper/PaymentMapper.java
@@ -0,0 +1,42 @@
+package com.bookmyvenue.backend.mapper;
+
+import com.bookmyvenue.backend.dto.payment.PaymentRequestDTO;
+import com.bookmyvenue.backend.dto.payment.PaymentResponseDTO;
+import com.bookmyvenue.backend.entity.Booking;
+import com.bookmyvenue.backend.entity.Payment;
+import com.bookmyvenue.backend.enums.PaymentStatus;
+import com.bookmyvenue.backend.enums.RefundStatus;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+
+@Component
+public class PaymentMapper {
+
+ public Payment toEntity(PaymentRequestDTO dto, Booking booking) {
+ return Payment.builder()
+ .booking(booking)
+ .paymentType(dto.getPaymentType())
+ .amount(dto.getAmount())
+ .paymentDueDate(dto.getPaymentDueDate())
+ .paymentStatus(PaymentStatus.PENDING)
+ .refundStatus(RefundStatus.REFUND_PENDING)
+ .refundAmount(BigDecimal.ZERO)
+ .build();
+ }
+
+ public PaymentResponseDTO toDto(Payment payment) {
+ return PaymentResponseDTO.builder()
+ .paymentId(payment.getPaymentId())
+ .bookingId(payment.getBooking().getBookingId())
+ .paymentType(payment.getPaymentType())
+ .amount(payment.getAmount())
+ .refundAmount(payment.getRefundAmount())
+ .paymentStatus(payment.getPaymentStatus())
+ .refundStatus(payment.getRefundStatus())
+ .razorOrderId(payment.getRazorOrderId())
+ .razorPaymentId(payment.getRazorPaymentId())
+ .paidAt(payment.getPaidAt())
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/mapper/VenuAvailabilityMapper.java b/backend/src/main/java/com/bookmyvenue/backend/mapper/VenuAvailabilityMapper.java
new file mode 100644
index 000000000..5f4a392bf
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/mapper/VenuAvailabilityMapper.java
@@ -0,0 +1,13 @@
+package com.bookmyvenue.backend.mapper;
+
+import com.bookmyvenue.backend.dto.venuAvailability.VenueAvailabilityRequest;
+import com.bookmyvenue.backend.dto.venuAvailability.VenueAvailabilityResponse;
+import com.bookmyvenue.backend.entity.VenueAvailability;
+import org.mapstruct.Mapper;
+@Mapper(componentModel = "spring")
+public interface VenuAvailabilityMapper {
+
+ VenueAvailability toEntity(VenueAvailabilityRequest request );
+
+ VenueAvailabilityResponse toResponse(VenueAvailability response);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/mapper/VenueDocumentMapper.java b/backend/src/main/java/com/bookmyvenue/backend/mapper/VenueDocumentMapper.java
new file mode 100644
index 000000000..a79cad4b5
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/mapper/VenueDocumentMapper.java
@@ -0,0 +1,17 @@
+package com.bookmyvenue.backend.mapper;
+
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityRequest;
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityResponse;
+import com.bookmyvenue.backend.dto.venueDocument.VenueDocumentRequest;
+import com.bookmyvenue.backend.dto.venueDocument.VenueDocumentResponse;
+import com.bookmyvenue.backend.entity.Amenity;
+import com.bookmyvenue.backend.entity.VenueDocument;
+import org.mapstruct.Mapper;
+
+@Mapper(componentModel = "spring")
+public interface VenueDocumentMapper {
+
+ VenueDocument toEntity(VenueDocumentRequest request );
+
+ VenueDocumentResponse toResponse(VenueDocument response);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/mapper/VenueMapper.java b/backend/src/main/java/com/bookmyvenue/backend/mapper/VenueMapper.java
new file mode 100644
index 000000000..4b2c52170
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/mapper/VenueMapper.java
@@ -0,0 +1,26 @@
+package com.bookmyvenue.backend.mapper;
+
+import com.bookmyvenue.backend.dto.Venue.VenueRequest;
+import com.bookmyvenue.backend.dto.Venue.VenueResponse;
+import com.bookmyvenue.backend.entity.Amenity;
+import com.bookmyvenue.backend.entity.Venue;
+import org.mapstruct.Mapper;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Mapper(componentModel = "spring")
+public interface VenueMapper {
+
+ Venue toEntity(VenueRequest request );
+
+ VenueResponse toResponse(Venue venue);
+
+ default Set mapAmenities(Set amenities) {
+ if (amenities == null) return null;
+ return amenities.stream()
+ .map(Amenity::getAmenityName)
+ .collect(Collectors.toSet());
+ }
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/mapper/VenuePhotoMapper.java b/backend/src/main/java/com/bookmyvenue/backend/mapper/VenuePhotoMapper.java
new file mode 100644
index 000000000..fdd5e231a
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/mapper/VenuePhotoMapper.java
@@ -0,0 +1,13 @@
+package com.bookmyvenue.backend.mapper;
+import com.bookmyvenue.backend.dto.venuePhoto.VenuePhotoRequest;
+import com.bookmyvenue.backend.dto.venuePhoto.VenuePhotoResponse;
+import com.bookmyvenue.backend.entity.VenuePhoto;
+import org.mapstruct.Mapper;
+
+@Mapper(componentModel = "spring")
+public interface VenuePhotoMapper {
+
+ VenuePhoto toEntity(VenuePhotoRequest request );
+
+ VenuePhotoResponse toResponse(VenuePhoto response);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/repository/AmenityRepository.java b/backend/src/main/java/com/bookmyvenue/backend/repository/AmenityRepository.java
new file mode 100644
index 000000000..644df50cc
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/repository/AmenityRepository.java
@@ -0,0 +1,9 @@
+package com.bookmyvenue.backend.repository;
+
+import com.bookmyvenue.backend.entity.Amenity;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AmenityRepository extends JpaRepository {
+
+ boolean existsByAmenityName(String amenityName);
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/repository/BookingRepository.java b/backend/src/main/java/com/bookmyvenue/backend/repository/BookingRepository.java
new file mode 100644
index 000000000..cf20d1fa2
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/repository/BookingRepository.java
@@ -0,0 +1,69 @@
+package com.bookmyvenue.backend.repository;
+
+import com.bookmyvenue.backend.dto.Book.BookingResponse;
+import com.bookmyvenue.backend.entity.Booking;
+import com.bookmyvenue.backend.enums.BookingStatus;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.util.Collection;
+import java.util.List;
+
+@Repository
+public interface BookingRepository
+ extends JpaRepository,
+ JpaSpecificationExecutor {
+
+ long countByUserUserId(Long userId);
+
+ long countByVenueOwnerUserUserId(Long ownerId);
+
+ List
+ findTop5ByVenueOwnerUserUserIdOrderByCreatedAtDesc(
+ Long ownerId);
+
+ long countByVenueVenueId(Long venueId);
+
+ @Query("""
+ SELECT COALESCE(SUM(b.totalAmount), 0)
+ FROM Booking b
+ WHERE b.venue.ownerUser.userId = :ownerId
+ AND b.bookingStatus = com.bookmyvenue.backend.enums.BookingStatus.CONFIRMED
+ """)
+ BigDecimal getRevenueByOwnerId(
+ @Param("ownerId") Long ownerId);
+
+
+
+ @Query("""
+ SELECT COUNT(b)
+ FROM Booking b
+ WHERE b.venue.venueId = :venueId
+ AND b.eventDate = :eventDate
+ AND b.bookingStatus NOT IN (
+ com.bookmyvenue.backend.enums.BookingStatus.REJECTED,
+ com.bookmyvenue.backend.enums.BookingStatus.CANCELLED
+ )
+ AND (
+ :startTime < b.endTime
+ AND :endTime > b.startTime
+ )
+ """)
+ long countOverlappingBookings(
+ Long venueId,
+ LocalDate eventDate,
+ LocalTime startTime,
+ LocalTime endTime);
+
+ List findByUserUserId(Long userId);
+
+ List findByVenueOwnerUserUserId(Long ownerId);
+}
+
+
diff --git a/backend/src/main/java/com/bookmyvenue/backend/repository/PaymentRepository.java b/backend/src/main/java/com/bookmyvenue/backend/repository/PaymentRepository.java
new file mode 100644
index 000000000..1ced1d39a
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/repository/PaymentRepository.java
@@ -0,0 +1,23 @@
+package com.bookmyvenue.backend.repository;
+
+import com.bookmyvenue.backend.entity.Payment;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+public interface PaymentRepository
+ extends JpaRepository {
+
+ Optional
+ findByBookingBookingId(
+ Long bookingId);
+
+ List findByBooking_BookingId(Long bookingId);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/repository/ReviewRepository.java b/backend/src/main/java/com/bookmyvenue/backend/repository/ReviewRepository.java
new file mode 100644
index 000000000..8e7c913df
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/repository/ReviewRepository.java
@@ -0,0 +1,39 @@
+package com.bookmyvenue.backend.repository;
+
+import com.bookmyvenue.backend.entity.Review;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface ReviewRepository
+ extends JpaRepository {
+
+ List findByVenueVenueId(Long venueId);
+
+ List findByUserUserId(Long userId);
+
+ boolean existsByVenueVenueIdAndUserUserId(
+ Long venueId,
+ Long userId);
+
+ @Query("""
+ SELECT AVG(r.rating)
+ FROM Review r
+ WHERE r.venue.venueId = :venueId
+ """)
+ Double getAverageRating(
+ @Param("venueId") Long venueId);
+
+ @Query("""
+ SELECT AVG(r.rating)
+ FROM Review r
+ WHERE r.venue.ownerUser.userId = :ownerId
+ """)
+ Double getAverageRatingByOwner(
+ @Param("ownerId") Long ownerId);
+
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/repository/UserRepository.java b/backend/src/main/java/com/bookmyvenue/backend/repository/UserRepository.java
new file mode 100644
index 000000000..c55937716
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/repository/UserRepository.java
@@ -0,0 +1,22 @@
+package com.bookmyvenue.backend.repository;
+
+import com.bookmyvenue.backend.entity.Users;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface UserRepository extends JpaRepository , JpaSpecificationExecutor {
+
+ Optional findByEmail(String Email);
+ Optional findByPhone(String Phone);
+ boolean existsByEmail(String Email);
+ boolean existsByPhone(String Phone);
+ List findByFirstNameContainingIgnoreCase(
+ String name);
+
+ List findByEmailContainingIgnoreCase(
+ String email);
+
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/repository/VenueAvailabilityRepository.java b/backend/src/main/java/com/bookmyvenue/backend/repository/VenueAvailabilityRepository.java
new file mode 100644
index 000000000..6b845a276
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/repository/VenueAvailabilityRepository.java
@@ -0,0 +1,11 @@
+package com.bookmyvenue.backend.repository;
+import com.bookmyvenue.backend.entity.VenueAvailability;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface VenueAvailabilityRepository
+ extends JpaRepository {
+
+ List findByVenue_VenueId(Long venueId);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/repository/VenueDocumentRepository.java b/backend/src/main/java/com/bookmyvenue/backend/repository/VenueDocumentRepository.java
new file mode 100644
index 000000000..e0131f1db
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/repository/VenueDocumentRepository.java
@@ -0,0 +1,12 @@
+package com.bookmyvenue.backend.repository;
+import com.bookmyvenue.backend.entity.VenueDocument;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+
+public interface VenueDocumentRepository extends JpaRepository {
+
+
+ List findByVenueVenueId(Long venueId);
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/repository/VenuePhotoRepository.java b/backend/src/main/java/com/bookmyvenue/backend/repository/VenuePhotoRepository.java
new file mode 100644
index 000000000..f85b71bf8
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/repository/VenuePhotoRepository.java
@@ -0,0 +1,13 @@
+package com.bookmyvenue.backend.repository;
+
+import com.bookmyvenue.backend.entity.VenuePhoto;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface VenuePhotoRepository extends JpaRepository {
+
+ List findByVenue_VenueId(Long venueId);
+
+ List findByVenue_VenueIdOrderByDisplayOrderAsc(Long venueId);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/repository/VenueRepository.java b/backend/src/main/java/com/bookmyvenue/backend/repository/VenueRepository.java
new file mode 100644
index 000000000..7e535fee8
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/repository/VenueRepository.java
@@ -0,0 +1,30 @@
+package com.bookmyvenue.backend.repository;
+import com.bookmyvenue.backend.entity.Venue;
+import com.bookmyvenue.backend.entity.VenueAvailability;
+import com.bookmyvenue.backend.enums.VenueStatus;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+import java.util.List;
+
+@Repository
+public interface VenueRepository extends JpaRepository ,
+ JpaSpecificationExecutor {
+
+ List findByVenueId(Long venueId);
+
+ List findByStatus(VenueStatus status);
+
+ List findByCity(String city);
+
+ List findByOwnerUserUserId(Long userId);
+
+ boolean existsByVenueName(String venueName);
+
+ long countByOwnerUserUserId(Long ownerId);
+
+ long countByOwnerUserUserIdAndStatus(
+ Long ownerId,
+ VenueStatus status);
+
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/security/CustomUserDetailsService.java b/backend/src/main/java/com/bookmyvenue/backend/security/CustomUserDetailsService.java
new file mode 100644
index 000000000..1da189141
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/security/CustomUserDetailsService.java
@@ -0,0 +1,34 @@
+package com.bookmyvenue.backend.security;
+
+import com.bookmyvenue.backend.entity.Users;
+import com.bookmyvenue.backend.enums.UserStatus;
+import com.bookmyvenue.backend.repository.UserRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class CustomUserDetailsService implements UserDetailsService {
+
+ private final UserRepository userRepository;
+
+ @Override
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+ Users user = userRepository.findByEmail(username).orElseThrow(() ->
+ new UsernameNotFoundException("User not found"));
+
+ if(user.getStatus()!= UserStatus.ACTIVE){
+ throw new UsernameNotFoundException("User is not active");
+ }
+
+ return User.builder()
+ .username(user.getEmail())
+ .password(user.getPasswordHash())
+ .roles(user.getRole().name())
+ .build();
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/security/JwtAuthenticationFilter.java b/backend/src/main/java/com/bookmyvenue/backend/security/JwtAuthenticationFilter.java
new file mode 100644
index 000000000..0a656b5cd
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/security/JwtAuthenticationFilter.java
@@ -0,0 +1,67 @@
+package com.bookmyvenue.backend.security;
+
+import com.auth0.jwt.exceptions.JWTVerificationException;
+import com.bookmyvenue.backend.service.JwtService;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import java.io.IOException;
+
+@Component
+@RequiredArgsConstructor
+public class JwtAuthenticationFilter extends OncePerRequestFilter {
+
+ private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);
+
+ private final CustomUserDetailsService customUserDetailsService;
+ private final JwtService jwtService;
+
+ @Override
+ protected void doFilterInternal
+ (HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+ throws ServletException, IOException {
+
+ String authHeader = request.getHeader("Authorization");
+ if (authHeader == null || !authHeader.startsWith("Bearer ")) {
+ filterChain.doFilter(request, response);
+ return;
+ }
+
+ try {
+
+ String jwtToken = authHeader.substring(7);
+ String username = jwtService.extractUserName(jwtToken);
+
+ if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
+ UserDetails userDetails = customUserDetailsService.loadUserByUsername(username);
+
+ if (jwtService.validateToken(jwtToken, userDetails)) {
+ UsernamePasswordAuthenticationToken authentication =
+ new UsernamePasswordAuthenticationToken(
+ userDetails,
+ null,
+ userDetails.getAuthorities());
+
+ authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ }
+ }
+ }
+ catch (JWTVerificationException ex){
+ SecurityContextHolder.clearContext();
+ logger.warn("JWT Token verification failed: {}",ex.getMessage());
+ }
+ filterChain.doFilter(request,response);
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/AdminRequestService.java b/backend/src/main/java/com/bookmyvenue/backend/service/AdminRequestService.java
new file mode 100644
index 000000000..d9d97a5c4
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/AdminRequestService.java
@@ -0,0 +1,30 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.adminDashboard.AdminRequestResponse;
+import com.bookmyvenue.backend.dto.adminDashboard.AdminRequestSearchRequest;
+
+import java.util.List;
+
+public interface AdminRequestService {
+
+ List
+ getAllRequests();
+
+ List
+ searchRequests(
+ AdminRequestSearchRequest request);
+
+ AdminRequestResponse
+ approveRequest(
+ Long venueId,
+ String remarks);
+
+ AdminRequestResponse
+ rejectRequest(
+ Long venueId,
+ String remarks);
+
+ AdminRequestResponse
+ getRequestDetails(
+ Long venueId);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/AdminRequestServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/AdminRequestServiceImpl.java
new file mode 100644
index 000000000..14343fb0c
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/AdminRequestServiceImpl.java
@@ -0,0 +1,117 @@
+package com.bookmyvenue.backend.service;
+import com.bookmyvenue.backend.dto.adminDashboard.AdminRequestResponse;
+import com.bookmyvenue.backend.dto.adminDashboard.AdminRequestSearchRequest;
+import com.bookmyvenue.backend.entity.Venue;
+import com.bookmyvenue.backend.enums.VenueStatus;
+import com.bookmyvenue.backend.exception.ResourceNotFoundException;
+import com.bookmyvenue.backend.repository.VenueRepository;
+import com.bookmyvenue.backend.specification.AdminRequestSpecification;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class AdminRequestServiceImpl implements AdminRequestService {
+
+ private final VenueRepository venueRepository;
+
+ @Override
+ public List getAllRequests() {
+
+ return venueRepository.findAll()
+ .stream()
+ .map(this::mapToResponse)
+ .toList();
+ }
+
+ @Override
+ public AdminRequestResponse getRequestDetails(Long venueId) {
+
+ Venue venue = venueRepository.findById(venueId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found with id : "
+ + venueId));
+
+ return mapToResponse(venue);
+ }
+
+ @Override
+ public List searchRequests(
+ AdminRequestSearchRequest request) {
+
+ Specification specification =
+ Specification.allOf(
+ AdminRequestSpecification.hasVenueName(
+ request.getVenueName()),
+ AdminRequestSpecification.hasStatus(
+ request.getStatus()),
+ AdminRequestSpecification.hasOwner(
+ request.getOwnerId())
+ );
+
+ return venueRepository.findAll(specification)
+ .stream()
+ .map(this::mapToResponse)
+ .toList();
+ }
+
+ @Override
+ public AdminRequestResponse approveRequest(
+ Long venueId,
+ String remarks) {
+
+ Venue venue = venueRepository.findById(venueId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found with id : "
+ + venueId));
+
+ venue.setStatus(VenueStatus.APPROVED);
+ venue.setApprovalRemarks(remarks);
+
+ Venue updatedVenue =
+ venueRepository.save(venue);
+
+ return mapToResponse(updatedVenue);
+ }
+
+ @Override
+ public AdminRequestResponse rejectRequest(
+ Long venueId,
+ String remarks) {
+
+ Venue venue = venueRepository.findById(venueId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found with id : "
+ + venueId));
+
+ venue.setStatus(VenueStatus.REJECTED);
+ venue.setApprovalRemarks(remarks);
+
+ Venue updatedVenue =
+ venueRepository.save(venue);
+
+ return mapToResponse(updatedVenue);
+ }
+
+ private AdminRequestResponse mapToResponse(
+ Venue venue) {
+
+ return AdminRequestResponse.builder()
+ .venueId(venue.getVenueId())
+ .venueName(venue.getVenueName())
+ .ownerId(venue.getOwnerUser().getUserId())
+ .ownerName(venue.getOwnerUser().getFirstName())
+ .requestType("NEW_LISTING")
+ .status(venue.getStatus())
+ .requestDate(venue.getCreatedAt())
+ .approvalRemarks(
+ venue.getApprovalRemarks())
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/AdminUserService.java b/backend/src/main/java/com/bookmyvenue/backend/service/AdminUserService.java
new file mode 100644
index 000000000..feee8f34b
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/AdminUserService.java
@@ -0,0 +1,22 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.adminDashboard.AdminUserResponse;
+
+import java.util.List;
+
+public interface AdminUserService {
+
+ List getAllUsers();
+
+ AdminUserResponse getUserById(
+ Long userId);
+
+ List searchUsers(
+ String keyword);
+
+ AdminUserResponse suspendUser(
+ Long userId);
+
+ AdminUserResponse activateUser(
+ Long userId);
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/AdminUserServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/AdminUserServiceImpl.java
new file mode 100644
index 000000000..8aa26294f
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/AdminUserServiceImpl.java
@@ -0,0 +1,113 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.adminDashboard.AdminUserResponse;
+import com.bookmyvenue.backend.entity.Users;
+import com.bookmyvenue.backend.enums.UserStatus;
+import com.bookmyvenue.backend.exception.ResourceNotFoundException;
+import com.bookmyvenue.backend.repository.BookingRepository;
+import com.bookmyvenue.backend.repository.UserRepository;
+import com.bookmyvenue.backend.specification.UserSpecification;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class AdminUserServiceImpl
+ implements AdminUserService {
+
+ private final UserRepository userRepository;
+
+ private final BookingRepository bookingRepository;
+
+ @Override
+ public List getAllUsers() {
+
+ return userRepository.findAll()
+ .stream()
+ .map(this::mapToResponse)
+ .toList();
+ }
+
+ @Override
+ public AdminUserResponse getUserById(
+ Long userId) {
+
+ Users user =
+ userRepository.findById(userId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "User not found"));
+
+ return mapToResponse(user);
+ }
+
+ @Override
+ public List searchUsers(
+ String keyword) {
+
+ Specification spec =
+ Specification.allOf(
+ UserSpecification
+ .hasKeyword(keyword));
+
+ return userRepository.findAll(spec)
+ .stream()
+ .map(this::mapToResponse)
+ .toList();
+ }
+
+ @Override
+ public AdminUserResponse suspendUser(
+ Long userId) {
+
+ Users user =
+ userRepository.findById(userId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "User not found"));
+
+ user.setStatus(
+ UserStatus.SUSPENDED);
+
+ return mapToResponse(
+ userRepository.save(user));
+ }
+
+ @Override
+ public AdminUserResponse activateUser(
+ Long userId) {
+
+ Users user =
+ userRepository.findById(userId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "User not found"));
+
+ user.setStatus(
+ UserStatus.ACTIVE);
+
+ return mapToResponse(
+ userRepository.save(user));
+ }
+
+ private AdminUserResponse mapToResponse(
+ Users user) {
+
+ long bookingCount =
+ bookingRepository
+ .countByUserUserId(
+ user.getUserId());
+
+ return AdminUserResponse.builder()
+ .userId(user.getUserId())
+ .fullName(user.getFirstName())
+ .email(user.getEmail())
+ .status(user.getStatus())
+ .createdAt(user.getCreatedAt())
+ .totalBookings(bookingCount)
+ .build();
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/AdminVenueOwnerService.java b/backend/src/main/java/com/bookmyvenue/backend/service/AdminVenueOwnerService.java
new file mode 100644
index 000000000..7095106c5
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/AdminVenueOwnerService.java
@@ -0,0 +1,25 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.adminDashboard.AdminVenueOwnerResponse;
+import com.bookmyvenue.backend.dto.adminDashboard.AdminVenueOwnerSearchRequest;
+
+import java.util.List;
+
+public interface AdminVenueOwnerService {
+
+ List
+ getAllVenueOwners();
+
+ AdminVenueOwnerResponse
+ getVenueOwnerById(Long ownerId);
+
+ List
+ searchVenueOwners(
+ AdminVenueOwnerSearchRequest request);
+
+ AdminVenueOwnerResponse
+ verifyVenueOwner(Long ownerId);
+
+ AdminVenueOwnerResponse
+ suspendVenueOwner(Long ownerId);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/AdminVenueOwnerServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/AdminVenueOwnerServiceImpl.java
new file mode 100644
index 000000000..bfe447ea4
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/AdminVenueOwnerServiceImpl.java
@@ -0,0 +1,122 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.adminDashboard.AdminVenueOwnerResponse;
+import com.bookmyvenue.backend.dto.adminDashboard.AdminVenueOwnerSearchRequest;
+import com.bookmyvenue.backend.entity.Users;
+import com.bookmyvenue.backend.enums.UserStatus;
+import com.bookmyvenue.backend.exception.ResourceNotFoundException;
+import com.bookmyvenue.backend.repository.BookingRepository;
+import com.bookmyvenue.backend.repository.UserRepository;
+import com.bookmyvenue.backend.repository.VenueRepository;
+import com.bookmyvenue.backend.specification.VenueOwnerSpecification;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class AdminVenueOwnerServiceImpl
+ implements AdminVenueOwnerService {
+
+ private final UserRepository userRepository;
+ private final VenueRepository venueRepository;
+ private final BookingRepository bookingRepository;
+
+ @Override
+ public List
+ getAllVenueOwners() {
+
+ return userRepository.findAll()
+ .stream()
+ .map(this::mapToResponse)
+ .toList();
+ }
+
+ @Override
+ public AdminVenueOwnerResponse
+ getVenueOwnerById(Long ownerId) {
+
+ Users owner = userRepository.findById(ownerId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue owner not found"));
+
+ return mapToResponse(owner);
+ }
+
+
+ @Override
+ public List
+ searchVenueOwners(
+ AdminVenueOwnerSearchRequest request) {
+
+ Specification spec =
+ Specification.allOf(
+ VenueOwnerSpecification.hasName(
+ request.getName()),
+ VenueOwnerSpecification.hasEmail(
+ request.getEmail()),
+ VenueOwnerSpecification.hasStatus(
+ request.getStatus())
+ );
+
+ return userRepository.findAll(spec)
+ .stream()
+ .map(this::mapToResponse)
+ .toList();
+ }
+
+ @Override
+ public AdminVenueOwnerResponse
+ verifyVenueOwner(Long ownerId) {
+
+ Users owner = userRepository.findById(ownerId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue owner not found"));
+
+ owner.setStatus(UserStatus.ACTIVE);
+
+ return mapToResponse(
+ userRepository.save(owner));
+ }
+
+ @Override
+ public AdminVenueOwnerResponse
+ suspendVenueOwner(Long ownerId) {
+
+ Users owner = userRepository.findById(ownerId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue owner not found"));
+
+ owner.setStatus(UserStatus.SUSPENDED);
+
+ return mapToResponse(
+ userRepository.save(owner));
+ }
+
+ private AdminVenueOwnerResponse
+ mapToResponse(Users owner) {
+
+ Long totalVenues =
+ venueRepository.countByOwnerUserUserId(
+ owner.getUserId());
+
+ java.math.BigDecimal revenue =
+ bookingRepository
+ .getRevenueByOwnerId(
+ owner.getUserId());
+
+ return AdminVenueOwnerResponse.builder()
+ .ownerId(owner.getUserId())
+ .ownerName(owner.getFirstName())
+ .email(owner.getEmail())
+ .totalVenues(totalVenues)
+ .revenue(revenue)
+ .status(owner.getStatus())
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/AmenityService.java b/backend/src/main/java/com/bookmyvenue/backend/service/AmenityService.java
new file mode 100644
index 000000000..031d2e3ac
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/AmenityService.java
@@ -0,0 +1,21 @@
+package com.bookmyvenue.backend.service;
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityRequest;
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityResponse;
+
+import java.util.List;
+
+public interface AmenityService {
+
+ AmenityResponse createAmenity(AmenityRequest request);
+
+ AmenityResponse getAmenityById(Long id);
+
+ List getAllAmenities();
+
+ AmenityResponse updateAmenity(Long id,
+ AmenityRequest request);
+ void deleteAmenity(Long id);
+
+
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/AmenityServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/AmenityServiceImpl.java
new file mode 100644
index 000000000..c5024b2d8
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/AmenityServiceImpl.java
@@ -0,0 +1,84 @@
+
+package com.bookmyvenue.backend.service;
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityRequest;
+import com.bookmyvenue.backend.dto.venueAmenity.AmenityResponse;
+import com.bookmyvenue.backend.entity.Amenity;
+import com.bookmyvenue.backend.mapper.AmenityMapper;
+import com.bookmyvenue.backend.repository.AmenityRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class AmenityServiceImpl implements AmenityService {
+
+ private final AmenityRepository amenityRepository;
+ private final AmenityMapper mapper;
+
+ @Override
+ public AmenityResponse createAmenity(AmenityRequest request)
+ {
+ Amenity amenity = Amenity.builder()
+ .amenityName(request.getAmenityName())
+ .description(request.getDescription())
+ .isActive(request.getIsActive())
+ .createdBy(1L)
+ .updatedBy(1L)
+ .build();
+
+ Amenity savedAmenity = amenityRepository.save(amenity);
+ return mapper.toResponse(savedAmenity);
+ }
+
+ @Override
+ public AmenityResponse getAmenityById(Long id) {
+
+ Amenity amenity = amenityRepository.findById(id)
+ .orElseThrow(() ->
+ new RuntimeException("Amenity not found"));
+ return mapper.toResponse(amenity);
+ }
+
+ @Override
+ public List getAllAmenities() {
+
+ return amenityRepository.findAll()
+ .stream()
+ .map(mapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ public AmenityResponse updateAmenity(Long id,
+ AmenityRequest request) {
+
+ Amenity amenity = amenityRepository.findById(id)
+ .orElseThrow(() ->
+ new RuntimeException("Amenity not found"));
+ amenity = Amenity.builder()
+ .amenityId(amenity.getAmenityId())
+ .amenityName(request.getAmenityName())
+ .description(request.getDescription())
+ .isActive(request.getIsActive())
+ .createdAt(amenity.getCreatedAt())
+ .createdBy(amenity.getCreatedBy())
+ .updatedAt(java.time.LocalDateTime.now())
+ .updatedBy(1L)
+ .build();
+ Amenity updatedAmenity =
+ amenityRepository.save(amenity);
+ return mapper.toResponse(updatedAmenity);
+ }
+
+ @Override
+ public void deleteAmenity(Long id) {
+
+ Amenity amenity = amenityRepository.findById(id)
+ .orElseThrow(() ->
+ new RuntimeException("Amenity not found"));
+
+ amenityRepository.delete(amenity);
+ }
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/AuthenticationService.java b/backend/src/main/java/com/bookmyvenue/backend/service/AuthenticationService.java
new file mode 100644
index 000000000..ceec9d270
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/AuthenticationService.java
@@ -0,0 +1,12 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.authentication.LoginRequest;
+import com.bookmyvenue.backend.dto.authentication.LoginResponse;
+import com.bookmyvenue.backend.dto.authentication.RegisterRequest;
+import com.bookmyvenue.backend.dto.authentication.RegisterResponse;
+
+public interface AuthenticationService {
+
+ RegisterResponse register(RegisterRequest registerRequest);
+ LoginResponse login(LoginRequest loginRequest);
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/AuthenticationServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/AuthenticationServiceImpl.java
new file mode 100644
index 000000000..8364f5b7f
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/AuthenticationServiceImpl.java
@@ -0,0 +1,105 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.authentication.LoginRequest;
+import com.bookmyvenue.backend.dto.authentication.LoginResponse;
+import com.bookmyvenue.backend.dto.authentication.RegisterRequest;
+import com.bookmyvenue.backend.dto.authentication.RegisterResponse;
+import com.bookmyvenue.backend.entity.Users;
+import com.bookmyvenue.backend.enums.UserRole;
+import com.bookmyvenue.backend.enums.UserStatus;
+import com.bookmyvenue.backend.exception.BadRequestException;
+import com.bookmyvenue.backend.exception.DuplicateResourceException;
+import com.bookmyvenue.backend.repository.UserRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class AuthenticationServiceImpl implements AuthenticationService {
+
+ private final UserRepository userRepository;
+
+ private final PasswordEncoder passwordEncoder;
+
+ private final JwtService jwtService;
+
+ @Override
+ public RegisterResponse register(RegisterRequest registerRequest) {
+
+ if(UserRole.ADMIN.equals(registerRequest.getRole())){
+ throw new BadRequestException("Admin Registration is not allowed");
+ }
+
+ if(userRepository.existsByEmail(registerRequest.getEmail())){
+ throw new DuplicateResourceException("Email already registered");
+ }
+
+ if(userRepository.existsByPhone(registerRequest.getPhone())){
+ throw new DuplicateResourceException("Phone number already registered");
+ }
+
+ String encodedPassword = passwordEncoder.encode(registerRequest.getPassword());
+
+ Users user = Users.builder()
+ .firstName(registerRequest.getFirstName())
+ .lastName(registerRequest.getLastName())
+ .email(registerRequest.getEmail())
+ .phone(registerRequest.getPhone())
+ .role(registerRequest.getRole())
+ .passwordHash(encodedPassword)
+ .status(UserStatus.ACTIVE)
+ .createdBy(1L)
+ .updatedBy(1L)
+ .build();
+
+ Users savedUser = userRepository.save(user);
+
+ RegisterResponse registerResponse = new RegisterResponse();
+ registerResponse.setUserId(savedUser.getUserId());
+ registerResponse.setFirstName(savedUser.getFirstName());
+ registerResponse.setLastName(savedUser.getLastName());
+ registerResponse.setEmail(savedUser.getEmail());
+ registerResponse.setRole(savedUser.getRole());
+ registerResponse.setMessage("Successfully registered. Please login with your credentials.");
+
+ return registerResponse;
+ }
+
+ @Override
+ public LoginResponse login(LoginRequest loginRequest) {
+ Users user;
+
+ if(loginRequest.getUserName().contains("@")){
+ user = userRepository.findByEmail(loginRequest.getUserName())
+ .orElseThrow(()-> new BadRequestException("Invalid Credentials"));
+ }
+ else if(loginRequest.getUserName().matches(("^[6-9][0-9]{9}$"))){
+ user = userRepository.findByPhone(loginRequest.getUserName())
+ .orElseThrow(()-> new BadRequestException("Invalid Credentials"));
+ }
+ else{
+ throw new BadRequestException("Invalid Credentials");
+ }
+
+ if(!passwordEncoder.matches(loginRequest.getPassword(),user.getPasswordHash())){
+ throw new BadRequestException("Invalid Credentials ");
+ }
+
+ LoginResponse loginResponse = new LoginResponse();
+
+ String token = jwtService.generateToken(user);
+ loginResponse.setToken(token);
+
+ loginResponse.setUserId(user.getUserId());
+ loginResponse.setFirstName(user.getFirstName());
+ loginResponse.setEmail(user.getEmail());
+ loginResponse.setPhone(user.getPhone());
+ loginResponse.setCity(user.getCity());
+ loginResponse.setRole(user.getRole());
+ loginResponse.setMessage("Login Successful");
+
+ return loginResponse;
+ }
+
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/BookingService.java b/backend/src/main/java/com/bookmyvenue/backend/service/BookingService.java
new file mode 100644
index 000000000..19e4a2953
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/BookingService.java
@@ -0,0 +1,34 @@
+package com.bookmyvenue.backend.service;
+import com.bookmyvenue.backend.dto.Book.BookingRequest;
+import com.bookmyvenue.backend.dto.Book.BookingResponse;
+import com.bookmyvenue.backend.dto.Book.BookingStatusRequest;
+import java.util.List;
+
+
+ public interface BookingService {
+
+ BookingResponse createBooking(
+ BookingRequest request);
+
+ BookingResponse getBookingById(
+ Long bookingId);
+
+ List getAllBookings();
+
+ List getBookingsByUser(
+ Long userId);
+
+ List getBookingsByOwner(
+ Long ownerId);
+
+ BookingResponse updateBookingStatus(
+ Long bookingId,
+ BookingStatusRequest request);
+
+ void cancelBooking(
+ Long bookingId);
+
+ List searchBookings(
+ BookingRequest request);
+ }
+
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/BookingServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/BookingServiceImpl.java
new file mode 100644
index 000000000..6454750e9
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/BookingServiceImpl.java
@@ -0,0 +1,206 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.Book.BookingRequest;
+import com.bookmyvenue.backend.dto.Book.BookingResponse;
+import com.bookmyvenue.backend.dto.Book.BookingStatusRequest;
+import com.bookmyvenue.backend.entity.Booking;
+import com.bookmyvenue.backend.entity.Users;
+import com.bookmyvenue.backend.entity.Venue;
+import com.bookmyvenue.backend.enums.BookingStatus;
+import com.bookmyvenue.backend.exception.ResourceNotFoundException;
+import com.bookmyvenue.backend.exception.SlotAlreadyBookedException;
+import com.bookmyvenue.backend.mapper.AmenityMapper;
+import com.bookmyvenue.backend.mapper.BookingMapper;
+import com.bookmyvenue.backend.repository.BookingRepository;
+import com.bookmyvenue.backend.repository.PaymentRepository;
+import com.bookmyvenue.backend.repository.UserRepository;
+import com.bookmyvenue.backend.repository.VenueRepository;
+import com.bookmyvenue.backend.specification.BookingSpecification;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Collections;
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class BookingServiceImpl implements BookingService {
+
+ private final VenueRepository venueRepository;
+ private final BookingRepository bookingRepository;
+ private final UserRepository usersRepository;
+
+ private final BookingMapper bookingMapper;
+ @Override
+ public BookingResponse createBooking(
+ BookingRequest request) {
+
+
+ Venue venue = venueRepository
+ .findById(request.getVenueId())
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found"));
+
+ Users user = usersRepository
+ .findById(request.getUserId())
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "User not found"));
+
+ // Time Slot Validation
+
+ long overlapCount =
+ bookingRepository.countOverlappingBookings(
+ request.getVenueId(),
+ request.getBookingDate(),
+ request.getStartTime(),
+ request.getEndTime());
+
+ if (overlapCount > 0) {
+ throw new SlotAlreadyBookedException(
+ "Venue is already booked for the selected time slot");
+ }
+
+ Booking booking =
+ bookingMapper.toEntity(request);
+
+ booking.setVenue(venue);
+ booking.setUser(user);
+
+ // Amount Calculation
+
+ BigDecimal totalAmount =
+ venue.getBasePrice();
+
+ booking.setTotalAmount(totalAmount);
+ booking.setPaidAmount(BigDecimal.ZERO);
+ booking.setBalanceAmount(totalAmount);
+
+ booking.setBookingStatus(
+ BookingStatus.PENDING_PAYMENT);
+
+ Booking savedBooking =
+ bookingRepository.save(booking);
+
+ return bookingMapper.toResponse(savedBooking);
+ }
+
+ @Override
+ public BookingResponse getBookingById(Long bookingId) {
+
+ Booking booking =
+ bookingRepository.findById(bookingId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Booking not found"));
+
+ return bookingMapper.toResponse(booking);
+ }
+
+
+ @Override
+ public List getAllBookings() {
+
+ return bookingRepository.findAll()
+ .stream()
+ .map(bookingMapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ public List getBookingsByUser(Long userId) {
+
+ return bookingRepository
+ .findByUserUserId(userId)
+ .stream()
+ .map(bookingMapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ public List getBookingsByOwner(Long ownerId) {
+
+ return bookingRepository
+ .findByVenueOwnerUserUserId(ownerId)
+ .stream()
+ .map(bookingMapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ public BookingResponse updateBookingStatus(
+ Long bookingId,
+ BookingStatusRequest request) {
+
+ Booking booking = bookingRepository
+ .findById(bookingId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Booking not found with id: " + bookingId));
+
+ BookingStatus newStatus =
+ request.getBookingStatus();
+
+ booking.setBookingStatus(newStatus);
+
+ // Handle cancellation
+ if (BookingStatus.CANCELLED.equals(newStatus)) {
+
+ booking.setCancellationAt(
+ LocalDateTime.now());
+
+ booking.setCancellationReason(
+ request.getCancellationReason());
+
+ booking.setCancelledBy(
+ request.getCancelledBy());
+ }
+
+ Booking updatedBooking =
+ bookingRepository.save(booking);
+
+ return bookingMapper.toResponse(
+ updatedBooking);
+ }
+ @Override
+ public void cancelBooking(Long bookingId) {
+
+ Booking booking =
+ bookingRepository.findById(bookingId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Booking not found"));
+
+ booking.setBookingStatus(
+ BookingStatus.CANCELLED);
+
+ booking.setCancellationAt(
+ LocalDateTime.now());
+
+ booking.setCancellationReason(
+ "Cancelled by User");
+
+ bookingRepository.save(booking);
+ }
+ @Override
+ public List searchBookings(BookingRequest request) {
+
+ Specification spec =
+ BookingSpecification.build(
+ request.getVenueId(),
+ request.getUserId(),
+ request.getBookingStatus(),
+ request.getBookingDate()
+ );
+
+ List bookings = bookingRepository.findAll(spec);
+ return bookings.stream()
+ .map(bookingMapper::toResponse)
+ .toList();
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/CustomUserDetailsService.java b/backend/src/main/java/com/bookmyvenue/backend/service/CustomUserDetailsService.java
new file mode 100644
index 000000000..2ec883838
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/CustomUserDetailsService.java
@@ -0,0 +1,31 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.entity.Users;
+import com.bookmyvenue.backend.repository.UserRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+
+@Service
+@RequiredArgsConstructor
+public class CustomUserDetailsService implements UserDetailsService {
+
+ private final UserRepository userRepository;
+
+ @Override
+ public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
+ Users user = userRepository.findByEmail(email)
+ .orElseThrow(() -> new UsernameNotFoundException("User not found with email: " + email));
+
+ return new org.springframework.security.core.userdetails.User(
+ user.getEmail(),
+ user.getPasswordHash(),
+ Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + user.getRole().name()))
+ );
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/JwtService.java b/backend/src/main/java/com/bookmyvenue/backend/service/JwtService.java
new file mode 100644
index 000000000..7e0dd27b4
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/JwtService.java
@@ -0,0 +1,13 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.entity.Users;
+import org.springframework.security.core.userdetails.UserDetails;
+
+public interface JwtService {
+
+ String generateToken(Users user);
+ String extractUserName(String token);
+ Long extractUserId(String token);
+ String extractUserRole(String token);
+ boolean validateToken(String token, UserDetails userDetails);
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/JwtServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/JwtServiceImpl.java
new file mode 100644
index 000000000..11f6c5f99
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/JwtServiceImpl.java
@@ -0,0 +1,73 @@
+package com.bookmyvenue.backend.service;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTVerificationException;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import com.bookmyvenue.backend.entity.Users;
+import jakarta.annotation.PostConstruct;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+@Service
+public class JwtServiceImpl implements JwtService {
+
+ @Value("${jwt.secret}")
+ private String jwtSecret;
+
+ @Value("${jwt.expiration-millis}")
+ private Long jwtExpirationMillis;
+
+ private Algorithm algorithm;
+
+ private DecodedJWT getDecodedJWT(String token) {
+ return JWT.require(algorithm).build().verify(token);
+ }
+
+ @PostConstruct
+ public void init() {
+ algorithm = Algorithm.HMAC256(jwtSecret);
+ }
+
+
+ @Override
+ public String generateToken(Users user) {
+
+ return JWT.create()
+ .withSubject(user.getEmail())
+ .withClaim("userId", user.getUserId())
+ .withClaim("role", user.getRole().name())
+ .withIssuedAt(new Date())
+ .withExpiresAt(new Date(System.currentTimeMillis() + jwtExpirationMillis))
+ .sign(algorithm);
+ }
+
+ @Override
+ public String extractUserName(String token) {
+ return getDecodedJWT(token).getSubject();
+ }
+
+ @Override
+ public String extractUserRole(String token) {
+ return getDecodedJWT(token).getClaims().get("role").asString();
+ }
+
+ @Override
+ public Long extractUserId(String token) {
+ return getDecodedJWT(token).getClaim("userId").asLong();
+ }
+
+ @Override
+ public boolean validateToken(String token, UserDetails userDetails) {
+ try {
+ DecodedJWT decodedJWT = getDecodedJWT(token);
+ return userDetails.getUsername().equals(decodedJWT.getSubject());
+ }
+ catch (JWTVerificationException ex) {
+ return false;
+ }
+ }
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/OwnerDashboardService.java b/backend/src/main/java/com/bookmyvenue/backend/service/OwnerDashboardService.java
new file mode 100644
index 000000000..48d8a770b
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/OwnerDashboardService.java
@@ -0,0 +1,9 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.venueOwnerDashboard.OwnerDashboardResponse;
+
+public interface OwnerDashboardService {
+
+ OwnerDashboardResponse
+ getDashboard(Long ownerId);
+}
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/OwnerDashboardServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/OwnerDashboardServiceImpl.java
new file mode 100644
index 000000000..4c434747b
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/OwnerDashboardServiceImpl.java
@@ -0,0 +1,113 @@
+package com.bookmyvenue.backend.service;
+import com.bookmyvenue.backend.dto.venueOwnerDashboard.OwnerDashboardResponse;
+import com.bookmyvenue.backend.dto.venueOwnerDashboard.OwnerVenueDto;
+import com.bookmyvenue.backend.dto.venueOwnerDashboard.RecentBookingDto;
+import com.bookmyvenue.backend.entity.Booking;
+import com.bookmyvenue.backend.entity.Payment;
+import com.bookmyvenue.backend.enums.VenueStatus;
+import com.bookmyvenue.backend.repository.BookingRepository;
+import com.bookmyvenue.backend.repository.PaymentRepository;
+import com.bookmyvenue.backend.repository.VenueRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class OwnerDashboardServiceImpl
+ implements OwnerDashboardService {
+
+ private final VenueRepository venueRepository;
+ private final BookingRepository bookingRepository;
+ private final PaymentRepository paymentRepository;
+
+
+ @Override
+ public OwnerDashboardResponse getDashboard(
+ Long ownerId) {
+
+ Long totalVenues =
+ venueRepository
+ .countByOwnerUserUserId(
+ ownerId);
+
+ Long activeVenues =
+ venueRepository
+ .countByOwnerUserUserIdAndStatus(
+ ownerId,
+ VenueStatus.APPROVED);
+
+ Long totalBookings =
+ bookingRepository
+ .countByVenueOwnerUserUserId(
+ ownerId);
+
+ BigDecimal revenue =
+ bookingRepository
+ .getRevenueByOwnerId(
+ ownerId);
+
+ List recentBookings =
+ bookingRepository
+ .findTop5ByVenueOwnerUserUserIdOrderByCreatedAtDesc(
+ ownerId)
+ .stream()
+ .map(this::mapBooking)
+ .toList();
+
+ List venues =
+ venueRepository
+ .findByOwnerUserUserId(
+ ownerId)
+ .stream()
+ .map(v -> OwnerVenueDto.builder()
+ .venueId(v.getVenueId())
+ .venueName(v.getVenueName())
+ .city(v.getCity())
+ .status(v.getStatus())
+ .bookingCount(
+ bookingRepository
+ .countByVenueVenueId(
+ v.getVenueId()))
+ .build())
+ .toList();
+
+ return OwnerDashboardResponse.builder()
+ .activeVenues(activeVenues)
+ .totalVenues(totalVenues)
+ .totalBookings(totalBookings)
+ .revenueEarned(revenue)
+ .averageRating(0.0)
+ .recentBookings(recentBookings)
+ .venues(venues)
+ .build();
+ }
+
+ private RecentBookingDto mapBooking(
+ Booking booking) {
+ Payment payment =
+ paymentRepository
+ .findByBookingBookingId(
+ booking.getBookingId())
+ .orElse(null);
+
+ return RecentBookingDto.builder()
+ .guestName(
+ booking.getUser()
+ .getFirstName())
+ .venueName(
+ booking.getVenue()
+ .getVenueName())
+ .bookingDate(
+ booking.getEventDate())
+ .amount(
+ payment != null
+ ? payment.getAmount()
+ : BigDecimal.ZERO)
+ .status(
+ booking.getBookingStatus())
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/PaymentService.java b/backend/src/main/java/com/bookmyvenue/backend/service/PaymentService.java
new file mode 100644
index 000000000..b532e3586
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/PaymentService.java
@@ -0,0 +1,20 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.payment.PaymentRequestDTO;
+import com.bookmyvenue.backend.dto.payment.PaymentResponseDTO;
+import com.bookmyvenue.backend.dto.payment.PaymentUpdateDTO;
+
+import java.util.List;
+
+public interface PaymentService {
+
+ PaymentResponseDTO createPayment(PaymentRequestDTO request);
+
+ PaymentResponseDTO getPaymentById(Long paymentId);
+
+ List getPaymentsByBookingId(Long bookingId);
+
+ PaymentResponseDTO updatePayment(Long paymentId, PaymentUpdateDTO request);
+
+ void deletePayment(Long paymentId);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/PaymentServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/PaymentServiceImpl.java
new file mode 100644
index 000000000..1d7aa7026
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/PaymentServiceImpl.java
@@ -0,0 +1,82 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.payment.PaymentRequestDTO;
+import com.bookmyvenue.backend.dto.payment.PaymentResponseDTO;
+import com.bookmyvenue.backend.dto.payment.PaymentUpdateDTO;
+import com.bookmyvenue.backend.entity.Booking;
+import com.bookmyvenue.backend.entity.Payment;
+import com.bookmyvenue.backend.exception.ResourceNotFoundException;
+import com.bookmyvenue.backend.mapper.PaymentMapper;
+import com.bookmyvenue.backend.repository.BookingRepository;
+import com.bookmyvenue.backend.repository.PaymentRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class PaymentServiceImpl implements PaymentService {
+
+ private final PaymentRepository paymentRepository;
+ private final BookingRepository bookingRepository;
+ private final PaymentMapper paymentMapper;
+
+ @Override
+ public PaymentResponseDTO createPayment(PaymentRequestDTO request) {
+
+ Booking booking = bookingRepository.findById(request.getBookingId())
+ .orElseThrow(() -> new ResourceNotFoundException("Booking not found"));
+
+ Payment payment = paymentMapper.toEntity(request, booking);
+
+ return paymentMapper.toDto(paymentRepository.save(payment));
+ }
+
+ @Override
+ public PaymentResponseDTO getPaymentById(Long paymentId) {
+
+ Payment payment = paymentRepository.findById(paymentId)
+ .orElseThrow(() -> new ResourceNotFoundException("Payment not found"));
+
+ return paymentMapper.toDto(payment);
+ }
+
+ @Override
+ public List getPaymentsByBookingId(Long bookingId) {
+
+ return paymentRepository.findByBooking_BookingId(bookingId)
+ .stream()
+ .map(paymentMapper::toDto)
+ .toList();
+ }
+
+ @Override
+ public PaymentResponseDTO updatePayment(Long paymentId, PaymentUpdateDTO request) {
+
+ Payment payment = paymentRepository.findById(paymentId)
+ .orElseThrow(() -> new ResourceNotFoundException("Payment not found"));
+
+ if (request.getPaymentStatus() != null) {
+ payment.setPaymentStatus(request.getPaymentStatus());
+ }
+
+ if (request.getRefundStatus() != null) {
+ payment.setRefundStatus(request.getRefundStatus());
+ }
+
+ if (request.getRazorPaymentId() != null) {
+ payment.setRazorPaymentId(request.getRazorPaymentId());
+ }
+
+ return paymentMapper.toDto(paymentRepository.save(payment));
+ }
+
+ @Override
+ public void deletePayment(Long paymentId) {
+ if (!paymentRepository.existsById(paymentId)) {
+ throw new ResourceNotFoundException("Payment not found");
+ }
+ paymentRepository.deleteById(paymentId);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/VenueAvailabilityService.java b/backend/src/main/java/com/bookmyvenue/backend/service/VenueAvailabilityService.java
new file mode 100644
index 000000000..5cce31958
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/VenueAvailabilityService.java
@@ -0,0 +1,23 @@
+package com.bookmyvenue.backend.service;
+import com.bookmyvenue.backend.dto.venuAvailability.VenueAvailabilityResponse;
+import com.bookmyvenue.backend.dto.venuAvailability.VenueAvailabilityRequest;
+
+import java.util.List;
+
+public interface VenueAvailabilityService {
+
+ VenueAvailabilityResponse create(
+ VenueAvailabilityRequest request);
+
+ VenueAvailabilityResponse getById(Long id);
+
+ List getAll();
+
+ List getByVenueId(Long venueId);
+
+ VenueAvailabilityResponse update(
+ Long id,
+ VenueAvailabilityRequest request);
+
+ void delete(Long id);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/VenueAvailabilityServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/VenueAvailabilityServiceImpl.java
new file mode 100644
index 000000000..bd40852d6
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/VenueAvailabilityServiceImpl.java
@@ -0,0 +1,118 @@
+package com.bookmyvenue.backend.service;
+import com.bookmyvenue.backend.dto.venuAvailability.VenueAvailabilityRequest;
+import com.bookmyvenue.backend.dto.venuAvailability.VenueAvailabilityResponse;
+import com.bookmyvenue.backend.entity.Venue;
+import com.bookmyvenue.backend.entity.VenueAvailability;
+import com.bookmyvenue.backend.exception.ResourceNotFoundException;
+import com.bookmyvenue.backend.mapper.VenuAvailabilityMapper;
+import com.bookmyvenue.backend.repository.VenueAvailabilityRepository;
+import com.bookmyvenue.backend.repository.VenueRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class VenueAvailabilityServiceImpl
+ implements VenueAvailabilityService {
+
+ private final VenueAvailabilityRepository repository;
+ private final VenueRepository venueRepository;
+ private final VenueAvailabilityRepository venueAvailabilityRepository;
+ private final VenuAvailabilityMapper mapper;
+
+ @Override
+ public VenueAvailabilityResponse create(
+ VenueAvailabilityRequest request) {
+
+ Venue venue = venueRepository.findById(
+ request.getVenueId())
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found"));
+
+ VenueAvailability availability =
+ VenueAvailability.builder()
+ .venue(venue)
+ .availableDate(request.getAvailableDate())
+ .startTime(request.getStartTime())
+ .endTime(request.getEndTime())
+ .availabilityStatus(
+ request.getAvailabilityStatus())
+ .reason(request.getReason())
+ .createdBy(request.getCreatedBy())
+ .updatedBy(request.getCreatedBy())
+ .build();
+
+ return mapper.toResponse(
+ repository.save(availability));
+ }
+
+ @Override
+ public VenueAvailabilityResponse getById(Long id) {
+
+ return mapper.toResponse(
+ repository.findById(id)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Availability not found")));
+ }
+
+ @Override
+ public List getAll() {
+
+ return repository.findAll()
+ .stream()
+ .map(mapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ public List getByVenueId(
+ Long venueId) {
+
+ return venueAvailabilityRepository.findByVenue_VenueId(venueId)
+ .stream()
+ .map(mapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ public VenueAvailabilityResponse update(
+ Long id,
+ VenueAvailabilityRequest request) {
+
+ VenueAvailability availability =
+ repository.findById(id)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Availability not found"));
+
+ availability.setAvailableDate(
+ request.getAvailableDate());
+ availability.setStartTime(
+ request.getStartTime());
+ availability.setEndTime(
+ request.getEndTime());
+ availability.setAvailabilityStatus(
+ request.getAvailabilityStatus());
+ availability.setReason(
+ request.getReason());
+
+ return mapper.toResponse(
+ repository.save(availability));
+ }
+
+ @Override
+ public void delete(Long id) {
+
+ VenueAvailability availability =
+ repository.findById(id)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Availability not found"));
+
+ repository.delete(availability);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/VenueDocumentService.java b/backend/src/main/java/com/bookmyvenue/backend/service/VenueDocumentService.java
new file mode 100644
index 000000000..cd41614fd
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/VenueDocumentService.java
@@ -0,0 +1,23 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.venueDocument.*;
+
+import java.util.List;
+
+public interface VenueDocumentService {
+
+ VenueDocumentResponse createDocument(
+ VenueDocumentRequest request);
+
+ VenueDocumentResponse getDocumentById(Long id);
+
+ List getAllDocuments();
+
+ List getDocumentsByVenue(Long venueId);
+
+ VenueDocumentResponse updateDocument(
+ Long id,
+ VenueDocumentRequest request);
+
+ void deleteDocument(Long id);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/VenueDocumentServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/VenueDocumentServiceImpl.java
new file mode 100644
index 000000000..10eb95aa0
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/VenueDocumentServiceImpl.java
@@ -0,0 +1,117 @@
+package com.bookmyvenue.backend.service;
+import com.bookmyvenue.backend.dto.venueDocument.VenueDocumentRequest;
+import com.bookmyvenue.backend.dto.venueDocument.VenueDocumentResponse;
+import com.bookmyvenue.backend.entity.Venue;
+import com.bookmyvenue.backend.entity.VenueDocument;
+import com.bookmyvenue.backend.exception.ResourceNotFoundException;
+import com.bookmyvenue.backend.mapper.VenueDocumentMapper;
+import com.bookmyvenue.backend.repository.VenueDocumentRepository;
+import com.bookmyvenue.backend.repository.VenueRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class VenueDocumentServiceImpl implements VenueDocumentService {
+
+ private final VenueDocumentRepository venueDocumentRepository;
+ private final VenueDocumentMapper venueDocumentMapper;
+ private final VenueRepository venueRepository;
+
+
+ @Override
+ public VenueDocumentResponse createDocument(
+ VenueDocumentRequest request) {
+
+ Venue venue = venueDocumentRepository.findById(request.getVenueId())
+ .orElseThrow(() -> new ResourceNotFoundException(
+ "Venue not found with id: " + request.getVenueId())).getVenue();
+
+ VenueDocument venueDocument = VenueDocument.builder()
+ .venue(venue)
+ .documentType(request.getDocumentType())
+ .documentName(request.getDocumentName())
+ .documentUrl(request.getDocumentUrl())
+ .documentStatus(request.getDocumentStatus())
+ .remarks(request.getRemarks())
+ .createdBy(1L)
+ .updatedBy(1L)
+ .build();
+
+ VenueDocument savedDocument =
+ venueDocumentRepository.save(venueDocument);
+
+ return venueDocumentMapper.toResponse(savedDocument);
+ }
+
+ @Override
+ public VenueDocumentResponse getDocumentById(Long id) {
+
+ VenueDocument venueDocument =
+ venueDocumentRepository.findById(id)
+ .orElseThrow(() -> new ResourceNotFoundException(
+ "Document not found with id: " + id));
+
+ return venueDocumentMapper.toResponse(venueDocument);
+ }
+
+ @Override
+ public List getAllDocuments() {
+
+ return venueDocumentRepository.findAll()
+ .stream()
+ .map(venueDocumentMapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ public List getDocumentsByVenue(Long venueId) {
+
+ return venueDocumentRepository
+ .findByVenueVenueId(venueId)
+ .stream()
+ .map(venueDocumentMapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ public VenueDocumentResponse updateDocument(
+ Long id,
+ VenueDocumentRequest request) {
+
+ VenueDocument existingDocument =
+ venueDocumentRepository.findById(id)
+ .orElseThrow(() -> new ResourceNotFoundException(
+ "Document not found with id: " + id));
+
+ Venue venue = venueRepository.findById(request.getVenueId())
+ .orElseThrow(() -> new ResourceNotFoundException(
+ "Venue not found with id: " + request.getVenueId()));
+
+ existingDocument.setVenue(venue);
+ existingDocument.setDocumentType(request.getDocumentType());
+ existingDocument.setDocumentName(request.getDocumentName());
+ existingDocument.setDocumentUrl(request.getDocumentUrl());
+ existingDocument.setDocumentStatus(request.getDocumentStatus());
+ existingDocument.setRemarks(request.getRemarks());
+ existingDocument.setUpdatedBy(1L);
+
+ VenueDocument updatedDocument =
+ venueDocumentRepository.save(existingDocument);
+
+ return venueDocumentMapper.toResponse(updatedDocument);
+ }
+
+ @Override
+ public void deleteDocument(Long id) {
+
+ VenueDocument venueDocument =
+ venueDocumentRepository.findById(id)
+ .orElseThrow(() -> new ResourceNotFoundException(
+ "Document not found with id: " + id));
+
+ venueDocumentRepository.delete(venueDocument);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/VenuePhotoService.java b/backend/src/main/java/com/bookmyvenue/backend/service/VenuePhotoService.java
new file mode 100644
index 000000000..b706e1772
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/VenuePhotoService.java
@@ -0,0 +1,19 @@
+package com.bookmyvenue.backend.service;
+import com.bookmyvenue.backend.dto.venuePhoto.VenuePhotoRequest;
+import com.bookmyvenue.backend.dto.venuePhoto.VenuePhotoResponse;
+
+import java.util.List;
+
+public interface VenuePhotoService {
+
+ VenuePhotoResponse create(VenuePhotoRequest request);
+
+ VenuePhotoResponse getById(Long photoId);
+
+ public List getAllPhotoByVenueId(Long venueId);
+
+ VenuePhotoResponse update(Long photoId,
+ VenuePhotoRequest request);
+
+ void delete(Long photoId);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/VenuePhotoServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/VenuePhotoServiceImpl.java
new file mode 100644
index 000000000..bfbfc6c68
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/VenuePhotoServiceImpl.java
@@ -0,0 +1,109 @@
+package com.bookmyvenue.backend.service;
+import com.bookmyvenue.backend.dto.venuePhoto.VenuePhotoRequest;
+import com.bookmyvenue.backend.dto.venuePhoto.VenuePhotoResponse;
+import com.bookmyvenue.backend.entity.Venue;
+import com.bookmyvenue.backend.entity.VenuePhoto;
+import com.bookmyvenue.backend.exception.ResourceNotFoundException;
+import com.bookmyvenue.backend.mapper.VenuePhotoMapper;
+import com.bookmyvenue.backend.repository.VenuePhotoRepository;
+import com.bookmyvenue.backend.repository.VenueRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class VenuePhotoServiceImpl implements VenuePhotoService {
+
+ private final VenuePhotoRepository venuePhotoRepository;
+ private final VenueRepository venueRepository;
+ private final VenuePhotoMapper mapper;
+
+ @Override
+ public VenuePhotoResponse create(VenuePhotoRequest request) {
+
+ Venue venue = venueRepository.findById(request.getVenueId())
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found with id: "
+ + request.getVenueId()));
+
+ VenuePhoto venuePhoto = VenuePhoto.builder()
+ .venue(venue)
+ .isPrimary(request.getIsPrimary())
+ .displayOrder(request.getDisplayOrder())
+ .createdBy(request.getCreatedBy())
+ .updatedBy(request.getUpdatedBy())
+ .build();
+
+ return mapper.toResponse(
+ venuePhotoRepository.save(venuePhoto)
+ );
+ }
+
+ @Override
+ public VenuePhotoResponse getById(Long photoId) {
+
+ VenuePhoto photo = venuePhotoRepository.findById(photoId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "VenuePhoto not found with id: "
+ + photoId));
+
+ return mapper.toResponse(photo);
+ }
+
+
+ @Override
+ public List getAllPhotoByVenueId(Long venueId) {
+
+ // Optional validation to ensure venue exists
+ venueRepository.findById(venueId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found with id: " + venueId));
+
+ return venuePhotoRepository.findByVenue_VenueId(venueId)
+ .stream()
+ .map(mapper::toResponse)
+ .toList();
+ }
+ @Override
+ public VenuePhotoResponse update(Long photoId,
+ VenuePhotoRequest request) {
+
+ VenuePhoto photo = venuePhotoRepository.findById(photoId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "VenuePhoto not found with id: "
+ + photoId));
+
+ Venue venue = venueRepository.findById(request.getVenueId())
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found with id: "
+ + request.getVenueId()));
+
+ photo.setVenue(venue);
+ photo.setIsPrimary(request.getIsPrimary());
+ photo.setDisplayOrder(request.getDisplayOrder());
+ photo.setUpdatedBy(request.getUpdatedBy());
+
+ return mapper.toResponse(
+ venuePhotoRepository.save(photo)
+ );
+ }
+
+ @Override
+ public void delete(Long photoId) {
+
+ VenuePhoto photo = venuePhotoRepository.findById(photoId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "VenuePhoto not found with id: "
+ + photoId));
+
+ venuePhotoRepository.delete(photo);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/VenueService.java b/backend/src/main/java/com/bookmyvenue/backend/service/VenueService.java
new file mode 100644
index 000000000..ae8b58596
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/VenueService.java
@@ -0,0 +1,34 @@
+package com.bookmyvenue.backend.service;
+
+import com.bookmyvenue.backend.dto.Venue.VenueRequest;
+import com.bookmyvenue.backend.dto.Venue.VenueResponse;
+import com.bookmyvenue.backend.dto.Venue.VenueSearchRequest;
+import com.bookmyvenue.backend.dto.Venue.VenueStatusRequest;
+import com.bookmyvenue.backend.enums.VenueStatus;
+
+import java.util.List;
+
+public interface VenueService {
+
+ VenueResponse createVenue(VenueRequest request);
+
+ VenueResponse getVenueById(Long venueId);
+
+ List getAllVenues();
+
+ VenueResponse updateVenue(Long venueId,
+ VenueRequest request);
+
+ void deleteVenue(Long venueId);
+
+ public List searchVenues(
+ VenueSearchRequest request);
+
+ List getVenuesByOwner(Long ownerId);
+
+ List getVenuesByStatus(VenueStatus status);
+
+ VenueResponse updateVenueStatus(
+ Long venueId,
+ VenueStatusRequest request);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/service/VenueServiceImpl.java b/backend/src/main/java/com/bookmyvenue/backend/service/VenueServiceImpl.java
new file mode 100644
index 000000000..52e7f857e
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/service/VenueServiceImpl.java
@@ -0,0 +1,212 @@
+package com.bookmyvenue.backend.service;
+
+
+import com.bookmyvenue.backend.dto.Venue.VenueRequest;
+import com.bookmyvenue.backend.dto.Venue.VenueResponse;
+import com.bookmyvenue.backend.dto.Venue.VenueSearchRequest;
+import com.bookmyvenue.backend.dto.Venue.VenueStatusRequest;
+import com.bookmyvenue.backend.entity.Users;
+import com.bookmyvenue.backend.entity.Venue;
+import com.bookmyvenue.backend.enums.VenueStatus;
+import com.bookmyvenue.backend.exception.ResourceNotFoundException;
+import com.bookmyvenue.backend.mapper.VenueMapper;
+import com.bookmyvenue.backend.repository.UserRepository;
+import com.bookmyvenue.backend.repository.VenueRepository;
+import com.bookmyvenue.backend.specification.VenueSpecification;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+@Transactional
+public class VenueServiceImpl implements VenueService {
+
+ private final VenueRepository venueRepository;
+ private final UserRepository userRepository;
+ private final VenueMapper venueMapper;
+
+ @Override
+ public VenueResponse createVenue(VenueRequest request) {
+
+ Users owner = userRepository.findById(request.getOwnerUserId())
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Owner not found with id : "
+ + request.getOwnerUserId()));
+
+ Venue venue = new Venue();
+
+ venue.setOwnerUser(owner);
+ venue.setVenueName(request.getVenueName());
+ venue.setAddressLine1(request.getAddressLine1());
+ venue.setAddressLine2(request.getAddressLine2());
+ venue.setCity(request.getCity());
+ venue.setDistrict(request.getDistrict());
+ venue.setState(request.getState());
+ venue.setCountry(request.getCountry());
+ venue.setPincode(request.getPincode());
+ venue.setLatitude(request.getLatitude());
+ venue.setLongitude(request.getLongitude());
+ venue.setCapacity(request.getCapacity());
+ venue.setPricingType(request.getPricingType());
+ venue.setBasePrice(request.getBasePrice());
+ venue.setAdvancePercentage(
+ request.getAdvancePercentage());
+ venue.setContactName(
+ request.getContactName());
+ venue.setContactEmail(
+ request.getContactEmail());
+ venue.setCreatedBy(
+ request.getCreatedBy());
+ venue.setUpdatedBy(
+ request.getCreatedBy());
+
+ Venue savedVenue =
+ venueRepository.save(venue);
+
+ return venueMapper.toResponse(savedVenue);
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public VenueResponse getVenueById(Long venueId) {
+
+ Venue venue = venueRepository.findById(venueId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found with id : "
+ + venueId));
+
+ return venueMapper.toResponse(venue);
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public List getAllVenues() {
+
+ return venueRepository.findAll()
+ .stream()
+ .map(venueMapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public List getVenuesByOwner(Long ownerId) {
+
+ return venueRepository
+ .findByOwnerUserUserId(ownerId)
+ .stream()
+ .map(venueMapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public List getVenuesByStatus(
+ VenueStatus status) {
+
+ return venueRepository
+ .findByStatus(status)
+ .stream()
+ .map(venueMapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ public VenueResponse updateVenue(
+ Long venueId,
+ VenueRequest request) {
+
+ Venue venue = venueRepository.findById(venueId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found with id : "
+ + venueId));
+
+ venue.setVenueName(request.getVenueName());
+ venue.setAddressLine1(request.getAddressLine1());
+ venue.setAddressLine2(request.getAddressLine2());
+ venue.setCity(request.getCity());
+ venue.setDistrict(request.getDistrict());
+ venue.setState(request.getState());
+ venue.setCountry(request.getCountry());
+ venue.setPincode(request.getPincode());
+ venue.setLatitude(request.getLatitude());
+ venue.setLongitude(request.getLongitude());
+ venue.setCapacity(request.getCapacity());
+ venue.setPricingType(request.getPricingType());
+ venue.setBasePrice(request.getBasePrice());
+ venue.setAdvancePercentage(
+ request.getAdvancePercentage());
+ venue.setContactName(
+ request.getContactName());
+ venue.setContactEmail(
+ request.getContactEmail());
+ venue.setUpdatedBy(
+ request.getCreatedBy());
+
+ Venue updatedVenue =
+ venueRepository.save(venue);
+
+ return venueMapper.toResponse(updatedVenue);
+ }
+
+ @Override
+ public void deleteVenue(Long venueId) {
+
+ Venue venue = venueRepository.findById(venueId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found with id : "
+ + venueId));
+
+ venueRepository.delete(venue);
+ }
+
+ @Override
+ public List searchVenues(
+ VenueSearchRequest request) {
+ Specification spec = Specification.allOf(
+ VenueSpecification.hasSupportedEventType(
+ request.getEventType()),
+ VenueSpecification.hasMinPrice(
+ request.getMinPrice()),
+ VenueSpecification.hasMaxPrice(
+ request.getMaxPrice()),
+ VenueSpecification.hasCapacity(
+ request.getCapacity()),
+ VenueSpecification.hasCity(
+ request.getCity()),
+ VenueSpecification.isAvailableOn(
+ request.getAvailableDate())
+ );
+
+
+ return venueRepository.findAll(spec)
+ .stream()
+ .map(venueMapper::toResponse)
+ .toList();
+ }
+
+ @Override
+ public VenueResponse updateVenueStatus(
+ Long venueId,
+ VenueStatusRequest request) {
+
+ Venue venue = venueRepository.findById(venueId)
+ .orElseThrow(() ->
+ new ResourceNotFoundException(
+ "Venue not found with id: " + venueId));
+
+ venue.setStatus(request.getStatus());
+
+ Venue updatedVenue = venueRepository.save(venue);
+
+ return venueMapper.toResponse(updatedVenue);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/specification/AdminRequestSpecification.java b/backend/src/main/java/com/bookmyvenue/backend/specification/AdminRequestSpecification.java
new file mode 100644
index 000000000..dc6585c62
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/specification/AdminRequestSpecification.java
@@ -0,0 +1,54 @@
+package com.bookmyvenue.backend.specification;
+
+import com.bookmyvenue.backend.entity.Venue;
+import com.bookmyvenue.backend.enums.VenueStatus;
+import org.springframework.data.jpa.domain.Specification;
+
+public class AdminRequestSpecification {
+
+ private AdminRequestSpecification() {
+ }
+
+ public static Specification
+ hasVenueName(String venueName) {
+
+ return (root, query, cb) -> {
+
+ if (venueName == null ||
+ venueName.isBlank()) {
+ return null;
+ }
+
+ return cb.like(
+ cb.lower(root.get("venueName")),
+ "%" +
+ venueName.toLowerCase() +
+ "%");
+ };
+ }
+
+ public static Specification
+ hasStatus(
+ VenueStatus status) {
+
+ return (root, query, cb) ->
+ status == null
+ ? null
+ : cb.equal(
+ root.get("status"),
+ status);
+ }
+
+ public static Specification
+ hasOwner(
+ Long ownerId) {
+
+ return (root, query, cb) ->
+ ownerId == null
+ ? null
+ : cb.equal(
+ root.get("ownerUser")
+ .get("userId"),
+ ownerId);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/specification/BookingSpecification.java b/backend/src/main/java/com/bookmyvenue/backend/specification/BookingSpecification.java
new file mode 100644
index 000000000..4b020bf57
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/specification/BookingSpecification.java
@@ -0,0 +1,60 @@
+package com.bookmyvenue.backend.specification;
+
+import com.bookmyvenue.backend.entity.Booking;
+import com.bookmyvenue.backend.enums.BookingStatus;
+import org.springframework.data.jpa.domain.Specification;
+
+import java.time.LocalDate;
+
+public class BookingSpecification {
+
+ public static Specification hasVenue(Long venueId) {
+ return (root, query, cb) ->
+ venueId == null
+ ? cb.conjunction()
+ : cb.equal(root.get("venue").get("venueId"), venueId);
+ }
+
+ public static Specification hasUser(Long userId) {
+ return (root, query, cb) ->
+ userId == null
+ ? cb.conjunction()
+ : cb.equal(root.get("user").get("userId"), userId);
+ }
+
+ public static Specification hasStatus(BookingStatus status) {
+ return (root, query, cb) ->
+ status == null
+ ? cb.conjunction()
+ : cb.equal(root.get("bookingStatus"), status);
+ }
+
+ public static Specification hasBookingDate(LocalDate bookingDate) {
+ return (root, query, cb) ->
+ bookingDate == null
+ ? cb.conjunction()
+ : cb.equal(root.get("bookingDate"), bookingDate);
+ }
+
+ public static Specification betweenDates(LocalDate fromDate, LocalDate toDate) {
+ return (root, query, cb) -> {
+ if (fromDate == null || toDate == null) {
+ return cb.conjunction();
+ }
+ return cb.between(root.get("bookingDate"), fromDate, toDate);
+ };
+ }
+
+ // ⭐ NEW: clean builder method (recommended)
+ public static Specification build(
+ Long venueId,
+ Long userId,
+ BookingStatus status,
+ LocalDate bookingDate
+ ) {
+ return Specification.where(hasVenue(venueId))
+ .and(hasUser(userId))
+ .and(hasStatus(status))
+ .and(hasBookingDate(bookingDate));
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/specification/PaymentSpecification.java b/backend/src/main/java/com/bookmyvenue/backend/specification/PaymentSpecification.java
new file mode 100644
index 000000000..226920528
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/specification/PaymentSpecification.java
@@ -0,0 +1,27 @@
+package com.bookmyvenue.backend.specification;
+
+import com.bookmyvenue.backend.entity.Payment;
+import com.bookmyvenue.backend.enums.PaymentStatus;
+import com.bookmyvenue.backend.enums.PaymentType;
+import org.springframework.data.jpa.domain.Specification;
+
+public class PaymentSpecification {
+
+ public static Specification hasBookingId(Long bookingId) {
+ return (root, query, cb) ->
+ bookingId == null ? cb.conjunction()
+ : cb.equal(root.get("booking").get("bookingId"), bookingId);
+ }
+
+ public static Specification hasStatus(PaymentStatus status) {
+ return (root, query, cb) ->
+ status == null ? cb.conjunction()
+ : cb.equal(root.get("paymentStatus"), status);
+ }
+
+ public static Specification hasType(PaymentType type) {
+ return (root, query, cb) ->
+ type == null ? cb.conjunction()
+ : cb.equal(root.get("paymentType"), type);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/specification/UserSpecification.java b/backend/src/main/java/com/bookmyvenue/backend/specification/UserSpecification.java
new file mode 100644
index 000000000..8d2d40e09
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/specification/UserSpecification.java
@@ -0,0 +1,48 @@
+package com.bookmyvenue.backend.specification;
+import com.bookmyvenue.backend.entity.Users;
+import com.bookmyvenue.backend.enums.UserStatus;
+import org.springframework.data.jpa.domain.Specification;
+
+public class UserSpecification {
+
+ private UserSpecification() {
+ }
+
+ public static Specification
+ hasKeyword(String keyword) {
+
+ return (root, query, cb) -> {
+
+ if (keyword == null ||
+ keyword.isBlank()) {
+ return null;
+ }
+
+ String search = "%" +
+ keyword.toLowerCase() +
+ "%";
+
+ return cb.or(
+ cb.like(
+ cb.lower(
+ root.get("first_name")),
+ search),
+ cb.like(
+ cb.lower(
+ root.get("email")),
+ search)
+ );
+ };
+ }
+
+ public static Specification
+ hasStatus(UserStatus status) {
+
+ return (root, query, cb) ->
+ status == null
+ ? null
+ : cb.equal(
+ root.get("status"),
+ status);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/specification/VenueOwnerSpecification.java b/backend/src/main/java/com/bookmyvenue/backend/specification/VenueOwnerSpecification.java
new file mode 100644
index 000000000..dbeedf3f4
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/specification/VenueOwnerSpecification.java
@@ -0,0 +1,65 @@
+package com.bookmyvenue.backend.specification;
+
+import com.bookmyvenue.backend.entity.Users;
+import com.bookmyvenue.backend.enums.UserStatus;
+import org.springframework.data.jpa.domain.Specification;
+
+public class VenueOwnerSpecification {
+
+ private VenueOwnerSpecification() {
+ }
+
+ public static Specification
+ hasName(String name) {
+
+ return (root, query, cb) -> {
+
+ if (name == null ||
+ name.isBlank()) {
+ return null;
+ }
+
+ String search = "%" +
+ name.toLowerCase() +
+ "%";
+
+ return cb.like(
+ cb.lower(
+ root.get("firstName")),
+ search);
+ };
+ }
+
+ public static Specification
+ hasEmail(String email) {
+
+ return (root, query, cb) -> {
+
+ if (email == null ||
+ email.isBlank()) {
+ return null;
+ }
+
+ String search = "%" +
+ email.toLowerCase() +
+ "%";
+
+ return cb.like(
+ cb.lower(
+ root.get("email")),
+ search);
+ };
+ }
+
+ public static Specification
+ hasStatus(UserStatus status) {
+
+ return (root, query, cb) ->
+ status == null
+ ? null
+ : cb.equal(
+ root.get("status"),
+ status);
+ }
+}
+
diff --git a/backend/src/main/java/com/bookmyvenue/backend/specification/VenueSpecification.java b/backend/src/main/java/com/bookmyvenue/backend/specification/VenueSpecification.java
new file mode 100644
index 000000000..4153b049e
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/specification/VenueSpecification.java
@@ -0,0 +1,149 @@
+package com.bookmyvenue.backend.specification;
+import com.bookmyvenue.backend.entity.Venue;
+import com.bookmyvenue.backend.enums.EventType;
+import com.bookmyvenue.backend.enums.VenueStatus;
+import org.springframework.data.jpa.domain.Specification;
+import java.math.BigDecimal;
+import com.bookmyvenue.backend.entity.VenueAvailability;
+import jakarta.persistence.criteria.Subquery;
+import java.time.LocalDate;
+import java.util.Set;
+
+public class VenueSpecification {
+
+ private VenueSpecification() {
+ }
+
+ public static Specification hasCapacity(
+ Integer capacity) {
+
+ return (root, query, cb) ->
+ capacity == null
+ ? null
+ : cb.greaterThanOrEqualTo(
+ root.get("capacity"),
+ capacity);
+ }
+
+ public static Specification hasMinPrice(
+ BigDecimal minPrice) {
+
+ return (root, query, cb) ->
+ minPrice == null
+ ? null
+ : cb.greaterThanOrEqualTo(
+ root.get("basePrice"),
+ minPrice);
+ }
+
+ public static Specification hasMaxPrice(
+ BigDecimal maxPrice) {
+
+ return (root, query, cb) ->
+ maxPrice == null
+ ? null
+ : cb.lessThanOrEqualTo(
+ root.get("basePrice"),
+ maxPrice);
+ }
+
+ public static Specification hasCity(
+ String city) {
+
+ return (root, query, cb) ->
+ city == null || city.isBlank()
+ ? null
+ : cb.equal(
+ cb.lower(root.get("city")),
+ city.toLowerCase());
+ }
+
+ /**
+ * Filter by Venue Type
+ */
+ public static Specification hasSupportedEventTypes(
+ Set venueType) {
+
+ return (root, query, cb) ->
+ venueType == null
+ ? cb.conjunction()
+ : cb.equal(
+ root.join("supportedVenueTypes"),
+ venueType);
+ }
+
+
+ public static Specification hasSupportedEventType(
+ EventType eventType) {
+
+ return (root, query, cb) -> {
+
+ if (eventType == null) {
+ return cb.conjunction();
+ }
+
+ return cb.isMember(
+ eventType,
+ root.get("supportedEventType"));
+ };
+ }
+ /**
+ * Filter by Available Date
+ */
+ public static Specification isAvailableOn(
+ LocalDate availableDate) {
+
+ return (root, query, cb) -> {
+
+ if (availableDate == null) {
+ return null;
+ }
+
+ Subquery subQuery =
+ query.subquery(Long.class);
+
+ var availabilityRoot =
+ subQuery.from(VenueAvailability.class);
+
+ subQuery.select(
+ availabilityRoot.get("venue")
+ .get("venueId"));
+
+ subQuery.where(
+ cb.equal(
+ availabilityRoot.get("availableDate"),
+ availableDate
+ ),
+ cb.equal(
+ availabilityRoot.get("availabilityStatus"),
+ "AVAILABLE"
+ )
+ );
+
+ return root.get("venueId").in(subQuery);
+ };
+ }
+ public static Specification hasOwner(
+ Long ownerId) {
+
+ return (root, query, cb) ->
+ ownerId == null
+ ? cb.conjunction()
+ : cb.equal(
+ root.get("owner")
+ .get("userId"),
+ ownerId);
+ }
+
+ public static Specification hasStatus(
+ VenueStatus status) {
+
+ return (root, query, cb) ->
+ status == null
+ ? cb.conjunction()
+ : cb.equal(
+ root.get("status"),
+ status);
+ }
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/bookmyvenue/backend/util/sample.java b/backend/src/main/java/com/bookmyvenue/backend/util/sample.java
new file mode 100644
index 000000000..7d1c701eb
--- /dev/null
+++ b/backend/src/main/java/com/bookmyvenue/backend/util/sample.java
@@ -0,0 +1,4 @@
+package com.bookmyvenue.backend.util;
+
+public class sample {
+}
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
new file mode 100644
index 000000000..a74b2cf28
--- /dev/null
+++ b/backend/src/main/resources/application.properties
@@ -0,0 +1,26 @@
+spring.application.name=backend
+
+spring.datasource.url=jdbc:postgresql://localhost:5432/bookmyvenue
+spring.datasource.username=postgres
+spring.datasource.password=postgres123
+
+
+spring.jpa.generate-ddl=true
+spring.jpa.hibernate.ddl-auto=update
+#spring.jpa.hibernate.ddl-auto=create-drop
+spring.jpa.show-sql=true
+spring.security.user.name=admin
+spring.security.user.password=admin123
+# Swagger/OpenAPI Configuration
+springdoc.api-docs.path=/api-docs
+springdoc.swagger-ui.path=/swagger-ui.html
+springdoc.swagger-ui.enabled=true
+springdoc.swagger-ui.operations-sorter=method
+springdoc.swagger-ui.tags-sorter=alpha
+springdoc.swagger-ui.display-request-duration=true
+springdoc.swagger-ui.try-it-out-enabled=true
+
+jwt.secret=${JWT_SECRET}
+jwt.expiration-millis=86400000
+
+logging.level.org.springframework.security=INFO
\ No newline at end of file
diff --git a/backend/src/test/java/com/bookmyvenue/backend/BackendApplicationTests.java b/backend/src/test/java/com/bookmyvenue/backend/BackendApplicationTests.java
new file mode 100644
index 000000000..01a122dc1
--- /dev/null
+++ b/backend/src/test/java/com/bookmyvenue/backend/BackendApplicationTests.java
@@ -0,0 +1,13 @@
+package com.bookmyvenue.backend;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class BackendApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}