Skip to content

build!: ship Magic Mark 4.0 as a free plugin with multi-process fixes and new docs - #3

Merged
Schero94 merged 9 commits into
mainfrom
chore/finish-free-docs
Nov 7, 2026
Merged

Schero94 merged 9 commits into
mainfrom
chore/finish-free-docs

Conversation

@Schero94

@Schero94 Schero94 commented Nov 7, 2026

Copy link
Copy Markdown
Owner

Summary

Finishes Magic Mark 4.0 as a free plugin with no installation ping or telemetry.

  • Server: bookmarks, shares, pins and permissions now stay consistent when several Strapi processes start or write at the same time. The 3.x migration runs once, never duplicates rows and removes the old licence store keys (7dffcef).
  • Package: peers now match the Strapi 5 app template. @strapi/utils is a dependency, and Design System, icons and react-intl are optional peers. Package metadata is fixed and the homepage points at the project site (6876a06, BREAKING).
  • CI: tests also run against the lowest supported Strapi version (abc2cc9).
  • Docs: README and the GitHub Pages site are rewritten for 4.0. Every claim was checked against the code (98fed3c).
  • Admin UI: 32 px link targets, pagination stays on screen on phones, focus stays inside dialogs, the unnamed tag buttons in the Roles field are gone, and old 3.x links such as /license and /upgrade now show Strapi's native "Page not found" state instead of "Whoops! Something went wrong" (2e6a729, 39cf414, ccc4560, 9e28d47, 6ddbca9).

Evidence

  • Gates on HEAD 6ddbca9: lint, format:check, test (87/87), test:ts:front, test:ts:back, build, verify and verify:runtime all exit 0. npm pack: 26 files, 109.7 kB.
  • Regression tests: run against the services from main (e83b7c0), 8 of the new tests fail. On HEAD they all pass.
  • Multi-instance test: Strapi 5.61 on Postgres 16, 8 processes (ports 1425-1432, two groups of 4) started at once against both 3.x dumps. Result: 450 bookmarks, 630 shares, 113 pins, 12 permissions, 0 duplicates, 0 legacy rows, licence keys deleted. The load test sent about 1,260 parallel requests with no 500s and no duplicate or orphaned rows.
  • Install warnings from the plugin (before → after): yarn 1.22.22 4 → 0, npm 11.21.2 0 → 0, pnpm 12.18.0 0 → 0.
  • Links: all 84 external links return 200. The only exceptions are two localhost examples and npmjs.com, which answers bots with 403. All anchors resolve. The site has no overflow or low-contrast text at 1440/1024/390/320 in light or dark mode.
  • Browser acceptance: the measure.js contract (11 widths × light/dark) and Tab walks on all 9 screens. No finding is in plugin-rendered UI. The remaining findings come from Design System controls or Strapi core. Focus stays inside every dialog (45 of 45 stops).
  • Removed routes: /license/*, /roles and /users return 404. POST /bookmarks/reorder returns 405. The Content API route returns 404.

Release impact

Major: 4.0.0. The breaking footer is in 6876a06. Magic Mark 4 needs @strapi/strapi 5.57 or newer. The licence, /roles, /users and /bookmarks/reorder routes are removed. The 3.x settings.read/settings.update permissions are replaced by six bookmark permissions, and the migration runs on first start (see the CHANGELOG migration notes).

Merge with a rebase or a merge commit, or copy the BREAKING CHANGE footer of 6876a06 into the squash message. Otherwise semantic-release publishes 3.5.0 instead of 4.0.0.

Only the owner can do

  1. Fix npm publishing: rotate the NPM_TOKEN repository secret (last updated 2025-12-14; release run 42396124153 failed with E401 EINVALIDNPMTOKEN), or add a trusted publisher on npmjs.com (package strapi-plugin-magic-mark, repo Schero94/Magicmark, workflow release.yml). release.yml needs no change.
  2. Review and merge this PR (see the merge note above).
  3. After the release, fold [Unreleased] into the 4.0.0 entry of the CHANGELOG.

Known items that are not plugin code and are documented in the README and CHANGELOG:

  • When several processes start at once for a schema-changing upgrade, Strapi core's schema sync crashes ("already exists"). A restart fixes it.
  • npm audit --omit=dev reports 2 high findings from zod <4.6.6 via @strapi/utils 5.61.0. Only a Strapi core update fixes them. Release audits at the critical level, so they do not block.

🤖 Generated with Claude Code

Schero94 and others added 9 commits November 7, 2026 22:08
… processes

Every write to an existing bookmark (edit, share, update view, pin, delete)
now locks the bookmark row with SELECT ... FOR UPDATE inside its
transaction, the pattern Strapi's admin uses for the first admin. Writes to
one bookmark run one after another across processes: share edits no longer
interleave, parallel pins no longer insert two preference rows, a delete no
longer deadlocks with a parallel edit, and a write that waited for a delete
answers 404 instead of leaving orphaned share or pin rows.

The 3.x permission migration grants each role's actions under a role row
lock. The Super Admin role gets the Magic Mark actions the same way before
Strapi's unlocked super admin sync runs, so a simultaneous start no longer
duplicates permission rows; leftovers from earlier starts are removed in
bootstrap.

Found and verified with 8 Strapi 5.61 processes on Postgres 16 (3.x
migration started by all of them at once plus about 1,260 parallel
requests). The fake db in the tests now yields per query and implements
row locks, so the races are reproduced in unit tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Design System link was as tall as its text (20 px), below the 24 px
WCAG 2.5.8 minimum and the 32 px the admin uses on small screens. Padding
on the link itself (DS Box props, no custom styles) makes the target 32 px.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@strapi/utils is used by the server code and is now a dependency: Strapi
apps do not list it, so as a peer it made yarn 1 warn about an unmet peer.
@strapi/design-system, @strapi/icons and react-intl reach an app only
through @strapi/admin and are optional peers. react and react-dom use
^18.0.0 like create-strapi-app 5.61.0. Installing the tarball into a new
Strapi 5.61 app prints no plugin warning with npm 11, yarn 1.22 or pnpm 12
(yarn 1 printed four before); the pnpm app still builds its admin.

The description is plain, homepage points at the project site, the
repository URL is in the normalised git+https form and keywords are updated.

BREAKING CHANGE: Magic Mark 4 needs @strapi/strapi 5.57 or newer. The
plugin-internal routes /license/*, /roles, /users and /bookmarks/reorder are
removed (sharing lookups moved to /sharing/roles and /sharing/users), every
admin route now checks the new bookmark permissions, and the 3.x permissions
settings.read and settings.update are replaced by six bookmark permissions.
Roles, shares and pins are migrated on the first start; see the CHANGELOG
migration notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The peer range says @strapi/strapi ^5.57.0, so a CI job installs 5.57.0
next to the lockfile and runs both type checks, the tests, the build and
both verify steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README: value first, badges, quick start for npm, yarn and pnpm, screenshot
gallery, full configuration, permission and admin API reference with a
response example, security, performance, running several instances
(Railway replicas, pm2 cluster) with the measured 8-process result and the
Strapi schema sync note, compatibility, upgrade notes from 3.x,
troubleshooting, FAQ and contributing links.

Site: hero with the product screenshot, steps, gallery, permissions, API,
security, several instances, upgrade and FAQ sections; dark mode, Open
Graph, Twitter and JSON-LD metadata. site.css is the byte-identical shared
theme again (and excluded from Prettier); page styles and dark mode live in
site-extra.css. Checked at 320, 390, 1024 and 1440 px in light and dark:
no overflow, no low-contrast text, no broken images or anchors.

CHANGELOG: [Unreleased] grouped into breaking changes, migration, removed,
added, changed, fixed and security.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The admin pagination row does not wrap, so with many pages it ran past the
right edge at 390 px and 320 px (measured in the browser). Below the medium
breakpoint the links show only the current page between the first and the
last page, and below the small breakpoint the page size select is left out.
The breakpoints come from the theme through the admin's useMediaQuery hooks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…targets

A Tab walk showed focus leaving the bookmark dialog and the Advanced
filters dialog for the page behind them. In Design System 2.2.4 every
Combobox trigger is wrapped in a Radix FocusScope that stays mounted while
the list is closed, which pauses the surrounding Modal's focus scope
(@strapi/ui-primitives ComboboxTrigger, trapped: open). Native Strapi
modals without a Combobox keep focus. Both dialogs now loop Tab and
Shift+Tab at their first and last focusable element.

measure.js found 20 to 24 px tall targets for the bookmark links in the
popover and the homepage widget and 16 px for "Add condition". They get the
same padding and negative margin as the page links (DS spacing props, no
custom styles), so the target is 32 px and the text does not move.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Tab walk reached a button without an accessible name in the Roles
field: in Design System 2.2.4 the remove button of each MultiSelect tag
contains only an icon. Without tags the trigger lists the chosen roles as
text and roles are removed by unticking them in the list, so every tab stop
in the dialog has a name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… paths

Old links below /plugins/magic-mark (pages that 3.x had) rendered Strapi's
"Something went wrong" error. They now show a not-found page built like
Strapi's own NotFoundPage, with a link back to Magic Mark, in five
languages. Measured clean at 1440/390/320 in light and dark; the Tab walk
reaches the link and the link opens the bookmarks page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Schero94
Schero94 merged commit 8e93d2a into main Nov 7, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant