Commit Graph

12 Commits

Author SHA1 Message Date
ed2d919aee fix: the CSV round trip keeps values that start with an apostrophe before a formula character (WR-21)
escapeCell left '=x as it was and unescapeCell then dropped its
apostrophe on import. A value of apostrophes followed by a formula
character now gets one more apostrophe on export, and the import drops
exactly one, so unescapeCell is the inverse of escapeCell.
2026-10-27 15:39:23 +01:00
d8aa989dfc fix: entry generation applies an unseen address change instead of overwriting it (WR-19)
refreshEntry set entry.url to the descriptor's address unconditionally, so
a slug change the job saw before any RecordSaved listener lost its 301 for
good. An entry whose URL differs now goes through AddressChanged (via
auto), which creates the 301 and moves the URL; an empty URL is filled.
2026-10-27 15:38:15 +01:00
cab1b9aef4 fix: document that the frontend server must be a trusted proxy for the public buckets (WR-15)
The resolve and 404 buckets key on the client IP, which is the SSR
server's address unless it is in http.trusted_proxies and forwards
X-Forwarded-For; otherwise they cap the whole site at 600 requests a
minute. The README and the Buckets comment now say so. An authenticated,
unthrottled resolve call would need a new token and a framework way to
skip a bucket, so it is left for a decision.
2026-10-27 15:34:01 +01:00
c2ba33ee94 fix: the runtime cycle log is keyed by rules and bounded (WR-13)
redirectHopsLogged was a never-evicted map keyed by the anonymous
request's URL with its query, so requests to a looping address with fresh
query strings grew it without limit and logged each one. The log is now
keyed by the cycle's rule ids, repeats at most once an hour and starts
over at 1024 keys.
2026-10-27 15:32:29 +01:00
c2f136ad7d fix: serialise redirect writes so concurrent saves cannot store a loop (WR-10)
The save-time simulation read the rules at READ COMMITTED without a lock,
so A -> B and B -> A written concurrently both passed. CheckRedirect,
AddressChanged and every batch now take a transaction-level advisory lock
before they read the rules.
2026-10-27 15:29:08 +01:00
cb614cb1fb fix: address changes run the loop simulation and validate their addresses (WR-09)
AddressChanged wrote its 301 and re-pointed rules without Problems or the
save-time simulation, and removed only an exact rule whose source equals
the new address literally. It now removes every exact rule that matches
the new address with its options, simulates the 301 and the re-pointing
with the stored rules and writes nothing when that loops, stores an
absolute old address on the site as its path, and skips an address that
is not a path on the site.
2026-10-27 15:27:21 +01:00
58b2504fe3 fix: an exact redirect with a query wins over the path-only rule (WR-08)
Match tried the path-only key before the path?query key, so a rule for
/products?id=5 never fired while /products had one.
2026-10-27 15:25:39 +01:00
b19cd069a5 chore: require SummerCMS v0.5.1 2026-10-27 14:02:14 +01:00
ab3b219fec feat: batches with dry run, undo, and CSV import and export
- POST /_seo/api/v1/batch runs changes in one transaction: dry_run
  answers the diff and the conflicts (loops, chains, noindex on a
  published record, canonicals to redirected or noindex addresses) and
  rolls back; a refused change refuses the batch (D-12)
- undo of a change or a whole batch from History and through MCP, with
  the undo_stale, undo_loop and undo_gone refusals (D-13)
- CSV export and import of redirects, rules and records by URL: BOM,
  comma or semicolon, formula cells escaped, a dry-run preview, all or
  nothing with via import; the screen's apply token is HMAC-SHA256 over
  the file and a fingerprint of the data (transfer.stale)
- Import and export singleton with the seo_transfer widget action,
  History record actions undo and undo_batch, navigation entry
- MCP tools undo_change, undo_batch, apply_batch, export_csv, import_csv
- TestBatch, TestUndo, TestCSVTransfer, TestLoopRefused mcp and import
2026-10-27 12:35:26 +01:00
aa0c3bcacf feat: management API and an MCP tool per SEO admin operation
- /_seo/api/v1 routes for the effective SEO of a URL with sources and
  owner, URL rules, redirects (loops refused with redirect_loop), the
  404 log actions, robots.txt and its tester, settings and history
- the CMS-data issue report: missing and duplicate titles and
  descriptions, rules over records, redirect chains, canonicals to
  noindex or redirected addresses, noindex addresses robots.txt blocks
- 24 MCP tools on those routes (backend guard, golem15.seo.manage)
- AdminOperations maps every admin operation to its tool;
  TestEveryAdminOperationHasTool and TestMCPReadToolsAreGET guard drift
- robots.txt writes go through classes.SaveRobots from the admin too
2026-10-27 12:17:36 +01:00
b3981614cb docs: robots.txt, AI bots and verification files in README
- redirects, address changes, the 404 log and its report endpoint, URL
  normalisation, strict URLs and the redirect decision of resolve
- robots.txt, AI bots, verification files, the new config keys and the
  grobotstxt dependency
2026-10-27 11:54:02 +01:00
b38eb4bf66 docs: plugin README 2026-10-27 11:04:42 +01:00