feat: Page Editor v1.0 - canonical schema, SSR parity, and migration

Major improvements to WooNooW Page Editor system:

Schema & Architecture:
- Canonical section schema with unified sectionSchema.ts
- Normalized feature-grid to use items (not features)
- Standardized default values across all section types
- Schema versioning with automatic migration on read

Backend (PHP):
- Enhanced PlaceholderRenderer with typed output contracts
- Added fallback behavior for empty/invalid dynamic sources
- Added caching support for post data resolution
- New SchemaMigration class for backward compatibility
- New Features class for feature flags
- Enhanced PageSSR with full style support
- Removed controller-level special-casing for related_posts

Frontend (Admin SPA):
- Updated CanvasRenderer with schema-aware transformation
- Enhanced InspectorPanel with canonical schema metadata
- Added new section renderers

Frontend (Customer SPA):
- New section components: BentoCategoryGrid, MarqueeBanner, ProductCarousel, ShoppableImage
- Updated FeatureGridSection for items prop contract

Testing:
- Add PHP tests: SchemaMigrationTest, PlaceholderRendererTest, PageSSRTest
- Add TypeScript tests: schema-integration, feature-grid-regression
- Add parity tests for React vs SSR content matching
- Add CI script: check-schema-drift.mjs
- Add VERIFICATION_CHECKLIST.md

Documentation:
- RELEASE_NOTES-v1.0.md with full release notes
- docs/PAGE_EDITOR_SECTION_SCHEMA_V1.md
- docs/PAGE_EDITOR_SSR_COVERAGE_AUDIT.md
This commit is contained in:
Dwindi Ramadhana
2026-05-30 13:02:08 +07:00
parent e70aa1f554
commit 396ca25be4
118 changed files with 10162 additions and 3726 deletions

View File

@@ -56,13 +56,10 @@ export default function TaxSettings() {
// Create tax rate
const createMutation = useMutation({
mutationFn: async (data: any) => {
console.log('[Tax] Creating rate:', data);
const response = await api.post('/settings/tax/rates', data);
console.log('[Tax] Create response:', response);
return response;
},
onSuccess: (data) => {
console.log('[Tax] Create success:', data);
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['tax-settings'] });
queryClient.invalidateQueries({ queryKey: ['tax-suggested'] });
setShowAddRate(false);
@@ -107,7 +104,6 @@ export default function TaxSettings() {
// Quick add suggested rate
const quickAddMutation = useMutation({
mutationFn: async (suggestedRate: any) => {
console.log('[Tax] Quick adding rate:', suggestedRate);
const response = await api.post('/settings/tax/rates', {
country: suggestedRate.code,
state: '',
@@ -118,11 +114,9 @@ export default function TaxSettings() {
compound: 0,
shipping: 1,
});
console.log('[Tax] Quick add response:', response);
return response;
},
onSuccess: (data) => {
console.log('[Tax] Quick add success:', data);
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['tax-settings'] });
queryClient.invalidateQueries({ queryKey: ['tax-suggested'] });
toast.success(__('Tax rate added'));