// Copyright 2026 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package project import ( "context" "code.gitea.io/gitea/models/db" project_model "code.gitea.io/gitea/models/project" "code.gitea.io/gitea/modules/optional" ) // UpdateProjectOptions represents updatable project fields. Fields with no value are left unchanged. type UpdateProjectOptions struct { Title optional.Option[string] Description optional.Option[string] CardType optional.Option[project_model.CardType] IsClosed optional.Option[bool] } // UpdateProject applies the provided options to the project atomically // and emits a ProjectUpdated SSE event when the txn commits. func UpdateProject(ctx context.Context, project *project_model.Project, opts UpdateProjectOptions) error { if err := db.WithTx(ctx, func(ctx context.Context) error { if opts.Title.Has() { project.Title = opts.Title.Value() } if opts.Description.Has() { project.Description = opts.Description.Value() } if opts.CardType.Has() { project.CardType = opts.CardType.Value() } if err := project_model.UpdateProject(ctx, project); err != nil { return err } if opts.IsClosed.Has() && opts.IsClosed.Value() != project.IsClosed { if err := project_model.ChangeProjectStatus(ctx, project, opts.IsClosed.Value()); err != nil { return err } } return nil }); err != nil { return err } publishProjectUpdated(ctx, project) return nil }