7.2 KiB
7.2 KiB
Database Detail Pages Refactor Plan (SvelteKit-centric)
This plan refactors the database detail pages to be modular, reusable, and easy to port across characters, weapons, and summons. It leans into SvelteKit features (server load, form actions, and use:enhance) and Svelte composition (slots, small components, and lightweight state helpers).
Goals
- Consistent scaffold for detail pages (header, edit toolbar, sections, feedback).
- Encapsulated edit-mode state + mapping to/from API payloads.
- Clean separation between server concerns (loading, saving, validation) and client UI.
- Reusable section components that can be shared or adapted per resource.
- Smooth path to port the architecture to weapons and summons.
Architecture Overview
- Client
DetailScaffold.svelte: Common header, edit/save/cancel controls, messages, and section slots.createEditForm.ts: Small factory returning state + helpers for edit lifecycle.- Initializes
editDatafrom the resource model via a schema mapping. - Exposes
editMode,toggleEdit,reset,set,get, andsubmitglue for forms.
- Initializes
image.ts:getResourceImage(type, granblue_id)centralizing image paths and fallbacks.- Section components per resource (e.g.,
CharacterMetadataSection.svelte, sharedStatsSectionwhen possible).
- Server
- Shared loader helpers (e.g.,
lib/server/detail/load.ts) to fetch a resource detail and normalize to a client-facing model. - Form actions in
+page.server.tsfor save (actions.save) with validation (optionally Zod) and proper error handling. - Progressive enhancement via
use:enhanceso the UI stays responsive without losing SSR form semantics.
- Shared loader helpers (e.g.,
- Schema-driven mapping
- Per resource (
characters/schema.ts,weapons/schema.ts,summons/schema.ts) define:toEditData(model): API model -> UI edit state.toPayload(editData): UI edit state -> API payload.- Optional field metadata (labels, formatter hooks) for low-ceremony sections.
- Per resource (
File Structure (proposed)
src/lib/features/database/detail/DetailScaffold.svelte(header + actions + slots)createEditForm.ts(state helper)image.ts(resource image helper)api.ts(client-side action helpers if needed)
src/lib/features/database/characters/schema.tssections/CharacterMetadataSection.svelteCharacterUncapSection.svelteCharacterTaxonomySection.svelteCharacterStatsSection.svelteHPStatsSubsection.svelteATKStatsSubsection.svelte
- Similar folders for
weaponsandsummonsas we port.
Form Actions and Loaders
- Loader strategy
- Current route
+page.ts/+page.server.tsfetches the detailed entity and returns a normalizedmodel. - A shared helper
getResourceDetail(resource, id)can live underlib/server/detail/load.tsto reduce duplication across resources.
- Current route
- Save strategy
- Define
export const actions = { save: async (event) => { ... } }in+page.server.ts. - Validate incoming form data (Zod/schema), map to API payload via the schema’s
toPayload, then persist via your backend API. - Return
fail(status, { fieldErrors, message })on validation errors. - On success, return the updated item;
loadcan pick it up or the client can reconcile locally.
- Define
- Client strategy
- Wrap the editable fields in a
<form method="POST">withuse:enhance. - For a gradual migration from controlled inputs, keep local
editDatabut mirror it into form fields (hidden or direct binds) to submit via actions. - Use action results to show success/error messages in
DetailScaffold.
- Wrap the editable fields in a
Phased Tasks
Phase 1 — Extract Scaffold + Edit Form Helper
- Create
src/lib/features/database/detail/DetailScaffold.sveltewith slots:- Header slot or props for resource
type,item,image. - Top-right action area for Edit/Cancel/Save.
- Message area for success/error.
- Default slot for sections.
- Header slot or props for resource
- Create
src/lib/features/database/detail/createEditForm.ts:- Accepts initial
modeland mappingtoEditData/toPayload. - Returns
editMode,editData(store or bindable object),toggleEdit,reset,submit. - Resets
editDatawhenmodelchanges.
- Accepts initial
- Replace inline header/controls in
characters/[id]/+page.sveltewithDetailScaffoldwhile preserving behavior.
Phase 2 — Extract Character Sections
CharacterMetadataSection.svelte(Rarity, Granblue ID): view/edit with existing utilities.CharacterUncapSection.svelte(Indicator + FLB/ULB/Transcendence/Special toggles).CharacterTaxonomySection.svelte(Element, Race1/2, Gender, Proficiency1/2).CharacterStatsSection.sveltewith subcomponents for HP and ATK stats.- Wire sections to
editModeandeditDatavia props/bindings; keep look-and-feel identical.
Phase 3 — Add Schema + Validation + Actions
src/lib/features/database/characters/schema.ts:toEditData(model)maps current character model to edit state.toPayload(editData)maps edit state to backend payload.- Optional Zod schemas for validation.
- Add
+page.server.tsactions.savefor characters:- Parse form data; validate; call backend; return updated item or errors.
- Handle cookies/credentials as needed.
- Wrap editable UI in
<form method="POST" use:enhance>and handle optimistic UI/disable Save while pending. - Show validation errors and success states in
DetailScaffold.
Phase 4 — Shared Loaders + Port to Weapons/Summons
- Add
lib/server/detail/load.tshelpers for shared resource fetching. - Update characters loader to use shared helper.
- Create
src/lib/features/database/weapons/schema.tsand sections; adopt the scaffold. - Create
src/lib/features/database/summons/schema.tsand sections; adopt the scaffold. - Implement
+page.server.tsactions for weapons and summons with validation.
Phase 5 — Polish and DX
image.tshelper and replace ad-hoc image path logic.- Extract
getDisplayNameto a single utility. - Add unit tests for schema mapping functions (to/from payload).
- Add basic e2e smoke for actions (save success and validation failure).
- Document conventions (where to put schemas, sections, and loaders).
Acceptance Criteria
- Character detail page renders identically, with no regressions.
- Edit mode and saving function via form actions, with graceful errors.
- Sections are split into components and trivially testable.
- Weapons and summons can be implemented by adding schema + sections and wiring the same scaffold and actions.
Risks and Mitigations
- Form action migration conflict with controlled inputs:
- Mitigate by mirroring
editDatainto form fields and usinguse:enhanceto reconcile results.
- Mitigate by mirroring
- Server validation shape mismatch:
- Use Zod schemas that align with backend; log/trace action failures early.
- Over-abstracting sections:
- Favor small, explicit components; introduce config-driven rendering only where repetition is high and behavior simple.
If we agree on this plan, start with Phase 1 (scaffold + helper) and wire it into the character page without changing behavior, then proceed section-by-section.