# Royal Wellness Center — Admin Backend (Laravel)

The CMS/API backend powering the Royal Wellness Center admin panel and public website. Built with **Laravel 11**, **Sanctum** (token auth), and a resource-based REST API.

## Modules

| Module | What it covers |
|---|---|
| **Authentication** | Login/logout, current user, password update — token-based via Sanctum |
| **Dashboard** | Lead counts, status/source breakdowns, 30-day trend, top treatments by lead volume |
| **Doctors** | Full CRUD, photo upload, treatment specialty assignment, soft delete + restore |
| **Treatments** | Full CRUD, categories, benefits/process steps (JSON), doctor assignment, drag-reorder endpoint |
| **Blogs** | Full CRUD, categories, doctor-as-author, draft/published/archived workflow |
| **Testimonials** | Full CRUD, star rating, source tracking, featured/published flags |
| **Gallery** | Before/after CRUD — **publishing is blocked unless `consent_confirmed` is true** |
| **Leads** | Captures bookings/contact form submissions, status workflow, assignment, CSV export |
| **Settings** | Grouped key-value store (general, contact, social, integrations) |
| **SEO** | Per-page meta (8 static pages), polymorphic overrides for treatments/doctors/blogs, redirects, sitemap preview |

A `users` module is also included (super-admin only) for managing admin/editor accounts, since "Authentication" implies someone needs to manage who can log in.

## Getting Started

```bash
composer install
cp .env.example .env
php artisan key:generate
php artisan migrate
php artisan db:seed
php artisan storage:link
php artisan serve
```

Default seeded accounts (**change passwords immediately**):
- `admin@royalwellness.lk` / `ChangeMe123!` — super_admin
- `editor@royalwellness.lk` / `ChangeMe123!` — editor

## Project Structure

```
app/
├── Http/
│   ├── Controllers/Api/
│   │   ├── AuthController.php
│   │   ├── Admin/          # Authenticated admin-panel endpoints
│   │   └── Public/         # Unauthenticated endpoints for the public React site
│   ├── Requests/           # Form validation per module
│   ├── Resources/          # API response transformers
│   └── Middleware/         # EnsureAdmin, EnsureSuperAdmin
├── Models/                 # One per table, with relationships/scopes/casts
database/
├── migrations/
└── seeders/                 # Seeds all 9 treatments, 4 doctors, blogs, testimonials, etc.
routes/
└── api.php                  # All routes — public/* and admin/* prefixes
```

## API Overview

**Public** (no auth, consumed by the React frontend):
```
GET  /api/public/treatments
GET  /api/public/treatments/{slug}
GET  /api/public/doctors
GET  /api/public/doctors/{slug}
GET  /api/public/gallery          # only consent-confirmed + published items
GET  /api/public/testimonials
GET  /api/public/blog
GET  /api/public/blog/{slug}
POST /api/public/leads            # booking dialog + contact form
```

**Admin** (requires `Authorization: Bearer {token}` + admin/super_admin role):
```
POST /api/auth/login
GET  /api/admin/dashboard
/api/admin/doctors        (full REST)
/api/admin/treatments     (full REST) + POST treatments/reorder
/api/admin/blogs          (full REST)
/api/admin/testimonials   (full REST)
/api/admin/gallery        (full REST)
/api/admin/leads          (no store — leads come from the public endpoint)
  + POST leads/{id}/assign, POST leads/{id}/mark-contacted, GET leads-export
GET/POST /api/admin/settings/{group}
/api/admin/seo/*           (pages, per-entity overrides, redirects, sitemap preview)
/api/admin/users           (super_admin only)
```

## Notable design decisions

- **Gallery consent safeguard**: `GalleryItem::published()` and the store/update form requests both enforce that `consent_confirmed` must be true before an item can be marked `is_published`. This is checked at the model scope, the form request, and seeded data defaults to unpublished/unconfirmed — so a real signed consent has to be on file before any patient photo reaches the public site.
- **Doctor ↔ Treatment is many-to-many**: a doctor can have multiple specialties, and a treatment can be performed by multiple doctors — matches how the frontend's `doctors` and `services` data relate.
- **SEO is two-layered**: `seo_pages` for the 8 static pages (Home, About, Treatments, etc.), and a polymorphic `seo_meta` table for per-record overrides on Treatments/Doctors/Blogs, plus a `seo_redirects` table for URL redirects.
- **Leads have no public update/delete** — only admins can change status, assign ownership, or add internal notes; the public can only create one.

## What's intentionally left for you to wire up

- Real database connection + credentials in `.env`
- Notification dispatch on new lead (email/SMS to care team + confirmation to patient) — `LeadController::store` has a comment marking where this goes
- Real before/after photography (seeded gallery items are placeholders, deliberately unpublished)
- Production CORS/Sanctum domains in `.env`
- Rate limiting tuning on the public lead endpoint (currently `throttle:10,1`)
