diff --git a/CHANGELOG.md b/CHANGELOG.md index c8a76b53..ec8e343a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ written while it was being built. See [RELEASING.md](RELEASING.md). ### Added +- Backend: A submission can now hold a description and a link to a folder of + attachments, next to the link to its repository. + ### Changed ### Fixed diff --git a/api/proto/API.md b/api/proto/API.md index fb583878..1fb6a80e 100644 --- a/api/proto/API.md +++ b/api/proto/API.md @@ -1409,7 +1409,7 @@ casbin role for this hackathon; `is_waiting` is false once approved. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| result | [string](#string) | optional | | +| result | [string](#string) | optional | URL of the repository holding the submission's output. TODO: rename to `repository_url` after the hackathon. | | status | [SubmissionStatus](#hackathon-entities-SubmissionStatus) | | | | version | [int32](#int32) | | | | created_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | @@ -1418,6 +1418,8 @@ casbin role for this hackathon; `is_waiting` is false once approved. | project_id | [string](#string) | | | | creator_id | [string](#string) | | | | modifier_id | [string](#string) | optional | | +| attachment_folder_url | [string](#string) | optional | | +| description | [string](#string) | optional | | @@ -4673,7 +4675,9 @@ casbin role for this hackathon; `is_waiting` is false once approved. | ----- | ---- | ----- | ----------- | | team_id | [string](#string) | | | | project_id | [string](#string) | | | -| result | [string](#string) | optional | | +| result | [string](#string) | optional | URL of the repository holding the submission's output. TODO: rename to `repository_url` after the hackathon. | +| attachment_folder_url | [string](#string) | optional | | +| description | [string](#string) | optional | | diff --git a/api/proto/hackathon/entities/submission.proto b/api/proto/hackathon/entities/submission.proto index 2030018f..5c250177 100644 --- a/api/proto/hackathon/entities/submission.proto +++ b/api/proto/hackathon/entities/submission.proto @@ -9,6 +9,8 @@ option go_package = "github.com/swissdatasciencecenter/hackagon/components/backe message Submission { string id = 1; + // URL of the repository holding the submission's output. + // TODO: rename to `repository_url` after the hackathon. optional string result = 2; SubmissionStatus status = 3; int32 version = 4; @@ -18,4 +20,6 @@ message Submission { string project_id = 8; string creator_id = 9; optional string modifier_id = 10; + optional string attachment_folder_url = 11; + optional string description = 12; } diff --git a/api/proto/hackathon/messages/team_svc/create_submission_request.proto b/api/proto/hackathon/messages/team_svc/create_submission_request.proto index 8ef2faf7..d8542ed6 100644 --- a/api/proto/hackathon/messages/team_svc/create_submission_request.proto +++ b/api/proto/hackathon/messages/team_svc/create_submission_request.proto @@ -7,5 +7,9 @@ option go_package = "github.com/swissdatasciencecenter/hackagon/components/backe message CreateSubmissionRequest { string team_id = 1; string project_id = 2; + // URL of the repository holding the submission's output. + // TODO: rename to `repository_url` after the hackathon. optional string result = 3; + optional string attachment_folder_url = 4; + optional string description = 5; } diff --git a/components/backend/Schema.md b/components/backend/Schema.md index 61f90fde..4aaa2292 100644 --- a/components/backend/Schema.md +++ b/components/backend/Schema.md @@ -294,7 +294,9 @@ A versioned submission from a team for a project. |--------|------|----------|--------|-----------|---------|-------------| | `created_at` | time.Time | yes | no | yes | yes | Timestamp when the submission was created. | | `modified_at` | time.Time | yes | no | no | yes | Timestamp of the last modification. | -| `result` | string | no | no | no | no | Result or output of the submission (e.g. a URL). | +| `result` | string | no | no | no | no | URL of the repository that contains the output of the submission. | +| `attachment_folder_url` | string | no | no | no | no | URL of the folder that contains the attachments. | +| `description` | string | no | no | no | no | Description of the submission. | | `status` | enum(draft, final) | yes | no | no | no | Whether the submission is a draft or final. | | `version` | int | yes | no | no | no | Monotonically increasing version number, unique per project+team. | diff --git a/components/backend/cmd/seed/h1.go b/components/backend/cmd/seed/h1.go index cf2da086..5cdea84b 100644 --- a/components/backend/cmd/seed/h1.go +++ b/components/backend/cmd/seed/h1.go @@ -286,18 +286,22 @@ func (h *harness) seedH1(now time.Time, admin, alice, bob, charles, dana *actor) // one finalized. if _, err := h.createSubmissions(teams, projects, []submissionSpec{ { - by: alice, - team: "Team Alpha", - project: "AutoML Pipeline Builder", - result: "", - final: false, + by: alice, + team: "Team Alpha", + project: "AutoML Pipeline Builder", + result: "", + description: "First pass at the search space; no evaluation yet.", + attachmentFolderURL: "", + final: false, }, { - by: alice, - team: "Team Alpha", - project: "AutoML Pipeline Builder", - result: "https://github.com/team-alpha/automl-pipeline", - final: true, + by: alice, + team: "Team Alpha", + project: "AutoML Pipeline Builder", + result: "https://github.com/team-alpha/automl-pipeline", + description: "End-to-end AutoML pipeline with model search and a benchmark report.", + attachmentFolderURL: "https://drive.example.com/team-alpha/automl-pipeline", + final: true, }, }); err != nil { return err diff --git a/components/backend/cmd/seed/h2.go b/components/backend/cmd/seed/h2.go index 6c4c33ff..df5d6472 100644 --- a/components/backend/cmd/seed/h2.go +++ b/components/backend/cmd/seed/h2.go @@ -238,11 +238,13 @@ func (h *harness) seedH2(now time.Time, admin, alice, bob, yuki *actor) error { // authored by somebody who is not an organizer. if _, err := h.createSubmissions(teams, projects, []submissionSpec{ { - by: bob, - team: "Team Gamma", - project: "Solar Panel Optimizer", - result: "https://github.com/team-gamma/solar-optimizer", - final: true, + by: bob, + team: "Team Gamma", + project: "Solar Panel Optimizer", + result: "https://github.com/team-gamma/solar-optimizer", + description: "Optimizes panel tilt from local irradiance data.", + attachmentFolderURL: "https://drive.example.com/team-gamma/solar-optimizer", + final: true, }, }); err != nil { return err diff --git a/components/backend/cmd/seed/h3.go b/components/backend/cmd/seed/h3.go index 8d37acb4..987e378e 100644 --- a/components/backend/cmd/seed/h3.go +++ b/components/backend/cmd/seed/h3.go @@ -213,25 +213,31 @@ func (h *harness) seedH3(now time.Time, admin, alice, dana *actor) error { // for a team they are not on. latest, err := h.createSubmissions(teams, projects, []submissionSpec{ { - by: alice, - team: "Team Delta", - project: "CLI Code Generator", - result: "", - final: false, + by: alice, + team: "Team Delta", + project: "CLI Code Generator", + result: "", + description: "", + attachmentFolderURL: "", + final: false, }, { - by: alice, - team: "Team Delta", - project: "CLI Code Generator", - result: "https://github.com/internal/cli-code-gen", - final: true, + by: alice, + team: "Team Delta", + project: "CLI Code Generator", + result: "https://github.com/internal/cli-code-gen", + description: "Generates CLI scaffolding from an OpenAPI spec.", + attachmentFolderURL: "https://drive.example.com/internal/cli-code-gen", + final: true, }, { - by: dana, - team: "Team Epsilon", - project: "Data Pipeline Visualizer", - result: "https://github.com/internal/data-pipeline-viz", - final: true, + by: dana, + team: "Team Epsilon", + project: "Data Pipeline Visualizer", + result: "https://github.com/internal/data-pipeline-viz", + description: "Renders pipeline DAGs with live run status.", + attachmentFolderURL: "", + final: true, }, }) if err != nil { diff --git a/components/backend/cmd/seed/h6.go b/components/backend/cmd/seed/h6.go index 712b40f6..067cf93f 100644 --- a/components/backend/cmd/seed/h6.go +++ b/components/backend/cmd/seed/h6.go @@ -304,27 +304,31 @@ func (h *harness) seedH6(now time.Time, alice, bob, charles *actor) error { } // Each team's submissions, made by a synthetic member — bob's team included, - // so his own ballot is untouched. Drafts carry no link, as an early draft - // often does not. + // so his own ballot is untouched. Drafts carry no link or description, as an + // early draft often does not. var subSpecs []submissionSpec for t, s := range specs { author := synthetic[t*teamSize] for range s.drafts { subSpecs = append(subSpecs, submissionSpec{ - by: author, - team: s.team, - project: s.title, - result: "", - final: false, + by: author, + team: s.team, + project: s.title, + result: "", + description: "", + attachmentFolderURL: "", + final: false, }) } if s.final { subSpecs = append(subSpecs, submissionSpec{ - by: author, - team: s.team, - project: s.title, - result: "https://github.com/open-science-hack/" + s.repo, - final: true, + by: author, + team: s.team, + project: s.title, + result: "https://github.com/open-science-hack/" + s.repo, + description: "Final submission of " + s.title, + attachmentFolderURL: "https://drive.example.com/open-science-hack/" + s.repo, + final: true, }) } } diff --git a/components/backend/cmd/seed/steps.go b/components/backend/cmd/seed/steps.go index 941b7665..d076782b 100644 --- a/components/backend/cmd/seed/steps.go +++ b/components/backend/cmd/seed/steps.go @@ -623,13 +623,16 @@ func (h *harness) createTeams( // Versions are not stated because they are not the seed's to choose: the // handler counts what the team has already submitted for the project, so the // order of the specs is the version order. `final` finalizes it afterwards; -// without it the submission stays a draft. +// without it the submission stays a draft. An empty `result`, `description` +// or `attachmentFolderURL` is left unset on the submission. type submissionSpec struct { - by *actor - team string - project string - result string - final bool + by *actor + team string + project string + result string + description string + attachmentFolderURL string + final bool } // createSubmissions writes submissions in order and returns each team's last @@ -650,13 +653,21 @@ func (h *harness) createSubmissions( } req := &teamMsgs.CreateSubmissionRequest{ - TeamId: teamID, - ProjectId: projectID, - Result: nil, + TeamId: teamID, + ProjectId: projectID, + Result: nil, + AttachmentFolderUrl: nil, + Description: nil, } if spec.result != "" { req.Result = &spec.result } + if spec.description != "" { + req.Description = &spec.description + } + if spec.attachmentFolderURL != "" { + req.AttachmentFolderUrl = &spec.attachmentFolderURL + } resp, err := h.team.CreateSubmission(spec.by.ctx, req) if err != nil { diff --git a/components/backend/db/schema/submission.go b/components/backend/db/schema/submission.go index 01c5a784..66e8721e 100644 --- a/components/backend/db/schema/submission.go +++ b/components/backend/db/schema/submission.go @@ -31,9 +31,16 @@ func (Submission) Fields() []ent.Field { field.Time("modified_at"). Default(time.Now).UpdateDefault(time.Now). Comment("Timestamp of the last modification."), + // TODO: rename to `repository_url` after the hackathon. field.String("result"). Optional(). - Comment("Result or output of the submission (e.g. a URL)."), + Comment("URL of the repository that contains the output of the submission."), + field.String("attachment_folder_url"). + Optional(). + Comment("URL of the folder that contains the attachments."), + field.String("description"). + Optional(). + Comment("Description of the submission."), field.Enum("status"). Values("draft", "final"). Comment("Whether the submission is a draft or final."), diff --git a/components/backend/ent/migrate/schema.go b/components/backend/ent/migrate/schema.go index 045d768f..395c5d7d 100644 --- a/components/backend/ent/migrate/schema.go +++ b/components/backend/ent/migrate/schema.go @@ -475,6 +475,8 @@ var ( {Name: "created_at", Type: field.TypeTime}, {Name: "modified_at", Type: field.TypeTime}, {Name: "result", Type: field.TypeString, Nullable: true}, + {Name: "attachment_folder_url", Type: field.TypeString, Nullable: true}, + {Name: "description", Type: field.TypeString, Nullable: true}, {Name: "status", Type: field.TypeEnum, Enums: []string{"draft", "final"}}, {Name: "version", Type: field.TypeInt}, {Name: "project_submissions", Type: field.TypeUUID}, @@ -490,25 +492,25 @@ var ( ForeignKeys: []*schema.ForeignKey{ { Symbol: "submissions_projects_submissions", - Columns: []*schema.Column{SubmissionsColumns[6]}, + Columns: []*schema.Column{SubmissionsColumns[8]}, RefColumns: []*schema.Column{ProjectsColumns[0]}, OnDelete: schema.NoAction, }, { Symbol: "submissions_teams_submissions", - Columns: []*schema.Column{SubmissionsColumns[7]}, + Columns: []*schema.Column{SubmissionsColumns[9]}, RefColumns: []*schema.Column{TeamsColumns[0]}, OnDelete: schema.Cascade, }, { Symbol: "submissions_users_created_submissions", - Columns: []*schema.Column{SubmissionsColumns[8]}, + Columns: []*schema.Column{SubmissionsColumns[10]}, RefColumns: []*schema.Column{UsersColumns[0]}, OnDelete: schema.Restrict, }, { Symbol: "submissions_users_modified_submissions", - Columns: []*schema.Column{SubmissionsColumns[9]}, + Columns: []*schema.Column{SubmissionsColumns[11]}, RefColumns: []*schema.Column{UsersColumns[0]}, OnDelete: schema.Restrict, }, @@ -517,7 +519,7 @@ var ( { Name: "submission_version_project_submissions_team_submissions", Unique: true, - Columns: []*schema.Column{SubmissionsColumns[5], SubmissionsColumns[6], SubmissionsColumns[7]}, + Columns: []*schema.Column{SubmissionsColumns[7], SubmissionsColumns[8], SubmissionsColumns[9]}, }, }, } diff --git a/components/backend/ent/mutation.go b/components/backend/ent/mutation.go index f8ba1589..2aff7212 100644 --- a/components/backend/ent/mutation.go +++ b/components/backend/ent/mutation.go @@ -9411,33 +9411,35 @@ func (m *QuestionMutation) ResetEdge(name string) error { // SubmissionMutation represents an operation that mutates the Submission nodes in the graph. type SubmissionMutation struct { config - op Op - typ string - id *uuid.UUID - created_at *time.Time - modified_at *time.Time - result *string - status *submission.Status - version *int - addversion *int - clearedFields map[string]struct{} - team *uuid.UUID - clearedteam bool - project *uuid.UUID - clearedproject bool - creator *uuid.UUID - clearedcreator bool - modifier *uuid.UUID - clearedmodifier bool - votes map[uuid.UUID]struct{} - removedvotes map[uuid.UUID]struct{} - clearedvotes bool - vote_results map[uuid.UUID]struct{} - removedvote_results map[uuid.UUID]struct{} - clearedvote_results bool - done bool - oldValue func(context.Context) (*Submission, error) - predicates []predicate.Submission + op Op + typ string + id *uuid.UUID + created_at *time.Time + modified_at *time.Time + result *string + attachment_folder_url *string + description *string + status *submission.Status + version *int + addversion *int + clearedFields map[string]struct{} + team *uuid.UUID + clearedteam bool + project *uuid.UUID + clearedproject bool + creator *uuid.UUID + clearedcreator bool + modifier *uuid.UUID + clearedmodifier bool + votes map[uuid.UUID]struct{} + removedvotes map[uuid.UUID]struct{} + clearedvotes bool + vote_results map[uuid.UUID]struct{} + removedvote_results map[uuid.UUID]struct{} + clearedvote_results bool + done bool + oldValue func(context.Context) (*Submission, error) + predicates []predicate.Submission } var _ ent.Mutation = (*SubmissionMutation)(nil) @@ -9665,6 +9667,104 @@ func (m *SubmissionMutation) ResetResult() { delete(m.clearedFields, submission.FieldResult) } +// SetAttachmentFolderURL sets the "attachment_folder_url" field. +func (m *SubmissionMutation) SetAttachmentFolderURL(s string) { + m.attachment_folder_url = &s +} + +// AttachmentFolderURL returns the value of the "attachment_folder_url" field in the mutation. +func (m *SubmissionMutation) AttachmentFolderURL() (r string, exists bool) { + v := m.attachment_folder_url + if v == nil { + return + } + return *v, true +} + +// OldAttachmentFolderURL returns the old "attachment_folder_url" field's value of the Submission entity. +// If the Submission object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubmissionMutation) OldAttachmentFolderURL(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldAttachmentFolderURL is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldAttachmentFolderURL requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldAttachmentFolderURL: %w", err) + } + return oldValue.AttachmentFolderURL, nil +} + +// ClearAttachmentFolderURL clears the value of the "attachment_folder_url" field. +func (m *SubmissionMutation) ClearAttachmentFolderURL() { + m.attachment_folder_url = nil + m.clearedFields[submission.FieldAttachmentFolderURL] = struct{}{} +} + +// AttachmentFolderURLCleared returns if the "attachment_folder_url" field was cleared in this mutation. +func (m *SubmissionMutation) AttachmentFolderURLCleared() bool { + _, ok := m.clearedFields[submission.FieldAttachmentFolderURL] + return ok +} + +// ResetAttachmentFolderURL resets all changes to the "attachment_folder_url" field. +func (m *SubmissionMutation) ResetAttachmentFolderURL() { + m.attachment_folder_url = nil + delete(m.clearedFields, submission.FieldAttachmentFolderURL) +} + +// SetDescription sets the "description" field. +func (m *SubmissionMutation) SetDescription(s string) { + m.description = &s +} + +// Description returns the value of the "description" field in the mutation. +func (m *SubmissionMutation) Description() (r string, exists bool) { + v := m.description + if v == nil { + return + } + return *v, true +} + +// OldDescription returns the old "description" field's value of the Submission entity. +// If the Submission object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubmissionMutation) OldDescription(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDescription is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDescription requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDescription: %w", err) + } + return oldValue.Description, nil +} + +// ClearDescription clears the value of the "description" field. +func (m *SubmissionMutation) ClearDescription() { + m.description = nil + m.clearedFields[submission.FieldDescription] = struct{}{} +} + +// DescriptionCleared returns if the "description" field was cleared in this mutation. +func (m *SubmissionMutation) DescriptionCleared() bool { + _, ok := m.clearedFields[submission.FieldDescription] + return ok +} + +// ResetDescription resets all changes to the "description" field. +func (m *SubmissionMutation) ResetDescription() { + m.description = nil + delete(m.clearedFields, submission.FieldDescription) +} + // SetStatus sets the "status" field. func (m *SubmissionMutation) SetStatus(s submission.Status) { m.status = &s @@ -10055,7 +10155,7 @@ func (m *SubmissionMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *SubmissionMutation) Fields() []string { - fields := make([]string, 0, 5) + fields := make([]string, 0, 7) if m.created_at != nil { fields = append(fields, submission.FieldCreatedAt) } @@ -10065,6 +10165,12 @@ func (m *SubmissionMutation) Fields() []string { if m.result != nil { fields = append(fields, submission.FieldResult) } + if m.attachment_folder_url != nil { + fields = append(fields, submission.FieldAttachmentFolderURL) + } + if m.description != nil { + fields = append(fields, submission.FieldDescription) + } if m.status != nil { fields = append(fields, submission.FieldStatus) } @@ -10085,6 +10191,10 @@ func (m *SubmissionMutation) Field(name string) (ent.Value, bool) { return m.ModifiedAt() case submission.FieldResult: return m.Result() + case submission.FieldAttachmentFolderURL: + return m.AttachmentFolderURL() + case submission.FieldDescription: + return m.Description() case submission.FieldStatus: return m.Status() case submission.FieldVersion: @@ -10104,6 +10214,10 @@ func (m *SubmissionMutation) OldField(ctx context.Context, name string) (ent.Val return m.OldModifiedAt(ctx) case submission.FieldResult: return m.OldResult(ctx) + case submission.FieldAttachmentFolderURL: + return m.OldAttachmentFolderURL(ctx) + case submission.FieldDescription: + return m.OldDescription(ctx) case submission.FieldStatus: return m.OldStatus(ctx) case submission.FieldVersion: @@ -10138,6 +10252,20 @@ func (m *SubmissionMutation) SetField(name string, value ent.Value) error { } m.SetResult(v) return nil + case submission.FieldAttachmentFolderURL: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAttachmentFolderURL(v) + return nil + case submission.FieldDescription: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDescription(v) + return nil case submission.FieldStatus: v, ok := value.(submission.Status) if !ok { @@ -10200,6 +10328,12 @@ func (m *SubmissionMutation) ClearedFields() []string { if m.FieldCleared(submission.FieldResult) { fields = append(fields, submission.FieldResult) } + if m.FieldCleared(submission.FieldAttachmentFolderURL) { + fields = append(fields, submission.FieldAttachmentFolderURL) + } + if m.FieldCleared(submission.FieldDescription) { + fields = append(fields, submission.FieldDescription) + } return fields } @@ -10217,6 +10351,12 @@ func (m *SubmissionMutation) ClearField(name string) error { case submission.FieldResult: m.ClearResult() return nil + case submission.FieldAttachmentFolderURL: + m.ClearAttachmentFolderURL() + return nil + case submission.FieldDescription: + m.ClearDescription() + return nil } return fmt.Errorf("unknown Submission nullable field %s", name) } @@ -10234,6 +10374,12 @@ func (m *SubmissionMutation) ResetField(name string) error { case submission.FieldResult: m.ResetResult() return nil + case submission.FieldAttachmentFolderURL: + m.ResetAttachmentFolderURL() + return nil + case submission.FieldDescription: + m.ResetDescription() + return nil case submission.FieldStatus: m.ResetStatus() return nil diff --git a/components/backend/ent/runtime/runtime.go b/components/backend/ent/runtime/runtime.go index f2a3ea03..c632aa89 100644 --- a/components/backend/ent/runtime/runtime.go +++ b/components/backend/ent/runtime/runtime.go @@ -284,7 +284,7 @@ func init() { // submission.UpdateDefaultModifiedAt holds the default value on update for the modified_at field. submission.UpdateDefaultModifiedAt = submissionDescModifiedAt.UpdateDefault.(func() time.Time) // submissionDescVersion is the schema descriptor for version field. - submissionDescVersion := submissionFields[4].Descriptor() + submissionDescVersion := submissionFields[6].Descriptor() // submission.VersionValidator is a validator for the "version" field. It is called by the builders before save. submission.VersionValidator = submissionDescVersion.Validators[0].(func(int) error) // submissionDescID is the schema descriptor for id field. diff --git a/components/backend/ent/submission.go b/components/backend/ent/submission.go index f6de4a64..059b0225 100644 --- a/components/backend/ent/submission.go +++ b/components/backend/ent/submission.go @@ -25,8 +25,12 @@ type Submission struct { CreatedAt time.Time `json:"created_at,omitempty"` // Timestamp of the last modification. ModifiedAt time.Time `json:"modified_at,omitempty"` - // Result or output of the submission (e.g. a URL). + // URL of the repository that contains the output of the submission. Result string `json:"result,omitempty"` + // URL of the folder that contains the attachments. + AttachmentFolderURL string `json:"attachment_folder_url,omitempty"` + // Description of the submission. + Description string `json:"description,omitempty"` // Whether the submission is a draft or final. Status submission.Status `json:"status,omitempty"` // Monotonically increasing version number, unique per project+team. @@ -129,7 +133,7 @@ func (*Submission) scanValues(columns []string) ([]any, error) { switch columns[i] { case submission.FieldVersion: values[i] = new(sql.NullInt64) - case submission.FieldResult, submission.FieldStatus: + case submission.FieldResult, submission.FieldAttachmentFolderURL, submission.FieldDescription, submission.FieldStatus: values[i] = new(sql.NullString) case submission.FieldCreatedAt, submission.FieldModifiedAt: values[i] = new(sql.NullTime) @@ -182,6 +186,18 @@ func (_m *Submission) assignValues(columns []string, values []any) error { } else if value.Valid { _m.Result = value.String } + case submission.FieldAttachmentFolderURL: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field attachment_folder_url", values[i]) + } else if value.Valid { + _m.AttachmentFolderURL = value.String + } + case submission.FieldDescription: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field description", values[i]) + } else if value.Valid { + _m.Description = value.String + } case submission.FieldStatus: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field status", values[i]) @@ -297,6 +313,12 @@ func (_m *Submission) String() string { builder.WriteString("result=") builder.WriteString(_m.Result) builder.WriteString(", ") + builder.WriteString("attachment_folder_url=") + builder.WriteString(_m.AttachmentFolderURL) + builder.WriteString(", ") + builder.WriteString("description=") + builder.WriteString(_m.Description) + builder.WriteString(", ") builder.WriteString("status=") builder.WriteString(fmt.Sprintf("%v", _m.Status)) builder.WriteString(", ") diff --git a/components/backend/ent/submission/submission.go b/components/backend/ent/submission/submission.go index 821db2d0..b1abe7f3 100644 --- a/components/backend/ent/submission/submission.go +++ b/components/backend/ent/submission/submission.go @@ -22,6 +22,10 @@ const ( FieldModifiedAt = "modified_at" // FieldResult holds the string denoting the result field in the database. FieldResult = "result" + // FieldAttachmentFolderURL holds the string denoting the attachment_folder_url field in the database. + FieldAttachmentFolderURL = "attachment_folder_url" + // FieldDescription holds the string denoting the description field in the database. + FieldDescription = "description" // FieldStatus holds the string denoting the status field in the database. FieldStatus = "status" // FieldVersion holds the string denoting the version field in the database. @@ -90,6 +94,8 @@ var Columns = []string{ FieldCreatedAt, FieldModifiedAt, FieldResult, + FieldAttachmentFolderURL, + FieldDescription, FieldStatus, FieldVersion, } @@ -177,6 +183,16 @@ func ByResult(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldResult, opts...).ToFunc() } +// ByAttachmentFolderURL orders the results by the attachment_folder_url field. +func ByAttachmentFolderURL(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldAttachmentFolderURL, opts...).ToFunc() +} + +// ByDescription orders the results by the description field. +func ByDescription(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDescription, opts...).ToFunc() +} + // ByStatus orders the results by the status field. func ByStatus(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldStatus, opts...).ToFunc() diff --git a/components/backend/ent/submission/where.go b/components/backend/ent/submission/where.go index e9b15de6..56eab5e8 100644 --- a/components/backend/ent/submission/where.go +++ b/components/backend/ent/submission/where.go @@ -71,6 +71,16 @@ func Result(v string) predicate.Submission { return predicate.Submission(sql.FieldEQ(FieldResult, v)) } +// AttachmentFolderURL applies equality check predicate on the "attachment_folder_url" field. It's identical to AttachmentFolderURLEQ. +func AttachmentFolderURL(v string) predicate.Submission { + return predicate.Submission(sql.FieldEQ(FieldAttachmentFolderURL, v)) +} + +// Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ. +func Description(v string) predicate.Submission { + return predicate.Submission(sql.FieldEQ(FieldDescription, v)) +} + // Version applies equality check predicate on the "version" field. It's identical to VersionEQ. func Version(v int) predicate.Submission { return predicate.Submission(sql.FieldEQ(FieldVersion, v)) @@ -231,6 +241,156 @@ func ResultContainsFold(v string) predicate.Submission { return predicate.Submission(sql.FieldContainsFold(FieldResult, v)) } +// AttachmentFolderURLEQ applies the EQ predicate on the "attachment_folder_url" field. +func AttachmentFolderURLEQ(v string) predicate.Submission { + return predicate.Submission(sql.FieldEQ(FieldAttachmentFolderURL, v)) +} + +// AttachmentFolderURLNEQ applies the NEQ predicate on the "attachment_folder_url" field. +func AttachmentFolderURLNEQ(v string) predicate.Submission { + return predicate.Submission(sql.FieldNEQ(FieldAttachmentFolderURL, v)) +} + +// AttachmentFolderURLIn applies the In predicate on the "attachment_folder_url" field. +func AttachmentFolderURLIn(vs ...string) predicate.Submission { + return predicate.Submission(sql.FieldIn(FieldAttachmentFolderURL, vs...)) +} + +// AttachmentFolderURLNotIn applies the NotIn predicate on the "attachment_folder_url" field. +func AttachmentFolderURLNotIn(vs ...string) predicate.Submission { + return predicate.Submission(sql.FieldNotIn(FieldAttachmentFolderURL, vs...)) +} + +// AttachmentFolderURLGT applies the GT predicate on the "attachment_folder_url" field. +func AttachmentFolderURLGT(v string) predicate.Submission { + return predicate.Submission(sql.FieldGT(FieldAttachmentFolderURL, v)) +} + +// AttachmentFolderURLGTE applies the GTE predicate on the "attachment_folder_url" field. +func AttachmentFolderURLGTE(v string) predicate.Submission { + return predicate.Submission(sql.FieldGTE(FieldAttachmentFolderURL, v)) +} + +// AttachmentFolderURLLT applies the LT predicate on the "attachment_folder_url" field. +func AttachmentFolderURLLT(v string) predicate.Submission { + return predicate.Submission(sql.FieldLT(FieldAttachmentFolderURL, v)) +} + +// AttachmentFolderURLLTE applies the LTE predicate on the "attachment_folder_url" field. +func AttachmentFolderURLLTE(v string) predicate.Submission { + return predicate.Submission(sql.FieldLTE(FieldAttachmentFolderURL, v)) +} + +// AttachmentFolderURLContains applies the Contains predicate on the "attachment_folder_url" field. +func AttachmentFolderURLContains(v string) predicate.Submission { + return predicate.Submission(sql.FieldContains(FieldAttachmentFolderURL, v)) +} + +// AttachmentFolderURLHasPrefix applies the HasPrefix predicate on the "attachment_folder_url" field. +func AttachmentFolderURLHasPrefix(v string) predicate.Submission { + return predicate.Submission(sql.FieldHasPrefix(FieldAttachmentFolderURL, v)) +} + +// AttachmentFolderURLHasSuffix applies the HasSuffix predicate on the "attachment_folder_url" field. +func AttachmentFolderURLHasSuffix(v string) predicate.Submission { + return predicate.Submission(sql.FieldHasSuffix(FieldAttachmentFolderURL, v)) +} + +// AttachmentFolderURLIsNil applies the IsNil predicate on the "attachment_folder_url" field. +func AttachmentFolderURLIsNil() predicate.Submission { + return predicate.Submission(sql.FieldIsNull(FieldAttachmentFolderURL)) +} + +// AttachmentFolderURLNotNil applies the NotNil predicate on the "attachment_folder_url" field. +func AttachmentFolderURLNotNil() predicate.Submission { + return predicate.Submission(sql.FieldNotNull(FieldAttachmentFolderURL)) +} + +// AttachmentFolderURLEqualFold applies the EqualFold predicate on the "attachment_folder_url" field. +func AttachmentFolderURLEqualFold(v string) predicate.Submission { + return predicate.Submission(sql.FieldEqualFold(FieldAttachmentFolderURL, v)) +} + +// AttachmentFolderURLContainsFold applies the ContainsFold predicate on the "attachment_folder_url" field. +func AttachmentFolderURLContainsFold(v string) predicate.Submission { + return predicate.Submission(sql.FieldContainsFold(FieldAttachmentFolderURL, v)) +} + +// DescriptionEQ applies the EQ predicate on the "description" field. +func DescriptionEQ(v string) predicate.Submission { + return predicate.Submission(sql.FieldEQ(FieldDescription, v)) +} + +// DescriptionNEQ applies the NEQ predicate on the "description" field. +func DescriptionNEQ(v string) predicate.Submission { + return predicate.Submission(sql.FieldNEQ(FieldDescription, v)) +} + +// DescriptionIn applies the In predicate on the "description" field. +func DescriptionIn(vs ...string) predicate.Submission { + return predicate.Submission(sql.FieldIn(FieldDescription, vs...)) +} + +// DescriptionNotIn applies the NotIn predicate on the "description" field. +func DescriptionNotIn(vs ...string) predicate.Submission { + return predicate.Submission(sql.FieldNotIn(FieldDescription, vs...)) +} + +// DescriptionGT applies the GT predicate on the "description" field. +func DescriptionGT(v string) predicate.Submission { + return predicate.Submission(sql.FieldGT(FieldDescription, v)) +} + +// DescriptionGTE applies the GTE predicate on the "description" field. +func DescriptionGTE(v string) predicate.Submission { + return predicate.Submission(sql.FieldGTE(FieldDescription, v)) +} + +// DescriptionLT applies the LT predicate on the "description" field. +func DescriptionLT(v string) predicate.Submission { + return predicate.Submission(sql.FieldLT(FieldDescription, v)) +} + +// DescriptionLTE applies the LTE predicate on the "description" field. +func DescriptionLTE(v string) predicate.Submission { + return predicate.Submission(sql.FieldLTE(FieldDescription, v)) +} + +// DescriptionContains applies the Contains predicate on the "description" field. +func DescriptionContains(v string) predicate.Submission { + return predicate.Submission(sql.FieldContains(FieldDescription, v)) +} + +// DescriptionHasPrefix applies the HasPrefix predicate on the "description" field. +func DescriptionHasPrefix(v string) predicate.Submission { + return predicate.Submission(sql.FieldHasPrefix(FieldDescription, v)) +} + +// DescriptionHasSuffix applies the HasSuffix predicate on the "description" field. +func DescriptionHasSuffix(v string) predicate.Submission { + return predicate.Submission(sql.FieldHasSuffix(FieldDescription, v)) +} + +// DescriptionIsNil applies the IsNil predicate on the "description" field. +func DescriptionIsNil() predicate.Submission { + return predicate.Submission(sql.FieldIsNull(FieldDescription)) +} + +// DescriptionNotNil applies the NotNil predicate on the "description" field. +func DescriptionNotNil() predicate.Submission { + return predicate.Submission(sql.FieldNotNull(FieldDescription)) +} + +// DescriptionEqualFold applies the EqualFold predicate on the "description" field. +func DescriptionEqualFold(v string) predicate.Submission { + return predicate.Submission(sql.FieldEqualFold(FieldDescription, v)) +} + +// DescriptionContainsFold applies the ContainsFold predicate on the "description" field. +func DescriptionContainsFold(v string) predicate.Submission { + return predicate.Submission(sql.FieldContainsFold(FieldDescription, v)) +} + // StatusEQ applies the EQ predicate on the "status" field. func StatusEQ(v Status) predicate.Submission { return predicate.Submission(sql.FieldEQ(FieldStatus, v)) diff --git a/components/backend/ent/submission_create.go b/components/backend/ent/submission_create.go index 1e1c4957..cade913f 100644 --- a/components/backend/ent/submission_create.go +++ b/components/backend/ent/submission_create.go @@ -71,6 +71,34 @@ func (_c *SubmissionCreate) SetNillableResult(v *string) *SubmissionCreate { return _c } +// SetAttachmentFolderURL sets the "attachment_folder_url" field. +func (_c *SubmissionCreate) SetAttachmentFolderURL(v string) *SubmissionCreate { + _c.mutation.SetAttachmentFolderURL(v) + return _c +} + +// SetNillableAttachmentFolderURL sets the "attachment_folder_url" field if the given value is not nil. +func (_c *SubmissionCreate) SetNillableAttachmentFolderURL(v *string) *SubmissionCreate { + if v != nil { + _c.SetAttachmentFolderURL(*v) + } + return _c +} + +// SetDescription sets the "description" field. +func (_c *SubmissionCreate) SetDescription(v string) *SubmissionCreate { + _c.mutation.SetDescription(v) + return _c +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (_c *SubmissionCreate) SetNillableDescription(v *string) *SubmissionCreate { + if v != nil { + _c.SetDescription(*v) + } + return _c +} + // SetStatus sets the "status" field. func (_c *SubmissionCreate) SetStatus(v submission.Status) *SubmissionCreate { _c.mutation.SetStatus(v) @@ -309,6 +337,14 @@ func (_c *SubmissionCreate) createSpec() (*Submission, *sqlgraph.CreateSpec) { _spec.SetField(submission.FieldResult, field.TypeString, value) _node.Result = value } + if value, ok := _c.mutation.AttachmentFolderURL(); ok { + _spec.SetField(submission.FieldAttachmentFolderURL, field.TypeString, value) + _node.AttachmentFolderURL = value + } + if value, ok := _c.mutation.Description(); ok { + _spec.SetField(submission.FieldDescription, field.TypeString, value) + _node.Description = value + } if value, ok := _c.mutation.Status(); ok { _spec.SetField(submission.FieldStatus, field.TypeEnum, value) _node.Status = value @@ -499,6 +535,42 @@ func (u *SubmissionUpsert) ClearResult() *SubmissionUpsert { return u } +// SetAttachmentFolderURL sets the "attachment_folder_url" field. +func (u *SubmissionUpsert) SetAttachmentFolderURL(v string) *SubmissionUpsert { + u.Set(submission.FieldAttachmentFolderURL, v) + return u +} + +// UpdateAttachmentFolderURL sets the "attachment_folder_url" field to the value that was provided on create. +func (u *SubmissionUpsert) UpdateAttachmentFolderURL() *SubmissionUpsert { + u.SetExcluded(submission.FieldAttachmentFolderURL) + return u +} + +// ClearAttachmentFolderURL clears the value of the "attachment_folder_url" field. +func (u *SubmissionUpsert) ClearAttachmentFolderURL() *SubmissionUpsert { + u.SetNull(submission.FieldAttachmentFolderURL) + return u +} + +// SetDescription sets the "description" field. +func (u *SubmissionUpsert) SetDescription(v string) *SubmissionUpsert { + u.Set(submission.FieldDescription, v) + return u +} + +// UpdateDescription sets the "description" field to the value that was provided on create. +func (u *SubmissionUpsert) UpdateDescription() *SubmissionUpsert { + u.SetExcluded(submission.FieldDescription) + return u +} + +// ClearDescription clears the value of the "description" field. +func (u *SubmissionUpsert) ClearDescription() *SubmissionUpsert { + u.SetNull(submission.FieldDescription) + return u +} + // SetStatus sets the "status" field. func (u *SubmissionUpsert) SetStatus(v submission.Status) *SubmissionUpsert { u.Set(submission.FieldStatus, v) @@ -615,6 +687,48 @@ func (u *SubmissionUpsertOne) ClearResult() *SubmissionUpsertOne { }) } +// SetAttachmentFolderURL sets the "attachment_folder_url" field. +func (u *SubmissionUpsertOne) SetAttachmentFolderURL(v string) *SubmissionUpsertOne { + return u.Update(func(s *SubmissionUpsert) { + s.SetAttachmentFolderURL(v) + }) +} + +// UpdateAttachmentFolderURL sets the "attachment_folder_url" field to the value that was provided on create. +func (u *SubmissionUpsertOne) UpdateAttachmentFolderURL() *SubmissionUpsertOne { + return u.Update(func(s *SubmissionUpsert) { + s.UpdateAttachmentFolderURL() + }) +} + +// ClearAttachmentFolderURL clears the value of the "attachment_folder_url" field. +func (u *SubmissionUpsertOne) ClearAttachmentFolderURL() *SubmissionUpsertOne { + return u.Update(func(s *SubmissionUpsert) { + s.ClearAttachmentFolderURL() + }) +} + +// SetDescription sets the "description" field. +func (u *SubmissionUpsertOne) SetDescription(v string) *SubmissionUpsertOne { + return u.Update(func(s *SubmissionUpsert) { + s.SetDescription(v) + }) +} + +// UpdateDescription sets the "description" field to the value that was provided on create. +func (u *SubmissionUpsertOne) UpdateDescription() *SubmissionUpsertOne { + return u.Update(func(s *SubmissionUpsert) { + s.UpdateDescription() + }) +} + +// ClearDescription clears the value of the "description" field. +func (u *SubmissionUpsertOne) ClearDescription() *SubmissionUpsertOne { + return u.Update(func(s *SubmissionUpsert) { + s.ClearDescription() + }) +} + // SetStatus sets the "status" field. func (u *SubmissionUpsertOne) SetStatus(v submission.Status) *SubmissionUpsertOne { return u.Update(func(s *SubmissionUpsert) { @@ -903,6 +1017,48 @@ func (u *SubmissionUpsertBulk) ClearResult() *SubmissionUpsertBulk { }) } +// SetAttachmentFolderURL sets the "attachment_folder_url" field. +func (u *SubmissionUpsertBulk) SetAttachmentFolderURL(v string) *SubmissionUpsertBulk { + return u.Update(func(s *SubmissionUpsert) { + s.SetAttachmentFolderURL(v) + }) +} + +// UpdateAttachmentFolderURL sets the "attachment_folder_url" field to the value that was provided on create. +func (u *SubmissionUpsertBulk) UpdateAttachmentFolderURL() *SubmissionUpsertBulk { + return u.Update(func(s *SubmissionUpsert) { + s.UpdateAttachmentFolderURL() + }) +} + +// ClearAttachmentFolderURL clears the value of the "attachment_folder_url" field. +func (u *SubmissionUpsertBulk) ClearAttachmentFolderURL() *SubmissionUpsertBulk { + return u.Update(func(s *SubmissionUpsert) { + s.ClearAttachmentFolderURL() + }) +} + +// SetDescription sets the "description" field. +func (u *SubmissionUpsertBulk) SetDescription(v string) *SubmissionUpsertBulk { + return u.Update(func(s *SubmissionUpsert) { + s.SetDescription(v) + }) +} + +// UpdateDescription sets the "description" field to the value that was provided on create. +func (u *SubmissionUpsertBulk) UpdateDescription() *SubmissionUpsertBulk { + return u.Update(func(s *SubmissionUpsert) { + s.UpdateDescription() + }) +} + +// ClearDescription clears the value of the "description" field. +func (u *SubmissionUpsertBulk) ClearDescription() *SubmissionUpsertBulk { + return u.Update(func(s *SubmissionUpsert) { + s.ClearDescription() + }) +} + // SetStatus sets the "status" field. func (u *SubmissionUpsertBulk) SetStatus(v submission.Status) *SubmissionUpsertBulk { return u.Update(func(s *SubmissionUpsert) { diff --git a/components/backend/ent/submission_update.go b/components/backend/ent/submission_update.go index 90a53a2d..89907fb2 100644 --- a/components/backend/ent/submission_update.go +++ b/components/backend/ent/submission_update.go @@ -60,6 +60,46 @@ func (_u *SubmissionUpdate) ClearResult() *SubmissionUpdate { return _u } +// SetAttachmentFolderURL sets the "attachment_folder_url" field. +func (_u *SubmissionUpdate) SetAttachmentFolderURL(v string) *SubmissionUpdate { + _u.mutation.SetAttachmentFolderURL(v) + return _u +} + +// SetNillableAttachmentFolderURL sets the "attachment_folder_url" field if the given value is not nil. +func (_u *SubmissionUpdate) SetNillableAttachmentFolderURL(v *string) *SubmissionUpdate { + if v != nil { + _u.SetAttachmentFolderURL(*v) + } + return _u +} + +// ClearAttachmentFolderURL clears the value of the "attachment_folder_url" field. +func (_u *SubmissionUpdate) ClearAttachmentFolderURL() *SubmissionUpdate { + _u.mutation.ClearAttachmentFolderURL() + return _u +} + +// SetDescription sets the "description" field. +func (_u *SubmissionUpdate) SetDescription(v string) *SubmissionUpdate { + _u.mutation.SetDescription(v) + return _u +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (_u *SubmissionUpdate) SetNillableDescription(v *string) *SubmissionUpdate { + if v != nil { + _u.SetDescription(*v) + } + return _u +} + +// ClearDescription clears the value of the "description" field. +func (_u *SubmissionUpdate) ClearDescription() *SubmissionUpdate { + _u.mutation.ClearDescription() + return _u +} + // SetStatus sets the "status" field. func (_u *SubmissionUpdate) SetStatus(v submission.Status) *SubmissionUpdate { _u.mutation.SetStatus(v) @@ -312,6 +352,18 @@ func (_u *SubmissionUpdate) sqlSave(ctx context.Context) (_node int, err error) if _u.mutation.ResultCleared() { _spec.ClearField(submission.FieldResult, field.TypeString) } + if value, ok := _u.mutation.AttachmentFolderURL(); ok { + _spec.SetField(submission.FieldAttachmentFolderURL, field.TypeString, value) + } + if _u.mutation.AttachmentFolderURLCleared() { + _spec.ClearField(submission.FieldAttachmentFolderURL, field.TypeString) + } + if value, ok := _u.mutation.Description(); ok { + _spec.SetField(submission.FieldDescription, field.TypeString, value) + } + if _u.mutation.DescriptionCleared() { + _spec.ClearField(submission.FieldDescription, field.TypeString) + } if value, ok := _u.mutation.Status(); ok { _spec.SetField(submission.FieldStatus, field.TypeEnum, value) } @@ -544,6 +596,46 @@ func (_u *SubmissionUpdateOne) ClearResult() *SubmissionUpdateOne { return _u } +// SetAttachmentFolderURL sets the "attachment_folder_url" field. +func (_u *SubmissionUpdateOne) SetAttachmentFolderURL(v string) *SubmissionUpdateOne { + _u.mutation.SetAttachmentFolderURL(v) + return _u +} + +// SetNillableAttachmentFolderURL sets the "attachment_folder_url" field if the given value is not nil. +func (_u *SubmissionUpdateOne) SetNillableAttachmentFolderURL(v *string) *SubmissionUpdateOne { + if v != nil { + _u.SetAttachmentFolderURL(*v) + } + return _u +} + +// ClearAttachmentFolderURL clears the value of the "attachment_folder_url" field. +func (_u *SubmissionUpdateOne) ClearAttachmentFolderURL() *SubmissionUpdateOne { + _u.mutation.ClearAttachmentFolderURL() + return _u +} + +// SetDescription sets the "description" field. +func (_u *SubmissionUpdateOne) SetDescription(v string) *SubmissionUpdateOne { + _u.mutation.SetDescription(v) + return _u +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (_u *SubmissionUpdateOne) SetNillableDescription(v *string) *SubmissionUpdateOne { + if v != nil { + _u.SetDescription(*v) + } + return _u +} + +// ClearDescription clears the value of the "description" field. +func (_u *SubmissionUpdateOne) ClearDescription() *SubmissionUpdateOne { + _u.mutation.ClearDescription() + return _u +} + // SetStatus sets the "status" field. func (_u *SubmissionUpdateOne) SetStatus(v submission.Status) *SubmissionUpdateOne { _u.mutation.SetStatus(v) @@ -826,6 +918,18 @@ func (_u *SubmissionUpdateOne) sqlSave(ctx context.Context) (_node *Submission, if _u.mutation.ResultCleared() { _spec.ClearField(submission.FieldResult, field.TypeString) } + if value, ok := _u.mutation.AttachmentFolderURL(); ok { + _spec.SetField(submission.FieldAttachmentFolderURL, field.TypeString, value) + } + if _u.mutation.AttachmentFolderURLCleared() { + _spec.ClearField(submission.FieldAttachmentFolderURL, field.TypeString) + } + if value, ok := _u.mutation.Description(); ok { + _spec.SetField(submission.FieldDescription, field.TypeString, value) + } + if _u.mutation.DescriptionCleared() { + _spec.ClearField(submission.FieldDescription, field.TypeString) + } if value, ok := _u.mutation.Status(); ok { _spec.SetField(submission.FieldStatus, field.TypeEnum, value) } diff --git a/components/backend/internal/proto/hackathon/entities/submission.pb.go b/components/backend/internal/proto/hackathon/entities/submission.pb.go index 35067e02..2bf1643e 100644 --- a/components/backend/internal/proto/hackathon/entities/submission.pb.go +++ b/components/backend/internal/proto/hackathon/entities/submission.pb.go @@ -23,19 +23,23 @@ const ( ) type Submission struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Result *string `protobuf:"bytes,2,opt,name=result,proto3,oneof" json:"result,omitempty"` - Status SubmissionStatus `protobuf:"varint,3,opt,name=status,proto3,enum=hackathon.entities.SubmissionStatus" json:"status,omitempty"` - Version int32 `protobuf:"varint,4,opt,name=version,proto3" json:"version,omitempty"` - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - ModifiedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=modified_at,json=modifiedAt,proto3" json:"modified_at,omitempty"` - TeamId string `protobuf:"bytes,7,opt,name=team_id,json=teamId,proto3" json:"team_id,omitempty"` - ProjectId string `protobuf:"bytes,8,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` - CreatorId string `protobuf:"bytes,9,opt,name=creator_id,json=creatorId,proto3" json:"creator_id,omitempty"` - ModifierId *string `protobuf:"bytes,10,opt,name=modifier_id,json=modifierId,proto3,oneof" json:"modifier_id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // URL of the repository holding the submission's output. + // TODO: rename to `repository_url` after the hackathon. + Result *string `protobuf:"bytes,2,opt,name=result,proto3,oneof" json:"result,omitempty"` + Status SubmissionStatus `protobuf:"varint,3,opt,name=status,proto3,enum=hackathon.entities.SubmissionStatus" json:"status,omitempty"` + Version int32 `protobuf:"varint,4,opt,name=version,proto3" json:"version,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + ModifiedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=modified_at,json=modifiedAt,proto3" json:"modified_at,omitempty"` + TeamId string `protobuf:"bytes,7,opt,name=team_id,json=teamId,proto3" json:"team_id,omitempty"` + ProjectId string `protobuf:"bytes,8,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + CreatorId string `protobuf:"bytes,9,opt,name=creator_id,json=creatorId,proto3" json:"creator_id,omitempty"` + ModifierId *string `protobuf:"bytes,10,opt,name=modifier_id,json=modifierId,proto3,oneof" json:"modifier_id,omitempty"` + AttachmentFolderUrl *string `protobuf:"bytes,11,opt,name=attachment_folder_url,json=attachmentFolderUrl,proto3,oneof" json:"attachment_folder_url,omitempty"` + Description *string `protobuf:"bytes,12,opt,name=description,proto3,oneof" json:"description,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Submission) Reset() { @@ -138,11 +142,25 @@ func (x *Submission) GetModifierId() string { return "" } +func (x *Submission) GetAttachmentFolderUrl() string { + if x != nil && x.AttachmentFolderUrl != nil { + return *x.AttachmentFolderUrl + } + return "" +} + +func (x *Submission) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + var File_hackathon_entities_submission_proto protoreflect.FileDescriptor const file_hackathon_entities_submission_proto_rawDesc = "" + "\n" + - "#hackathon/entities/submission.proto\x12\x12hackathon.entities\x1a\x1fgoogle/protobuf/timestamp.proto\x1a*hackathon/entities/submission_status.proto\"\xa1\x03\n" + + "#hackathon/entities/submission.proto\x12\x12hackathon.entities\x1a\x1fgoogle/protobuf/timestamp.proto\x1a*hackathon/entities/submission_status.proto\"\xab\x04\n" + "\n" + "Submission\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x1b\n" + @@ -160,9 +178,13 @@ const file_hackathon_entities_submission_proto_rawDesc = "" + "creator_id\x18\t \x01(\tR\tcreatorId\x12$\n" + "\vmodifier_id\x18\n" + " \x01(\tH\x01R\n" + - "modifierId\x88\x01\x01B\t\n" + + "modifierId\x88\x01\x01\x127\n" + + "\x15attachment_folder_url\x18\v \x01(\tH\x02R\x13attachmentFolderUrl\x88\x01\x01\x12%\n" + + "\vdescription\x18\f \x01(\tH\x03R\vdescription\x88\x01\x01B\t\n" + "\a_resultB\x0e\n" + - "\f_modifier_idBaZ_github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/entitiesb\x06proto3" + "\f_modifier_idB\x18\n" + + "\x16_attachment_folder_urlB\x0e\n" + + "\f_descriptionBaZ_github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/entitiesb\x06proto3" var ( file_hackathon_entities_submission_proto_rawDescOnce sync.Once diff --git a/components/backend/internal/proto/hackathon/messages/team_svc/create_submission_request.pb.go b/components/backend/internal/proto/hackathon/messages/team_svc/create_submission_request.pb.go index 12cb97ef..2bc3b9e6 100644 --- a/components/backend/internal/proto/hackathon/messages/team_svc/create_submission_request.pb.go +++ b/components/backend/internal/proto/hackathon/messages/team_svc/create_submission_request.pb.go @@ -22,12 +22,16 @@ const ( ) type CreateSubmissionRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - TeamId string `protobuf:"bytes,1,opt,name=team_id,json=teamId,proto3" json:"team_id,omitempty"` - ProjectId string `protobuf:"bytes,2,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` - Result *string `protobuf:"bytes,3,opt,name=result,proto3,oneof" json:"result,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + TeamId string `protobuf:"bytes,1,opt,name=team_id,json=teamId,proto3" json:"team_id,omitempty"` + ProjectId string `protobuf:"bytes,2,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + // URL of the repository holding the submission's output. + // TODO: rename to `repository_url` after the hackathon. + Result *string `protobuf:"bytes,3,opt,name=result,proto3,oneof" json:"result,omitempty"` + AttachmentFolderUrl *string `protobuf:"bytes,4,opt,name=attachment_folder_url,json=attachmentFolderUrl,proto3,oneof" json:"attachment_folder_url,omitempty"` + Description *string `protobuf:"bytes,5,opt,name=description,proto3,oneof" json:"description,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *CreateSubmissionRequest) Reset() { @@ -81,17 +85,35 @@ func (x *CreateSubmissionRequest) GetResult() string { return "" } +func (x *CreateSubmissionRequest) GetAttachmentFolderUrl() string { + if x != nil && x.AttachmentFolderUrl != nil { + return *x.AttachmentFolderUrl + } + return "" +} + +func (x *CreateSubmissionRequest) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + var File_hackathon_messages_team_svc_create_submission_request_proto protoreflect.FileDescriptor const file_hackathon_messages_team_svc_create_submission_request_proto_rawDesc = "" + "\n" + - ";hackathon/messages/team_svc/create_submission_request.proto\x12\x1bhackathon.messages.team_svc\"y\n" + + ";hackathon/messages/team_svc/create_submission_request.proto\x12\x1bhackathon.messages.team_svc\"\x83\x02\n" + "\x17CreateSubmissionRequest\x12\x17\n" + "\ateam_id\x18\x01 \x01(\tR\x06teamId\x12\x1d\n" + "\n" + "project_id\x18\x02 \x01(\tR\tprojectId\x12\x1b\n" + - "\x06result\x18\x03 \x01(\tH\x00R\x06result\x88\x01\x01B\t\n" + - "\a_resultBjZhgithub.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/team_svcb\x06proto3" + "\x06result\x18\x03 \x01(\tH\x00R\x06result\x88\x01\x01\x127\n" + + "\x15attachment_folder_url\x18\x04 \x01(\tH\x01R\x13attachmentFolderUrl\x88\x01\x01\x12%\n" + + "\vdescription\x18\x05 \x01(\tH\x02R\vdescription\x88\x01\x01B\t\n" + + "\a_resultB\x18\n" + + "\x16_attachment_folder_urlB\x0e\n" + + "\f_descriptionBjZhgithub.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/team_svcb\x06proto3" var ( file_hackathon_messages_team_svc_create_submission_request_proto_rawDescOnce sync.Once diff --git a/components/backend/internal/service/mappers.go b/components/backend/internal/service/mappers.go index d861f3c6..7e09f1a8 100644 --- a/components/backend/internal/service/mappers.go +++ b/components/backend/internal/service/mappers.go @@ -251,6 +251,14 @@ func submissionEntryFromEnt(s *ent.Submission) *hackEnts.Submission { res := s.Result e.Result = &res } + if s.AttachmentFolderURL != "" { + url := s.AttachmentFolderURL + e.AttachmentFolderUrl = &url + } + if s.Description != "" { + desc := s.Description + e.Description = &desc + } if s.Edges.Modifier != nil { modID := s.Edges.Modifier.ID.String() e.ModifierId = &modID diff --git a/components/backend/internal/service/team_service.go b/components/backend/internal/service/team_service.go index d7c76511..72a3e50c 100644 --- a/components/backend/internal/service/team_service.go +++ b/components/backend/internal/service/team_service.go @@ -1012,6 +1012,8 @@ func (s *TeamService) CreateSubmission( SetTeamID(teamID). SetProjectID(projectID). SetResult(req.GetResult()). + SetAttachmentFolderURL(req.GetAttachmentFolderUrl()). + SetDescription(req.GetDescription()). SetStatus(entsubmission.StatusDraft). SetVersion(version + 1). SetCreatorID(u.ID). diff --git a/components/backend/internal/service/team_service_test.go b/components/backend/internal/service/team_service_test.go index 57fb6341..42737202 100644 --- a/components/backend/internal/service/team_service_test.go +++ b/components/backend/internal/service/team_service_test.go @@ -1150,9 +1150,11 @@ var _ = Describe("TeamService", func() { ) resp, err := teamClient.CreateSubmission(ctx, &teamMsgs.CreateSubmissionRequest{ - TeamId: teamID, - ProjectId: projectID, - Result: testutils.StringPtr("https://github.com/test/repo"), + TeamId: teamID, + ProjectId: projectID, + Result: testutils.StringPtr("https://github.com/test/repo"), + AttachmentFolderUrl: testutils.StringPtr("https://drive.example.com/folder"), + Description: testutils.StringPtr("What we built and why."), }) Expect(err).NotTo(HaveOccurred()) Expect(resp.GetId()).NotTo(BeEmpty()) @@ -1164,6 +1166,9 @@ var _ = Describe("TeamService", func() { Expect(err).NotTo(HaveOccurred()) Expect(s.Version).To(Equal(1)) Expect(s.Status).To(Equal(entsubmission.StatusDraft)) + Expect(s.Result).To(Equal("https://github.com/test/repo")) + Expect(s.AttachmentFolderURL).To(Equal("https://drive.example.com/folder")) + Expect(s.Description).To(Equal("What we built and why.")) }) It("increments version on subsequent submissions", func() { @@ -1445,16 +1450,20 @@ var _ = Describe("TeamService", func() { ) _, err = teamClient.CreateSubmission(ctx, &teamMsgs.CreateSubmissionRequest{ - TeamId: teamID, - ProjectId: projectID, - Result: testutils.StringPtr("https://github.com/test/repo/v1"), + TeamId: teamID, + ProjectId: projectID, + Result: testutils.StringPtr("https://github.com/test/repo/v1"), + AttachmentFolderUrl: testutils.StringPtr("https://drive.example.com/v1"), + Description: testutils.StringPtr("Description v1"), }) Expect(err).NotTo(HaveOccurred()) _, err = teamClient.CreateSubmission(ctx, &teamMsgs.CreateSubmissionRequest{ - TeamId: teamID, - ProjectId: projectID, - Result: testutils.StringPtr("https://github.com/test/repo/v2"), + TeamId: teamID, + ProjectId: projectID, + Result: testutils.StringPtr("https://github.com/test/repo/v2"), + AttachmentFolderUrl: testutils.StringPtr("https://drive.example.com/v2"), + Description: testutils.StringPtr("Description v2"), }) Expect(err).NotTo(HaveOccurred()) }) @@ -1473,6 +1482,10 @@ var _ = Describe("TeamService", func() { Expect(resp.GetSubmission()).NotTo(BeNil()) Expect(resp.GetSubmission().GetVersion()).To(Equal(int32(2))) Expect(resp.GetSubmission().GetResult()).To(Equal("https://github.com/test/repo/v2")) + Expect( + resp.GetSubmission().GetAttachmentFolderUrl(), + ).To(Equal("https://drive.example.com/v2")) + Expect(resp.GetSubmission().GetDescription()).To(Equal("Description v2")) }) It("returns NOT_FOUND when no submission exists for team", func() { diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/entities/submission.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/entities/submission.ts index b6e4cc72..3b6afdc6 100644 --- a/components/frontend/src/lib/server/grpc/generated/hackathon/entities/submission.ts +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/entities/submission.ts @@ -13,6 +13,10 @@ export const protobufPackage = "hackathon.entities"; export interface Submission { id: string; + /** + * URL of the repository holding the submission's output. + * TODO: rename to `repository_url` after the hackathon. + */ result?: string | undefined; status: SubmissionStatus; version: number; @@ -22,6 +26,8 @@ export interface Submission { projectId: string; creatorId: string; modifierId?: string | undefined; + attachmentFolderUrl?: string | undefined; + description?: string | undefined; } function createBaseSubmission(): Submission { @@ -36,6 +42,8 @@ function createBaseSubmission(): Submission { projectId: "", creatorId: "", modifierId: undefined, + attachmentFolderUrl: undefined, + description: undefined, }; } @@ -71,6 +79,12 @@ export const Submission: MessageFns = { if (message.modifierId !== undefined) { writer.uint32(82).string(message.modifierId); } + if (message.attachmentFolderUrl !== undefined) { + writer.uint32(90).string(message.attachmentFolderUrl); + } + if (message.description !== undefined) { + writer.uint32(98).string(message.description); + } return writer; }, @@ -161,6 +175,22 @@ export const Submission: MessageFns = { message.modifierId = reader.string(); continue; } + case 11: { + if (tag !== 90) { + break; + } + + message.attachmentFolderUrl = reader.string(); + continue; + } + case 12: { + if (tag !== 98) { + break; + } + + message.description = reader.string(); + continue; + } } if ((tag & 7) === 4 || tag === 0) { break; @@ -206,6 +236,12 @@ export const Submission: MessageFns = { : isSet(object.modifier_id) ? globalThis.String(object.modifier_id) : undefined, + attachmentFolderUrl: isSet(object.attachmentFolderUrl) + ? globalThis.String(object.attachmentFolderUrl) + : isSet(object.attachment_folder_url) + ? globalThis.String(object.attachment_folder_url) + : undefined, + description: isSet(object.description) ? globalThis.String(object.description) : undefined, }; }, @@ -241,6 +277,12 @@ export const Submission: MessageFns = { if (message.modifierId !== undefined) { obj.modifierId = message.modifierId; } + if (message.attachmentFolderUrl !== undefined) { + obj.attachmentFolderUrl = message.attachmentFolderUrl; + } + if (message.description !== undefined) { + obj.description = message.description; + } return obj; }, @@ -259,6 +301,8 @@ export const Submission: MessageFns = { message.projectId = object.projectId ?? ""; message.creatorId = object.creatorId ?? ""; message.modifierId = object.modifierId ?? undefined; + message.attachmentFolderUrl = object.attachmentFolderUrl ?? undefined; + message.description = object.description ?? undefined; return message; }, }; diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/team_svc/create_submission_request.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/team_svc/create_submission_request.ts index db5e80f1..c9cabced 100644 --- a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/team_svc/create_submission_request.ts +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/team_svc/create_submission_request.ts @@ -12,11 +12,17 @@ export const protobufPackage = "hackathon.messages.team_svc"; export interface CreateSubmissionRequest { teamId: string; projectId: string; + /** + * URL of the repository holding the submission's output. + * TODO: rename to `repository_url` after the hackathon. + */ result?: string | undefined; + attachmentFolderUrl?: string | undefined; + description?: string | undefined; } function createBaseCreateSubmissionRequest(): CreateSubmissionRequest { - return { teamId: "", projectId: "", result: undefined }; + return { teamId: "", projectId: "", result: undefined, attachmentFolderUrl: undefined, description: undefined }; } export const CreateSubmissionRequest: MessageFns = { @@ -30,6 +36,12 @@ export const CreateSubmissionRequest: MessageFns = { if (message.result !== undefined) { writer.uint32(26).string(message.result); } + if (message.attachmentFolderUrl !== undefined) { + writer.uint32(34).string(message.attachmentFolderUrl); + } + if (message.description !== undefined) { + writer.uint32(42).string(message.description); + } return writer; }, @@ -64,6 +76,22 @@ export const CreateSubmissionRequest: MessageFns = { message.result = reader.string(); continue; } + case 4: { + if (tag !== 34) { + break; + } + + message.attachmentFolderUrl = reader.string(); + continue; + } + case 5: { + if (tag !== 42) { + break; + } + + message.description = reader.string(); + continue; + } } if ((tag & 7) === 4 || tag === 0) { break; @@ -86,6 +114,12 @@ export const CreateSubmissionRequest: MessageFns = { ? globalThis.String(object.project_id) : "", result: isSet(object.result) ? globalThis.String(object.result) : undefined, + attachmentFolderUrl: isSet(object.attachmentFolderUrl) + ? globalThis.String(object.attachmentFolderUrl) + : isSet(object.attachment_folder_url) + ? globalThis.String(object.attachment_folder_url) + : undefined, + description: isSet(object.description) ? globalThis.String(object.description) : undefined, }; }, @@ -100,6 +134,12 @@ export const CreateSubmissionRequest: MessageFns = { if (message.result !== undefined) { obj.result = message.result; } + if (message.attachmentFolderUrl !== undefined) { + obj.attachmentFolderUrl = message.attachmentFolderUrl; + } + if (message.description !== undefined) { + obj.description = message.description; + } return obj; }, @@ -111,6 +151,8 @@ export const CreateSubmissionRequest: MessageFns = { message.teamId = object.teamId ?? ""; message.projectId = object.projectId ?? ""; message.result = object.result ?? undefined; + message.attachmentFolderUrl = object.attachmentFolderUrl ?? undefined; + message.description = object.description ?? undefined; return message; }, };