LinkRepository.enable runs UPDATE links SET expires_at = NULL WHERE id = ? unconditionally (src/db/link-repository.ts). Disable writes expires_at = now, so enable was meant to undo that. But expires_at is also caller-settable at create and at update (CreateLinkSchema, UpdateLinkSchema in src/api/schemas.ts), and enable cannot tell the two apart.
Round trip that loses data
- Create a link with
expires_at six months out.
- Disable it.
- Enable it.
The link comes back with expires_at: null and never expires. No error, and nothing in the response hints at it beyond the nulled field.
Current state
PR #69 documents the behavior as it stands: the enable route description on POST /links/{id}/enable says it clears expires_at outright, including an expiry set at create or update. Nothing pins the round trip either way, so a fix would need a test first.
Options
- Store the disable marker separately from the expiry (a
disabled_at column on links, as slugs already have), so enable clears only the marker and a caller-set expiry survives.
- Keep the single column but have disable remember the prior value somewhere enable can restore it.
The first matches the slug model and keeps the redirect check a single comparison. Either way the route description, the enable_link MCP tool text and docs/access-control.md need the same pass afterwards.
Raised in review of #69.
LinkRepository.enablerunsUPDATE links SET expires_at = NULL WHERE id = ?unconditionally (src/db/link-repository.ts). Disable writesexpires_at = now, so enable was meant to undo that. Butexpires_atis also caller-settable at create and at update (CreateLinkSchema,UpdateLinkSchemainsrc/api/schemas.ts), and enable cannot tell the two apart.Round trip that loses data
expires_atsix months out.The link comes back with
expires_at: nulland never expires. No error, and nothing in the response hints at it beyond the nulled field.Current state
PR #69 documents the behavior as it stands: the enable route description on
POST /links/{id}/enablesays it clearsexpires_atoutright, including an expiry set at create or update. Nothing pins the round trip either way, so a fix would need a test first.Options
disabled_atcolumn onlinks, as slugs already have), so enable clears only the marker and a caller-set expiry survives.The first matches the slug model and keeps the redirect check a single comparison. Either way the route description, the
enable_linkMCP tool text anddocs/access-control.mdneed the same pass afterwards.Raised in review of #69.