39 lines
3.4 KiB
Markdown
39 lines
3.4 KiB
Markdown
# EDU-017 — Tenant appearance, public settings, and theme lifecycle
|
|
|
|
- **Status:** done — bounded appearance/theme slice implemented and verified
|
|
- **Type:** tenant administration / public presentation configuration
|
|
- **Phase:** 4 / tenant operations
|
|
- **Blockers:** EDU-003, System Tenant authority, Vben admin foundation
|
|
|
|
## Decision
|
|
|
|
System Tenant remains authoritative for tenant identity, display name, lifecycle, and bound websites. Education owns only presentation-specific configuration: branding extensions, student/admin feature flags, public runtime configuration, and draft/published theme state. The public tenant locator response remains the minimal EDU-003 contract; appearance is exposed separately under the normal request tenant context.
|
|
|
|
Platform theme templates are global trusted configuration and are explicitly excluded from MyBatis tenant injection. Tenant appearance rows extend `TenantBaseDO`, retain one live row per tenant, and use optimistic versions for every update. RuoYi System RBAC, tenant validation, admin projection, API access/operation logging, and the normal `tenant-id` security filter remain authoritative.
|
|
|
|
## Delivered contract
|
|
|
|
- Admin read, branding write, settings write, theme preview, and theme publish endpoints with independent permissions.
|
|
- `GET /education/tenant-appearance/public` is anonymous but not tenant-ignored; it requires the normal validated tenant header/context and returns no admin flags or draft data.
|
|
- System tenant name is the lazy-row default and fallback; no duplicate Education tenant identity or domain authority is created.
|
|
- Three legacy-compatible templates are seeded: `classic`, `focus`, and `high-contrast`.
|
|
- Theme preview is a shallow template/override merge. Publication revalidates the persisted draft and clears it atomically.
|
|
- Recursively rejects secret/password/token/private-key/API-key-like public keys except `secretRef`; theme tokens, CSS variables, icons, assets, colors, radii, modes, and density are allowlisted and unsafe renderable strings fail closed.
|
|
- Vben page `education/tenant-appearance/index` manages branding, JSON settings, templates, draft preview, and explicit publication with client-side preflight checks.
|
|
|
|
## Verification
|
|
|
|
- Policy unit tests cover recursive secret rejection, closed theme/asset key sets, colors/radii/CSS, URLs, and shallow merge.
|
|
- Service unit tests cover System-name fallback, optimistic conflict, sanitized draft persistence, and public projection.
|
|
- Method-security contract tests prove query, branding, settings, and theme permissions are independent.
|
|
- Real PostgreSQL service tests prove lazy defaults, shared templates, settings, draft/publish, public projection, stale-version rejection, and cross-tenant isolation through the production MyBatis interceptor.
|
|
- Flyway tests prove the V4290 schema, exact template seeds, menu shape, unique tenant row, and draft/publish database state.
|
|
|
|
## Explicitly open
|
|
|
|
- Domains stay in System Tenant `websites`; no Education domain CRUD authority is planned.
|
|
- Payment-account configuration must compose Pay rather than copy the legacy table.
|
|
- Authentication-provider configuration must reuse System/Member authentication seams.
|
|
- Tenant secret storage/rotation needs a dedicated encrypted private-storage decision and must never be added to the public appearance table.
|
|
- Activation codes and coupons need a Mall Promotion/Member entitlement ownership and idempotent redemption decision.
|