fix: resolve architecture validation errors

- Create platform_service.py to move DB queries from platforms.py API
- Create platform.py exceptions for PlatformNotFoundException
- Update platforms.py API to use platform_service
- Update vendor/content_pages.py to use vendor_service
- Add get_vendor_by_id_optional method to VendorService
- Fix platforms.js: add centralized logger and init guard
- Fix content-page-edit.html: use modal macro instead of inline modal

All 21 architecture validation errors resolved.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-19 18:42:30 +01:00
parent 4f55fe31c8
commit d70a9f38d4
7 changed files with 432 additions and 276 deletions

View File

@@ -3,6 +3,7 @@
{% from 'shared/macros/alerts.html' import loading_state, error_state, alert_dynamic %}
{% from 'shared/macros/headers.html' import back_button %}
{% from 'shared/macros/inputs.html' import number_stepper %}
{% from 'shared/macros/modals.html' import modal %}
{% block title %}{% if page_id %}Edit{% else %}Create{% endif %} Content Page{% endblock %}
@@ -71,46 +72,18 @@
</div>
<!-- Default Content Preview Modal -->
<div
x-show="showingDefaultPreview"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
@click.self="showingDefaultPreview = false"
>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-3xl w-full mx-4 max-h-[80vh] overflow-hidden">
<div class="flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-gray-700">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Platform Default Content</h3>
<button @click="showingDefaultPreview = false" class="text-gray-500 hover:text-gray-700 dark:hover:text-gray-300">
<span x-html="$icon('x-mark', 'w-6 h-6')"></span>
</button>
</div>
<div class="p-6 overflow-y-auto max-h-[60vh]">
<div x-show="loadingDefault" class="text-center py-8">
<span x-html="$icon('spinner', 'inline w-8 h-8 text-purple-600')"></span>
<p class="mt-2 text-sm text-gray-500">Loading default content...</p>
</div>
<div x-show="!loadingDefault && defaultContent">
<h4 class="text-sm font-medium text-gray-500 dark:text-gray-400 mb-2">Title</h4>
<p class="text-lg font-semibold text-gray-900 dark:text-white mb-4" x-text="defaultContent?.title"></p>
<h4 class="text-sm font-medium text-gray-500 dark:text-gray-400 mb-2">Content</h4>
<div class="prose dark:prose-invert max-w-none bg-gray-50 dark:bg-gray-700 rounded-lg p-4" x-html="defaultContent?.content"></div>
</div>
</div>
<div class="flex justify-end px-6 py-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/50">
<button
@click="showingDefaultPreview = false"
class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700"
>
Close
</button>
</div>
{% call modal('defaultPreviewModal', 'Platform Default Content', 'showingDefaultPreview', size='lg', show_footer=false) %}
<div x-show="loadingDefault" class="text-center py-8">
<span x-html="$icon('spinner', 'inline w-8 h-8 text-purple-600')"></span>
<p class="mt-2 text-sm text-gray-500">Loading default content...</p>
</div>
</div>
<div x-show="!loadingDefault && defaultContent">
<h4 class="text-sm font-medium text-gray-500 dark:text-gray-400 mb-2">Title</h4>
<p class="text-lg font-semibold text-gray-900 dark:text-white mb-4" x-text="defaultContent?.title"></p>
<h4 class="text-sm font-medium text-gray-500 dark:text-gray-400 mb-2">Content</h4>
<div class="prose dark:prose-invert max-w-none bg-gray-50 dark:bg-gray-700 rounded-lg p-4" x-html="defaultContent?.content"></div>
</div>
{% endcall %}
<!-- Main Form -->
<div x-show="!loading" class="bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden">