Files
amare/database/seeders/ContentSeeder.php
manoel freitas fc1c6177d6
All checks were successful
CI / static (push) Successful in 2m21s
CI / unit (push) Successful in 3m17s
CI / feature (push) Successful in 2m29s
CI / container (push) Successful in 18s
CI / browser (push) Successful in 3m8s
feat: remodelar /sobre conforme mock editorial
Co-authored-by: manoel freitas <manoel.josefneto@gmail.com>
Co-committed-by: manoel freitas <manoel.josefneto@gmail.com>
2026-08-12 20:34:13 +00:00

220 lines
10 KiB
PHP

<?php
declare(strict_types=1);
namespace Database\Seeders;
use App\Models\PortfolioCase;
use App\Models\PortfolioImage;
use App\Models\Service;
use App\Models\SiteSetting;
use App\Support\PublicImageUploadRules;
use Illuminate\Database\Seeder;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
class ContentSeeder extends Seeder
{
private const SEED_TIMESTAMP = '2026-01-15 10:00:00';
/**
* Demo/fixture content is meant for local dev, automated testing, and
* staging visual review only. It must never overwrite owner-edited
* SiteSetting, Service, and PortfolioCase records, never re-upload
* fixture images to the production storage disk, and never auto-publish
* the fictional portfolio cases or (via TestimonialsSeeder) the real
* testimonials.
*
* This is deliberately an allow-list of the known-safe environments
* ('local', 'staging', 'testing') rather than a deny-list of
* 'production'. APP_ENV is a free-text value hand-typed into the
* Dokploy environment UI with no validation — a blank value, a typo, or
* an unexpected casing (e.g. '', 'Production', 'staginng') must fail
* closed (skip seeding) rather than fail open (seed/overwrite
* production data). Only the three recognized values run this seeder;
* everything else, including 'production' itself, is a no-op.
*
* Publishing testimonials in production remains a deliberate, manually
* triggered step — see docs/deployment/dokploy.md.
*/
public function run(): void
{
if (! App::environment(['local', 'staging', 'testing'])) {
return;
}
$this->seedSiteSettings();
$this->seedServices();
$this->seedPortfolioCases();
$this->call(TestimonialsSeeder::class);
$this->call(WeddingPackagesSeeder::class);
}
private function seedSiteSettings(): void
{
SiteSetting::query()->updateOrCreate([], [
'brand_name' => 'Amare Assessoria',
'hero_eyebrow' => 'Assessoria e produção de eventos · São Paulo',
'hero_title' => 'Celebrações com propósito',
'hero_subtitle' => 'Planejamento completo para casamentos e eventos corporativos em São Paulo.',
'hero_cta_label' => 'Solicitar proposta',
'hero_secondary_cta_label' => 'Conheça nosso olhar',
'hero_note' => 'Planejamento cuidadoso, comunicação clara e execução segura — do primeiro encontro ao último detalhe.',
'hero_image_path' => $this->copyFixture('case-casamento-ana-lucas.jpg', 'content/heroes/home.jpg'),
'hero_image_alt' => 'Celebração ao ar livre em São Paulo',
'services_hero_image_path' => $this->copyFixture('service-eventos-corporativos.jpg', 'content/heroes/services.jpg'),
'services_hero_image_alt' => 'Mesa preparada para um evento corporativo',
'portfolio_hero_image_path' => $this->copyFixture('case-lancamento-verano.jpg', 'content/heroes/portfolio.jpg'),
'portfolio_hero_image_alt' => 'Ambientação de um evento de lançamento',
'about_summary' => 'Assessoria boutique especializada em experiências memoráveis em São Paulo.',
'about_image_path' => $this->copyFixture('about-image.jpg', 'content/about/about-image.jpg'),
'about_image_alt' => 'Mesa de planejamento com caderno, café e guardanapos de pano',
'founder_image_path' => $this->copyFixture('about-image.jpg', 'content/about/founder/michele.jpg'),
'founder_image_alt' => 'Michele, da Amare',
'manifesto_title' => 'Sofisticação que também se traduz em organização.',
'manifesto_lead' => 'Um evento memorável não nasce apenas de uma boa estética. Ele depende de decisões bem conduzidas, fornecedores alinhados e atenção constante ao que realmente importa.',
'manifesto_body' => 'A Amare combina sensibilidade e precisão para criar encontros coerentes com cada cliente, marca e ocasião — sem fórmulas prontas, excessos ou ruído.',
'method_intro' => 'Clareza em cada etapa. Tranquilidade durante todo o processo.',
'method_steps' => SiteSetting::defaultMethodSteps(),
'corporate_steps' => SiteSetting::defaultCorporateSteps(),
'principles' => SiteSetting::defaultPrinciples(),
'email' => 'amareassessoriaeventos@gmail.com',
'phone' => '(11) 99999-9999',
'city' => 'São Paulo - SP',
'social_links' => [
'instagram' => 'https://instagram.com/amare',
],
'default_meta_title' => 'Amare Assessoria de Eventos',
'default_meta_description' => 'Assessoria premium para casamentos e eventos corporativos em São Paulo.',
'default_og_image_path' => $this->copyFixture('og-default.jpg', 'content/og/og-default.jpg'),
'default_og_image_alt' => 'Identidade visual da Amare Assessoria de Eventos',
'analytics_enabled' => false,
'analytics_script' => null,
]);
}
private function seedServices(): void
{
$services = [
[
'title' => 'Casamentos',
'slug' => 'casamentos',
'summary' => 'Planejamento completo do grande dia.',
'description' => 'Do briefing ao último brinde, cuidamos de cada detalhe do casamento.',
'sort_order' => 1,
'is_featured' => true,
],
[
'title' => 'Eventos corporativos',
'slug' => 'eventos-corporativos',
'summary' => 'Experiências alinhadas à marca.',
'description' => 'Lançamentos, convenções e encontros corporativos com operação impecável.',
'sort_order' => 2,
'is_featured' => true,
],
[
'title' => 'Celebrações intimistas',
'slug' => 'celebracoes-intimistas',
'summary' => 'Encontros especiais em escala reduzida.',
'description' => 'Aniversários, mini weddings e jantares com curadoria editorial.',
'sort_order' => 3,
'is_featured' => false,
],
];
foreach ($services as $service) {
Service::query()->updateOrCreate(
['slug' => $service['slug']],
[
...$service,
'cover_image_path' => $this->copyFixture('service-'.$service['slug'].'.jpg', 'content/services/'.$service['slug'].'.jpg'),
'cover_image_alt' => 'Capa do serviço '.$service['title'],
'published_at' => Carbon::parse(self::SEED_TIMESTAMP),
],
);
}
}
private function seedPortfolioCases(): void
{
$cases = [
[
'title' => 'Casamento Ana e Lucas',
'slug' => 'casamento-ana-lucas',
'summary' => 'Cerimônia ao ar livre em São Paulo.',
'event_type' => 'Casamento',
'city' => 'São Paulo',
'venue' => 'Espaço Jardim Atlântico',
'event_date' => '2025-11-20',
'challenge' => 'Integrar cerimônia e recepção em áreas distintas.',
'solution' => 'Operação sincronizada com sinalização e timing detalhado.',
'result' => 'Experiência fluida para 180 convidados.',
'sort_order' => 1,
],
[
'title' => 'Lançamento Verano',
'slug' => 'lancamento-verano',
'summary' => 'Evento corporativo de lançamento de coleção.',
'event_type' => 'Corporativo',
'city' => 'São Paulo',
'venue' => 'Centro de Convenções',
'event_date' => '2025-09-10',
'challenge' => 'Ativar marca em ambiente multiestação.',
'solution' => 'Fluxo de convidados e fornecedores com cronograma minuto a minuto.',
'result' => 'Alta percepção de marca e cobertura de imprensa.',
'sort_order' => 2,
],
[
'title' => 'Mini wedding Marina',
'slug' => 'mini-wedding-marina',
'summary' => 'Celebração intimista em São Paulo.',
'event_type' => 'Mini wedding',
'city' => 'São Paulo',
'venue' => 'Espaço intimista',
'event_date' => '2025-06-02',
'challenge' => 'Clima e logística em área externa.',
'solution' => 'Plano B estruturado e fornecedores locais alinhados.',
'result' => 'Cerimônia emocionante com 40 convidados.',
'sort_order' => 3,
],
];
foreach ($cases as $caseData) {
$case = PortfolioCase::query()->updateOrCreate(
['slug' => $caseData['slug']],
[
...$caseData,
'cover_image_path' => $this->copyFixture('case-'.$caseData['slug'].'.jpg', 'content/portfolio/'.$caseData['slug'].'-cover.jpg'),
'cover_image_alt' => 'Capa do caso '.$caseData['title'],
'is_featured' => true,
'published_at' => Carbon::parse(self::SEED_TIMESTAMP),
],
);
PortfolioImage::query()->where('portfolio_case_id', $case->id)->delete();
foreach ([1, 2] as $index) {
PortfolioImage::query()->create([
'portfolio_case_id' => $case->id,
'path' => $this->copyFixture('gallery-'.$caseData['slug'].'-'.$index.'.jpg', 'content/portfolio/'.$caseData['slug'].'-gallery-'.$index.'.jpg'),
'alt_text' => 'Galeria '.$caseData['title'].' '.$index,
'caption' => $index === 1 ? 'Detalhe da decoração' : null,
'sort_order' => $index,
]);
}
}
}
private function copyFixture(string $fixtureName, string $destination): string
{
$source = base_path('database/fixtures/images/'.$fixtureName);
$disk = PublicImageUploadRules::disk();
Storage::disk($disk)->put($destination, File::get($source), 'public');
return $destination;
}
}