From 0d0f6faf40f70f8e51a253b94cefd959c2a1fd50df58e50e7503403a74b71d3f Mon Sep 17 00:00:00 2001 From: Andrew Date: Sun, 26 Apr 2026 17:33:23 -0400 Subject: [PATCH] docs(spec): dedicated server lineup design Captures the brainstorm: 8 new Dell 14th-gen chassis SKUs alongside existing rack inventory, per-chassis configurator at /dedicated-servers/{slug}, 5-stage post-order build tracker, tiered setup fees waived at Semi-Annual+ cycles. User approved design + skipped spec-review gate. Implementation phasing in 4 commits per the spec. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...26-04-26-dedicated-server-lineup-design.md | 275 ++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-26-dedicated-server-lineup-design.md diff --git a/docs/superpowers/specs/2026-04-26-dedicated-server-lineup-design.md b/docs/superpowers/specs/2026-04-26-dedicated-server-lineup-design.md new file mode 100644 index 0000000..16421d8 --- /dev/null +++ b/docs/superpowers/specs/2026-04-26-dedicated-server-lineup-design.md @@ -0,0 +1,275 @@ +# Dedicated Server Lineup — Design Spec + +**Date:** 2026-04-26 +**Status:** Approved (skip user-review gate per owner override — implementation starting immediately) +**Owner:** Andrew +**Repo:** `EZSCALE/website` + +## Goals + +1. Ship the **new Dell 14th-gen dedicated server lineup** (8 chassis SKUs sourced from SaveMyServer per order) on `/dedicated-servers`. +2. Re-surface the **existing 12th/13th-gen rack inventory** (currently `status: hidden` in the seeder) so it's visible alongside the new line as instant-deploy "in stock" SKUs. +3. Build an interactive **per-chassis configurator** at `/dedicated-servers/{slug}` covering CPU, RAM, per-bay drives, OS, bandwidth, networking, IPv4. +4. Add a **5-stage post-order build status tracker** (Ordered → Hardware acquired → Assembly → Racked → Deployed) visible to the customer and editable by admins. +5. Wire **tiered setup fees** that waive automatically on Semi-Annual / Annual cycles. + +## Non-goals (deferred) + +- **C from Q6: Two-preset cards** (`Starter` + `Performance` per chassis) — v1.1, after first-month signal on what people actually buy +- **Workload bundles page** — v2 if pricing-positioning-vs-budget-bundlers keeps coming up in support +- **Automated SaveMyServer order placement** — admin-driven for v1 +- **Live capacity check at order time** — buffer-stock model not in v1 +- **Multi-region (currently Atlanta-only)** — `Location` selector renders but only has one option +- **Custom-quote builder for non-catalog requests** — uses existing `/contact` form +- **Hetzner comparison rows** — placeholder; fills in when separate research lands + +## Sources of truth + +| Asset | Path | Role | +|---|---|---| +| Catalog JSON | `docs/integrations/savemyserver/dedicated-server-catalog.json` | 27 raw SaveMyServer products, drive options, BOM costs | +| Build sheets | `../infrastructure/docs/dedicated-server-configurations.md` | Curated 8-product BOMs, EZSCALE Standard Build (locked baseline) | +| Pricing | `../infrastructure/docs/dedicated-server-pricing-2026q2.md` | Customer-facing monthly prices, margin math, drive add-on tables | +| Configurator design | `../infrastructure/docs/superpowers/specs/2026-04-24-dedicated-server-gen14-configurator-design.md` | 15 configurable option groups, cross-server compliance matrix | +| Competitor research | `../infrastructure/docs/competitors-atlanta-2026.md` | ColoCrossing/GTHost positioning baseline | +| Rack reality | `../infrastructure/docs/reference/rack-atl.md` | Existing customer-rentable rack slots | + +## EZSCALE Standard Build (locked baseline — applies to all 8 14th-gen chassis) + +Non-negotiable per `dedicated-server-configurations.md`: + +| Component | Selection | +|---|---| +| CPU | 2× Intel Xeon Gold 6230 (40C / 2.10 GHz) | +| RAM | 32 GB DDR4-2666 ECC RDIMM (2× 16 GB) | +| Boot | Dell BOSS Card with 2× 240 GB M.2 SSDs (mirrored) — **all main bays free for data** | +| Storage controller | PERC HBA330 (Non-RAID, IT mode) — N/A on R740xd NVMe (pure-PCIe) | +| iDRAC | iDRAC9 Enterprise License | +| Power | Dual redundant PSU | +| Network | 1× 1 GbE onboard + 1× 10 Gbps SFP+ | +| Drive trays | Pre-installed in every bay | +| OS | No OS (customer choice via post-provisioning panel) | +| Bandwidth | 1 Gbps unmetered uplink | +| IPv4 | 1× included | +| IPv6 | /64 included | + +## The 8 14th-gen chassis + +| Slug | Title | Form | Bays | Std build cost | Starting $/mo | Setup tier | +|---|---|---|---|---|---|---| +| `r440-4lff` | R440 4-Bay 3.5" LFF (1U) | 1U | 4× LFF | $1,690.61 | $119 | 2 ($349) | +| `r540-8lff` | R540 8-Bay 3.5" LFF (2U) | 2U | 8× LFF | $1,877.03 | $159 | 3 ($549) | +| `r640-8sff` | R640 8-Bay 2.5" SFF (1U) | 1U | 8× SFF | $1,411.83 | $179 | 2 ($349) | +| `r740-16sff` | R740 16-Bay 2.5" SFF (2U) | 2U | 16× SFF | $1,704.26 | $229 | 3 ($549) | +| `r740xd-24sff` | R740xd 24-Bay 2.5" SFF (2U) | 2U | 24× SFF | $1,919.73 | $279 | 3 ($549) | +| `r740xd-12lff` | R740xd 12-Bay 3.5" LFF (2U) | 2U | 12× LFF | $2,148.96 | $249 | 3 ($549) | +| `r640-10nvme` | R640 10-Bay U.2 NVMe (1U) | 1U | 10× NVMe | $1,606.79 | $239 | 4 ($799) | +| `r740xd-24nvme` | R740xd 24-Bay U.2 NVMe (2U) | 2U | 24× NVMe | $2,275.44 | $279 | 4 ($799) | + +Setup tiers (per Q5 brainstorm): + +| Tier | Chassis class | Setup fee | +|---|---|---| +| 1 | Single-socket Budget (R240/R340) — *not in v1 lineup* | $149 | +| 2 | Dual-socket 1U | $349 | +| 3 | Dual-socket 2U | $549 | +| 4 | NVMe / Quad-socket Enterprise | $799 | + +**Setup fee waived on Semi-Annual (6 mo) and Annual (12 mo) cycles. Non-refundable once hardware is purchased** (typically within 24h of order). Rental fees stay under the 14-day money-back guarantee. + +## Architecture + +### Routes + +``` +/dedicated-servers ← catalog landing (chassis grid) +/dedicated-servers/{slug} ← per-chassis detail + configurator + +account./services/{service} ← existing route, gets BuildStatusPanel +admin./orders/{order}/build ← admin milestone updater +``` + +### Database + +**1. Migration: `add_setup_fee_to_plans_table`** + +```php +$table->decimal('setup_fee', 10, 2)->default(0)->after('price'); +``` + +**2. Migration: `create_service_build_milestones_table`** + +```php +Schema::create('service_build_milestones', function (Blueprint $table): void { + $table->id(); + $table->foreignId('subscription_id')->constrained()->cascadeOnDelete(); + $table->string('stage'); // 'ordered' | 'hardware_acquired' | 'assembly' | 'racked' | 'deployed' + $table->timestamp('reached_at')->nullable(); + $table->text('note')->nullable(); + $table->foreignId('updated_by')->nullable()->constrained('users'); + $table->timestamps(); + $table->unique(['subscription_id', 'stage']); +}); +``` + +**3. PlanSeeder updates** + +- Re-enable existing 12th/13th-gen rows: `status: hidden` → `status: active`. Stock counts preserved. +- Insert 8 new 14th-gen rows with: `features` JSON containing `cpu`, `ram`, `storage`, `bays`, `tier` (chassis tier number), `lead_time_days: '7-10'`, `generation: '14th-gen'`. Setup fee per the table above. + +**4. ConfigOptionSeeder updates** + +Add a `Dedicated Gen14 Configurator` group cluster per `2026-04-24-dedicated-server-gen14-configurator-design.md`: + +- `dedicated_server_gen14_cpu` (standard CPU group — R440/R540/R640/R740) +- `dedicated_server_gen14_cpu_r740xd` (R740xd-only CPU group) +- `dedicated_server_gen14_ram` (RAM tiers) +- `dedicated_server_gen14_os` (OS selector) +- `dedicated_server_gen14_bandwidth` (bandwidth tiers) +- `dedicated_server_gen14_networking` (private networking add-on) +- `dedicated_server_gen14_ipv4` (IPv4 block size) +- `dedicated_server_gen14_location` (Atlanta only for v1) +- `dedicated_server_gen14_lff_bays_1_4` (drive selection bays 1-4 LFF) +- `dedicated_server_gen14_lff_bays_5_8` (drive selection bays 5-8 LFF) +- `dedicated_server_gen14_r740xd_lff_bays` (R740xd 12-bay LFF) +- `dedicated_server_gen14_sff_slots_1_8` (SFF slots 1-8) +- `dedicated_server_gen14_sff_slots_9_16` (SFF slots 9-16, R740 only) +- `dedicated_server_gen14_sff_slots_17_24` (SFF slots 17-24, R740xd SFF only) +- `dedicated_server_gen14_nvme_slots` (U.2 NVMe slots) + +Attach each sub-group only to applicable chassis per the cross-server compliance matrix. + +### Frontend file map + +``` +resources/ts/Pages/Marketing/ +├─ DedicatedServers.vue (REWRITE) +└─ DedicatedServerDetail.vue (NEW) + +resources/ts/Pages/Account/Services/ +└─ Show.vue (extend with BuildStatusPanel) + +resources/ts/Pages/Admin/Orders/ +└─ BuildTracker.vue (NEW) + +resources/ts/Components/Marketing/Dedicated/ +├─ ChassisCard.vue (NEW) +├─ GenerationFilter.vue (NEW) +├─ DedicatedConfigurator/ +│ ├─ index.vue +│ ├─ CpuSelector.vue +│ ├─ RamSelector.vue +│ ├─ DriveBayPicker.vue +│ ├─ OsSelector.vue +│ ├─ BandwidthSelector.vue +│ ├─ NetworkingSelector.vue +│ ├─ Ipv4Selector.vue +│ └─ ConfiguratorFooter.vue +└─ BuildStatusPanel.vue (used by both customer + admin) + +resources/ts/stores/ +└─ dedicatedConfigurator.ts (NEW Pinia store) +``` + +### Pinia state + +```ts +state = { + chassis: Plan | null, + cpu: string, + ramGb: number, // 32, 64, 128, 256, 512, 1024, 1536 + bays: Array, + os: string, + bandwidth: string, + privateNetworking: boolean, + ipv4: 1 | 5 | 13 | 29, + cycle: 'monthly' | 'quarterly' | 'semi_annual' | 'annual', +} + +getters = { + baselinePrice, cpuUpgradeCost, ramUpgradeCost, driveCost, + bandwidthCost, ipv4Cost, cycleSubtotal, setupFee, + cycleTotal, shareUrl, checkoutUrl, +} +``` + +### URL state contract + +`/dedicated-servers/{slug}?` and `/checkout/{plan_id}?` share: + +| Param | Values | Default | +|---|---|---| +| `cpu` | option value slug | baseline | +| `ram` | `32` `64` `128` `256` `512` `1024` `1536` | `32` | +| `bays` | comma-list, length = bay count | chassis-specific lean preset | +| `os` | `none` `alma9` `ubuntu24` `debian12` `windows-byol` | `none` | +| `bw` | `1g-unmetered` `10g-1tb` `10g-10tb` `10g-100tb` `10g-unmetered` | `1g-unmetered` | +| `pn` | `0` `1` | `0` | +| `ipv4` | `1` `5` `13` `29` | `1` | +| `cycle` | `monthly` `quarterly` `semi_annual` `annual` | `monthly` | + +### Setup fee flow + +Setup fee is calculated at checkout based on `plan.setup_fee` and selected cycle: + +```php +$includesSetupFee = in_array($cycle, ['monthly', 'quarterly']); +$setupFee = $includesSetupFee ? $plan->setup_fee : 0; +``` + +Surfaced as a separate line item on the checkout page with explanatory text. + +### Build tracker stages + +| # | Stage | Triggered by | Customer-visible message | +|---|---|---|---| +| 1 | `ordered` | Subscription `created` event | "Order received. We're placing the hardware order with our supplier." | +| 2 | `hardware_acquired` | Admin click | "Hardware acquired and en route to our datacenter (typically 2-3 days)." | +| 3 | `assembly` | Admin click | "Server received in Atlanta. Our DC tech is configuring iDRAC and assembly." | +| 4 | `racked` | Admin click | "Server racked, powered up, and online for final QA." | +| 5 | `deployed` | Admin click | "Server is live. Root credentials and iDRAC access have been emailed." | + +The `deployed` milestone flips `subscription.status` from `pending` → `active` and triggers the deployment email. + +## Edge cases + +| Case | Behavior | +|---|---| +| URL has more bay entries than chassis has bays | Truncate; toast warning | +| URL has invalid CPU for the chassis | Fall back to baseline; snackbar | +| Subscription cancelled before `hardware_acquired` | Full refund (rental + setup fee) | +| Subscription cancelled after `hardware_acquired`, inside 14 days | Pro-rated rental refund; setup fee non-refundable; chassis added to "ready-to-deploy" inventory | +| Customer wants off-catalog chassis | "Need something custom?" CTA → `/contact` form | +| Mobile (< 768 px) | DriveBayPicker collapses to single-column list; sticky footer docks to viewport bottom | +| Browser back/forward | URL hydration restores everything | + +## Testing + +- **Pest** — `tests/Feature/Marketing/DedicatedServersTest.php` and `tests/Feature/Account/BuildTrackerTest.php` +- **Vitest** — *deferred (Vitest not currently installed in this project; covered by Playwright + Pest)* +- **Playwright** — `tests/e2e/dedicated-configurator.spec.ts` (one happy-path E2E) + +## Acceptance criteria + +- [ ] Migration adds `plans.setup_fee` and `service_build_milestones` table +- [ ] PlanSeeder seeds 8 new 14th-gen rows; un-hides existing 12th/13th-gen rows +- [ ] ConfigOptionSeeder adds 15 sub-groups under "Dedicated Gen14 Configurator" with chassis-specific attachments +- [ ] `/dedicated-servers` lists all dedicated plans (both lines), generation filter works +- [ ] `/dedicated-servers/{slug}` works for all 8 new chassis slugs +- [ ] Configurator computes correct totals across all option groups +- [ ] Setup fee shows on Monthly/Quarterly, hides on Semi-Annual/Annual +- [ ] Setup fee non-refundable note on checkout + FAQ +- [ ] `Order this configuration` deep-links with all params; checkout pre-selects them +- [ ] `Copy share link` works +- [ ] BuildStatusPanel renders during build; admin can mark milestones; customer sees timestamps +- [ ] `deployed` milestone flips subscription `pending` → `active` +- [ ] Pest tests pass +- [ ] `npm run build` and `php artisan test --compact` pass +- [ ] Mobile layout works without horizontal scroll + +## Open implementation questions (deferred to phase work) + +- Exact RAM upgrade pricing tiers — pull from `dedicated-server-pricing-2026q2.md` at seeder-write time +- Exact drive add-on prices per chassis — pull from catalog JSON `drives.drives` array per chassis +- Bandwidth tier pricing — pull from `dedicated-server-pricing-2026q2.md` +- Hetzner comparison row data — pending separate research