Multi-Domain-Asset-Infrastruktur: geteilte Vite-Konfiguration und DomainAssetContext

- vite.shared.js als gemeinsame Quelle fuer Ports, Hot-Files, HMR-Hosts
  und CORS-Origins der beiden Vite-Builds (Portal/Web)
- App\Support\DomainAssetContext kapselt die Vite-Build-Directory-
  Konfiguration pro Domain (ThemeServiceProvider + Auth-Layout nutzen ihn)
- Tailwind-Portal-Content-Globs auf die tatsaechliche View-Struktur gezogen
- Dev-Beispiel-Routen + Tests (DomainAssetContextTest, DevExampleRoutesTest)
- Aufraeumen: versehentliche Leerdatei dev:web entfernt

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-06-12 08:16:09 +00:00
parent 4bb9094207
commit 0efabaf446
15 changed files with 485 additions and 109 deletions

View file

@ -0,0 +1,84 @@
<?php
use App\Support\DomainAssetContext;
use Illuminate\Http\Request;
test('pressekonto homepage resolves to web assets', function () {
$defaults = ['theme' => 'fallback', 'assets_dir' => 'build/b2in'];
$domains = config('domains.domains');
$config = DomainAssetContext::resolve(
'pressekonto.test',
$defaults,
$domains,
null,
Request::create('https://pressekonto.test/', 'GET'),
);
expect($config['theme'])->toBe('pressekonto')
->and($config['assets_dir'])->toBe('build/web');
});
test('pressekonto admin routes resolve to portal assets', function () {
$defaults = ['theme' => 'fallback', 'assets_dir' => 'build/b2in'];
$domains = config('domains.domains');
$config = DomainAssetContext::resolve(
'pressekonto.test',
$defaults,
$domains,
null,
Request::create('https://pressekonto.test/admin/users', 'GET'),
);
expect($config['theme'])->toBe('portal')
->and($config['assets_dir'])->toBe('build/portal')
->and($config['asset_url'])->toBe('https://assets.pressekonto.test');
});
test('presseecho resolves to its own web theme', function () {
$defaults = ['theme' => 'fallback', 'assets_dir' => 'build/b2in'];
$domains = config('domains.domains');
$config = DomainAssetContext::resolve(
'presseecho.test',
$defaults,
$domains,
);
expect($config['theme'])->toBe('presseecho')
->and($config['assets_dir'])->toBe('build/web');
});
test('hot file path depends on asset bundle', function () {
expect(DomainAssetContext::hotFilePath('build/web'))
->toEndWith('hot-web')
->and(DomainAssetContext::hotFilePath('build/portal'))
->toEndWith('hot-portal');
});
test('static asset origin always uses main domain not vite subdomain', function () {
expect(DomainAssetContext::staticAssetOrigin([
'url' => 'https://pressekonto.test',
'asset_url' => 'https://assets.pressekonto.test',
]))->toBe('https://pressekonto.test');
});
test('vite dev server url uses asset subdomain from domain config', function () {
expect(DomainAssetContext::viteDevServerUrl([
'url' => 'https://pressekonto.test',
'asset_url' => 'https://assets.pressekonto.test',
'assets_dir' => 'build/portal',
]))->toBe('https://assets.pressekonto.test');
});
test('backend request detection covers admin and livewire paths', function () {
expect(DomainAssetContext::isBackendRequest(Request::create('/admin/users')))
->toBeTrue()
->and(DomainAssetContext::isBackendRequest(Request::create('/livewire/update', 'POST')))
->toBeTrue()
->and(DomainAssetContext::isBackendRequest(Request::create('/kategorien')))
->toBeFalse()
->and(DomainAssetContext::isBackendRequest(Request::create('/')))
->toBeFalse();
});

View file

@ -0,0 +1,7 @@
<?php
test('example', function () {
$response = $this->get('/');
$response->assertStatus(200);
});