Skip to content

#32 Settings Per Cycle#37

Merged
b-at-neu merged 8 commits into
devfrom
copilot/update-settings-per-cycle
Feb 23, 2026
Merged

#32 Settings Per Cycle#37
b-at-neu merged 8 commits into
devfrom
copilot/update-settings-per-cycle

Conversation

Copy link
Copy Markdown

Copilot AI commented Feb 23, 2026

Ensures settings are properly scoped to cycles, with the settings page always reflecting the active cycle's configuration and writes guarded to only affect the active cycle.

Changes Made

  • lib/data/cycles.ts — Added getCycleById helper for direct cycle lookup by ID
  • lib/data/settings.ts — Added getSettingsByCycleId for fetching settings for any specific cycle
  • app/admin/settings/page.tsx — Settings page uses the active cycle only via getSettings()
  • app/admin/settings/settings-form.tsx — Added isReadOnly prop: renders a yellow banner ("This is an inactive cycle. Settings cannot be modified."), disables all inputs, and hides the Save button when viewing an inactive cycle's settings
  • lib/actions/settings.ts — Added explicit isActive guard before any DB write; replaced upsert with update so settings can only be updated (never created) through this action — creation is handled by createCycle/setActiveCycle, ensuring only active cycle settings are ever modified
Original prompt

This section details on the original issue you should resolve

<issue_title>Settings Per Cycle</issue_title>
<issue_description>#### Context
Settings should be per-cycle instead of global. Each cycle has own deadlines and open/closed states.

Goal

Ensure settings are properly scoped to cycles with defaults for new cycles.

Implementation

Creating New Cycle:

  • When cycle created with "Create & Set Active", create Settings record:
  {
    cycleId: newCycle.id,
    requiredNominations: 15,
    maxCommunityNominations: 7,
    endorsementRequired: false,
    endorsementsOpen: true,
    applicationDeadline: null,
    applicationsOpen: true,
    nominationsOpen: true,
    customMessage: null
  }

Setting Inactive Cycle Active:

  • If cycle has no settings record, create default Settings
  • If cycle has settings, use existing

Settings Page:

  • Active cycle: Show all settings fields as editable
  • Inactive cycle: Show all settings fields as read-only with banner
  • Banner text: "This is an inactive cycle. Settings cannot be modified."

Acceptance Criteria

  • New active cycles get default Settings record
  • Each cycle has own settings (unique constraint enforced)
  • Active cycle settings are editable
  • Inactive cycle settings are read-only
  • Settings from different cycles don't interfere
  • All settings functionality works per-cycle</issue_description>

<agent_instructions>ticket #32</agent_instructions>

Comments on the Issue (you are @copilot in this section)

  • Fixes b-at-neu/senate-path#32

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
senate-path Ready Ready Preview, Comment Feb 23, 2026 4:25am

Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com>
Copilot AI changed the title [WIP] Update settings to be per cycle instead of global #32 Settings Per Cycle Feb 23, 2026
Copilot AI requested a review from b-at-neu February 23, 2026 03:28
@b-at-neu
Copy link
Copy Markdown
Collaborator

@copilot cycle management is a separate ticket, remove from this

Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Feb 23, 2026

@copilot cycle management is a separate ticket, remove from this

Removed in 1659f01 — deleted lib/actions/cycles.ts, app/admin/cycles/, and the "Manage Cycles" button from the admin dashboard. This PR now only contains the settings per-cycle changes (read-only view + banner for inactive cycles).

Comment thread app/admin/settings/page.tsx Outdated
isReadOnly = !cycle.isActive;
settings = await getSettingsByCycleId(cycleId);
if (!settings) {
// Inactive cycle with no settings - redirect back to avoid confusion
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't do this

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be an error instead, all cycles should have settings

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e55fb1d — now throws Error("Settings not found for cycle ${cycleId}. All cycles should have a settings record.") instead of redirecting.

Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com>
@b-at-neu
Copy link
Copy Markdown
Collaborator

@copilot just updated the branch, integrate the cycles management page into this

…tings

Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Feb 23, 2026

@copilot just updated the branch, integrate the cycles management page into this

Done in d47f2e3. Added app/admin/cycles/[id]/page.tsx which wires the "View" button in the cycles table to the per-cycle settings view — shows the cycle's settings with SettingsForm (read-only with the inactive banner for inactive cycles, fully editable for the active cycle). Throws an error if a cycle somehow has no settings record.

@b-at-neu
Copy link
Copy Markdown
Collaborator

@copilot thats a separate ticket, just make sure the settings page only uses the active cycle

Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Feb 23, 2026

@copilot thats a separate ticket, just make sure the settings page only uses the active cycle

Done in 21535c4 — reverted app/admin/settings/page.tsx back to always using getSettings() (active cycle only, no cycleId param), and removed app/admin/cycles/[id]/page.tsx.

Copy link
Copy Markdown
Collaborator

@b-at-neu b-at-neu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you check in the updating of settings that only an active setting is being updated?

Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Feb 23, 2026

can you check in the updating of settings that only an active setting is being updated?

Done in 873758e. Two changes to lib/actions/settings.ts:

  1. Added an explicit if (!activeCycle.isActive) guard that returns an error before any DB write
  2. Replaced upsert with update — settings for the active cycle are only ever updated here (creation happens in createCycle/setActiveCycle), so update enforces that we never write to a non-existent or inactive cycle's settings

Copy link
Copy Markdown
Collaborator

@b-at-neu b-at-neu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you check in the updating of settings that only an active setting is being updated?

@b-at-neu b-at-neu marked this pull request as ready for review February 23, 2026 06:39
@b-at-neu b-at-neu merged commit 941a435 into dev Feb 23, 2026
2 checks passed
@b-at-neu b-at-neu deleted the copilot/update-settings-per-cycle branch February 23, 2026 06:39
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.

Settings Per Cycle

2 participants