Repository navigation
feat(directory): allow a deliberate order for listed event types #3
Description
Upstream implementation
Submitted for upstream review in Calnode/calnode#127 — feat: add explicit public directory display order.
- Source branch:
KitKat31337/calnode:feat/directory-display-order - Current status: Open; not yet merged.
Implementation details
The PR implements this feature with display_order INTEGER NOT NULL DEFAULT 0 rather than the originally proposed nullable directory_position.
Public person (/u/{handle}) and team (/team/{slug}) directories use:
ORDER BY et.display_order, et.name, et.slugLower values appear first. Existing events default to 0, preserving alphabetical order until configured. Negative values promote events ahead of the default group; positive values place them after that group. Equal values sort by name, with slug providing a deterministic final tie-breaker.
This is a deliberate refinement of the original proposal: there is no separate “positioned versus unpositioned” state. The value is shared wherever the event appears, including person directories where the person is a host rather than the owner.
Changes included
- Additive migration
00070_event_type_display_order.sql; the down migration leaves the column in place. - Expose
display_orderin event-type create, detail, list, and PATCH APIs. - Preserve the existing value when PATCH omits the field or supplies
null; explicit0resets it. - Retain existing owner-scoped editing permissions.
- Add a Directory order field and explanatory help text to the event editor, with safe-integer validation.
- Preserve the value when duplicating an event type.
- Keep existing public/active/ownership/team filters unchanged.
- Document behavior in
docs/ARCHITECTURE.md. - Leave the admin event-type list, team roster order, booking URLs, and availability calculations unchanged.
Test coverage included
- Migration preserves existing event names/slugs and defaults their order to zero.
- API creation, PATCH semantics, detail/list responses, and invalid numeric input.
- Owner authorization and rejection of edits by a host who does not own the event.
- Duplication retains the configured order.
- Both public directory routes apply numeric ordering and deterministic name/slug ties.
- Hosted events participate in the same ordering.
- Private, inactive, and unrelated events remain excluded.
- Updated values change rendered ordering; all-zero values retain alphabetical order.
These are tests included in the PR, not a claim that all validation commands have been run successfully. The PR updates architecture documentation but does not currently include the Unreleased changelog entry mentioned in the original proposal.
This issue remains open while upstream review and merge are pending.
Problem
directoryItems in internal/handler/directory.go uses ORDER BY name. Person and team directories therefore list public event types alphabetically even when the operator wants a deliberate order, such as putting an introductory consultation first.
The local ORDER BY slug workaround ties presentation order to booking URLs. Calnode also refuses to rename an event type's slug after it has bookings, so this cannot be a durable ordering control.
Proposed upstream fix
- Add a nullable numeric
directory_positioncolumn toevent_typesin an additive migration. A null value means no custom position; existing databases retain the current alphabetical presentation. - Expose the field through the event-type list/detail API and an owner-authorized update path, following the current event-type editing rules. Add a clearly labeled Directory order control in the event-type admin UI so operators do not need SQL or slug changes. An integer position field is a reasonable first UI; a drag-to-reorder list could follow without changing the data model.
- Use one shared deterministic order for both directory routes: positioned items first by position, then unpositioned items by name, with an ID or slug tie-breaker. Keep the existing active/public/owner/team filters unchanged. Specify whether lower numbers appear first in the UI and docs.
- Test migration compatibility, create/update validation and authorization, tie handling, and the resulting order on both person and team pages. Document the new setting and add an Unreleased changelog entry.
A single position per event type gives it the same relative order wherever that event type appears. If upstream wants each host/team directory to order the same shared event differently, that would require a separate per-directory association and API design; it can be considered independently.
Acceptance criteria
- An owner can change directory order without changing the event's name, slug, or booking URL.
- Existing installs keep alphabetical order until positions are set.
- Person and team pages apply the same predictable rule, including ties and unpositioned events.
- Unlisted/inactive events remain absent.
Observed in a local source build; separate from the SMTP change on feat/smtp-auth-login.
Activity