summaryrefslogtreecommitdiff
path: root/app/models
AgeCommit message (Collapse)Author
9 daysAdd banner render logicerdgeist
9 daysSurface redirects in nodes#show, the action log and when publishingerdgeist
9 daysForce a blank redirect status to nilerdgeist
9 daysAlso redirect on restricted pageserdgeist
9 daysAdd redirect ui in in nodes#edit and apply some minor cleanuperdgeist
Also give search inputs a magnifier and a clear control: input_group wraps a field with an icon and, where clearing is meaningful, a button that empties it and any hidden companion named by data-clears. Clean up some inconistency between field hints presented as p and as span. Remove stray console.log.
10 daysRedirect a page to a node or an external URLerdgeist
Page#redirect_target resolves the precedence and returns nil for a destination that is restricted or has no head, so a page with a broken target renders itself rather than linking nowhere. The banner partial will call the same method, so the redirect and the link cannot drift. One hop, no exceptions, checked in publish_draft! rather than as a validation: two nodes publishing concurrently could each pass a save-time check and still produce a chain. "Live" means heads only, a draft redirect that has not published is not yet a link anyone can follow. Node.search excludes redirecting pages. editor_search does not: an editor looking for one searches by title, and only the body is worth hiding.
2026-08-09Drop nodes.external_urlerdgeist
The column moved to page.rb and was now written only by publish_draft! and by the chapter seed, and read by nothing. lib/tasks/pages.rake goes with it. backfill_external_url reads the dropped column. backfill_address is spent and no longer safe to re-run.
2026-08-09Report every editorial attribute in the revision differdgeist
diff_against gained external_url, published_at and user. The view renders each metadata section only when that attribute changed, and says so once when none did. Metadata now precedes the locale pointer, which speaks only of translations: above the metadata it read as "nothing changed" on a revision that had moved the page.
2026-08-09Refuse destroying an asset that is still attachederdgeist
2026-08-09Attach assets to the draft instead of to every lifecycle rowerdgeist
Node#attach_asset! writes to the node's draft alone, creating one from the head when none is pending. It refuses when another user holds the lock, and when an autosave already exists The asset_attach verb goes with it. create_new_draft names the editor on the draft it creates and the publish entry's asset delta reports the attachment.
2026-08-08Move the external homepage onto the drafterdgeist
2026-08-07Show a pending address in the cockpit, the diff and the publish confirmerdgeist
2026-08-07Move the pending address from the node onto the drafterdgeist
2026-08-06Let editors set a node external homepage, gated and witnessederdgeist
2026-08-06Preload page titles for the sitemap, and order containers before leaveserdgeist
2026-08-05Search assets and events, and order events by when they happenerdgeist
2026-08-04Give node lists a flag column and a shared action barerdgeist
2026-08-04Witness every promotion and demotion made through the roles formerdgeist
2026-08-03Render dates, booleans and counts through the locale fileserdgeist
2026-08-03Believe the file over the browser about what was uploadederdgeist
2026-08-03Run ImageMagick under a policy that travels with the projecterdgeist
2026-08-03Display stale accounts in users#indexerdgeist
2026-08-02Let an event start without endingerdgeist
2026-08-02Witness calendar entrieserdgeist
2026-08-02Witness account creationerdgeist
2026-08-01Require a second factor for elevation, not for holding adminerdgeist
2026-08-01Allow aggregate to order by slug and paint chapters list more nicelyerdgeist
2026-08-01Let Redaktion grant and revoke its own roleerdgeist
Any holder may add or remove another account, witnessed as redaktion_grant/revoke so the vouching is legible. Not behind elevation: onboarding must not wait for a keyholder, and a compromised Redaktion account can already publish.
2026-07-31Warn before the gate refuses, and check restore destinationserdgeist
nodes#new marks the kinds that place under /updates, derived from each kind's own path_prefix. The three parent pickers mark candidates the current user cannot publish into; menu_search returns needs_redaktion per result, computed per user rather than as a bare restricted flag, and the menu-item picker opts out. restore_from_trash! checks its destination: the restore is the move, applied rather than staged, so no later publish would have caught it. The node returns as a draft either way.
2026-07-31Show the gate before it refuses, and check the destinationerdgeist
nodes#show renders publish and trash as disabled_action spans with a hint naming what an editor can still do, matching how locked_by_other already reads. Editing and reverting stay live: drafting is free everywhere.
2026-07-31Bind aggregates over scoped tags to their subtreeerdgeist
CccConventions::TAG_SCOPES maps "update" and "pressemitteilung" to /updates and "disclosure" to /disclosure. Page.aggregate applies the mapping, so an aggregate over one of those tags is bounded by its subtree regardless of what the shortcode says. Tags stay unrestricted; positions are publish-gated. Both RSS actions call Page.aggregate rather than repeating its tag join. Empty feeds no longer crash: Atom falls back to the current time for the required <updated>, and the optional dc:date is omitted.
2026-07-31Gate live-content changes on restricted surfaceserdgeist
publish_draft!, trash!, destroy_from_trash!, attach_asset! and Asset#destroy_witnessed! now refuse unless the acting user holds redaktion, and only when the subject is on a restricted surface: the front page, the updates tree that feeds ~100k subscribers, or disclosure. Drafting, autosaving, tagging and creating stay free everywhere for everyone. Enforcement is in the models rather than the controllers, since attach_asset! and the rest are reachable from rake tasks and internal paths. It follows the errors.add-plus-bare-raise pattern the rest of Node already uses, so every existing RecordInvalid rescue reports it with a localised message; only assets_controller#destroy needed a rescue added. A nil user is treated as a system context and bypasses the gate. The default nil on three of those verbs is what makes that reachable, and removing those defaults once every call site passes a user is the next tightening.
2026-07-31Replace user deletion with deactivationerdgeist
Deactivation adds the alumni role and leaves the others in place, so reactivation is lossless and nobody has to remember what an account held. login_from_session checks alumni? on every request, so a signed-in user is locked out on their next one without any session invalidation. Guards prevent deactivating yourself or the last active admin, and both verbs are witnessed in the action log.
2026-07-31Group user accounts by roleerdgeist
Replaces the two-way admin/user split with four groups ordered by capability: administration, Redaktion, editors, alumni. alumni takes precedence over capability in role_group, so a retired admin appears at the bottom rather than the top. Forms now offer the three roles as checkboxes rather than a single admin checkbox, with a trailing hidden blank so an empty set can be posted, and user_params permits roles only for admins. Three create buttons prefill the common combinations.
2026-07-31Retire the unused per-node permission subsystemerdgeist
Every path through Permission raised or lied: validates_presence_of on a boolean made granted = false unsaveable, since false.blank? is true; get_permission_for read a nonexistent identifier attribute; has_permission? called an undefined plural method and returned a truthy relation in every case; and set_permission mutated granted without saving. Nothing outside the model referenced it and the table was empty.
2026-07-31Validate format of slug to be alphanum or _-erdgeist
2026-07-30Give action_participants an explicit ordererdgeist
2026-07-30Localise model validation messages and refusal reasonserdgeist
2026-07-30Generate a 1200x630 social card variant for every asseterdgeist
2026-07-28Let editors manage menu titles in both localeserdgeist
2026-07-27Surface held locks in the dashboard's work-in-progress widgeterdgeist
A lock with no draft or autosave behind it was invisible to everyone including its holder, until the next editor collided with it. work_in_progress now admits those nodes, and the widget names the holder rather than the last editor on any locked row. Also flips the ordering to stalest-first, so a backlog reads as a queue rather than a feed, and gives the heading a real total: the count came from the already-limited relation and could never exceed five.
2026-07-27Let Globalize decide what locale to display for a page translationerdgeist
2026-07-25Extract admin strings to i18n: assets and events clusterserdgeist
2026-07-24Add TOTP enrollment and verification to User, witnessed in the action logerdgeist
2026-07-23Restyle pdf headline cardserdgeist
2026-07-23Keep in-editor asset curation off the head, layering it like every editerdgeist
ensure_autosave! gives body keystrokes and asset curation one shared layer, so head is never mutated in place and every curation change surfaces in the publish delta. Stale rendered join ids are mapped across the clone via asset_id. Curation now requires holding the lock; a missing lock answers 423, matching the autosave endpoint.
2026-07-23Record asset deltas at publish, with changed assets as participantserdgeist
2026-07-23Witness asset uploads and out-of-band attaches in the action logerdgeist
2026-07-23Witness asset destruction, naming every node it stripserdgeist
2026-07-23Convert the log's node zoom to participants, completing subtree historieserdgeist