# Hosting Module - User Journeys ## Personas | # | Persona | Role / Auth | Description | |---|---------|-------------|-------------| | 1 | **Platform Admin** | `admin` role | Manages the POC → live website pipeline, tracks client services, monitors renewals | | 2 | **Prospect** | No auth (receives proposal link) | Views their POC website preview via a shared link | !!! note "Admin-only module" The hosting module is primarily an admin-only module. The only non-admin page is the **POC Viewer** — a public preview page that shows the prospect's POC website with a HostWizard banner. Prospects do not have accounts until their proposal is accepted, at which point a Merchant account is created for them. --- ## Lifecycle Overview The hosting module manages the complete POC → live website pipeline: ```mermaid flowchart TD A[Prospect identified] --> B[Create Hosted Site] B --> C[Status: DRAFT] C --> D[Build POC website via CMS] D --> E[Mark POC Ready] E --> F[Status: POC_READY] F --> G[Send Proposal to prospect] G --> H[Status: PROPOSAL_SENT] H --> I{Prospect accepts?} I -->|Yes| J[Accept Proposal] J --> K[Status: ACCEPTED] K --> L[Merchant account created] L --> M[Go Live with domain] M --> N[Status: LIVE] I -->|No| O[Cancel] O --> P[Status: CANCELLED] N --> Q{Issues?} Q -->|Payment issues| R[Suspend] R --> S[Status: SUSPENDED] S --> T[Reactivate → LIVE] Q -->|Client leaves| O ``` ### Status Transitions | From | Allowed Targets | |------|----------------| | `draft` | `poc_ready`, `cancelled` | | `poc_ready` | `proposal_sent`, `cancelled` | | `proposal_sent` | `accepted`, `cancelled` | | `accepted` | `live`, `cancelled` | | `live` | `suspended`, `cancelled` | | `suspended` | `live`, `cancelled` | | `cancelled` | _(terminal)_ | --- ## Dev URLs (localhost:9999) The dev server uses path-based platform routing: `http://localhost:9999/platforms/hosting/...` ### 1. Admin Pages Login as: `admin@orion.lu` or `samir.boulahtit@gmail.com` | Page | Dev URL | |------|---------| | Dashboard | `http://localhost:9999/platforms/hosting/admin/hosting` | | Sites List | `http://localhost:9999/platforms/hosting/admin/hosting/sites` | | New Site | `http://localhost:9999/platforms/hosting/admin/hosting/sites/new` | | Site Detail | `http://localhost:9999/platforms/hosting/admin/hosting/sites/{site_id}` | | Client Services | `http://localhost:9999/platforms/hosting/admin/hosting/clients` | ### 2. Public Pages | Page | Dev URL | |------|---------| | POC Viewer | `http://localhost:9999/platforms/hosting/hosting/sites/{site_id}/preview` | ### 3. Admin API Endpoints **Sites** (prefix: `/platforms/hosting/api/admin/hosting/`): | Method | Endpoint | Dev URL | |--------|----------|---------| | GET | list sites | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites` | | GET | site detail | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}` | | POST | create site | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites` | | POST | create from prospect | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/from-prospect/{prospect_id}` | | PUT | update site | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}` | | DELETE | delete site | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}` | **Lifecycle** (prefix: `/platforms/hosting/api/admin/hosting/`): | Method | Endpoint | Dev URL | |--------|----------|---------| | POST | mark POC ready | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/mark-poc-ready` | | POST | send proposal | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/send-proposal` | | POST | accept proposal | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/accept` | | POST | go live | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/go-live` | | POST | suspend | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/suspend` | | POST | cancel | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/cancel` | **Client Services** (prefix: `/platforms/hosting/api/admin/hosting/`): | Method | Endpoint | Dev URL | |--------|----------|---------| | GET | list services | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{site_id}/services` | | POST | create service | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{site_id}/services` | | PUT | update service | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{site_id}/services/{id}` | | DELETE | delete service | `http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{site_id}/services/{id}` | **Stats** (prefix: `/platforms/hosting/api/admin/hosting/`): | Method | Endpoint | Dev URL | |--------|----------|---------| | GET | dashboard stats | `http://localhost:9999/platforms/hosting/api/admin/hosting/stats/dashboard` | --- ## Production URLs (hostwizard.lu) In production, the platform uses **domain-based routing**. ### Admin Pages & API | Page / Endpoint | Production URL | |-----------------|----------------| | Dashboard | `https://hostwizard.lu/admin/hosting` | | Sites | `https://hostwizard.lu/admin/hosting/sites` | | New Site | `https://hostwizard.lu/admin/hosting/sites/new` | | Site Detail | `https://hostwizard.lu/admin/hosting/sites/{id}` | | Client Services | `https://hostwizard.lu/admin/hosting/clients` | | API - Sites | `GET https://hostwizard.lu/api/admin/hosting/sites` | | API - Stats | `GET https://hostwizard.lu/api/admin/hosting/stats/dashboard` | ### Public Pages | Page | Production URL | |------|----------------| | POC Viewer | `https://hostwizard.lu/hosting/sites/{site_id}/preview` | --- ## Data Model ### Hosted Site ``` HostedSite ├── id (PK) ├── store_id (FK → stores.id, unique) # The CMS-powered website ├── prospect_id (FK → prospects.id, nullable) # Origin prospect ├── status: draft | poc_ready | proposal_sent | accepted | live | suspended | cancelled ├── business_name (str) ├── contact_name, contact_email, contact_phone ├── proposal_sent_at, proposal_accepted_at, went_live_at (datetime) ├── proposal_notes (text) ├── live_domain (str, unique) ├── internal_notes (text) ├── created_at, updated_at └── Relationships: store, prospect, client_services ``` ### Client Service ``` ClientService ├── id (PK) ├── hosted_site_id (FK → hosted_sites.id, CASCADE) ├── service_type: domain | email | ssl | hosting | website_maintenance ├── name (str) # e.g., "acme.lu domain", "5 mailboxes" ├── status: pending | active | suspended | expired | cancelled ├── billing_period: monthly | annual | one_time ├── price_cents (int), currency (str, default EUR) ├── addon_product_id (FK, nullable) # Link to billing product ├── domain_name, registrar # Domain-specific ├── mailbox_count # Email-specific ├── expires_at, period_start, period_end, auto_renew ├── notes (text) └── created_at, updated_at ``` --- ## User Journeys ### Journey 1: Create Hosted Site from Prospect **Persona:** Platform Admin **Goal:** Convert a qualified prospect into a hosted site with a POC website **Prerequisite:** A prospect exists in the prospecting module (see [Prospecting Journeys](prospecting.md)) ```mermaid flowchart TD A[View prospect in prospecting module] --> B[Click 'Create Hosted Site from Prospect'] B --> C[HostedSite created with status DRAFT] C --> D[Store auto-created on hosting platform] D --> E[Contact info pre-filled from prospect] E --> F[Navigate to site detail] F --> G[Build POC website via CMS editor] ``` **Steps:** 1. Create hosted site from prospect: - API Dev: `POST http://localhost:9999/platforms/hosting/api/admin/hosting/sites/from-prospect/{prospect_id}` - API Prod: `POST https://hostwizard.lu/api/admin/hosting/sites/from-prospect/{prospect_id}` 2. This automatically: - Creates a Store on the hosting platform - Creates a HostedSite record linked to the Store and Prospect - Pre-fills business_name, contact_name, contact_email, contact_phone from prospect data 3. View the new site: - Dev: `http://localhost:9999/platforms/hosting/admin/hosting/sites/{site_id}` - Prod: `https://hostwizard.lu/admin/hosting/sites/{site_id}` 4. Click the Store link to open the CMS editor and build the POC website --- ### Journey 2: Create Hosted Site Manually **Persona:** Platform Admin **Goal:** Create a hosted site without an existing prospect (e.g., direct referral) ```mermaid flowchart TD A[Navigate to New Site page] --> B[Fill in business details] B --> C[Submit form] C --> D[HostedSite + Store created] D --> E[Navigate to site detail] E --> F[Build POC website] ``` **Steps:** 1. Navigate to New Site form: - Dev: `http://localhost:9999/platforms/hosting/admin/hosting/sites/new` - Prod: `https://hostwizard.lu/admin/hosting/sites/new` 2. Create the site: - API Dev: `POST http://localhost:9999/platforms/hosting/api/admin/hosting/sites` - API Prod: `POST https://hostwizard.lu/api/admin/hosting/sites` - Body: `{ "business_name": "Boulangerie du Parc", "contact_name": "Jean Müller", "contact_email": "jean@boulangerie-parc.lu", "contact_phone": "+352 26 123 456" }` 3. A Store is auto-created with subdomain `boulangerie-du-parc` on the hosting platform --- ### Journey 3: POC → Proposal Flow **Persona:** Platform Admin **Goal:** Build a POC website, mark it ready, and send a proposal to the prospect ```mermaid flowchart TD A[Site is DRAFT] --> B[Build POC website via CMS] B --> C[Mark POC Ready] C --> D[Site is POC_READY] D --> E[Preview the POC site] E --> F[Send Proposal with notes] F --> G[Site is PROPOSAL_SENT] G --> H[Share preview link with prospect] ``` **Steps:** 1. Build the POC website using the Store's CMS editor (linked from site detail page) 2. When the POC is ready, mark it: - API Dev: `POST http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/mark-poc-ready` - API Prod: `POST https://hostwizard.lu/api/admin/hosting/sites/{id}/mark-poc-ready` 3. Preview the POC site (public link, no auth needed): - Dev: `http://localhost:9999/platforms/hosting/hosting/sites/{id}/preview` - Prod: `https://hostwizard.lu/hosting/sites/{id}/preview` 4. Send proposal to the prospect: - API Dev: `POST http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/send-proposal` - API Prod: `POST https://hostwizard.lu/api/admin/hosting/sites/{id}/send-proposal` - Body: `{ "notes": "Custom website with 5 pages, domain registration included" }` 5. Share the preview link with the prospect via email !!! info "POC Viewer" The POC Viewer page renders the Store's storefront in an iframe with a teal HostWizard banner at the top. It only works for sites with status `poc_ready` or `proposal_sent`. Once the site goes live, the preview is disabled. --- ### Journey 4: Accept Proposal & Create Merchant **Persona:** Platform Admin **Goal:** When a prospect accepts, create their merchant account and subscription ```mermaid flowchart TD A[Prospect accepts proposal] --> B{Existing merchant?} B -->|Yes| C[Link to existing merchant] B -->|No| D[Auto-create merchant + owner account] C --> E[Accept Proposal] D --> E E --> F[Site is ACCEPTED] F --> G[Store reassigned to merchant] G --> H[Subscription created on hosting platform] H --> I[Prospect marked as CONVERTED] ``` **Steps:** 1. Accept the proposal (auto-creates merchant if no merchant_id provided): - API Dev: `POST http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/accept` - API Prod: `POST https://hostwizard.lu/api/admin/hosting/sites/{id}/accept` - Body: `{}` (auto-create merchant) or `{ "merchant_id": 5 }` (link to existing) 2. This automatically: - Creates a new Merchant from contact info (name, email, phone) - Creates a store owner account with a temporary password - Reassigns the Store from the system merchant to the new merchant - Creates a MerchantSubscription on the hosting platform (essential tier) - Marks the linked prospect as CONVERTED (if prospect_id is set) 3. View the updated site detail: - Dev: `http://localhost:9999/platforms/hosting/admin/hosting/sites/{id}` - Prod: `https://hostwizard.lu/admin/hosting/sites/{id}` !!! warning "Merchant account credentials" When accepting without an existing `merchant_id`, a new merchant owner account is created with a temporary password. The admin should communicate these credentials to the client so they can log in and self-edit their website via the CMS. --- ### Journey 5: Go Live with Custom Domain **Persona:** Platform Admin **Goal:** Assign a production domain to the website and make it live ```mermaid flowchart TD A[Site is ACCEPTED] --> B[Configure DNS for client domain] B --> C[Go Live with domain] C --> D[Site is LIVE] D --> E[StoreDomain created] E --> F[Website accessible at client domain] ``` **Steps:** 1. Ensure DNS is configured for the client's domain (A/AAAA records pointing to the server) 2. Go live: - API Dev: `POST http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/go-live` - API Prod: `POST https://hostwizard.lu/api/admin/hosting/sites/{id}/go-live` - Body: `{ "domain": "boulangerie-parc.lu" }` 3. This automatically: - Sets `went_live_at` timestamp - Creates a StoreDomain record (primary) for the domain - Sets `live_domain` on the hosted site 4. The website is now accessible at `https://boulangerie-parc.lu` --- ### Journey 6: Add Client Services **Persona:** Platform Admin **Goal:** Track operational services (domains, email, SSL, hosting) for a client ```mermaid flowchart TD A[Open site detail] --> B[Go to Services tab] B --> C[Add domain service] C --> D[Add email service] D --> E[Add SSL service] E --> F[Add hosting service] F --> G[Services tracked with expiry dates] ``` **Steps:** 1. Navigate to site detail, Services tab: - Dev: `http://localhost:9999/platforms/hosting/admin/hosting/sites/{site_id}` - Prod: `https://hostwizard.lu/admin/hosting/sites/{site_id}` 2. Add a domain service: - API Dev: `POST http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{site_id}/services` - API Prod: `POST https://hostwizard.lu/api/admin/hosting/sites/{site_id}/services` - Body: `{ "service_type": "domain", "name": "boulangerie-parc.lu domain", "domain_name": "boulangerie-parc.lu", "registrar": "Namecheap", "billing_period": "annual", "price_cents": 1500, "expires_at": "2027-03-01T00:00:00", "auto_renew": true }` 3. Add an email service: - Body: `{ "service_type": "email", "name": "5 mailboxes", "mailbox_count": 5, "billing_period": "monthly", "price_cents": 999 }` 4. Add an SSL service: - Body: `{ "service_type": "ssl", "name": "SSL certificate", "billing_period": "annual", "price_cents": 0, "expires_at": "2027-03-01T00:00:00" }` 5. View all services for a site: - API Dev: `GET http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{site_id}/services` - API Prod: `GET https://hostwizard.lu/api/admin/hosting/sites/{site_id}/services` --- ### Journey 7: Dashboard & Renewal Monitoring **Persona:** Platform Admin **Goal:** Monitor business KPIs and upcoming service renewals ```mermaid flowchart TD A[Navigate to Dashboard] --> B[View KPIs] B --> C[Total sites, live sites, POC sites] C --> D[Monthly revenue] D --> E[Active services count] E --> F[Upcoming renewals in 30 days] F --> G[Navigate to Client Services] G --> H[Filter by expiring soon] H --> I[Renew or update services] ``` **Steps:** 1. Navigate to Dashboard: - Dev: `http://localhost:9999/platforms/hosting/admin/hosting` - Prod: `https://hostwizard.lu/admin/hosting` 2. View dashboard stats: - API Dev: `GET http://localhost:9999/platforms/hosting/api/admin/hosting/stats/dashboard` - API Prod: `GET https://hostwizard.lu/api/admin/hosting/stats/dashboard` - Returns: `total_sites`, `live_sites`, `poc_sites`, `sites_by_status`, `active_services`, `monthly_revenue_cents`, `upcoming_renewals`, `services_by_type` 3. Navigate to Client Services for detailed view: - Dev: `http://localhost:9999/platforms/hosting/admin/hosting/clients` - Prod: `https://hostwizard.lu/admin/hosting/clients` 4. Filter by type (domain, email, ssl, hosting) or status 5. Toggle "Expiring Soon" to see services expiring within 30 days --- ### Journey 8: Suspend & Reactivate **Persona:** Platform Admin **Goal:** Handle suspension (e.g., unpaid invoices) and reactivation **Steps:** 1. Suspend a site: - API Dev: `POST http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/suspend` - API Prod: `POST https://hostwizard.lu/api/admin/hosting/sites/{id}/suspend` 2. Site status changes to `suspended` 3. Once payment is resolved, reactivate by transitioning back to live: - The `suspended → live` transition is allowed 4. To permanently close a site: - API Dev: `POST http://localhost:9999/platforms/hosting/api/admin/hosting/sites/{id}/cancel` - API Prod: `POST https://hostwizard.lu/api/admin/hosting/sites/{id}/cancel` 5. `cancelled` is a terminal state — no further transitions allowed --- ### Journey 9: Complete Pipeline (Prospect → Live Site) **Persona:** Platform Admin **Goal:** Walk the complete pipeline from prospect to live website This journey combines the prospecting and hosting modules end-to-end: ```mermaid flowchart TD A[Import domain / capture lead] --> B[Enrich & score prospect] B --> C[Create hosted site from prospect] C --> D[Build POC website via CMS] D --> E[Mark POC ready] E --> F[Send proposal + share preview link] F --> G{Prospect accepts?} G -->|Yes| H[Accept → Merchant created] H --> I[Add client services] I --> J[Go live with domain] J --> K[Website live at client domain] K --> L[Monitor renewals & services] G -->|No| M[Cancel or follow up later] ``` **Steps:** 1. **Prospecting phase** (see [Prospecting Journeys](prospecting.md)): - Import domain or capture lead offline - Run enrichment pipeline - Score and qualify the prospect 2. **Create hosted site**: `POST /api/admin/hosting/sites/from-prospect/{prospect_id}` 3. **Build POC**: Edit the auto-created Store via CMS 4. **Mark POC ready**: `POST /api/admin/hosting/sites/{id}/mark-poc-ready` 5. **Send proposal**: `POST /api/admin/hosting/sites/{id}/send-proposal` 6. **Share preview**: Send `https://hostwizard.lu/hosting/sites/{id}/preview` to prospect 7. **Accept proposal**: `POST /api/admin/hosting/sites/{id}/accept` 8. **Add services**: `POST /api/admin/hosting/sites/{id}/services` (domain, email, SSL, hosting) 9. **Go live**: `POST /api/admin/hosting/sites/{id}/go-live` with domain 10. **Monitor**: Dashboard at `https://hostwizard.lu/admin/hosting` --- ## Recommended Test Order 1. **Journey 2** - Create a site manually first (simplest path, no prospect dependency) 2. **Journey 3** - Walk the POC → proposal flow 3. **Journey 4** - Accept proposal and verify merchant creation 4. **Journey 5** - Go live with a test domain 5. **Journey 6** - Add client services 6. **Journey 7** - Check dashboard stats 7. **Journey 1** - Test the prospect → hosted site conversion (requires prospecting data) 8. **Journey 8** - Test suspend/reactivate/cancel 9. **Journey 9** - Walk the complete end-to-end pipeline !!! tip "Test Journey 2 before Journey 1" Journey 2 (manual creation) doesn't require any prospecting data and is the fastest way to verify the hosting module works. Journey 1 (from prospect) requires running the prospecting module first.