Skip to content

feat: add explicit public directory display order - #127

Open
KitKat31337 wants to merge 1 commit into
Calnode:mainfrom
KitKat31337:feat/directory-display-order
Open

KitKat31337 wants to merge 1 commit into
Calnode:mainfrom
KitKat31337:feat/directory-display-order

Conversation

@KitKat31337

Copy link
Copy Markdown
Contributor

Summary

Add an explicit display_order property to event types so owners can control how appointments appear on public person and team directories without renaming the event or changing its booking URL.

Public directory entries are now ordered by:

  1. display_order ascending
  2. Event name
  3. Event slug as a deterministic final tie-breaker

The new value defaults to 0, so existing installations retain their current alphabetical directory order until an owner deliberately changes it.

Related proposal: KitKat31337#3

Problem

Public person and team directories currently order event types alphabetically by name.

That works as a default, but it does not allow an operator to deliberately prioritize an event—for example, placing an introductory consultation before longer or more specialized appointments.

Ordering by slug is not a suitable workaround because it couples presentation order to the public booking URL. Slugs may also become impractical to change after an event type has accumulated bookings.

Directory order should therefore be independent of:

  • Event names
  • Booking slugs and URLs
  • Creation order
  • Database insertion order

Behavior

Each event type now has an integer display_order.

Lower numbers appear first:

-10  Introductory consultation
  0  Standard consultation
  0  Technical assessment
 20  Follow-up appointment

Events with the same value remain alphabetically ordered by name. Slug is used as the final tie-breaker when both the display order and name are equal.

Negative values are supported, making it possible to promote an event ahead of the default 0 group without renumbering existing event types.

The order applies consistently anywhere the event type appears in a public directory:

  • Person directories at /u/{handle}
  • Team directories at /team/{slug}
  • Events owned by the person
  • Events where the person participates as a configured host

The change does not affect:

  • The administrative event-type list
  • Team member roster ordering
  • Individual booking pages
  • Availability or slot calculation
  • Existing active/public visibility filtering

Implementation

Database

Add migration 00070_event_type_display_order.sql with:

ALTER TABLE event_types
ADD COLUMN display_order INTEGER NOT NULL DEFAULT 0;

The migration is additive and preserves all existing event types. Existing rows receive the default value of 0.

Consistent with the project’s other additive SQLite column migrations, the down migration leaves the column in place.

API

Expose display_order through the event-type API:

  • Event-type creation accepts an optional integer value.
  • Event-type detail and list responses include the value.
  • Event-type PATCH requests can update it.
  • Omitting the field during PATCH preserves the existing value.
  • Supplying null during PATCH also leaves the value unchanged.
  • Supplying 0 explicitly resets the event to the default ordering group.
  • Negative integer values are accepted.
  • Fractional, string, and out-of-range values are rejected as invalid JSON input.

The existing owner-scoped authorization remains unchanged. Being configured only as an event host does not grant permission to update the event’s directory order.

Directory queries

Both directory routes use the shared deterministic ordering rule:

ORDER BY
    et.display_order,
    et.name,
    et.slug

The existing directory filters remain unchanged, so inactive, private, and unrelated event types are still excluded.

Admin UI

Add a Directory order number field to the event-type editor.

The UI explains that:

  • Lower numbers appear first.
  • Equal numbers are ordered by name.
  • The value applies wherever the event is publicly listed.

The frontend verifies that the submitted value is a safe whole number before sending the PATCH request.

Event duplication

Duplicating an event type retains its display_order, along with the other reusable event-type configuration.

Documentation

Document the ordering behavior in docs/ARCHITECTURE.md, including:

  • Default compatibility behavior
  • Tie-breaking rules
  • Negative values
  • Person and team directory coverage
  • Duplication behavior
  • Surfaces intentionally unaffected by the setting

Backward compatibility

This is an additive schema and API change.

Existing event types receive:

{
  "display_order": 0
}

Because events with equal values are ordered by name, an existing directory where every event has the default value continues to appear alphabetically.

The slug tie-breaker only makes otherwise identical names deterministic.

Existing API clients may ignore the additional response property. No existing request fields or endpoint behavior are removed.

Test coverage

The included tests cover:

  • Migrating an existing database without changing event names or slugs
  • Assigning the default value to existing event types
  • Creating an event with omitted, negative, zero, and positive order values
  • Updating the value through PATCH
  • Preserving the value when PATCH omits it
  • Treating null as no change
  • Explicitly resetting the value to 0
  • Rejecting fractional, string, and out-of-range values
  • Returning the value from event-type detail and list endpoints
  • Preventing a host who does not own the event from changing its order
  • Retaining the value when duplicating an event type
  • Applying the order to both person and team directories
  • Including hosted events in the same ordering rule
  • Deterministic name and slug tie-breaking
  • Preserving alphabetical order when all values remain at 0
  • Continuing to exclude private, inactive, and unrelated events
  • Immediately reflecting an updated value in rendered directory order

@pullfrog

pullfrog Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Run failed. View the logs →

Pullfrog  | Rerun failed job ➔ | View workflow run | via Pullfrog | Using deepseek-v4.1-flash | 𝕏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(directory): allow a deliberate order for listed event types

1 participant