<feed xmlns='http://www.w3.org/2005/Atom'>
<title>cccms/db/migrate, branch erdgeist-modernize-auth</title>
<subtitle>[no description]</subtitle>
<id>https://erdgeist.org/gitweb/cccms/atom?h=erdgeist-modernize-auth</id>
<link rel='self' href='https://erdgeist.org/gitweb/cccms/atom?h=erdgeist-modernize-auth'/>
<link rel='alternate' type='text/html' href='https://erdgeist.org/gitweb/cccms/'/>
<updated>2026-07-16T20:36:12Z</updated>
<entry>
<title>Add migraton for bcrypt password digest on user model</title>
<updated>2026-07-16T20:36:12Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-16T20:36:12Z</published>
<link rel='alternate' type='text/html' href='https://erdgeist.org/gitweb/cccms/commit/?id=455d659ffbb0d12d75cc975fbe4cc24ce635ea3a'/>
<id>urn:sha1:455d659ffbb0d12d75cc975fbe4cc24ce635ea3a</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Add NodeAction: an append-only log of who did what to a node</title>
<updated>2026-07-15T02:23:09Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-14T23:41:34Z</published>
<link rel='alternate' type='text/html' href='https://erdgeist.org/gitweb/cccms/commit/?id=d56155231814633e04f856d22646fea24ef97011'/>
<id>urn:sha1:d56155231814633e04f856d22646fea24ef97011</id>
<content type='text'>
node_id/page_id/user_id are lookup and ordering only -- all three
nullify on delete, so an entry outlives its actor and its subject.
Everything that must survive those deletions lives in a mandatory
metadata jsonb written once at creation: the actor's username, the
node's human-readable name (pinned to the default locale), and
action-specific extras such as publish's title from/to.

NodeAction.record! is the single constructor, so every entry gets
the same baseline metadata without each call site re-implementing
it. occurred_at is one field for live and backfilled entries alike;
inferred_from distinguishes them -- nil means witnessed at the
moment it happened, populated names how a backfilled entry was
estimated.

Instrumented so far: publish (crediting the actual publisher,
threaded through from the controller -- previously nobody had the
act of publishing recorded anywhere), revert's discard_autosave and
destroy_draft branches, and translation destroy. publish_draft! now
runs in a transaction so the promotion and its log entry land
together. The remaining verbs follow once this mechanism has proven
itself.
</content>
</entry>
<entry>
<title>Add head/draft/autosave hierarchy to Node</title>
<updated>2026-07-08T14:22:17Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-08T14:22:17Z</published>
<link rel='alternate' type='text/html' href='https://erdgeist.org/gitweb/cccms/commit/?id=a006440f59bf99380e179cc2963cb98d4d894d3a'/>
<id>urn:sha1:a006440f59bf99380e179cc2963cb98d4d894d3a</id>
<content type='text'>
Introduces autosave_id as a third, unversioned layer above draft/head,
with lock_for_editing!, autosave!, and save_draft! as the new entry
points. Also fixes a real bug in wipe_draft!: its "no draft" branch
unconditionally released the lock, which was safe when "no draft" only
ever meant "nothing is happening" — no longer true now that a lock can
exist with only an autosave beneath it. lock_for_editing! deliberately
does not call wipe_draft! at all, for the same reason: an intruder
calling it while a lock was genuinely held would otherwise silently
steal it via wipe_draft!'s own unlock side effect, caught by the new
two-user lock test.
</content>
</entry>
<entry>
<title>Add preview_token to pages</title>
<updated>2026-07-06T04:05:06Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-06T04:05:06Z</published>
<link rel='alternate' type='text/html' href='https://erdgeist.org/gitweb/cccms/commit/?id=b547decd1f85b43d5fb9e86cd7462b455059b1d1'/>
<id>urn:sha1:b547decd1f85b43d5fb9e86cd7462b455059b1d1</id>
<content type='text'>
New column + unique index, plus ensure_preview_token!/revoke_preview_token!
on Page. Generated lazily (only when explicitly requested) rather than
via has_secure_token's default auto-generate-on-create, so a live,
shareable secret isn't silently minted for every page ever created.
</content>
</entry>
<entry>
<title>Drop dead custom_rrule column from events</title>
<updated>2026-07-06T02:37:06Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-06T02:37:06Z</published>
<link rel='alternate' type='text/html' href='https://erdgeist.org/gitweb/cccms/commit/?id=2345668365640901658ca8085721ed1dd7d1c106'/>
<id>urn:sha1:2345668365640901658ca8085721ed1dd7d1c106</id>
<content type='text'>
Forms were already cleaned up in an earlier commit; the column itself
was the last remnant.

Dropping the column surfaced a live reference in events#index (fixed
separately, 970f108) - this migration file itself just never got
staged until now.
</content>
</entry>
<entry>
<title>Add FK with ON DELETE CASCADE on occurrences.event_id</title>
<updated>2026-07-06T02:36:36Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-06T02:36:36Z</published>
<link rel='alternate' type='text/html' href='https://erdgeist.org/gitweb/cccms/commit/?id=7384522a84e0f1d80ff471e4023f865c84768b2c'/>
<id>urn:sha1:7384522a84e0f1d80ff471e4023f865c84768b2c</id>
<content type='text'>
Was the last remaining gap in the occurrence-orphaning fix from earlier
this session: dependent: :destroy on Event#occurrences covers deletion
through ActiveRecord, this covers anything that bypasses it (raw SQL,
Model.delete). Confirmed zero existing orphans and zero NULL event_ids
before adding the constraint (event_id stays nullable - an occurrence
without an event is valid, one with a bogus event_id is not). Also adds
the index that should have existed on this column already - Postgres
needs one for the cascade to be anything other than a full table scan
per delete, and none existed before this. deferrable: :immediate added
so legitimate application code can still defer the check within a
transaction if ever needed - unrelated to, and not a fix for, the
fixture-loading issue below.

Applying this constraint broke fixture loading entirely (config fix:
81a07bf) and exposed a live bug in events#index (fix: 970f108), both
already committed separately - this migration file itself just never
got staged until now.
</content>
</entry>
<entry>
<title>Add migration for the default template name feature</title>
<updated>2026-07-06T02:19:16Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-06T02:19:16Z</published>
<link rel='alternate' type='text/html' href='https://erdgeist.org/gitweb/cccms/commit/?id=3dea62f4b9421621ac15c87aee6d65150bb4295f'/>
<id>urn:sha1:3dea62f4b9421621ac15c87aee6d65150bb4295f</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Rewrite chapter seeds: multi-event support, drop is_primary, fix data</title>
<updated>2026-07-01T22:13:28Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-07-01T22:13:28Z</published>
<link rel='alternate' type='text/html' href='https://erdgeist.org/gitweb/cccms/commit/?id=db9bd097ec54964a93efccd3056bfcb4a9484052'/>
<id>urn:sha1:db9bd097ec54964a93efccd3056bfcb4a9484052</id>
<content type='text'>
- seed_chapter now accepts events: array instead of flat rrule:/
  start_time: params; each event hash supports rrule:, start_time:,
  tag_list:, location:, duration_hours:
- Chapters with multiple open days now represented correctly
  (Stralsund: Thursday Chaostreff + 2nd/4th Saturday OpenSpace;
  Hamburg: 2nd Friday + last Tuesday; Stuttgart: 1st Tuesday +
  3rd Wednesday; Freiburg: Mon+Tue open + biweekly Plenum;
  Backnang: 3rd Sunday + 1st Tuesday; Tübingen: last Sunday +
  2nd Monday at different venues)
- is_primary removed from migration entirely — replaced by
  tag_list: 'open-day' on events
- Stale EN descriptions corrected: Berlin, Darmstadt, Erlangen,
  Essen, Freiburg, Göttingen, Hamburg, Hannover, Karlsruhe,
  Paderborn, Stuttgart, Ulm
- chaostreff-stralsund duplicate entry removed (Port39 is erfa only)
</content>
</entry>
<entry>
<title>Phase 1: standalone events, external_url on nodes</title>
<updated>2026-06-30T17:22:24Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-06-30T17:15:22Z</published>
<link rel='alternate' type='text/html' href='https://erdgeist.org/gitweb/cccms/commit/?id=a7a6ad786eeb9f94f7882462bccbdd31e1bb4743'/>
<id>urn:sha1:a7a6ad786eeb9f94f7882462bccbdd31e1bb4743</id>
<content type='text'>
- Migration: node_id nullable on events and occurrences, add
  title/description/is_primary to events, external_url to nodes
- Existing events marked is_primary: true (were all 1:1 with nodes)
- Node: has_one :event -&gt; has_many :events
- Event: belongs_to :node optional, validates title presence for
  standalone events, is_primary uniqueness scoped to node_id,
  display_title helper falling back through node title
- Occurrence: belongs_to :node optional, summary falls back to
  event.display_title
- nodes_helper: event_information uses events.first (interim; will
  be replaced in Phase 3 event UI)
- Tests: fix node.event -&gt; node.events.first in event_test
</content>
</entry>
<entry>
<title>Fix unversioned migrations</title>
<updated>2026-06-27T02:23:37Z</updated>
<author>
<name>erdgeist</name>
<email>erdgeist@erdgeist.org</email>
</author>
<published>2026-06-27T02:23:37Z</published>
<link rel='alternate' type='text/html' href='https://erdgeist.org/gitweb/cccms/commit/?id=241d5e91b2b6716e2861cc77d319c3d3568343a8'/>
<id>urn:sha1:241d5e91b2b6716e2861cc77d319c3d3568343a8</id>
<content type='text'>
</content>
</entry>
</feed>
