Skip to content

feat: let members schedule commits as their organization, canceled if they left it by then - #1375

Merged
mnapoli merged 1 commit into
productionfrom
feat/org-scheduled-commits
Nov 1, 2026
Merged

mnapoli merged 1 commit into
productionfrom
feat/org-scheduled-commits

Conversation

@mnapoli

@mnapoli mnapoli commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

Summary

Next layer of letting organizations post commits (#938): admins and members can now schedule a commit as their organization, the same way they post as it.

  • In the composer: they pick the organization from their avatar, then schedule. Before, scheduling always posted as yourself and hid the Post as menu.
  • When it's due: it goes out as the organization, through the usual review, like one posted right away.
  • If the poster is no longer a member when it's due: it's canceled instead, images included, the way a ban cancels scheduled commits. Same if posting as organizations has been switched off by then.

It sits behind the same organization_commits switch as posting, which stays off: while it's off, the menu doesn't show, and the web and the API refuse author when scheduling too.

Changes

  • scheduled_commits.author_id, new and nullable, a foreign key to profiles that doesn't cascade:

    • Why: a scheduled commit has to remember which organization it goes out as until it's due. Null means it goes out as the user who scheduled it, as before.
    • Who sees it: only the user who scheduled it, in their queue (web and /api/v1/scheduled-commits). It isn't shown to the organization's other members.
    • When it's deleted: with the scheduled commit, which is deleted along with the user's account (by the existing cascade on user_id), and when GitHub no longer has the organization: DeleteOrganization deletes its scheduled commits and their images in code, before the profile.

    The column is indexed, so deleting a profile doesn't scan the table to check the key.

  • Scheduling: CreateScheduledCommitRequest and CreateApiScheduledCommitRequest accept author with the OrganizationToPostAs rule from feat: let members post commits as their organization #1361, so members only, and only once the switch is on.

  • Submission (UpdateScheduledCommitSubmittedAt): the claim also requires the poster to still be a member of the organization, read when it's due. One that can no longer go out as its organization is canceled with DeleteScheduledCommit, as a ban cancels one. That applies to Commit now too.

  • API: ScheduledCommitResource adds author: the organization as a ProfileResource, or null when it goes out as the user. It is additive.

  • Web: the composer keeps the Post as menu while scheduling, and the Scheduled page says As @laravel under the time.

  • KNOWLEDGE_BASE.md says organizations can schedule.

Visual evidence

Local preview with seeded data, Chromium, the switch on. The viewer is @local-dev, an admin of @laravel.

Before, 1440×900 After, 1440×900
Scheduling hides the Post as menu: the avatar is the user's own Scheduling as @laravel: the Post as menu is open with Laravel checked
Scheduled page before: no author on any row Scheduled page after: one row says As @laravel
Before, 390×844 After, 390×844
Scheduling on mobile, own avatar Scheduling as @laravel on mobile
Scheduled page on mobile before Scheduled page on mobile after, with As @laravel

Device verification

Viewport emulation in headless Chromium at 390×844 only, not a real phone. No horizontal overflow at either size.

Limitations

  • A member who leaves still sees what they scheduled as the organization in their queue until it's due, when it's canceled.
  • Scheduled commits are still not in the data export, as before (documented in the knowledge base).
Decisions for organization commits (#938), made before building
  • Scheduled commits keep the identity they were scheduled with. If the poster is no longer a member when the commit is due, it's canceled, like a ban cancels scheduled commits.
  • Who can post as an organization? Admins and members: anyone listed on the org's dev/null page.
  • What do readers see? Only the organization, like a brand account. The person who posted is recorded for moderation and accountability.
  • API? It follows the internal model, built for the long term: breaking changes are fine.
  • How is it split? Stacked PRs, each reviewable and deployable on its own.

Settled while building: switching posting as organizations off cancels what was scheduled as one, when it's due, rather than letting it out or keeping it waiting.

Summary by CodeRabbit

  • New Features
    • Schedule commits as an organization. Scheduled commits display the organization’s avatar and identity, and API responses include the author.
  • Bug Fixes
    • Scheduled commits that can no longer be posted under an organization’s identity are canceled. Deleting an organization also removes its scheduled commits and associated images.
  • Tests
    • Added coverage for organization scheduling, authorization, posting restrictions, and cleanup.

@coderabbitai

coderabbitai Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0d2a44ff-fea2-4178-9fed-d6c4d3a61304
Commits

Reviewing files that changed from the base of the PR and between c521484 and 1ebf3b4.

Files selected for processing: 16
  • KNOWLEDGE_BASE.md
  • app/Actions/CreateScheduledCommit.php
  • app/Actions/DeleteOrganization.php
  • app/Actions/UpdateScheduledCommitSubmittedAt.php
  • app/Http/Controllers/Api/ScheduledCommitController.php
  • app/Http/Controllers/ScheduledCommitController.php
  • app/Http/Requests/CreateApiScheduledCommitRequest.php
  • app/Http/Requests/CreateScheduledCommitRequest.php
  • app/Http/Resources/ScheduledCommitResource.php
  • app/Models/ScheduledCommit.php
  • app/Queries/ScheduledCommitsQuery.php
  • database/migrations/2026_11_01_160000_add_author_id_to_scheduled_commits_table.php
  • resources/js/components/commit-composer.tsx
  • resources/js/pages/scheduled-commits/index.tsx
  • tests/Feature/OrganizationScheduledCommitsTest.php
  • tests/Unit/ComposerDraft.test.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

Walkthrough

Organization members can schedule commits under an organization through web and API routes. Scheduled commits record and display the selected author. Submission checks membership and feature availability; organization deletion removes its scheduled commits and associated images.

Changes: Organization scheduled commits

Layer / File(s) Summary
Store and expose the scheduled author
database/migrations/*, app/Models/ScheduledCommit.php, app/Actions/CreateScheduledCommit.php, app/Queries/ScheduledCommitsQuery.php, app/Http/Resources/ScheduledCommitResource.php
Scheduled commits now store an optional author profile. Queries load the author relation, and API resources include the author or null.
Select and display an organization author
app/Http/Requests/*ScheduledCommitRequest.php, app/Http/Controllers/*/ScheduledCommitController.php, resources/js/components/commit-composer.tsx, resources/js/pages/scheduled-commits/index.tsx, tests/Unit/ComposerDraft.test.tsx, KNOWLEDGE_BASE.md
Web and API requests validate and resolve the selected organization. The composer sends the selected author when scheduling, and the scheduled-commit page displays the organization avatar and handle. Documentation and a composer test cover the update.
Check eligibility and clean up scheduled commits
app/Actions/UpdateScheduledCommitSubmittedAt.php, app/Actions/DeleteOrganization.php, tests/Feature/OrganizationScheduledCommitsTest.php
Submission checks organization membership and feature availability, and cancels ineligible commits. Organization deletion removes its scheduled commits and handles their stored images. Feature tests cover creation, eligibility, cancellation, and deletion.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Composer as commit-composer.tsx
  participant Request as CreateScheduledCommitRequest
  participant Controller as ScheduledCommitController
  participant Action as CreateScheduledCommit
  participant Table as scheduled_commits
  Composer->>Request: Submit scheduled time and author handle
  Request->>Controller: Validate and resolve organization
  Controller->>Action: Pass organization to handle
  Action->>Table: Store author_id
Loading

Suggested reviewers: nunomaduro, xheaven

Merge Risk: Minimal · up to 1ebf3

No actionable merge-blocking risk remains for organization-authored scheduled commits after normal checks.

Security architecture risk: Low · up to 1ebf3

Organization-authored scheduling retains private queues, membership checks, and transactional publication. No material authorization bypass was established. Remaining uncertainty concerns concurrent revocation timing and image-cleanup recovery.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The added authority is deferred public authorship for organizations associated with the scheduling user, not organization-wide access to private scheduled content. The inspected flow does not introduce infrastructure credentials or cross-service authority.

Trust Boundaries and Controls

  • observed — The attacker-controlled author handle is resolved through the authenticated user's organization relationship. Scheduling persists the resolved model's ID, and publication rechecks membership against that persisted ID rather than trusting the original handle.
  • observed — Membership eligibility is evaluated at the conditional publication claim. Membership removal uses a separate organization-row lock, and feature reads use memoized state; neither mechanism establishes revocation of an already-claimed publication.

Resilience and Maintainability Implications

  • observed — The cancellation guard requires a pending, uncanceled row belonging to the scheduling user. Consequently, the new failed-eligibility fallback cannot erase content or images already transferred to a submitted commit, even if it loads a submitted row.

Hardening Proposals

  • proposed — Define whether revocation takes effect at publication claim or must also stop in-flight work. If a stronger cutoff is required, coordinate membership changes and feature refresh with publication rather than assuming a final authorization check.
  • proposed — Consider using durable, after-commit file cleanup for cancellation as well as organization deletion. Cancellation's synchronous deletion predates this PR, but its new transactional caller makes database rollback and filesystem recovery worth treating explicitly.
Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly describes the main change: members can schedule commits as their organization, with cancellation if membership ends before submission.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 6 functions across 15 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@mnapoli
mnapoli marked this pull request as ready for review November 1, 2026 16:09
@mnapoli
mnapoli merged commit 4bbf95f into production Nov 1, 2026
10 checks passed
@mnapoli
mnapoli deleted the feat/org-scheduled-commits branch November 1, 2026 16:22
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.

1 participant