* add pb models * api rules has updated to view public * pb setup is completed * add migrate script * add pb migrations * ignore storage * add pocketbase SDK dependency * change Tag.id and PageCardDto.id to string for PocketBase * add DocV1 content block types * add PB client singleton and PB record types * rewrite factory for PocketBase record types * rewrite api.ts for PocketBase SDK * remove unused Strapi files, add PB to config * mark Task 7 complete in plan * feat: verify build, tests, and lint pass with PocketBase API layer * move completed plan: 2026-04-06-pocketbase-api-layer.md * scaffold hudozka-writer with Vite 8, React 19, TS 5.9, Tiptap * add PocketBase client and DocV1 types to writer * add Login component for PocketBase superuser auth * add App shell with auth gate and page loader * add DocV1 <-> Tiptap serialization layer * mark Task 5 complete in writer redesign plan * add custom Tiptap nodes for DocV1 block types * add Tiptap editor with toolbar and save to PocketBase * add image picker with browse and upload * feat: verify writer build and complete integration task * move completed plan: 2026-04-06-hudozka-writer-redesign.md * add local env * rm textblock from writer * add writer editor improvements design spec * add writer editor improvements implementation plan * feat: use @tiptap/markdown for text block serialization * feat: add global markdown/rendered toggle * feat: add BlockMenu component for block type selection * feat: add hover + button for block insertion * feat: add slash commands for block insertion * feat: add interactive file block editor with FilePicker * feat: show resolved page titles in card grid block * move completed plan: 2026-04-07-writer-editor-improvements.md * writer ui improved * pages migration * spec: draft/publish workflow for hudozka-writer * spec: rename draft_doc to draft in spec * plan: writer draft/publish implementation * plan has moved * gitignores * plans upd * feat(writer): update PbPage type for draft/publish workflow * feat(writer): add save/publish/discard handlers with dirty tracking * feat(writer): add DraftBanner component * feat(writer): add Publish button and update toolbar layout * feat(writer): add published toggle and update duplicate for new schema * docs: mark manual verification steps as skipped in writer draft/publish plan * move completed plan: 20260407-writer-draft-publish.md * feat(writer): add BlockActions component for inline block menus * feat(writer): add draggable NodeViews for text blocks * feat(writer): use BlockActions in custom block NodeViews * feat(writer): replace floating BlockInsert with inline BlockActions * fix(writer): ensure all block wrappers have position: relative for BlockActions * chore: mark manual verification tasks as skipped in writer block actions plan * move completed plan: 20260408-writer-block-actions.md * writer update * refactor(writer): simplify BlockActions to always-visible delete + drag handle * feat(writer): add BlockInsert component for inserting blocks between nodes * feat(writer): redesign block sidebar with always-visible actions and insert button * move completed plan: 20260408-writer-block-actions-redesign.md * add spec: textblock container redesign for writer editor * feat(writer): add TextBlock container node definition * feat(writer): replace DraggableXxx wrappers with TextBlock container * feat(writer): update Editor extensions for TextBlock container * feat(writer): add split button to BlockActions for text blocks * feat(writer): update serialization for TextBlock container * feat(writer): update BlockMenu and SlashCommands for TextBlock * fix(writer): use Fragment.from() for replaceWith calls in BlockActions and SlashCommands * move completed plan: 20260408-textblock-container.md * add air
5.6 KiB
PocketBase Migration Plan
Based on verified live data from hudozka.tmshv.com.
Verified Data Volume
| Entity | Count |
|---|---|
| Pages | 316 |
| Tags | 70 |
| Home cards | 17 |
| Menu items | 4 |
Part 1: PocketBase Setup (manual)
See 20260403-pocketbase-setup-guide.md.
Part 2: Migration Script
Script location: modules/migrate-to-pocketbase/
What it does
-
Fetches all data from Strapi (
hudozka.tmshv.com):GET /pages?_limit=100&_start={n}(4 batches)GET /tagsGET /homeGET /menu
-
Creates 70 tag records in PocketBase, builds
strapiTagId -> pbTagIdmap. -
Collects all unique Strapi media used as images (covers +
hudozka.imageblocks). For each:- Downloads file from
hudozkacdn.tmshv.com - Reads dimensions with
sharp, computes blurhash - Creates
imagesrecord withfile, alt, caption, width, height, blur, filename - Builds
strapiMediaId -> pbImageIdmap
- Downloads file from
-
Collects all unique Strapi media used as documents (
hudozka.documentblocks). For each:- Downloads file from
hudozkacdn.tmshv.com - Creates
filesrecord withfile, title, mime, size, filename(preview left empty) - Builds
strapiMediaId -> pbFileIdmap
- Downloads file from
-
For each of 316 pages:
- Resolves
covertopbImageIdvia image map - Converts
content[]from Strapi component format to simplified JSON blocks:hudozka.text->{ type: "text", text }hudozka.image->{ type: "image", image: pbImageId, wide, caption }hudozka.document->{ type: "document", file: pbFileId, title }hudozka.embed->{ type: "embed", src }hudozka.card-grid->{ type: "card-grid", items: [{ page: strapiPageId, layout }] }
- Creates page record with
cover+tagsrelations +contentJSON
- Resolves
-
Second pass: replaces Strapi page IDs in
card-gridblocks with PocketBase page IDs. -
Creates 2
kvrecords:key: "home"with card list (PocketBase page IDs + layouts)key: "menu"with menu items (PocketBase page IDs) +homeLabel
-
Verification: counts check, spot-check, HTTP HEAD on file URLs.
Environment
Requires STRAPI_URL (default https://hudozka.tmshv.com) and POCKETBASE_URL + POCKETBASE_EMAIL + POCKETBASE_PASSWORD env vars.
Part 3: App Changes
Only src/remote/ changes. src/types.ts stays unchanged.
New file: src/remote/pb.ts
PocketBase client singleton. Reads POCKETBASE_URL from env.
Rewrite: src/remote/types.ts
Replace Strapi* types with Pb* types matching PocketBase record shape + new content block types.
Rewrite: src/remote/api.ts
Same exported function signatures, PocketBase SDK calls instead of raw fetch:
| Function | Current | New (PocketBase SDK) |
|---|---|---|
getUrls() |
GET /pages?_limit=100&_start={n} |
pb.collection("pages").getFullList({ fields: "slug" }) |
getPageBySlug(slug) |
GET /pages?slug={slug} |
pb.collection("pages").getFirstListItem('slug="..."', { expand: "cover,tags" }) + resolve image/file IDs from content via prefetched maps |
getHomeCards() |
GET /home |
pb.collection("kv").getFirstListItem('key="home"') + fetch pages |
getMenu() |
GET /menu |
pb.collection("kv").getFirstListItem('key="menu"') + fetch pages |
getRecentPages(n) |
GET /pages?_sort=date:DESC&_limit={n} |
pb.collection("pages").getList(1, n, { filter: "date!=''", sort: "-date" }) |
Rewrite: src/remote/factory.ts
Transform functions accept PocketBase records, output identical app types. Key changes:
- At build start, prefetch all
imagesandfilesrecords once → in-memoryMap<id, record> - Content blocks reference image/file IDs; resolved via the maps (no per-page expand)
- Pages fetched with
expand: "cover,tags"only - File URLs via
pb.files.getURL(record, record.file) - Blurhash read from image record (
blurfield) — no runtimesharpcalls needed contentis already clean JSON (no__componentprefix)asItem()fromlib.tsno longer neededcreatePicFromMedia()->createPicFromImageRecord(imageRecord)- Text processing (
markdownToHtml+typograf) stays identical
Update: next.config.ts
Add PocketBase host to images.remotePatterns.
New dependency
pocketbase (JS SDK)
Files summary
| File | Action |
|---|---|
src/remote/pb.ts |
New — PocketBase client |
src/remote/types.ts |
Rewrite — Pb* types |
src/remote/api.ts |
Rewrite — PocketBase SDK calls |
src/remote/factory.ts |
Rewrite — new input shapes |
src/remote/image.ts |
Remove — blurhash precomputed in migration |
src/remote/lib.ts |
Remove or simplify |
src/types.ts |
No changes |
next.config.ts |
Update — remotePatterns |
.env.example |
Update — add POCKETBASE_URL |
package.json |
Update — add pocketbase dependency |