Below is a **complete end-to-end Requirements Specification** you can copy/paste into Codex (or any code generator) to build the Laravel app in one go. I kept your original requirements, filled the missing parts, and made everything **implementation-ready** (routes, modules, DB schema, validations, permissions, SEO rules, and acceptance criteria).
---
## 1) Project Overview
### Product name
**bestorthohospitals.com Directory App** (Laravel)
### Purpose
A global directory listing website for **Orthopedic Hospitals** and **Orthopedic Doctors** with:
* Country & city based SEO URLs
* Search/filter on every page
* Hospital/Doctor profiles
* Appointment slot management (Hospitals/Doctors)
* User bookings with live availability
* Admin moderation (block/unblock, manage content)
* Home page aggregation (featured doctors/hospitals + latest posts from WordPress blog + Flarum forum)
### Primary user journeys
1. Visitor searches doctors/hospitals → opens profile → logs in with Google → books a slot.
2. Hospital logs in with Google → creates/updates hospital profile → creates slots → receives bookings → approves/cancels.
3. Doctor logs in with Google → creates/updates doctor profile → creates slots → receives bookings → approves/cancels.
4. Admin logs in with password → manages users/profiles → blocks/unblocks → controls featured ranking → reviews bookings.
---
## 2) Tech Stack & Constraints
* PHP **8.2**
* Laravel **12**
* DB: **SQLite (latest)**
* UX: **Bootstrap (latest)**
* Auth: **Google OAuth only** for Users/Hospitals/Doctors
* Admin auth: **Email/Username + Password** (separate guard, separate URL)
* Deployment mode: **No `/public` in URL** (Flarum-style)
---
## 3) Top/Bottom Menus (Global)
Top Menu & Bottom Menu:
**Home | Hospitals | Doctors | Blog | Forum | Surgery | Treatments | Diseases | Procedures | About | Contact us**
Rules:
* “Blog” menu links to the WordPress blog (external).
* “Forum” menu links to the Flarum forum (external).
* All other items are served from Laravel app.
---
## 4) Roles & Permissions (RBAC)
### Roles
* **USER**: can book appointments; manage own profile basics
* **HOSPITAL**: manage hospital profile + slots + bookings
* **DOCTOR**: manage doctor profile + slots + bookings
* **ADMIN**: manage everything; block/unblock accounts; feature/rank; view logs/bookings
### Permission matrix (must)
| Action | User | Hospital | Doctor | Admin |
| ------------------------------- | -------: | -----------------------: | -----------------------: | ----------: |
| Google login | ✅ | ✅ | ✅ | ❌ |
| Admin password login | ❌ | ❌ | ❌ | ✅ |
| View directory | ✅ | ✅ | ✅ | ✅ |
| Create/update own profile | ✅(basic) | ✅(hospital) | ✅(doctor) | ✅ |
| Create slots | ❌ | ✅ | ✅ | ✅ |
| Book slot | ✅ | ❌(unless also USER role) | ❌(unless also USER role) | ✅(optional) |
| Manage bookings for own profile | ❌ | ✅ | ✅ | ✅ |
| Block/unblock accounts | ❌ | ❌ | ❌ | ✅ |
| Manage featured/top ranking | ❌ | ❌ | ❌ | ✅ |
**Important rule:** One Google account = one primary role chosen during onboarding (USER/HOSPITAL/DOCTOR). Admin is separate login system.
---
## 5) Authentication Requirements
### Google OAuth (mandatory for non-admin)
* Use Laravel Socialite with Google.
* Only Google login: **no password login** for USER/HOSPITAL/DOCTOR.
Required `.env` keys (example; keep in code block):
```env
APP_URL=http://localhost/bestcanow
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=http://localhost/bestcanow/auth/google/callback
```
### Onboarding after first Google login
If first-time login:
1. Ask user to select account type: **User / Hospital / Doctor**
2. Create user row with role
3. Redirect to role dashboard:
* USER → “My Bookings”
* HOSPITAL → “Hospital Dashboard”
* DOCTOR → “Doctor Dashboard”
### Account block/unblock
* Admin can set `is_blocked = true`.
* Blocked accounts cannot login (show message: “Account blocked. Contact support.”).
### Admin auth (separate)
* Separate admin guard and routes, e.g.:
* `/admin/login` (password)
* `/admin` (dashboard)
* Admin credentials seeded via seeder or created with CLI.
* Admin accounts stored in `admin_users` table (separate from users).
---
## 6) Global UI Components (Must)
### Global Search/Filter (Must appear at top of EVERY page)
Filter supports:
* Search keyword (doctor/hospital name)
* Country (dropdown)
* City (dependent dropdown or autocomplete)
* Type toggle (Doctors / Hospitals / Both)
* Optional filters (recommended MVP):
* Specialty tags (orthopedic sub-specialty)
* Treatments/Procedures tags
* “Has available slots” checkbox
Behavior:
* Submitting search takes user to a combined results page OR stays within page context:
* If user is on `/doctors`, show doctor results.
* If on `/hospitals`, show hospital results.
* If on home, show combined results with tabs.
---
## 7) Pages & Content Requirements
### 7.1 Home (`/`)
Sections:
1. **Search/Filter bar** (global component)
2. **Bootstrap Carousel/Slider**
* Admin-manageable slides (title, subtitle, CTA link)
3. **Top 20 Doctors**
4. **Top 20 Hospitals**
5. **Top 20 Blog posts** from WordPress blog
6. **Top 20 Forum posts** from Flarum forum
Rules for “Top”:
* Only `published` profiles
* Ordered by:
1. `is_featured DESC`
2. `featured_rank ASC` (admin-controlled)
3. `profile_views DESC` (optional)
4. `updated_at DESC`
### 7.2 Hospitals listing (`/hospitals`)
* Search/Filter bar (global)
* List **Top 30 hospitals** with pagination
* Each item: name, city/country, thumbnail, short summary, “Book Appointment” button, profile link
### 7.3 Doctors listing (`/doctors`)
* Search/Filter bar (global)
* List **Top 30 doctors** with pagination
* Each item: name, specialization, city/country, thumbnail, short summary, “Book Appointment” button, profile link
### 7.4 Blog menu item
* Clicking “Blog” opens external WP blog.
* Home page also shows “Top 20 Blog posts” via feed integration (see Section 12).
### 7.5 Forum menu item
* Clicking “Forum” opens external Flarum forum.
* Home page shows “Top 20 Forum posts” via feed integration (see Section 12).
### 7.6 Medical Library Pages (Surgery/Treatments/Diseases/Procedures)
MVP requirement:
* Each of these menu items goes to a list page:
* `/surgery`
* `/treatments`
* `/diseases`
* `/procedures`
* Each item has detail page:
* `/{type}/{slug}`
* Admin can create/edit/delete items.
* Each detail page has SEO meta + optional related doctors/hospitals.
### 7.7 About (`/about`)
Static CMS page editable by Admin.
### 7.8 Contact (`/contact`)
* Contact form fields: Name, Email, Subject, Message
* Save in DB + optional email notification to site admin
* Add anti-spam protections (minimum):
* rate limit per IP
* honeypot field
---
## 8) SEO & Slug Requirements (Strict)
### 8.1 Profile URL patterns (Must)
**Doctor profile URL:**
`/doctors/{country}/{city}/{ca-name}`
**Hospital profile URL:**
`/hospitals/{country}/{city}/{ca-name}`
Examples:
* `/doctors/india/delhi/doctor-name`
* `/hospitals/india/delhi/hospital-name`
### 8.2 Slug generation rules
* `country` = slug from country name (lowercase)
* `city` = **city_slug** (lowercase)
* `{ca-name}` = slug from doctor/hospital name (lowercase)
* Also store a **combined unique slug key** internally:
* `slug_key = "{country_slug}-{city_slug}-{name_slug}"`
### 8.3 City normalization (Must)
* Store:
* `city_display` = Title Case (“New Delhi”)
* `city_slug` = lowercase slug (“new-delhi”)
* When saving, normalize inputs to avoid duplicates like “delhi”, “DELHI”, “Delhi”.
* Search must be case-insensitive; URLs always use `city_slug`.
### 8.4 Top pages (Must)
Implement these routes:
* `/top-hospitals` → shows all countries (country cards with counts)
* `/top-doctors/{country}` → shows 45 doctors for that country in **3 columns x 15 rows**
* `/{doctors|hospitals}/{country}/{city}` → list for that city
> Even if naming feels inconsistent, implement exactly as above since you requested these patterns.
### 8.5 SEO tags (Must on ALL pages)
Every page must output:
* `<title>`
* meta description
* meta keywords
* canonical URL
* Open Graph tags
* Twitter Card tags
Also required:
* `robots.txt`
* `sitemap.xml` (auto-generated, includes all public profiles + medical library pages)
---
## 9) “No Public Directory” Installation Requirement (Strict)
Must run as:
* `http://localhost/bestcanow/` (no `/public`)
* No vhost required
* Root `.htaccess` handles routing + serves assets
* Root `index.php` boots Laravel
Acceptance criteria:
* Visiting `/` loads home page
* Visiting `/css/app.css` (or compiled assets path) works
* Visiting any route works without `/public`
(Implementation may either move public assets to root or forward requests to `public/` while keeping URL root clean—your spec requires the final behavior, not a specific internal technique.)
---
## 10) Profiles (Hospitals & Doctors)
### 10.1 Hospital Profile Fields (MVP + validation-ready)
Required fields:
* Hospital name
* About/Description (rich text optional)
* Country
* City (city_display + city_slug)
* Full address
* Phone
* Email (optional)
* Website (optional)
* 1–2 photos (upload)
Recommended fields:
* Latitude/Longitude (optional)
* Services/Treatments tags
* Working hours text
* Emergency available (yes/no)
### 10.2 Doctor Profile Fields (MVP + validation-ready)
Required fields:
* Doctor full name
* About/Description
* Country
* City (city_display + city_slug)
* Clinic/Hospital association (optional)
* Specialization (orthopedics + subspecialty)
* Experience years (number)
* Phone (optional)
* Email (optional)
* 1–2 photos (upload)
Recommended fields:
* Degrees/Qualifications
* Languages spoken
* Consultation fee (optional)
### 10.3 Profile publishing workflow
* New profiles start as `draft`.
* Owner can submit for publishing → becomes `pending_review`.
* Admin can approve → `published` or reject → `draft` with reason.
---
## 11) Appointment Booking & Slot System (Core Feature)
### 11.1 Core concepts
* **Slot**: A time window available for booking (date + start_time + end_time).
* Slots belong to either:
* a Hospital profile, or
* a Doctor profile
* **Booking**: A user reserves a slot.
### 11.2 Slot management (Hospital/Doctor)
Must allow:
* Create slots:
* single slot
* bulk create (e.g., “every day 10:00–13:00 for next 14 days”)
* Edit future slots
* Delete future slots (if not booked)
* View slot calendar/list
Constraints:
* No overlapping slots for same owner (doctor/hospital)
* Slot duration min 10 mins, max 4 hours (configurable)
### 11.3 Booking flow (User)
* On profile page: show available dates/slots
* User chooses slot → must be logged in (Google)
* Booking form fields:
* Patient name (default from Google profile, editable)
* Email (from Google, read-only)
* Phone (required)
* Reason/Notes (optional)
* Booking statuses:
* `pending` (default)
* `confirmed` (owner confirms)
* `cancelled_by_user`
* `cancelled_by_owner`
* `completed` (optional)
Rules:
* One slot can be booked by only one user.
* Prevent double-book by DB unique constraints + transaction lock.
* User can cancel up to configurable cutoff (e.g. 2 hours before start).
### 11.4 Notifications (MVP)
At minimum:
* Show dashboard notifications (in-app)
Recommended (if possible):
* Email notification on booking create/confirm/cancel
### 11.5 Timezone
* Store slot times in UTC in DB
* Display using:
* profile timezone (default from country) OR
* site timezone setting
---
## 12) External Content Integration (Home Page)
### 12.1 WordPress blog “Top 20 posts”
Use WordPress REST API (cache results).
Example endpoint format (put in code/config; shown here as requirement):
```text
https://bestorthohospitals.com/blog/wp-json/wp/v2/posts?per_page=20
```
Data displayed:
* Title
* Publish date
* Featured image (if available)
* Short excerpt
* Link to original post (open external)
Caching:
* Cache for 15 minutes (configurable)
* If API fails: show “View all blog posts” link only
### 12.2 Flarum forum “Top 20 posts/discussions”
Use Flarum JSON:API (cache results).
Example endpoint format:
```text
https://bestorthohospitals.com/forum/api/discussions?page[limit]=20&sort=-createdAt
```
Data displayed:
* Discussion title
* Created date
* Comment/reply count if available
* Link to original discussion (external)
Caching:
* Cache for 15 minutes
* Failure fallback similar to blog
---
## 13) Database Schema (SQLite)
### 13.1 Tables (minimum)
**users**
* id (pk)
* google_id (unique)
* name
* email (unique)
* avatar_url (nullable)
* role (enum: user/hospital/doctor)
* is_blocked (bool default false)
* last_login_at (nullable)
* created_at, updated_at
**admin_users**
* id
* username/email (unique)
* password_hash
* is_active
* last_login_at
* created_at, updated_at
**hospital_profiles**
* id
* user_id (unique FK users)
* name
* name_slug
* slug_key (unique)
* country_name
* country_slug
* city_display
* city_slug
* address
* description
* phone
* email (nullable)
* website (nullable)
* photo1_path (nullable)
* photo2_path (nullable)
* status (draft/pending_review/published)
* is_featured (bool)
* featured_rank (int nullable)
* profile_views (int default 0)
* created_at, updated_at
**doctor_profiles**
* id
* user_id (unique FK users)
* full_name
* name_slug
* slug_key (unique)
* country_name
* country_slug
* city_display
* city_slug
* specialization
* experience_years
* description
* phone (nullable)
* email (nullable)
* photo1_path (nullable)
* photo2_path (nullable)
* status (draft/pending_review/published)
* is_featured
* featured_rank
* profile_views
* created_at, updated_at
**slots**
* id
* owner_type (enum: doctor/hospital)
* owner_id (doctor_profiles.id or hospital_profiles.id)
* start_at_utc (datetime)
* end_at_utc (datetime)
* status (available/booked/cancelled)
* created_at, updated_at
Indexes:
* unique(owner_type, owner_id, start_at_utc, end_at_utc)
**bookings**
* id
* slot_id (unique FK slots) ← ensures single booking per slot
* user_id (FK users)
* owner_type / owner_id (redundant for quick access)
* patient_name
* patient_phone
* patient_email
* notes (nullable)
* status (pending/confirmed/cancelled_by_user/cancelled_by_owner/completed)
* created_at, updated_at
**medical_library_items**
* id
* type (surgery/treatment/disease/procedure)
* title
* slug (unique within type)
* content
* seo_title, seo_description, seo_keywords
* status (draft/published)
* created_at, updated_at
**pages** (About/Contact content blocks)
* id
* key (about/contact etc) unique
* title
* content
* seo_title, seo_description, seo_keywords
* updated_at
**contact_messages**
* id
* name
* email
* subject
* message
* created_at
---
## 14) Validation Rules (Must)
### 14.1 Shared validation
* All slugs: lowercase, hyphen-separated, max 120 chars
* City normalization required
* Country required from configured list
### 14.2 Hospital profile validation
* name: required, min 3, max 120
* country_name: required
* city_display: required, min 2, max 80
* address: required, min 5, max 255
* phone: required, min 7, max 20
* email: nullable, valid email, max 120
* website: nullable, valid URL, max 255
* description: required, min 20
* photos: max 2
* types: jpg/png/webp
* max size: 2MB each
### 14.3 Doctor profile validation
* full_name: required, min 3, max 120
* specialization: required, max 120
* experience_years: required integer, 0–80
* country/city: required
* description: required, min 20
* phone/email/photos similar rules
### 14.4 Slot validation
* start_at < end_at
* start_at must be in future (for creating)
* no overlap with existing slots (same owner)
* duration 10–240 minutes (configurable)
### 14.5 Booking validation
* must be logged in USER role
* slot must be `available`
* patient_name: required, 2–120
* patient_phone: required, 7–20
* patient_email: required, valid email
* notes: optional max 500
---
## 15) Admin Panel Requirements
### Admin modules
1. Dashboard (counts: users, doctors, hospitals, bookings)
2. Users management
* list/filter by role/status
* view details
* block/unblock
3. Doctors management
* approve/reject profiles
* set featured + featured_rank
4. Hospitals management
* approve/reject profiles
* set featured + featured_rank
5. Bookings viewer
* filter by status/date/owner
6. Medical library CMS
* CRUD items for surgery/treatments/diseases/procedures
7. Carousel manager
* CRUD slides
Admin acceptance criteria:
* Admin pages inaccessible without admin login
* Admin can block a user and that user cannot login via Google afterward
---
## 16) Performance & Security Requirements
### Performance
* Pagination everywhere (doctors/hospitals lists)
* Cache external WP/Flarum feeds
* Index commonly filtered fields:
* country_slug, city_slug, is_featured, status
### Security
* CSRF protection enabled
* Rate limiting:
* login attempts (admin)
* contact form submissions
* booking attempts
* File upload security:
* restrict MIME + extension
* store outside web root via Laravel storage
* Authorization checks:
* hospital cannot edit doctor profile and vice versa
* owners can only manage their own slots/bookings
---
## 17) Deployment & Environment
### No-public-directory mode acceptance checklist
* Works from `htdocs/bestcanow`
* No vhost needed
* Root routing works
* Assets load
### Environment config
* `.env` drives all secrets (Google OAuth, mail settings, cache TTLs)
---
## 18) Testing & Acceptance Criteria (Must)
### Automated tests (minimum)
* Slug generation tests (city normalization, uniqueness)
* Booking conflict test (double-book prevention)
* Role authorization tests (hospital cannot book, user cannot create slots)
* Admin block/unblock test
### Manual acceptance tests
1. Google login creates user and routes to correct dashboard
2. Hospital creates profile → submits for review → admin publishes → appears in listings
3. Doctor creates slots → user books slot → doctor confirms → status updates
4. `/doctors/{country}/{city}/{name}` works and SEO meta present
5. `/top-hospitals` shows all countries
6. `/top-doctors/{country}` shows 45 entries in 3x15 layout
7. Home shows WP + Flarum items (or graceful fallback)
---
## 19) Recommended “Nice-to-have” (Optional, not required for MVP)
* Reviews & ratings
* Verified badge for doctors/hospitals
* Multi-language SEO fields
* Advanced search (full-text index)
* Map view (lat/lng)
---
### If you want, I can also produce a **single “Codex Master Prompt”** version of the above (condensed, no repetition, written like a build instruction to generate the full Laravel project structure + migrations + controllers + views).
Code language: PHP (php)