Migrate to Stack A: PHP-fpm + nginx + supervisord, drop flat HTML + Python API

- Remove old flat HTML pages (index, about, blog, contact, reviews, services/*, locations/*)
- Remove Python/Flask API container (api/)
- Remove old root nginx.conf and components/
- Add infra/: full nginx.conf (http block at /etc/nginx/nginx.conf), php-fpm-pool.conf (TCP listen), supervisord.conf, entrypoint.sh (auto-generates ALTCHA_HMAC_KEY)
- Add src/: PHP router, page/service/location/blog templates, contact handler, altcha handler, promo endpoint, SQLite data files
- Rewrite Dockerfile: single container, tini PID 1, healthcheck, all env vars declared
- Update docker-compose.yml: port 8096, env_file, healthcheck
- Update .dockerignore: exclude .env.*, include robots.txt/sitemap.xml/404.html/500.html
- Update assets: tokens.css, promo-popup.css/js, altcha.min.js, refactored form.js/main.js

Verified: all 17 routes 200, protection audit PASS, Resend confirmed working

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Concept Agent
2026-05-29 18:56:56 +02:00
parent 88ed4e6bda
commit 81feccdc1a
61 changed files with 2460 additions and 5747 deletions
+73
View File
@@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
exit;
}
header('Content-Type: application/json');
$email = trim(strip_tags($_POST['email'] ?? ''));
$phone = trim(strip_tags($_POST['phone'] ?? ''));
$sqft = trim(strip_tags($_POST['sqft'] ?? ''));
if (!$email || !$phone || !$sqft) {
http_response_code(400);
echo json_encode(['ok' => false, 'error' => 'All fields are required.']);
exit;
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
http_response_code(400);
echo json_encode(['ok' => false, 'error' => 'Invalid email address.']);
exit;
}
$sqft_int = (int) preg_replace('/[^0-9]/', '', $sqft);
if ($sqft_int < 50 || $sqft_int > 50000) {
http_response_code(400);
echo json_encode(['ok' => false, 'error' => 'Please enter a valid square footage.']);
exit;
}
$api_key = getenv('RESEND_API_KEY');
$from = getenv('FROM_EMAIL') ?: 'Floor It Hardwood Floors <webleads@floorithardwoods.com>';
$to_email = getenv('TO_EMAIL') ?: 'floorithardwoods@gmail.com';
if (!$api_key) {
http_response_code(500);
echo json_encode(['ok' => false, 'error' => 'Server configuration error.']);
exit;
}
$body = "Summer Refinishing Savings Lead\n\nEmail: {$email}\nPhone: {$phone}\nSquare Footage: {$sqft_int} sq ft\n\nOffer: Save up to 15% off through June 30, 2026.";
$payload = json_encode([
'from' => $from,
'to' => [$to_email],
'subject' => "Summer Promo Lead: {$sqft_int} sq ft from {$email}",
'text' => $body,
]);
$ch = curl_init('https://api.resend.com/emails');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $api_key,
'Content-Type: application/json',
],
CURLOPT_TIMEOUT => 10,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 200 && $status < 300) {
echo json_encode(['ok' => true]);
} else {
http_response_code(502);
echo json_encode(['ok' => false, 'error' => 'Something went wrong. Please call (716) 602-1429.']);
}