From e4a1e5f50a3719fce21329723f2e0c1441aeb3d8 Mon Sep 17 00:00:00 2001 From: Ralf Grubenmann Date: Mon, 24 Aug 2026 14:58:41 +0200 Subject: [PATCH 1/3] feat: support invites for private hackathons --- .../hackathon/entities/hackathon_invite.proto | 16 ++ api/proto/hackathon/hackathon_service.proto | 12 + .../hackathon_svc/create_invite_request.proto | 14 + .../create_invite_response.proto | 11 + .../messages/hackathon_svc/join_request.proto | 1 + .../hackathon_svc/list_invites_request.proto | 11 + .../hackathon_svc/list_invites_response.proto | 11 + .../preview_invite_request.proto | 12 + .../preview_invite_response.proto | 14 + .../hackathon_svc/revoke_invite_request.proto | 11 + .../revoke_invite_response.proto | 7 + .../backend/db/schema/hackathoninvite.go | 68 +++++ components/backend/db/schema/user.go | 3 + .../internal/service/hackathon_service.go | 269 +++++++++++++++++- .../backend/internal/service/mappers.go | 19 ++ 15 files changed, 475 insertions(+), 4 deletions(-) create mode 100644 api/proto/hackathon/entities/hackathon_invite.proto create mode 100644 api/proto/hackathon/messages/hackathon_svc/create_invite_request.proto create mode 100644 api/proto/hackathon/messages/hackathon_svc/create_invite_response.proto create mode 100644 api/proto/hackathon/messages/hackathon_svc/list_invites_request.proto create mode 100644 api/proto/hackathon/messages/hackathon_svc/list_invites_response.proto create mode 100644 api/proto/hackathon/messages/hackathon_svc/preview_invite_request.proto create mode 100644 api/proto/hackathon/messages/hackathon_svc/preview_invite_response.proto create mode 100644 api/proto/hackathon/messages/hackathon_svc/revoke_invite_request.proto create mode 100644 api/proto/hackathon/messages/hackathon_svc/revoke_invite_response.proto create mode 100644 components/backend/db/schema/hackathoninvite.go diff --git a/api/proto/hackathon/entities/hackathon_invite.proto b/api/proto/hackathon/entities/hackathon_invite.proto new file mode 100644 index 00000000..02b0e7a4 --- /dev/null +++ b/api/proto/hackathon/entities/hackathon_invite.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package hackathon.entities; + +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/entities"; + +message HackathonInvite { + string id = 1; + string token = 2; + optional string note = 3; + google.protobuf.Timestamp created_at = 4; + optional google.protobuf.Timestamp revoked_at = 5; + optional google.protobuf.Timestamp expires_at = 6; +} \ No newline at end of file diff --git a/api/proto/hackathon/hackathon_service.proto b/api/proto/hackathon/hackathon_service.proto index a488df27..769112d0 100644 --- a/api/proto/hackathon/hackathon_service.proto +++ b/api/proto/hackathon/hackathon_service.proto @@ -16,9 +16,17 @@ import "hackathon/messages/hackathon_svc/edit_request.proto"; import "hackathon/messages/hackathon_svc/edit_response.proto"; import "hackathon/messages/hackathon_svc/get_request.proto"; import "hackathon/messages/hackathon_svc/get_response.proto"; +import "hackathon/messages/hackathon_svc/create_invite_request.proto"; +import "hackathon/messages/hackathon_svc/create_invite_response.proto"; import "hackathon/messages/hackathon_svc/join_request.proto"; import "hackathon/messages/hackathon_svc/join_response.proto"; +import "hackathon/messages/hackathon_svc/list_invites_request.proto"; +import "hackathon/messages/hackathon_svc/list_invites_response.proto"; import "hackathon/messages/hackathon_svc/list_participant_answers_request.proto"; +import "hackathon/messages/hackathon_svc/preview_invite_request.proto"; +import "hackathon/messages/hackathon_svc/preview_invite_response.proto"; +import "hackathon/messages/hackathon_svc/revoke_invite_request.proto"; +import "hackathon/messages/hackathon_svc/revoke_invite_response.proto"; import "hackathon/messages/hackathon_svc/list_participant_answers_response.proto"; import "hackathon/messages/hackathon_svc/list_questions_request.proto"; import "hackathon/messages/hackathon_svc/list_questions_response.proto"; @@ -46,6 +54,10 @@ service HackathonService { rpc Edit(hackathon.messages.hackathon_svc.EditRequest) returns (hackathon.messages.hackathon_svc.EditResponse); rpc SetCapabilities(hackathon.messages.hackathon_svc.SetCapabilitiesRequest) returns (hackathon.messages.hackathon_svc.SetCapabilitiesResponse); rpc SetCurrentPhase(hackathon.messages.hackathon_svc.SetCurrentPhaseRequest) returns (hackathon.messages.hackathon_svc.SetCurrentPhaseResponse); + rpc CreateInvite(hackathon.messages.hackathon_svc.CreateInviteRequest) returns (hackathon.messages.hackathon_svc.CreateInviteResponse); + rpc ListInvites(hackathon.messages.hackathon_svc.ListInvitesRequest) returns (hackathon.messages.hackathon_svc.ListInvitesResponse); + rpc RevokeInvite(hackathon.messages.hackathon_svc.RevokeInviteRequest) returns (hackathon.messages.hackathon_svc.RevokeInviteResponse); + rpc PreviewInvite(hackathon.messages.hackathon_svc.PreviewInviteRequest) returns (hackathon.messages.hackathon_svc.PreviewInviteResponse); rpc Join(hackathon.messages.hackathon_svc.JoinRequest) returns (hackathon.messages.hackathon_svc.JoinResponse); rpc ApproveParticipant(hackathon.messages.hackathon_svc.ApproveParticipantRequest) returns (hackathon.messages.hackathon_svc.ApproveParticipantResponse); rpc RemoveParticipant(hackathon.messages.hackathon_svc.RemoveParticipantRequest) returns (hackathon.messages.hackathon_svc.RemoveParticipantResponse); diff --git a/api/proto/hackathon/messages/hackathon_svc/create_invite_request.proto b/api/proto/hackathon/messages/hackathon_svc/create_invite_request.proto new file mode 100644 index 00000000..193dc695 --- /dev/null +++ b/api/proto/hackathon/messages/hackathon_svc/create_invite_request.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package hackathon.messages.hackathon_svc; + +import "buf/validate/validate.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svc"; + +message CreateInviteRequest { + string hackathon_id = 1 [(buf.validate.field).string.uuid = true]; + optional string note = 2 [(buf.validate.field).string.max_len = 500]; + optional google.protobuf.Timestamp expires_at = 3; +} \ No newline at end of file diff --git a/api/proto/hackathon/messages/hackathon_svc/create_invite_response.proto b/api/proto/hackathon/messages/hackathon_svc/create_invite_response.proto new file mode 100644 index 00000000..c7f2b5ae --- /dev/null +++ b/api/proto/hackathon/messages/hackathon_svc/create_invite_response.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package hackathon.messages.hackathon_svc; + +import "hackathon/entities/hackathon_invite.proto"; + +option go_package = "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svc"; + +message CreateInviteResponse { + hackathon.entities.HackathonInvite invite = 1; +} \ No newline at end of file diff --git a/api/proto/hackathon/messages/hackathon_svc/join_request.proto b/api/proto/hackathon/messages/hackathon_svc/join_request.proto index 709975ed..1c9d6b6c 100644 --- a/api/proto/hackathon/messages/hackathon_svc/join_request.proto +++ b/api/proto/hackathon/messages/hackathon_svc/join_request.proto @@ -10,4 +10,5 @@ option go_package = "github.com/swissdatasciencecenter/hackagon/components/backe message JoinRequest { string hackathon_id = 1 [(buf.validate.field).string.uuid = true]; repeated hackathon.entities.Answer answers = 2; + optional string invite_token = 3; } diff --git a/api/proto/hackathon/messages/hackathon_svc/list_invites_request.proto b/api/proto/hackathon/messages/hackathon_svc/list_invites_request.proto new file mode 100644 index 00000000..7ab8551f --- /dev/null +++ b/api/proto/hackathon/messages/hackathon_svc/list_invites_request.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package hackathon.messages.hackathon_svc; + +import "buf/validate/validate.proto"; + +option go_package = "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svc"; + +message ListInvitesRequest { + string hackathon_id = 1 [(buf.validate.field).string.uuid = true]; +} \ No newline at end of file diff --git a/api/proto/hackathon/messages/hackathon_svc/list_invites_response.proto b/api/proto/hackathon/messages/hackathon_svc/list_invites_response.proto new file mode 100644 index 00000000..63b78959 --- /dev/null +++ b/api/proto/hackathon/messages/hackathon_svc/list_invites_response.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package hackathon.messages.hackathon_svc; + +import "hackathon/entities/hackathon_invite.proto"; + +option go_package = "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svc"; + +message ListInvitesResponse { + repeated hackathon.entities.HackathonInvite invites = 1; +} \ No newline at end of file diff --git a/api/proto/hackathon/messages/hackathon_svc/preview_invite_request.proto b/api/proto/hackathon/messages/hackathon_svc/preview_invite_request.proto new file mode 100644 index 00000000..8f881340 --- /dev/null +++ b/api/proto/hackathon/messages/hackathon_svc/preview_invite_request.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +package hackathon.messages.hackathon_svc; + +import "buf/validate/validate.proto"; + +option go_package = "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svc"; + +message PreviewInviteRequest { + // The invite token — the only credential. No hackathon_id to prevent probing. + string token = 1 [(buf.validate.field).string.uuid = true]; +} \ No newline at end of file diff --git a/api/proto/hackathon/messages/hackathon_svc/preview_invite_response.proto b/api/proto/hackathon/messages/hackathon_svc/preview_invite_response.proto new file mode 100644 index 00000000..584b852e --- /dev/null +++ b/api/proto/hackathon/messages/hackathon_svc/preview_invite_response.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package hackathon.messages.hackathon_svc; + +import "hackathon/entities/hackathon.proto"; +import "hackathon/entities/question.proto"; + +option go_package = "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svc"; + +message PreviewInviteResponse { + hackathon.entities.Hackathon hackathon = 1; + repeated hackathon.entities.Question questions = 2; + bool already_participant = 3; +} \ No newline at end of file diff --git a/api/proto/hackathon/messages/hackathon_svc/revoke_invite_request.proto b/api/proto/hackathon/messages/hackathon_svc/revoke_invite_request.proto new file mode 100644 index 00000000..f7d247ed --- /dev/null +++ b/api/proto/hackathon/messages/hackathon_svc/revoke_invite_request.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package hackathon.messages.hackathon_svc; + +import "buf/validate/validate.proto"; + +option go_package = "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svc"; + +message RevokeInviteRequest { + string invite_id = 1 [(buf.validate.field).string.uuid = true]; +} \ No newline at end of file diff --git a/api/proto/hackathon/messages/hackathon_svc/revoke_invite_response.proto b/api/proto/hackathon/messages/hackathon_svc/revoke_invite_response.proto new file mode 100644 index 00000000..39149384 --- /dev/null +++ b/api/proto/hackathon/messages/hackathon_svc/revoke_invite_response.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +package hackathon.messages.hackathon_svc; + +option go_package = "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svc"; + +message RevokeInviteResponse {} \ No newline at end of file diff --git a/components/backend/db/schema/hackathoninvite.go b/components/backend/db/schema/hackathoninvite.go new file mode 100644 index 00000000..995da15f --- /dev/null +++ b/components/backend/db/schema/hackathoninvite.go @@ -0,0 +1,68 @@ +package schema + +import ( + "time" + + "entgo.io/ent" + "entgo.io/ent/schema" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "github.com/google/uuid" +) + +// HackathonInvite holds the schema definition for the HackathonInvite entity. +type HackathonInvite struct { + ent.Schema +} + +func (HackathonInvite) Annotations() []schema.Annotation { + return []schema.Annotation{ + schema.Comment("An invite for a hackathon."), + } +} + +// Fields of the HackathonInvite. +func (HackathonInvite) Fields() []ent.Field { + return []ent.Field{ + field.Time("created_at"). + Immutable(). + Default(time.Now), + field.Time("revoked_at"). + Optional(). + Nillable(), + field.UUID("token", uuid.UUID{}). + Unique(). + Default(func() uuid.UUID { + id, err := uuid.NewV7() + if err != nil { + panic(err) + } + return id + }), + field.String("note"). + Optional(). + MaxLen(500), + field.Time("expires_at"). + Optional(). + Nillable(), + } +} + +// Edges of the HackathonInvite. +func (HackathonInvite) Edges() []ent.Edge { + return []ent.Edge{ + edge.To("hackathon", Hackathon.Type). + Unique().Required().Immutable(). + Field("hackathon_id"). + Comment("The hackathon this invite grants access to."), + edge.From("creator", User.Type). + Ref("created_hackathon_invites").Unique().Required().Immutable(). + Comment("The user who created this invite."), + } +} + +func (HackathonInvite) Mixin() []ent.Mixin { + return []ent.Mixin{ + UUIDMixin{}, + } +} diff --git a/components/backend/db/schema/user.go b/components/backend/db/schema/user.go index 69453576..accb5f6c 100644 --- a/components/backend/db/schema/user.go +++ b/components/backend/db/schema/user.go @@ -46,6 +46,9 @@ func (User) Edges() []ent.Edge { edge.To("created_hackathons", Hackathon.Type). Annotations(entsql.OnDelete(entsql.Restrict)). Comment("Hackathons this user created."), + edge.To("created_hackathon_invites", HackathonInvite.Type). + Annotations(entsql.OnDelete(entsql.Restrict)). + Comment("Invites this user created."), edge.To("modified_hackathons", Hackathon.Type). Annotations(entsql.OnDelete(entsql.Restrict)). Comment("Hackathons this user last modified."), diff --git a/components/backend/internal/service/hackathon_service.go b/components/backend/internal/service/hackathon_service.go index 22e4d4af..6944e66e 100644 --- a/components/backend/internal/service/hackathon_service.go +++ b/components/backend/internal/service/hackathon_service.go @@ -10,6 +10,7 @@ import ( entanswer "github.com/swissdatasciencecenter/hackagon/components/backend/ent/answer" enthackathon "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" enthackathonstate "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathonstate" + enthackathoninvite "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" entparticipant "github.com/swissdatasciencecenter/hackagon/components/backend/ent/participant" entphase "github.com/swissdatasciencecenter/hackagon/components/backend/ent/phase" entquestion "github.com/swissdatasciencecenter/hackagon/components/backend/ent/question" @@ -223,6 +224,234 @@ func (s *HackathonService) Get( return &msgs.GetResponse{Hackathon: entry}, nil } + +// --- Invite RPCs --- + +func (s *HackathonService) CreateInvite( + ctx context.Context, + req *msgs.CreateInviteRequest, +) (*msgs.CreateInviteResponse, error) { + uid, _, err := mw.RequireSubject(ctx) + if err != nil { + return nil, err + } + + id, err := uuid.Parse(req.GetHackathonId()) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid hackathon_id: %v", err) + } + if err := s.enforcer.RequirePermission(ctx, id.String(), mw.Hackathon, mw.Write); err != nil { + return nil, err + } + + // Fetch hackathon (exists check + ends_at for default expires_at) + h, err := s.dbClient.Hackathon.Query().Where(enthackathon.IDEQ(id)).Only(ctx) + if err != nil { + if ent.IsNotFound(err) { + return nil, status.Errorf(codes.NotFound, "hackathon %s not found", req.GetHackathonId()) + } + slog.Error("query hackathon", "err", err) + return nil, status.Error(codes.Internal, "couldn't query database") + } + + // Resolve user entity for the creator edge + user, err := s.dbClient.User.Query().Where(entuser.KeycloakIDEQ(uid)).Only(ctx) + if err != nil { + if ent.IsNotFound(err) { + return nil, status.Errorf(codes.NotFound, "user %s not found", uid) + } + slog.Error("query user", "err", err) + return nil, status.Error(codes.Internal, "couldn't query database") + } + + // Build create query with expires_at resolved upfront + createQ := s.dbClient.HackathonInvite.Create(). + SetHackathonID(id). + SetCreatorID(user.ID) + + if note := req.GetNote(); note != "" { + createQ = createQ.SetNote(note) + } + + // Default expires_at to hackathon.ends_at when nil + if req.GetExpiresAt() == nil && h.EndsAt != nil { + createQ = createQ.SetExpiresAt(*h.EndsAt) + } + + invite, err := createQ.Save(ctx) + if err != nil { + slog.Error("create invite", "err", err) + return nil, status.Error(codes.Internal, "couldn't create invite") + } + + return &msgs.CreateInviteResponse{Invite: hackathonInviteEntryFromEnt(invite)}, nil +} + +func (s *HackathonService) ListInvites( + ctx context.Context, + req *msgs.ListInvitesRequest, +) (*msgs.ListInvitesResponse, error) { + uid, _, err := mw.RequireSubject(ctx) + if err != nil { + return nil, err + } + + id, err := uuid.Parse(req.GetHackathonId()) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid hackathon_id: %v", err) + } + if err := s.enforcer.RequirePermission(ctx, id.String(), mw.Hackathon, mw.Write); err != nil { + return nil, err + } + + invites, err := s.dbClient.HackathonInvite.Query(). + Where(enthackathoninvite.HackathonIDEQ(id)). + All(ctx) + if err != nil { + slog.Error("query invites", "err", err) + return nil, status.Error(codes.Internal, "couldn't query invites") + } + + entries := make([]*hackEnts.HackathonInvite, 0, len(invites)) + for _, i := range invites { + entries = append(entries, hackathonInviteEntryFromEnt(i)) + } + + return &msgs.ListInvitesResponse{Invites: entries}, nil +} + +func (s *HackathonService) RevokeInvite( + ctx context.Context, + req *msgs.RevokeInviteRequest, +) (*msgs.RevokeInviteResponse, error) { + uid, _, err := mw.RequireSubject(ctx) + if err != nil { + return nil, err + } + + inviteID, err := uuid.Parse(req.GetInviteId()) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid invite_id: %v", err) + } + + invite, err := s.dbClient.HackathonInvite.Query(). + Where(enthackathoninvite.IDEQ(inviteID)). + Only(ctx) + if err != nil { + if ent.IsNotFound(err) { + return nil, status.Errorf(codes.NotFound, "invite %s not found", req.GetInviteId()) + } + slog.Error("query invite", "err", err) + return nil, status.Error(codes.Internal, "couldn't query invite") + } + + // Check write permission on the invite's hackathon + hackID := invite.HackathonID + if err := s.enforcer.RequirePermission(ctx, hackID.String(), mw.Hackathon, mw.Write); err != nil { + return nil, err + } + + // Idempotent: if already revoked, just succeed + if invite.RevokedAt != nil { + return &msgs.RevokeInviteResponse{}, nil + } + + _, err = s.dbClient.HackathonInvite.Update().Where(enthackathoninvite.IDEQ(inviteID)). + SetRevokedAt(time.Now()). + Save(ctx) + if err != nil { + slog.Error("revoke invite", "err", err) + return nil, status.Error(codes.Internal, "couldn't revoke invite") + } + + return &msgs.RevokeInviteResponse{}, nil +} + +func (s *HackathonService) PreviewInvite( + ctx context.Context, + req *msgs.PreviewInviteRequest, +) (*msgs.PreviewInviteResponse, error) { + token := req.GetToken() + tokenID, err := uuid.Parse(token) + if err != nil { + return nil, status.Error(codes.NotFound, "invalid or expired invitation") + } + + invite, err := s.dbClient.HackathonInvite.Query(). + Where(enthackathoninvite.Token(tokenID.String())). + Only(ctx) + if err != nil { + if ent.IsNotFound(err) { + return nil, status.Error(codes.NotFound, "invalid or expired invitation") + } + slog.Error("query invite", "err", err) + return nil, status.Error(codes.Internal, "couldn't query invite") + } + + // Check not revoked + if invite.RevokedAt != nil { + return nil, status.Error(codes.NotFound, "invalid or expired invitation") + } + + // Check not expired + if invite.ExpiresAt != nil && invite.ExpiresAt.Before(time.Now()) { + return nil, status.Error(codes.NotFound, "invalid or expired invitation") + } + + hackID := invite.HackathonID + + // Get shallow hackathon + h, err := s.dbClient.Hackathon.Query(). + Where(enthackathon.IDEQ(hackID)). + Only(ctx) + if err != nil { + if ent.IsNotFound(err) { + return nil, status.Error(codes.NotFound, "invalid or expired invitation") + } + slog.Error("query hackathon", "err", err) + return nil, status.Error(codes.Internal, "couldn't query hackathon") + } + + hackEntry := hackathonEntryFromEnt(h, time.Now()) + + // Get questions for this hackathon + questions, err := s.dbClient.Question.Query(). + Where(entquestion.HackathonIDEQ(hackID)). + All(ctx) + if err != nil { + slog.Error("query questions", "err", err) + return nil, status.Error(codes.Internal, "couldn't query questions") + } + + qEntries := make([]*hackEnts.Question, 0, len(questions)) + for _, q := range questions { + qEntries = append(qEntries, questionEntryFromEnt(q)) + } + + // Check if caller is already a participant + alreadyParticipant := false + uid, _, _ := mw.RequireSubject(ctx) + if uid != mw.AnonSubject { + user, err := s.dbClient.User.Query().Where(entuser.KeycloakIDEQ(uid)).Only(ctx) + if err == nil { + _, err := s.dbClient.Participant.Query(). + Where( + entparticipant.HackathonIDEQ(hackID), + entparticipant.UserID(user.ID), + ).Only(ctx) + if err == nil { + alreadyParticipant = true + } + } + } + + return &msgs.PreviewInviteResponse{ + Hackathon: hackEntry, + Questions: qEntries, + AlreadyParticipant: alreadyParticipant, + }, nil +} + func (s *HackathonService) Join( ctx context.Context, req *msgs.JoinRequest, @@ -241,10 +470,6 @@ func (s *HackathonService) Join( if err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid hackathon_id: %v", err) } - if err := s.enforcer.RequirePermission(ctx, id.String(), mw.Hackathon, mw.Join); err != nil { - return nil, err - } - // Check if hackathon exists and get it h, err := s.dbClient.Hackathon.Query().Where(enthackathon.IDEQ(id)).Only(ctx) if err != nil { @@ -260,6 +485,42 @@ func (s *HackathonService) Join( return nil, status.Error(codes.Internal, "couldn't query database") } + // Permission check: invite token OR casbin role. If either passes, allow. + // For private hackathons the invite is the admission ticket — without it + // the user has no casbin role and casbin would reject anyway. For public + // hackathons casbin handles everything. We check both and allow if either + // succeeds. + inviteValid := false + if h.Visibility == enthackathon.VisibilityPrivate { + inviteToken := req.GetInviteToken() + if inviteToken != "" { + inviteID, parseErr := uuid.Parse(inviteToken) + if parseErr == nil { + invite, err := s.dbClient.HackathonInvite.Query(). + Where( + enthackathoninvite.Token(inviteID.String()), + enthackathoninvite.HackathonIDEQ(id), + ).Only(ctx) + if err == nil && invite.RevokedAt == nil && (invite.ExpiresAt == nil || !invite.ExpiresAt.Before(time.Now())) { + inviteValid = true + } + } + } + } else { + // Public hackathons: no invite needed, rely on casbin + inviteValid = true + } + + casbinOk, err := s.enforcer.CheckPermission(uid, id.String(), mw.Hackathon, mw.Join) + if err != nil { + slog.Error("check permission", "err", err) + return nil, status.Error(codes.Internal, "authorization error") + } + + if !inviteValid && !casbinOk { + return nil, status.Error(codes.PermissionDenied, "invalid or expired invitation") + } + if h.EndsAt.Before(time.Now()) { return nil, status.Error(codes.FailedPrecondition, "hackathon is already finished") } diff --git a/components/backend/internal/service/mappers.go b/components/backend/internal/service/mappers.go index 31ad08c9..b8798ce1 100644 --- a/components/backend/internal/service/mappers.go +++ b/components/backend/internal/service/mappers.go @@ -6,6 +6,7 @@ import ( "github.com/google/uuid" "github.com/swissdatasciencecenter/hackagon/components/backend/ent" enthackathon "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" + enthackathoninvite "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" entquestion "github.com/swissdatasciencecenter/hackagon/components/backend/ent/question" entvote "github.com/swissdatasciencecenter/hackagon/components/backend/ent/vote" entvotecategory "github.com/swissdatasciencecenter/hackagon/components/backend/ent/votecategory" @@ -529,6 +530,24 @@ func questionEntryFromEnt(q *ent.Question) *hackEnts.Question { } } +func hackathonInviteEntryFromEnt(i *enthackathoninvite.HackathonInvite) *hackEnts.HackathonInvite { + e := &hackEnts.HackathonInvite{ + Id: i.ID.String(), + Token: i.Token, + CreatedAt: timestamppb.New(i.CreatedAt), + } + if i.Note != "" { + e.Note = &i.Note + } + if i.RevokedAt != nil { + e.RevokedAt = timestamppb.New(*i.RevokedAt) + } + if i.ExpiresAt != nil { + e.ExpiresAt = timestamppb.New(*i.ExpiresAt) + } + return e +} + func answerEntryFromEnt(a *ent.Answer) *hackEnts.Answer { entry := &hackEnts.Answer{ QuestionId: a.QuestionID.String(), From 6aea0645d276871e1ff22f1e60666ddff8fc3197 Mon Sep 17 00:00:00 2001 From: Ralf Grubenmann Date: Mon, 24 Aug 2026 16:08:12 +0200 Subject: [PATCH 2/3] add tests --- api/proto/API.md | 315 +++++++ components/backend/Schema.md | 22 + .../backend/db/schema/hackathoninvite.go | 1 - components/backend/ent/client.go | 213 ++++- components/backend/ent/ent.go | 2 + components/backend/ent/hackathoninvite.go | 225 +++++ .../ent/hackathoninvite/hackathoninvite.go | 152 ++++ .../backend/ent/hackathoninvite/where.go | 398 ++++++++ .../backend/ent/hackathoninvite_create.go | 855 ++++++++++++++++++ .../backend/ent/hackathoninvite_delete.go | 88 ++ .../backend/ent/hackathoninvite_query.go | 690 ++++++++++++++ .../backend/ent/hackathoninvite_update.go | 405 +++++++++ components/backend/ent/hook/hook.go | 12 + components/backend/ent/migrate/schema.go | 34 + components/backend/ent/mutation.go | 825 ++++++++++++++++- components/backend/ent/predicate/predicate.go | 3 + components/backend/ent/runtime/runtime.go | 22 + components/backend/ent/tx.go | 3 + components/backend/ent/user.go | 68 +- components/backend/ent/user/user.go | 30 + components/backend/ent/user/where.go | 23 + components/backend/ent/user_create.go | 32 + components/backend/ent/user_query.go | 79 +- components/backend/ent/user_update.go | 163 ++++ components/backend/go.sum | 26 + .../hackathon/entities/hackathon_invite.pb.go | 179 ++++ .../proto/hackathon/hackathon_service.pb.go | 140 +-- .../hackathon/hackathon_service_grpc.pb.go | 152 ++++ .../hackathon_svc/create_invite_request.pb.go | 148 +++ .../create_invite_response.pb.go | 125 +++ .../messages/hackathon_svc/join_request.pb.go | 15 +- .../hackathon_svc/list_invites_request.pb.go | 123 +++ .../hackathon_svc/list_invites_response.pb.go | 125 +++ .../preview_invite_request.pb.go | 124 +++ .../preview_invite_response.pb.go | 145 +++ .../hackathon_svc/revoke_invite_request.pb.go | 123 +++ .../revoke_invite_response.pb.go | 113 +++ .../service/hackathon_service_test.go | 628 ++++++++++++- .../hackathon/entities/hackathon_invite.ts | 215 +++++ .../generated/hackathon/hackathon_service.ts | 72 ++ .../hackathon_svc/create_invite_request.ts | 160 ++++ .../hackathon_svc/create_invite_response.ts | 96 ++ .../messages/hackathon_svc/join_request.ts | 23 +- .../hackathon_svc/list_invites_request.ts | 99 ++ .../hackathon_svc/list_invites_response.ts | 94 ++ .../hackathon_svc/preview_invite_request.ts | 94 ++ .../hackathon_svc/preview_invite_response.ts | 139 +++ .../hackathon_svc/revoke_invite_request.ts | 99 ++ .../hackathon_svc/revoke_invite_response.ts | 73 ++ 49 files changed, 7883 insertions(+), 107 deletions(-) create mode 100644 components/backend/ent/hackathoninvite.go create mode 100644 components/backend/ent/hackathoninvite/hackathoninvite.go create mode 100644 components/backend/ent/hackathoninvite/where.go create mode 100644 components/backend/ent/hackathoninvite_create.go create mode 100644 components/backend/ent/hackathoninvite_delete.go create mode 100644 components/backend/ent/hackathoninvite_query.go create mode 100644 components/backend/ent/hackathoninvite_update.go create mode 100644 components/backend/internal/proto/hackathon/entities/hackathon_invite.pb.go create mode 100644 components/backend/internal/proto/hackathon/messages/hackathon_svc/create_invite_request.pb.go create mode 100644 components/backend/internal/proto/hackathon/messages/hackathon_svc/create_invite_response.pb.go create mode 100644 components/backend/internal/proto/hackathon/messages/hackathon_svc/list_invites_request.pb.go create mode 100644 components/backend/internal/proto/hackathon/messages/hackathon_svc/list_invites_response.pb.go create mode 100644 components/backend/internal/proto/hackathon/messages/hackathon_svc/preview_invite_request.pb.go create mode 100644 components/backend/internal/proto/hackathon/messages/hackathon_svc/preview_invite_response.pb.go create mode 100644 components/backend/internal/proto/hackathon/messages/hackathon_svc/revoke_invite_request.pb.go create mode 100644 components/backend/internal/proto/hackathon/messages/hackathon_svc/revoke_invite_response.pb.go create mode 100644 components/frontend/src/lib/server/grpc/generated/hackathon/entities/hackathon_invite.ts create mode 100644 components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/create_invite_request.ts create mode 100644 components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/create_invite_response.ts create mode 100644 components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/list_invites_request.ts create mode 100644 components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/list_invites_response.ts create mode 100644 components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/preview_invite_request.ts create mode 100644 components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/preview_invite_response.ts create mode 100644 components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/revoke_invite_request.ts create mode 100644 components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/revoke_invite_response.ts diff --git a/api/proto/API.md b/api/proto/API.md index fc8864f3..b29c553d 100644 --- a/api/proto/API.md +++ b/api/proto/API.md @@ -49,6 +49,9 @@ - [hackathon/entities/hackathon.proto](#hackathon_entities_hackathon-proto) - [Hackathon](#hackathon-entities-Hackathon) +- [hackathon/entities/hackathon_invite.proto](#hackathon_entities_hackathon_invite-proto) + - [HackathonInvite](#hackathon-entities-HackathonInvite) + - [hackathon/entities/project_preference.proto](#hackathon_entities_project_preference-proto) - [ProjectWithPreferences](#hackathon-entities-ProjectWithPreferences) @@ -108,15 +111,39 @@ - [hackathon/messages/hackathon_svc/get_response.proto](#hackathon_messages_hackathon_svc_get_response-proto) - [GetResponse](#hackathon-messages-hackathon_svc-GetResponse) +- [hackathon/messages/hackathon_svc/create_invite_request.proto](#hackathon_messages_hackathon_svc_create_invite_request-proto) + - [CreateInviteRequest](#hackathon-messages-hackathon_svc-CreateInviteRequest) + +- [hackathon/messages/hackathon_svc/create_invite_response.proto](#hackathon_messages_hackathon_svc_create_invite_response-proto) + - [CreateInviteResponse](#hackathon-messages-hackathon_svc-CreateInviteResponse) + - [hackathon/messages/hackathon_svc/join_request.proto](#hackathon_messages_hackathon_svc_join_request-proto) - [JoinRequest](#hackathon-messages-hackathon_svc-JoinRequest) - [hackathon/messages/hackathon_svc/join_response.proto](#hackathon_messages_hackathon_svc_join_response-proto) - [JoinResponse](#hackathon-messages-hackathon_svc-JoinResponse) +- [hackathon/messages/hackathon_svc/list_invites_request.proto](#hackathon_messages_hackathon_svc_list_invites_request-proto) + - [ListInvitesRequest](#hackathon-messages-hackathon_svc-ListInvitesRequest) + +- [hackathon/messages/hackathon_svc/list_invites_response.proto](#hackathon_messages_hackathon_svc_list_invites_response-proto) + - [ListInvitesResponse](#hackathon-messages-hackathon_svc-ListInvitesResponse) + - [hackathon/messages/hackathon_svc/list_participant_answers_request.proto](#hackathon_messages_hackathon_svc_list_participant_answers_request-proto) - [ListParticipantAnswersRequest](#hackathon-messages-hackathon_svc-ListParticipantAnswersRequest) +- [hackathon/messages/hackathon_svc/preview_invite_request.proto](#hackathon_messages_hackathon_svc_preview_invite_request-proto) + - [PreviewInviteRequest](#hackathon-messages-hackathon_svc-PreviewInviteRequest) + +- [hackathon/messages/hackathon_svc/preview_invite_response.proto](#hackathon_messages_hackathon_svc_preview_invite_response-proto) + - [PreviewInviteResponse](#hackathon-messages-hackathon_svc-PreviewInviteResponse) + +- [hackathon/messages/hackathon_svc/revoke_invite_request.proto](#hackathon_messages_hackathon_svc_revoke_invite_request-proto) + - [RevokeInviteRequest](#hackathon-messages-hackathon_svc-RevokeInviteRequest) + +- [hackathon/messages/hackathon_svc/revoke_invite_response.proto](#hackathon_messages_hackathon_svc_revoke_invite_response-proto) + - [RevokeInviteResponse](#hackathon-messages-hackathon_svc-RevokeInviteResponse) + - [hackathon/messages/hackathon_svc/list_participant_answers_response.proto](#hackathon_messages_hackathon_svc_list_participant_answers_response-proto) - [ListParticipantAnswersResponse](#hackathon-messages-hackathon_svc-ListParticipantAnswersResponse) @@ -1139,6 +1166,42 @@ casbin role for this hackathon; `is_waiting` is false once approved. + +

Top

+ +## hackathon/entities/hackathon_invite.proto + + + + + +### HackathonInvite + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [string](#string) | | | +| token | [string](#string) | | | +| note | [string](#string) | optional | | +| created_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| revoked_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | optional | | +| expires_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | optional | | + + + + + + + + + + + + + + +

Top

@@ -1783,6 +1846,70 @@ casbin role for this hackathon; `is_waiting` is false once approved. + +

Top

+ +## hackathon/messages/hackathon_svc/create_invite_request.proto + + + + + +### CreateInviteRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| hackathon_id | [string](#string) | | | +| note | [string](#string) | optional | | +| expires_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | optional | | + + + + + + + + + + + + + + + + +

Top

+ +## hackathon/messages/hackathon_svc/create_invite_response.proto + + + + + +### CreateInviteResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| invite | [hackathon.entities.HackathonInvite](#hackathon-entities-HackathonInvite) | | | + + + + + + + + + + + + + + +

Top

@@ -1800,6 +1927,7 @@ casbin role for this hackathon; `is_waiting` is false once approved. | ----- | ---- | ----- | ----------- | | hackathon_id | [string](#string) | | | | answers | [hackathon.entities.Answer](#hackathon-entities-Answer) | repeated | | +| invite_token | [string](#string) | optional | | @@ -1846,6 +1974,68 @@ casbin role for this hackathon; `is_waiting` is false once approved. + +

Top

+ +## hackathon/messages/hackathon_svc/list_invites_request.proto + + + + + +### ListInvitesRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| hackathon_id | [string](#string) | | | + + + + + + + + + + + + + + + + +

Top

+ +## hackathon/messages/hackathon_svc/list_invites_response.proto + + + + + +### ListInvitesResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| invites | [hackathon.entities.HackathonInvite](#hackathon-entities-HackathonInvite) | repeated | | + + + + + + + + + + + + + + +

Top

@@ -1878,6 +2068,127 @@ casbin role for this hackathon; `is_waiting` is false once approved. + +

Top

+ +## hackathon/messages/hackathon_svc/preview_invite_request.proto + + + + + +### PreviewInviteRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token | [string](#string) | | The invite token — the only credential. No hackathon_id to prevent probing. | + + + + + + + + + + + + + + + + +

Top

+ +## hackathon/messages/hackathon_svc/preview_invite_response.proto + + + + + +### PreviewInviteResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| hackathon | [hackathon.entities.Hackathon](#hackathon-entities-Hackathon) | | | +| questions | [hackathon.entities.Question](#hackathon-entities-Question) | repeated | | +| already_participant | [bool](#bool) | | | + + + + + + + + + + + + + + + + +

Top

+ +## hackathon/messages/hackathon_svc/revoke_invite_request.proto + + + + + +### RevokeInviteRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| invite_id | [string](#string) | | | + + + + + + + + + + + + + + + + +

Top

+ +## hackathon/messages/hackathon_svc/revoke_invite_response.proto + + + + + +### RevokeInviteResponse + + + + + + + + + + + + + + + +

Top

@@ -2436,6 +2747,10 @@ casbin role for this hackathon; `is_waiting` is false once approved. | Edit | [messages.hackathon_svc.EditRequest](#hackathon-messages-hackathon_svc-EditRequest) | [messages.hackathon_svc.EditResponse](#hackathon-messages-hackathon_svc-EditResponse) | | | SetCapabilities | [messages.hackathon_svc.SetCapabilitiesRequest](#hackathon-messages-hackathon_svc-SetCapabilitiesRequest) | [messages.hackathon_svc.SetCapabilitiesResponse](#hackathon-messages-hackathon_svc-SetCapabilitiesResponse) | | | SetCurrentPhase | [messages.hackathon_svc.SetCurrentPhaseRequest](#hackathon-messages-hackathon_svc-SetCurrentPhaseRequest) | [messages.hackathon_svc.SetCurrentPhaseResponse](#hackathon-messages-hackathon_svc-SetCurrentPhaseResponse) | | +| CreateInvite | [messages.hackathon_svc.CreateInviteRequest](#hackathon-messages-hackathon_svc-CreateInviteRequest) | [messages.hackathon_svc.CreateInviteResponse](#hackathon-messages-hackathon_svc-CreateInviteResponse) | | +| ListInvites | [messages.hackathon_svc.ListInvitesRequest](#hackathon-messages-hackathon_svc-ListInvitesRequest) | [messages.hackathon_svc.ListInvitesResponse](#hackathon-messages-hackathon_svc-ListInvitesResponse) | | +| RevokeInvite | [messages.hackathon_svc.RevokeInviteRequest](#hackathon-messages-hackathon_svc-RevokeInviteRequest) | [messages.hackathon_svc.RevokeInviteResponse](#hackathon-messages-hackathon_svc-RevokeInviteResponse) | | +| PreviewInvite | [messages.hackathon_svc.PreviewInviteRequest](#hackathon-messages-hackathon_svc-PreviewInviteRequest) | [messages.hackathon_svc.PreviewInviteResponse](#hackathon-messages-hackathon_svc-PreviewInviteResponse) | | | Join | [messages.hackathon_svc.JoinRequest](#hackathon-messages-hackathon_svc-JoinRequest) | [messages.hackathon_svc.JoinResponse](#hackathon-messages-hackathon_svc-JoinResponse) | | | ApproveParticipant | [messages.hackathon_svc.ApproveParticipantRequest](#hackathon-messages-hackathon_svc-ApproveParticipantRequest) | [messages.hackathon_svc.ApproveParticipantResponse](#hackathon-messages-hackathon_svc-ApproveParticipantResponse) | | | RemoveParticipant | [messages.hackathon_svc.RemoveParticipantRequest](#hackathon-messages-hackathon_svc-RemoveParticipantRequest) | [messages.hackathon_svc.RemoveParticipantResponse](#hackathon-messages-hackathon_svc-RemoveParticipantResponse) | | diff --git a/components/backend/Schema.md b/components/backend/Schema.md index e8b78b77..7092652a 100644 --- a/components/backend/Schema.md +++ b/components/backend/Schema.md @@ -66,6 +66,27 @@ A hackathon event containing tracks, projects, phases, and participants. - `ends_at` - `visibility` +## HackathonInvite + +An invite for a hackathon. + +### Fields + +| Column | Type | Required | Unique | Immutable | Default | Description | +|--------|------|----------|--------|-----------|---------|-------------| +| `created_at` | time.Time | yes | no | yes | yes | | +| `revoked_at` | time.Time | no | no | no | no | | +| `token` | uuid.UUID | yes | yes | no | yes | | +| `note` | string | no | no | no | no | | +| `expires_at` | time.Time | no | no | no | no | | + +### Relationships + +| Edge | Target | Relation | Inverse | Required | Description | +|------|--------|----------|---------|----------|-------------| +| `hackathon` | Hackathon | M2O | no | yes | The hackathon this invite grants access to. | +| `creator` | User | M2O | yes | yes | The user who created this invite. | + ## HackathonState Configuration state for a hackathon. One row per hackathon, pre-created on hackathon creation. @@ -360,6 +381,7 @@ An authenticated user, synced from Keycloak on first login. | Edge | Target | Relation | Inverse | Required | Description | |------|--------|----------|---------|----------|-------------| | `created_hackathons` | Hackathon | O2M | no | no | Hackathons this user created. | +| `created_hackathon_invites` | HackathonInvite | O2M | no | no | Invites this user created. | | `modified_hackathons` | Hackathon | O2M | no | no | Hackathons this user last modified. | | `created_projects` | Project | O2M | no | no | Projects this user created. | | `modified_projects` | Project | O2M | no | no | Projects this user last modified. | diff --git a/components/backend/db/schema/hackathoninvite.go b/components/backend/db/schema/hackathoninvite.go index 995da15f..1d996619 100644 --- a/components/backend/db/schema/hackathoninvite.go +++ b/components/backend/db/schema/hackathoninvite.go @@ -53,7 +53,6 @@ func (HackathonInvite) Edges() []ent.Edge { return []ent.Edge{ edge.To("hackathon", Hackathon.Type). Unique().Required().Immutable(). - Field("hackathon_id"). Comment("The hackathon this invite grants access to."), edge.From("creator", User.Type). Ref("created_hackathon_invites").Unique().Required().Immutable(). diff --git a/components/backend/ent/client.go b/components/backend/ent/client.go index f5254fb0..378d9946 100644 --- a/components/backend/ent/client.go +++ b/components/backend/ent/client.go @@ -18,6 +18,7 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/answer" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathonstate" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/page" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/participant" @@ -43,6 +44,8 @@ type Client struct { Answer *AnswerClient // Hackathon is the client for interacting with the Hackathon builders. Hackathon *HackathonClient + // HackathonInvite is the client for interacting with the HackathonInvite builders. + HackathonInvite *HackathonInviteClient // HackathonState is the client for interacting with the HackathonState builders. HackathonState *HackathonStateClient // Page is the client for interacting with the Page builders. @@ -84,6 +87,7 @@ func (c *Client) init() { c.Schema = migrate.NewSchema(c.driver) c.Answer = NewAnswerClient(c.config) c.Hackathon = NewHackathonClient(c.config) + c.HackathonInvite = NewHackathonInviteClient(c.config) c.HackathonState = NewHackathonStateClient(c.config) c.Page = NewPageClient(c.config) c.Participant = NewParticipantClient(c.config) @@ -192,6 +196,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { config: cfg, Answer: NewAnswerClient(cfg), Hackathon: NewHackathonClient(cfg), + HackathonInvite: NewHackathonInviteClient(cfg), HackathonState: NewHackathonStateClient(cfg), Page: NewPageClient(cfg), Participant: NewParticipantClient(cfg), @@ -227,6 +232,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) config: cfg, Answer: NewAnswerClient(cfg), Hackathon: NewHackathonClient(cfg), + HackathonInvite: NewHackathonInviteClient(cfg), HackathonState: NewHackathonStateClient(cfg), Page: NewPageClient(cfg), Participant: NewParticipantClient(cfg), @@ -270,9 +276,9 @@ func (c *Client) Close() error { // In order to add hooks to a specific client, call: `client.Node.Use(...)`. func (c *Client) Use(hooks ...Hook) { for _, n := range []interface{ Use(...Hook) }{ - c.Answer, c.Hackathon, c.HackathonState, c.Page, c.Participant, c.Phase, - c.Project, c.Question, c.Submission, c.Team, c.TeamParticipant, c.Track, - c.User, c.Vote, c.VoteCategory, c.VoteResult, + c.Answer, c.Hackathon, c.HackathonInvite, c.HackathonState, c.Page, + c.Participant, c.Phase, c.Project, c.Question, c.Submission, c.Team, + c.TeamParticipant, c.Track, c.User, c.Vote, c.VoteCategory, c.VoteResult, } { n.Use(hooks...) } @@ -282,9 +288,9 @@ func (c *Client) Use(hooks ...Hook) { // In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`. func (c *Client) Intercept(interceptors ...Interceptor) { for _, n := range []interface{ Intercept(...Interceptor) }{ - c.Answer, c.Hackathon, c.HackathonState, c.Page, c.Participant, c.Phase, - c.Project, c.Question, c.Submission, c.Team, c.TeamParticipant, c.Track, - c.User, c.Vote, c.VoteCategory, c.VoteResult, + c.Answer, c.Hackathon, c.HackathonInvite, c.HackathonState, c.Page, + c.Participant, c.Phase, c.Project, c.Question, c.Submission, c.Team, + c.TeamParticipant, c.Track, c.User, c.Vote, c.VoteCategory, c.VoteResult, } { n.Intercept(interceptors...) } @@ -297,6 +303,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { return c.Answer.mutate(ctx, m) case *HackathonMutation: return c.Hackathon.mutate(ctx, m) + case *HackathonInviteMutation: + return c.HackathonInvite.mutate(ctx, m) case *HackathonStateMutation: return c.HackathonState.mutate(ctx, m) case *PageMutation: @@ -820,6 +828,171 @@ func (c *HackathonClient) mutate(ctx context.Context, m *HackathonMutation) (Val } } +// HackathonInviteClient is a client for the HackathonInvite schema. +type HackathonInviteClient struct { + config +} + +// NewHackathonInviteClient returns a client for the HackathonInvite from the given config. +func NewHackathonInviteClient(c config) *HackathonInviteClient { + return &HackathonInviteClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `hackathoninvite.Hooks(f(g(h())))`. +func (c *HackathonInviteClient) Use(hooks ...Hook) { + c.hooks.HackathonInvite = append(c.hooks.HackathonInvite, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `hackathoninvite.Intercept(f(g(h())))`. +func (c *HackathonInviteClient) Intercept(interceptors ...Interceptor) { + c.inters.HackathonInvite = append(c.inters.HackathonInvite, interceptors...) +} + +// Create returns a builder for creating a HackathonInvite entity. +func (c *HackathonInviteClient) Create() *HackathonInviteCreate { + mutation := newHackathonInviteMutation(c.config, OpCreate) + return &HackathonInviteCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of HackathonInvite entities. +func (c *HackathonInviteClient) CreateBulk(builders ...*HackathonInviteCreate) *HackathonInviteCreateBulk { + return &HackathonInviteCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *HackathonInviteClient) MapCreateBulk(slice any, setFunc func(*HackathonInviteCreate, int)) *HackathonInviteCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &HackathonInviteCreateBulk{err: fmt.Errorf("calling to HackathonInviteClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*HackathonInviteCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &HackathonInviteCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for HackathonInvite. +func (c *HackathonInviteClient) Update() *HackathonInviteUpdate { + mutation := newHackathonInviteMutation(c.config, OpUpdate) + return &HackathonInviteUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *HackathonInviteClient) UpdateOne(_m *HackathonInvite) *HackathonInviteUpdateOne { + mutation := newHackathonInviteMutation(c.config, OpUpdateOne, withHackathonInvite(_m)) + return &HackathonInviteUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *HackathonInviteClient) UpdateOneID(id uuid.UUID) *HackathonInviteUpdateOne { + mutation := newHackathonInviteMutation(c.config, OpUpdateOne, withHackathonInviteID(id)) + return &HackathonInviteUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for HackathonInvite. +func (c *HackathonInviteClient) Delete() *HackathonInviteDelete { + mutation := newHackathonInviteMutation(c.config, OpDelete) + return &HackathonInviteDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *HackathonInviteClient) DeleteOne(_m *HackathonInvite) *HackathonInviteDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *HackathonInviteClient) DeleteOneID(id uuid.UUID) *HackathonInviteDeleteOne { + builder := c.Delete().Where(hackathoninvite.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &HackathonInviteDeleteOne{builder} +} + +// Query returns a query builder for HackathonInvite. +func (c *HackathonInviteClient) Query() *HackathonInviteQuery { + return &HackathonInviteQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeHackathonInvite}, + inters: c.Interceptors(), + } +} + +// Get returns a HackathonInvite entity by its id. +func (c *HackathonInviteClient) Get(ctx context.Context, id uuid.UUID) (*HackathonInvite, error) { + return c.Query().Where(hackathoninvite.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *HackathonInviteClient) GetX(ctx context.Context, id uuid.UUID) *HackathonInvite { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryHackathon queries the hackathon edge of a HackathonInvite. +func (c *HackathonInviteClient) QueryHackathon(_m *HackathonInvite) *HackathonQuery { + query := (&HackathonClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(hackathoninvite.Table, hackathoninvite.FieldID, id), + sqlgraph.To(hackathon.Table, hackathon.FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, hackathoninvite.HackathonTable, hackathoninvite.HackathonColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryCreator queries the creator edge of a HackathonInvite. +func (c *HackathonInviteClient) QueryCreator(_m *HackathonInvite) *UserQuery { + query := (&UserClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(hackathoninvite.Table, hackathoninvite.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, hackathoninvite.CreatorTable, hackathoninvite.CreatorColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *HackathonInviteClient) Hooks() []Hook { + return c.hooks.HackathonInvite +} + +// Interceptors returns the client interceptors. +func (c *HackathonInviteClient) Interceptors() []Interceptor { + return c.inters.HackathonInvite +} + +func (c *HackathonInviteClient) mutate(ctx context.Context, m *HackathonInviteMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&HackathonInviteCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&HackathonInviteUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&HackathonInviteUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&HackathonInviteDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown HackathonInvite mutation op: %q", m.Op()) + } +} + // HackathonStateClient is a client for the HackathonState schema. type HackathonStateClient struct { config @@ -2880,6 +3053,22 @@ func (c *UserClient) QueryCreatedHackathons(_m *User) *HackathonQuery { return query } +// QueryCreatedHackathonInvites queries the created_hackathon_invites edge of a User. +func (c *UserClient) QueryCreatedHackathonInvites(_m *User) *HackathonInviteQuery { + query := (&HackathonInviteClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, id), + sqlgraph.To(hackathoninvite.Table, hackathoninvite.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.CreatedHackathonInvitesTable, user.CreatedHackathonInvitesColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + // QueryModifiedHackathons queries the modified_hackathons edge of a User. func (c *UserClient) QueryModifiedHackathons(_m *User) *HackathonQuery { query := (&HackathonClient{config: c.config}).Query() @@ -3852,13 +4041,13 @@ func (c *VoteResultClient) mutate(ctx context.Context, m *VoteResultMutation) (V // hooks and interceptors per client, for fast access. type ( hooks struct { - Answer, Hackathon, HackathonState, Page, Participant, Phase, Project, Question, - Submission, Team, TeamParticipant, Track, User, Vote, VoteCategory, - VoteResult []ent.Hook + Answer, Hackathon, HackathonInvite, HackathonState, Page, Participant, Phase, + Project, Question, Submission, Team, TeamParticipant, Track, User, Vote, + VoteCategory, VoteResult []ent.Hook } inters struct { - Answer, Hackathon, HackathonState, Page, Participant, Phase, Project, Question, - Submission, Team, TeamParticipant, Track, User, Vote, VoteCategory, - VoteResult []ent.Interceptor + Answer, Hackathon, HackathonInvite, HackathonState, Page, Participant, Phase, + Project, Question, Submission, Team, TeamParticipant, Track, User, Vote, + VoteCategory, VoteResult []ent.Interceptor } ) diff --git a/components/backend/ent/ent.go b/components/backend/ent/ent.go index 4f7ce58c..ec79f63a 100644 --- a/components/backend/ent/ent.go +++ b/components/backend/ent/ent.go @@ -14,6 +14,7 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/answer" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathonstate" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/page" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/participant" @@ -90,6 +91,7 @@ func checkColumn(t, c string) error { columnCheck = sql.NewColumnCheck(map[string]func(string) bool{ answer.Table: answer.ValidColumn, hackathon.Table: hackathon.ValidColumn, + hackathoninvite.Table: hackathoninvite.ValidColumn, hackathonstate.Table: hackathonstate.ValidColumn, page.Table: page.ValidColumn, participant.Table: participant.ValidColumn, diff --git a/components/backend/ent/hackathoninvite.go b/components/backend/ent/hackathoninvite.go new file mode 100644 index 00000000..885da6fe --- /dev/null +++ b/components/backend/ent/hackathoninvite.go @@ -0,0 +1,225 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/google/uuid" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/user" +) + +// An invite for a hackathon. +type HackathonInvite struct { + config `json:"-"` + // ID of the ent. + ID uuid.UUID `json:"id,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + // RevokedAt holds the value of the "revoked_at" field. + RevokedAt *time.Time `json:"revoked_at,omitempty"` + // Token holds the value of the "token" field. + Token uuid.UUID `json:"token,omitempty"` + // Note holds the value of the "note" field. + Note string `json:"note,omitempty"` + // ExpiresAt holds the value of the "expires_at" field. + ExpiresAt *time.Time `json:"expires_at,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the HackathonInviteQuery when eager-loading is set. + Edges HackathonInviteEdges `json:"edges"` + hackathon_invite_hackathon *uuid.UUID + user_created_hackathon_invites *uuid.UUID + selectValues sql.SelectValues +} + +// HackathonInviteEdges holds the relations/edges for other nodes in the graph. +type HackathonInviteEdges struct { + // The hackathon this invite grants access to. + Hackathon *Hackathon `json:"hackathon,omitempty"` + // The user who created this invite. + Creator *User `json:"creator,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [2]bool +} + +// HackathonOrErr returns the Hackathon value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e HackathonInviteEdges) HackathonOrErr() (*Hackathon, error) { + if e.Hackathon != nil { + return e.Hackathon, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: hackathon.Label} + } + return nil, &NotLoadedError{edge: "hackathon"} +} + +// CreatorOrErr returns the Creator value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e HackathonInviteEdges) CreatorOrErr() (*User, error) { + if e.Creator != nil { + return e.Creator, nil + } else if e.loadedTypes[1] { + return nil, &NotFoundError{label: user.Label} + } + return nil, &NotLoadedError{edge: "creator"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*HackathonInvite) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case hackathoninvite.FieldNote: + values[i] = new(sql.NullString) + case hackathoninvite.FieldCreatedAt, hackathoninvite.FieldRevokedAt, hackathoninvite.FieldExpiresAt: + values[i] = new(sql.NullTime) + case hackathoninvite.FieldID, hackathoninvite.FieldToken: + values[i] = new(uuid.UUID) + case hackathoninvite.ForeignKeys[0]: // hackathon_invite_hackathon + values[i] = &sql.NullScanner{S: new(uuid.UUID)} + case hackathoninvite.ForeignKeys[1]: // user_created_hackathon_invites + values[i] = &sql.NullScanner{S: new(uuid.UUID)} + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the HackathonInvite fields. +func (_m *HackathonInvite) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case hackathoninvite.FieldID: + if value, ok := values[i].(*uuid.UUID); !ok { + return fmt.Errorf("unexpected type %T for field id", values[i]) + } else if value != nil { + _m.ID = *value + } + case hackathoninvite.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + _m.CreatedAt = value.Time + } + case hackathoninvite.FieldRevokedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field revoked_at", values[i]) + } else if value.Valid { + _m.RevokedAt = new(time.Time) + *_m.RevokedAt = value.Time + } + case hackathoninvite.FieldToken: + if value, ok := values[i].(*uuid.UUID); !ok { + return fmt.Errorf("unexpected type %T for field token", values[i]) + } else if value != nil { + _m.Token = *value + } + case hackathoninvite.FieldNote: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field note", values[i]) + } else if value.Valid { + _m.Note = value.String + } + case hackathoninvite.FieldExpiresAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field expires_at", values[i]) + } else if value.Valid { + _m.ExpiresAt = new(time.Time) + *_m.ExpiresAt = value.Time + } + case hackathoninvite.ForeignKeys[0]: + if value, ok := values[i].(*sql.NullScanner); !ok { + return fmt.Errorf("unexpected type %T for field hackathon_invite_hackathon", values[i]) + } else if value.Valid { + _m.hackathon_invite_hackathon = new(uuid.UUID) + *_m.hackathon_invite_hackathon = *value.S.(*uuid.UUID) + } + case hackathoninvite.ForeignKeys[1]: + if value, ok := values[i].(*sql.NullScanner); !ok { + return fmt.Errorf("unexpected type %T for field user_created_hackathon_invites", values[i]) + } else if value.Valid { + _m.user_created_hackathon_invites = new(uuid.UUID) + *_m.user_created_hackathon_invites = *value.S.(*uuid.UUID) + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the HackathonInvite. +// This includes values selected through modifiers, order, etc. +func (_m *HackathonInvite) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// QueryHackathon queries the "hackathon" edge of the HackathonInvite entity. +func (_m *HackathonInvite) QueryHackathon() *HackathonQuery { + return NewHackathonInviteClient(_m.config).QueryHackathon(_m) +} + +// QueryCreator queries the "creator" edge of the HackathonInvite entity. +func (_m *HackathonInvite) QueryCreator() *UserQuery { + return NewHackathonInviteClient(_m.config).QueryCreator(_m) +} + +// Update returns a builder for updating this HackathonInvite. +// Note that you need to call HackathonInvite.Unwrap() before calling this method if this HackathonInvite +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *HackathonInvite) Update() *HackathonInviteUpdateOne { + return NewHackathonInviteClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the HackathonInvite entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *HackathonInvite) Unwrap() *HackathonInvite { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("ent: HackathonInvite is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *HackathonInvite) String() string { + var builder strings.Builder + builder.WriteString("HackathonInvite(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("created_at=") + builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) + builder.WriteString(", ") + if v := _m.RevokedAt; v != nil { + builder.WriteString("revoked_at=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteString(", ") + builder.WriteString("token=") + builder.WriteString(fmt.Sprintf("%v", _m.Token)) + builder.WriteString(", ") + builder.WriteString("note=") + builder.WriteString(_m.Note) + builder.WriteString(", ") + if v := _m.ExpiresAt; v != nil { + builder.WriteString("expires_at=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteByte(')') + return builder.String() +} + +// HackathonInvites is a parsable slice of HackathonInvite. +type HackathonInvites []*HackathonInvite diff --git a/components/backend/ent/hackathoninvite/hackathoninvite.go b/components/backend/ent/hackathoninvite/hackathoninvite.go new file mode 100644 index 00000000..0be3a692 --- /dev/null +++ b/components/backend/ent/hackathoninvite/hackathoninvite.go @@ -0,0 +1,152 @@ +// Code generated by ent, DO NOT EDIT. + +package hackathoninvite + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/google/uuid" +) + +const ( + // Label holds the string label denoting the hackathoninvite type in the database. + Label = "hackathon_invite" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // FieldRevokedAt holds the string denoting the revoked_at field in the database. + FieldRevokedAt = "revoked_at" + // FieldToken holds the string denoting the token field in the database. + FieldToken = "token" + // FieldNote holds the string denoting the note field in the database. + FieldNote = "note" + // FieldExpiresAt holds the string denoting the expires_at field in the database. + FieldExpiresAt = "expires_at" + // EdgeHackathon holds the string denoting the hackathon edge name in mutations. + EdgeHackathon = "hackathon" + // EdgeCreator holds the string denoting the creator edge name in mutations. + EdgeCreator = "creator" + // Table holds the table name of the hackathoninvite in the database. + Table = "hackathon_invites" + // HackathonTable is the table that holds the hackathon relation/edge. + HackathonTable = "hackathon_invites" + // HackathonInverseTable is the table name for the Hackathon entity. + // It exists in this package in order to avoid circular dependency with the "hackathon" package. + HackathonInverseTable = "hackathons" + // HackathonColumn is the table column denoting the hackathon relation/edge. + HackathonColumn = "hackathon_invite_hackathon" + // CreatorTable is the table that holds the creator relation/edge. + CreatorTable = "hackathon_invites" + // CreatorInverseTable is the table name for the User entity. + // It exists in this package in order to avoid circular dependency with the "user" package. + CreatorInverseTable = "users" + // CreatorColumn is the table column denoting the creator relation/edge. + CreatorColumn = "user_created_hackathon_invites" +) + +// Columns holds all SQL columns for hackathoninvite fields. +var Columns = []string{ + FieldID, + FieldCreatedAt, + FieldRevokedAt, + FieldToken, + FieldNote, + FieldExpiresAt, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the "hackathon_invites" +// table and are not defined as standalone fields in the schema. +var ForeignKeys = []string{ + "hackathon_invite_hackathon", + "user_created_hackathon_invites", +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + for i := range ForeignKeys { + if column == ForeignKeys[i] { + return true + } + } + return false +} + +var ( + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time + // DefaultToken holds the default value on creation for the "token" field. + DefaultToken func() uuid.UUID + // NoteValidator is a validator for the "note" field. It is called by the builders before save. + NoteValidator func(string) error + // DefaultID holds the default value on creation for the "id" field. + DefaultID func() uuid.UUID +) + +// OrderOption defines the ordering options for the HackathonInvite queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} + +// ByRevokedAt orders the results by the revoked_at field. +func ByRevokedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRevokedAt, opts...).ToFunc() +} + +// ByToken orders the results by the token field. +func ByToken(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldToken, opts...).ToFunc() +} + +// ByNote orders the results by the note field. +func ByNote(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldNote, opts...).ToFunc() +} + +// ByExpiresAt orders the results by the expires_at field. +func ByExpiresAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldExpiresAt, opts...).ToFunc() +} + +// ByHackathonField orders the results by hackathon field. +func ByHackathonField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newHackathonStep(), sql.OrderByField(field, opts...)) + } +} + +// ByCreatorField orders the results by creator field. +func ByCreatorField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newCreatorStep(), sql.OrderByField(field, opts...)) + } +} +func newHackathonStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(HackathonInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, HackathonTable, HackathonColumn), + ) +} +func newCreatorStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(CreatorInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, CreatorTable, CreatorColumn), + ) +} diff --git a/components/backend/ent/hackathoninvite/where.go b/components/backend/ent/hackathoninvite/where.go new file mode 100644 index 00000000..b95cf12b --- /dev/null +++ b/components/backend/ent/hackathoninvite/where.go @@ -0,0 +1,398 @@ +// Code generated by ent, DO NOT EDIT. + +package hackathoninvite + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/google/uuid" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLTE(FieldID, id)) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldCreatedAt, v)) +} + +// RevokedAt applies equality check predicate on the "revoked_at" field. It's identical to RevokedAtEQ. +func RevokedAt(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldRevokedAt, v)) +} + +// Token applies equality check predicate on the "token" field. It's identical to TokenEQ. +func Token(v uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldToken, v)) +} + +// Note applies equality check predicate on the "note" field. It's identical to NoteEQ. +func Note(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldNote, v)) +} + +// ExpiresAt applies equality check predicate on the "expires_at" field. It's identical to ExpiresAtEQ. +func ExpiresAt(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldExpiresAt, v)) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldCreatedAt, v)) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNEQ(FieldCreatedAt, v)) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldIn(FieldCreatedAt, vs...)) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNotIn(FieldCreatedAt, vs...)) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGT(FieldCreatedAt, v)) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGTE(FieldCreatedAt, v)) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLT(FieldCreatedAt, v)) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLTE(FieldCreatedAt, v)) +} + +// RevokedAtEQ applies the EQ predicate on the "revoked_at" field. +func RevokedAtEQ(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldRevokedAt, v)) +} + +// RevokedAtNEQ applies the NEQ predicate on the "revoked_at" field. +func RevokedAtNEQ(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNEQ(FieldRevokedAt, v)) +} + +// RevokedAtIn applies the In predicate on the "revoked_at" field. +func RevokedAtIn(vs ...time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldIn(FieldRevokedAt, vs...)) +} + +// RevokedAtNotIn applies the NotIn predicate on the "revoked_at" field. +func RevokedAtNotIn(vs ...time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNotIn(FieldRevokedAt, vs...)) +} + +// RevokedAtGT applies the GT predicate on the "revoked_at" field. +func RevokedAtGT(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGT(FieldRevokedAt, v)) +} + +// RevokedAtGTE applies the GTE predicate on the "revoked_at" field. +func RevokedAtGTE(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGTE(FieldRevokedAt, v)) +} + +// RevokedAtLT applies the LT predicate on the "revoked_at" field. +func RevokedAtLT(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLT(FieldRevokedAt, v)) +} + +// RevokedAtLTE applies the LTE predicate on the "revoked_at" field. +func RevokedAtLTE(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLTE(FieldRevokedAt, v)) +} + +// RevokedAtIsNil applies the IsNil predicate on the "revoked_at" field. +func RevokedAtIsNil() predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldIsNull(FieldRevokedAt)) +} + +// RevokedAtNotNil applies the NotNil predicate on the "revoked_at" field. +func RevokedAtNotNil() predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNotNull(FieldRevokedAt)) +} + +// TokenEQ applies the EQ predicate on the "token" field. +func TokenEQ(v uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldToken, v)) +} + +// TokenNEQ applies the NEQ predicate on the "token" field. +func TokenNEQ(v uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNEQ(FieldToken, v)) +} + +// TokenIn applies the In predicate on the "token" field. +func TokenIn(vs ...uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldIn(FieldToken, vs...)) +} + +// TokenNotIn applies the NotIn predicate on the "token" field. +func TokenNotIn(vs ...uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNotIn(FieldToken, vs...)) +} + +// TokenGT applies the GT predicate on the "token" field. +func TokenGT(v uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGT(FieldToken, v)) +} + +// TokenGTE applies the GTE predicate on the "token" field. +func TokenGTE(v uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGTE(FieldToken, v)) +} + +// TokenLT applies the LT predicate on the "token" field. +func TokenLT(v uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLT(FieldToken, v)) +} + +// TokenLTE applies the LTE predicate on the "token" field. +func TokenLTE(v uuid.UUID) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLTE(FieldToken, v)) +} + +// NoteEQ applies the EQ predicate on the "note" field. +func NoteEQ(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldNote, v)) +} + +// NoteNEQ applies the NEQ predicate on the "note" field. +func NoteNEQ(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNEQ(FieldNote, v)) +} + +// NoteIn applies the In predicate on the "note" field. +func NoteIn(vs ...string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldIn(FieldNote, vs...)) +} + +// NoteNotIn applies the NotIn predicate on the "note" field. +func NoteNotIn(vs ...string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNotIn(FieldNote, vs...)) +} + +// NoteGT applies the GT predicate on the "note" field. +func NoteGT(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGT(FieldNote, v)) +} + +// NoteGTE applies the GTE predicate on the "note" field. +func NoteGTE(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGTE(FieldNote, v)) +} + +// NoteLT applies the LT predicate on the "note" field. +func NoteLT(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLT(FieldNote, v)) +} + +// NoteLTE applies the LTE predicate on the "note" field. +func NoteLTE(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLTE(FieldNote, v)) +} + +// NoteContains applies the Contains predicate on the "note" field. +func NoteContains(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldContains(FieldNote, v)) +} + +// NoteHasPrefix applies the HasPrefix predicate on the "note" field. +func NoteHasPrefix(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldHasPrefix(FieldNote, v)) +} + +// NoteHasSuffix applies the HasSuffix predicate on the "note" field. +func NoteHasSuffix(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldHasSuffix(FieldNote, v)) +} + +// NoteIsNil applies the IsNil predicate on the "note" field. +func NoteIsNil() predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldIsNull(FieldNote)) +} + +// NoteNotNil applies the NotNil predicate on the "note" field. +func NoteNotNil() predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNotNull(FieldNote)) +} + +// NoteEqualFold applies the EqualFold predicate on the "note" field. +func NoteEqualFold(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEqualFold(FieldNote, v)) +} + +// NoteContainsFold applies the ContainsFold predicate on the "note" field. +func NoteContainsFold(v string) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldContainsFold(FieldNote, v)) +} + +// ExpiresAtEQ applies the EQ predicate on the "expires_at" field. +func ExpiresAtEQ(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldEQ(FieldExpiresAt, v)) +} + +// ExpiresAtNEQ applies the NEQ predicate on the "expires_at" field. +func ExpiresAtNEQ(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNEQ(FieldExpiresAt, v)) +} + +// ExpiresAtIn applies the In predicate on the "expires_at" field. +func ExpiresAtIn(vs ...time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldIn(FieldExpiresAt, vs...)) +} + +// ExpiresAtNotIn applies the NotIn predicate on the "expires_at" field. +func ExpiresAtNotIn(vs ...time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNotIn(FieldExpiresAt, vs...)) +} + +// ExpiresAtGT applies the GT predicate on the "expires_at" field. +func ExpiresAtGT(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGT(FieldExpiresAt, v)) +} + +// ExpiresAtGTE applies the GTE predicate on the "expires_at" field. +func ExpiresAtGTE(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldGTE(FieldExpiresAt, v)) +} + +// ExpiresAtLT applies the LT predicate on the "expires_at" field. +func ExpiresAtLT(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLT(FieldExpiresAt, v)) +} + +// ExpiresAtLTE applies the LTE predicate on the "expires_at" field. +func ExpiresAtLTE(v time.Time) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldLTE(FieldExpiresAt, v)) +} + +// ExpiresAtIsNil applies the IsNil predicate on the "expires_at" field. +func ExpiresAtIsNil() predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldIsNull(FieldExpiresAt)) +} + +// ExpiresAtNotNil applies the NotNil predicate on the "expires_at" field. +func ExpiresAtNotNil() predicate.HackathonInvite { + return predicate.HackathonInvite(sql.FieldNotNull(FieldExpiresAt)) +} + +// HasHackathon applies the HasEdge predicate on the "hackathon" edge. +func HasHackathon() predicate.HackathonInvite { + return predicate.HackathonInvite(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, HackathonTable, HackathonColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasHackathonWith applies the HasEdge predicate on the "hackathon" edge with a given conditions (other predicates). +func HasHackathonWith(preds ...predicate.Hackathon) predicate.HackathonInvite { + return predicate.HackathonInvite(func(s *sql.Selector) { + step := newHackathonStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasCreator applies the HasEdge predicate on the "creator" edge. +func HasCreator() predicate.HackathonInvite { + return predicate.HackathonInvite(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, CreatorTable, CreatorColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasCreatorWith applies the HasEdge predicate on the "creator" edge with a given conditions (other predicates). +func HasCreatorWith(preds ...predicate.User) predicate.HackathonInvite { + return predicate.HackathonInvite(func(s *sql.Selector) { + step := newCreatorStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.HackathonInvite) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.HackathonInvite) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.HackathonInvite) predicate.HackathonInvite { + return predicate.HackathonInvite(sql.NotPredicates(p)) +} diff --git a/components/backend/ent/hackathoninvite_create.go b/components/backend/ent/hackathoninvite_create.go new file mode 100644 index 00000000..2c0eac21 --- /dev/null +++ b/components/backend/ent/hackathoninvite_create.go @@ -0,0 +1,855 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/google/uuid" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/user" +) + +// HackathonInviteCreate is the builder for creating a HackathonInvite entity. +type HackathonInviteCreate struct { + config + mutation *HackathonInviteMutation + hooks []Hook + conflict []sql.ConflictOption +} + +// SetCreatedAt sets the "created_at" field. +func (_c *HackathonInviteCreate) SetCreatedAt(v time.Time) *HackathonInviteCreate { + _c.mutation.SetCreatedAt(v) + return _c +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (_c *HackathonInviteCreate) SetNillableCreatedAt(v *time.Time) *HackathonInviteCreate { + if v != nil { + _c.SetCreatedAt(*v) + } + return _c +} + +// SetRevokedAt sets the "revoked_at" field. +func (_c *HackathonInviteCreate) SetRevokedAt(v time.Time) *HackathonInviteCreate { + _c.mutation.SetRevokedAt(v) + return _c +} + +// SetNillableRevokedAt sets the "revoked_at" field if the given value is not nil. +func (_c *HackathonInviteCreate) SetNillableRevokedAt(v *time.Time) *HackathonInviteCreate { + if v != nil { + _c.SetRevokedAt(*v) + } + return _c +} + +// SetToken sets the "token" field. +func (_c *HackathonInviteCreate) SetToken(v uuid.UUID) *HackathonInviteCreate { + _c.mutation.SetToken(v) + return _c +} + +// SetNillableToken sets the "token" field if the given value is not nil. +func (_c *HackathonInviteCreate) SetNillableToken(v *uuid.UUID) *HackathonInviteCreate { + if v != nil { + _c.SetToken(*v) + } + return _c +} + +// SetNote sets the "note" field. +func (_c *HackathonInviteCreate) SetNote(v string) *HackathonInviteCreate { + _c.mutation.SetNote(v) + return _c +} + +// SetNillableNote sets the "note" field if the given value is not nil. +func (_c *HackathonInviteCreate) SetNillableNote(v *string) *HackathonInviteCreate { + if v != nil { + _c.SetNote(*v) + } + return _c +} + +// SetExpiresAt sets the "expires_at" field. +func (_c *HackathonInviteCreate) SetExpiresAt(v time.Time) *HackathonInviteCreate { + _c.mutation.SetExpiresAt(v) + return _c +} + +// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil. +func (_c *HackathonInviteCreate) SetNillableExpiresAt(v *time.Time) *HackathonInviteCreate { + if v != nil { + _c.SetExpiresAt(*v) + } + return _c +} + +// SetID sets the "id" field. +func (_c *HackathonInviteCreate) SetID(v uuid.UUID) *HackathonInviteCreate { + _c.mutation.SetID(v) + return _c +} + +// SetNillableID sets the "id" field if the given value is not nil. +func (_c *HackathonInviteCreate) SetNillableID(v *uuid.UUID) *HackathonInviteCreate { + if v != nil { + _c.SetID(*v) + } + return _c +} + +// SetHackathonID sets the "hackathon" edge to the Hackathon entity by ID. +func (_c *HackathonInviteCreate) SetHackathonID(id uuid.UUID) *HackathonInviteCreate { + _c.mutation.SetHackathonID(id) + return _c +} + +// SetHackathon sets the "hackathon" edge to the Hackathon entity. +func (_c *HackathonInviteCreate) SetHackathon(v *Hackathon) *HackathonInviteCreate { + return _c.SetHackathonID(v.ID) +} + +// SetCreatorID sets the "creator" edge to the User entity by ID. +func (_c *HackathonInviteCreate) SetCreatorID(id uuid.UUID) *HackathonInviteCreate { + _c.mutation.SetCreatorID(id) + return _c +} + +// SetCreator sets the "creator" edge to the User entity. +func (_c *HackathonInviteCreate) SetCreator(v *User) *HackathonInviteCreate { + return _c.SetCreatorID(v.ID) +} + +// Mutation returns the HackathonInviteMutation object of the builder. +func (_c *HackathonInviteCreate) Mutation() *HackathonInviteMutation { + return _c.mutation +} + +// Save creates the HackathonInvite in the database. +func (_c *HackathonInviteCreate) Save(ctx context.Context) (*HackathonInvite, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *HackathonInviteCreate) SaveX(ctx context.Context) *HackathonInvite { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *HackathonInviteCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *HackathonInviteCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_c *HackathonInviteCreate) defaults() { + if _, ok := _c.mutation.CreatedAt(); !ok { + v := hackathoninvite.DefaultCreatedAt() + _c.mutation.SetCreatedAt(v) + } + if _, ok := _c.mutation.Token(); !ok { + v := hackathoninvite.DefaultToken() + _c.mutation.SetToken(v) + } + if _, ok := _c.mutation.ID(); !ok { + v := hackathoninvite.DefaultID() + _c.mutation.SetID(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *HackathonInviteCreate) check() error { + if _, ok := _c.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "HackathonInvite.created_at"`)} + } + if _, ok := _c.mutation.Token(); !ok { + return &ValidationError{Name: "token", err: errors.New(`ent: missing required field "HackathonInvite.token"`)} + } + if v, ok := _c.mutation.Note(); ok { + if err := hackathoninvite.NoteValidator(v); err != nil { + return &ValidationError{Name: "note", err: fmt.Errorf(`ent: validator failed for field "HackathonInvite.note": %w`, err)} + } + } + if len(_c.mutation.HackathonIDs()) == 0 { + return &ValidationError{Name: "hackathon", err: errors.New(`ent: missing required edge "HackathonInvite.hackathon"`)} + } + if len(_c.mutation.CreatorIDs()) == 0 { + return &ValidationError{Name: "creator", err: errors.New(`ent: missing required edge "HackathonInvite.creator"`)} + } + return nil +} + +func (_c *HackathonInviteCreate) sqlSave(ctx context.Context) (*HackathonInvite, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != nil { + if id, ok := _spec.ID.Value.(*uuid.UUID); ok { + _node.ID = *id + } else if err := _node.ID.Scan(_spec.ID.Value); err != nil { + return nil, err + } + } + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *HackathonInviteCreate) createSpec() (*HackathonInvite, *sqlgraph.CreateSpec) { + var ( + _node = &HackathonInvite{config: _c.config} + _spec = sqlgraph.NewCreateSpec(hackathoninvite.Table, sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID)) + ) + _spec.OnConflict = _c.conflict + if id, ok := _c.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = &id + } + if value, ok := _c.mutation.CreatedAt(); ok { + _spec.SetField(hackathoninvite.FieldCreatedAt, field.TypeTime, value) + _node.CreatedAt = value + } + if value, ok := _c.mutation.RevokedAt(); ok { + _spec.SetField(hackathoninvite.FieldRevokedAt, field.TypeTime, value) + _node.RevokedAt = &value + } + if value, ok := _c.mutation.Token(); ok { + _spec.SetField(hackathoninvite.FieldToken, field.TypeUUID, value) + _node.Token = value + } + if value, ok := _c.mutation.Note(); ok { + _spec.SetField(hackathoninvite.FieldNote, field.TypeString, value) + _node.Note = value + } + if value, ok := _c.mutation.ExpiresAt(); ok { + _spec.SetField(hackathoninvite.FieldExpiresAt, field.TypeTime, value) + _node.ExpiresAt = &value + } + if nodes := _c.mutation.HackathonIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: false, + Table: hackathoninvite.HackathonTable, + Columns: []string{hackathoninvite.HackathonColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(hackathon.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.hackathon_invite_hackathon = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := _c.mutation.CreatorIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: hackathoninvite.CreatorTable, + Columns: []string{hackathoninvite.CreatorColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.user_created_hackathon_invites = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.HackathonInvite.Create(). +// SetCreatedAt(v). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.HackathonInviteUpsert) { +// SetCreatedAt(v+v). +// }). +// Exec(ctx) +func (_c *HackathonInviteCreate) OnConflict(opts ...sql.ConflictOption) *HackathonInviteUpsertOne { + _c.conflict = opts + return &HackathonInviteUpsertOne{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.HackathonInvite.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *HackathonInviteCreate) OnConflictColumns(columns ...string) *HackathonInviteUpsertOne { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &HackathonInviteUpsertOne{ + create: _c, + } +} + +type ( + // HackathonInviteUpsertOne is the builder for "upsert"-ing + // one HackathonInvite node. + HackathonInviteUpsertOne struct { + create *HackathonInviteCreate + } + + // HackathonInviteUpsert is the "OnConflict" setter. + HackathonInviteUpsert struct { + *sql.UpdateSet + } +) + +// SetRevokedAt sets the "revoked_at" field. +func (u *HackathonInviteUpsert) SetRevokedAt(v time.Time) *HackathonInviteUpsert { + u.Set(hackathoninvite.FieldRevokedAt, v) + return u +} + +// UpdateRevokedAt sets the "revoked_at" field to the value that was provided on create. +func (u *HackathonInviteUpsert) UpdateRevokedAt() *HackathonInviteUpsert { + u.SetExcluded(hackathoninvite.FieldRevokedAt) + return u +} + +// ClearRevokedAt clears the value of the "revoked_at" field. +func (u *HackathonInviteUpsert) ClearRevokedAt() *HackathonInviteUpsert { + u.SetNull(hackathoninvite.FieldRevokedAt) + return u +} + +// SetToken sets the "token" field. +func (u *HackathonInviteUpsert) SetToken(v uuid.UUID) *HackathonInviteUpsert { + u.Set(hackathoninvite.FieldToken, v) + return u +} + +// UpdateToken sets the "token" field to the value that was provided on create. +func (u *HackathonInviteUpsert) UpdateToken() *HackathonInviteUpsert { + u.SetExcluded(hackathoninvite.FieldToken) + return u +} + +// SetNote sets the "note" field. +func (u *HackathonInviteUpsert) SetNote(v string) *HackathonInviteUpsert { + u.Set(hackathoninvite.FieldNote, v) + return u +} + +// UpdateNote sets the "note" field to the value that was provided on create. +func (u *HackathonInviteUpsert) UpdateNote() *HackathonInviteUpsert { + u.SetExcluded(hackathoninvite.FieldNote) + return u +} + +// ClearNote clears the value of the "note" field. +func (u *HackathonInviteUpsert) ClearNote() *HackathonInviteUpsert { + u.SetNull(hackathoninvite.FieldNote) + return u +} + +// SetExpiresAt sets the "expires_at" field. +func (u *HackathonInviteUpsert) SetExpiresAt(v time.Time) *HackathonInviteUpsert { + u.Set(hackathoninvite.FieldExpiresAt, v) + return u +} + +// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create. +func (u *HackathonInviteUpsert) UpdateExpiresAt() *HackathonInviteUpsert { + u.SetExcluded(hackathoninvite.FieldExpiresAt) + return u +} + +// ClearExpiresAt clears the value of the "expires_at" field. +func (u *HackathonInviteUpsert) ClearExpiresAt() *HackathonInviteUpsert { + u.SetNull(hackathoninvite.FieldExpiresAt) + return u +} + +// UpdateNewValues updates the mutable fields using the new values that were set on create except the ID field. +// Using this option is equivalent to using: +// +// client.HackathonInvite.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// sql.ResolveWith(func(u *sql.UpdateSet) { +// u.SetIgnore(hackathoninvite.FieldID) +// }), +// ). +// Exec(ctx) +func (u *HackathonInviteUpsertOne) UpdateNewValues() *HackathonInviteUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + if _, exists := u.create.mutation.ID(); exists { + s.SetIgnore(hackathoninvite.FieldID) + } + if _, exists := u.create.mutation.CreatedAt(); exists { + s.SetIgnore(hackathoninvite.FieldCreatedAt) + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.HackathonInvite.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *HackathonInviteUpsertOne) Ignore() *HackathonInviteUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *HackathonInviteUpsertOne) DoNothing() *HackathonInviteUpsertOne { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the HackathonInviteCreate.OnConflict +// documentation for more info. +func (u *HackathonInviteUpsertOne) Update(set func(*HackathonInviteUpsert)) *HackathonInviteUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&HackathonInviteUpsert{UpdateSet: update}) + })) + return u +} + +// SetRevokedAt sets the "revoked_at" field. +func (u *HackathonInviteUpsertOne) SetRevokedAt(v time.Time) *HackathonInviteUpsertOne { + return u.Update(func(s *HackathonInviteUpsert) { + s.SetRevokedAt(v) + }) +} + +// UpdateRevokedAt sets the "revoked_at" field to the value that was provided on create. +func (u *HackathonInviteUpsertOne) UpdateRevokedAt() *HackathonInviteUpsertOne { + return u.Update(func(s *HackathonInviteUpsert) { + s.UpdateRevokedAt() + }) +} + +// ClearRevokedAt clears the value of the "revoked_at" field. +func (u *HackathonInviteUpsertOne) ClearRevokedAt() *HackathonInviteUpsertOne { + return u.Update(func(s *HackathonInviteUpsert) { + s.ClearRevokedAt() + }) +} + +// SetToken sets the "token" field. +func (u *HackathonInviteUpsertOne) SetToken(v uuid.UUID) *HackathonInviteUpsertOne { + return u.Update(func(s *HackathonInviteUpsert) { + s.SetToken(v) + }) +} + +// UpdateToken sets the "token" field to the value that was provided on create. +func (u *HackathonInviteUpsertOne) UpdateToken() *HackathonInviteUpsertOne { + return u.Update(func(s *HackathonInviteUpsert) { + s.UpdateToken() + }) +} + +// SetNote sets the "note" field. +func (u *HackathonInviteUpsertOne) SetNote(v string) *HackathonInviteUpsertOne { + return u.Update(func(s *HackathonInviteUpsert) { + s.SetNote(v) + }) +} + +// UpdateNote sets the "note" field to the value that was provided on create. +func (u *HackathonInviteUpsertOne) UpdateNote() *HackathonInviteUpsertOne { + return u.Update(func(s *HackathonInviteUpsert) { + s.UpdateNote() + }) +} + +// ClearNote clears the value of the "note" field. +func (u *HackathonInviteUpsertOne) ClearNote() *HackathonInviteUpsertOne { + return u.Update(func(s *HackathonInviteUpsert) { + s.ClearNote() + }) +} + +// SetExpiresAt sets the "expires_at" field. +func (u *HackathonInviteUpsertOne) SetExpiresAt(v time.Time) *HackathonInviteUpsertOne { + return u.Update(func(s *HackathonInviteUpsert) { + s.SetExpiresAt(v) + }) +} + +// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create. +func (u *HackathonInviteUpsertOne) UpdateExpiresAt() *HackathonInviteUpsertOne { + return u.Update(func(s *HackathonInviteUpsert) { + s.UpdateExpiresAt() + }) +} + +// ClearExpiresAt clears the value of the "expires_at" field. +func (u *HackathonInviteUpsertOne) ClearExpiresAt() *HackathonInviteUpsertOne { + return u.Update(func(s *HackathonInviteUpsert) { + s.ClearExpiresAt() + }) +} + +// Exec executes the query. +func (u *HackathonInviteUpsertOne) Exec(ctx context.Context) error { + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for HackathonInviteCreate.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *HackathonInviteUpsertOne) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} + +// Exec executes the UPSERT query and returns the inserted/updated ID. +func (u *HackathonInviteUpsertOne) ID(ctx context.Context) (id uuid.UUID, err error) { + if u.create.driver.Dialect() == dialect.MySQL { + // In case of "ON CONFLICT", there is no way to get back non-numeric ID + // fields from the database since MySQL does not support the RETURNING clause. + return id, errors.New("ent: HackathonInviteUpsertOne.ID is not supported by MySQL driver. Use HackathonInviteUpsertOne.Exec instead") + } + node, err := u.create.Save(ctx) + if err != nil { + return id, err + } + return node.ID, nil +} + +// IDX is like ID, but panics if an error occurs. +func (u *HackathonInviteUpsertOne) IDX(ctx context.Context) uuid.UUID { + id, err := u.ID(ctx) + if err != nil { + panic(err) + } + return id +} + +// HackathonInviteCreateBulk is the builder for creating many HackathonInvite entities in bulk. +type HackathonInviteCreateBulk struct { + config + err error + builders []*HackathonInviteCreate + conflict []sql.ConflictOption +} + +// Save creates the HackathonInvite entities in the database. +func (_c *HackathonInviteCreateBulk) Save(ctx context.Context) ([]*HackathonInvite, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*HackathonInvite, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*HackathonInviteMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.OnConflict = _c.conflict + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *HackathonInviteCreateBulk) SaveX(ctx context.Context) []*HackathonInvite { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *HackathonInviteCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *HackathonInviteCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.HackathonInvite.CreateBulk(builders...). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.HackathonInviteUpsert) { +// SetCreatedAt(v+v). +// }). +// Exec(ctx) +func (_c *HackathonInviteCreateBulk) OnConflict(opts ...sql.ConflictOption) *HackathonInviteUpsertBulk { + _c.conflict = opts + return &HackathonInviteUpsertBulk{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.HackathonInvite.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *HackathonInviteCreateBulk) OnConflictColumns(columns ...string) *HackathonInviteUpsertBulk { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &HackathonInviteUpsertBulk{ + create: _c, + } +} + +// HackathonInviteUpsertBulk is the builder for "upsert"-ing +// a bulk of HackathonInvite nodes. +type HackathonInviteUpsertBulk struct { + create *HackathonInviteCreateBulk +} + +// UpdateNewValues updates the mutable fields using the new values that +// were set on create. Using this option is equivalent to using: +// +// client.HackathonInvite.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// sql.ResolveWith(func(u *sql.UpdateSet) { +// u.SetIgnore(hackathoninvite.FieldID) +// }), +// ). +// Exec(ctx) +func (u *HackathonInviteUpsertBulk) UpdateNewValues() *HackathonInviteUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + for _, b := range u.create.builders { + if _, exists := b.mutation.ID(); exists { + s.SetIgnore(hackathoninvite.FieldID) + } + if _, exists := b.mutation.CreatedAt(); exists { + s.SetIgnore(hackathoninvite.FieldCreatedAt) + } + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.HackathonInvite.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *HackathonInviteUpsertBulk) Ignore() *HackathonInviteUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *HackathonInviteUpsertBulk) DoNothing() *HackathonInviteUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the HackathonInviteCreateBulk.OnConflict +// documentation for more info. +func (u *HackathonInviteUpsertBulk) Update(set func(*HackathonInviteUpsert)) *HackathonInviteUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&HackathonInviteUpsert{UpdateSet: update}) + })) + return u +} + +// SetRevokedAt sets the "revoked_at" field. +func (u *HackathonInviteUpsertBulk) SetRevokedAt(v time.Time) *HackathonInviteUpsertBulk { + return u.Update(func(s *HackathonInviteUpsert) { + s.SetRevokedAt(v) + }) +} + +// UpdateRevokedAt sets the "revoked_at" field to the value that was provided on create. +func (u *HackathonInviteUpsertBulk) UpdateRevokedAt() *HackathonInviteUpsertBulk { + return u.Update(func(s *HackathonInviteUpsert) { + s.UpdateRevokedAt() + }) +} + +// ClearRevokedAt clears the value of the "revoked_at" field. +func (u *HackathonInviteUpsertBulk) ClearRevokedAt() *HackathonInviteUpsertBulk { + return u.Update(func(s *HackathonInviteUpsert) { + s.ClearRevokedAt() + }) +} + +// SetToken sets the "token" field. +func (u *HackathonInviteUpsertBulk) SetToken(v uuid.UUID) *HackathonInviteUpsertBulk { + return u.Update(func(s *HackathonInviteUpsert) { + s.SetToken(v) + }) +} + +// UpdateToken sets the "token" field to the value that was provided on create. +func (u *HackathonInviteUpsertBulk) UpdateToken() *HackathonInviteUpsertBulk { + return u.Update(func(s *HackathonInviteUpsert) { + s.UpdateToken() + }) +} + +// SetNote sets the "note" field. +func (u *HackathonInviteUpsertBulk) SetNote(v string) *HackathonInviteUpsertBulk { + return u.Update(func(s *HackathonInviteUpsert) { + s.SetNote(v) + }) +} + +// UpdateNote sets the "note" field to the value that was provided on create. +func (u *HackathonInviteUpsertBulk) UpdateNote() *HackathonInviteUpsertBulk { + return u.Update(func(s *HackathonInviteUpsert) { + s.UpdateNote() + }) +} + +// ClearNote clears the value of the "note" field. +func (u *HackathonInviteUpsertBulk) ClearNote() *HackathonInviteUpsertBulk { + return u.Update(func(s *HackathonInviteUpsert) { + s.ClearNote() + }) +} + +// SetExpiresAt sets the "expires_at" field. +func (u *HackathonInviteUpsertBulk) SetExpiresAt(v time.Time) *HackathonInviteUpsertBulk { + return u.Update(func(s *HackathonInviteUpsert) { + s.SetExpiresAt(v) + }) +} + +// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create. +func (u *HackathonInviteUpsertBulk) UpdateExpiresAt() *HackathonInviteUpsertBulk { + return u.Update(func(s *HackathonInviteUpsert) { + s.UpdateExpiresAt() + }) +} + +// ClearExpiresAt clears the value of the "expires_at" field. +func (u *HackathonInviteUpsertBulk) ClearExpiresAt() *HackathonInviteUpsertBulk { + return u.Update(func(s *HackathonInviteUpsert) { + s.ClearExpiresAt() + }) +} + +// Exec executes the query. +func (u *HackathonInviteUpsertBulk) Exec(ctx context.Context) error { + if u.create.err != nil { + return u.create.err + } + for i, b := range u.create.builders { + if len(b.conflict) != 0 { + return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the HackathonInviteCreateBulk instead", i) + } + } + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for HackathonInviteCreateBulk.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *HackathonInviteUpsertBulk) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/components/backend/ent/hackathoninvite_delete.go b/components/backend/ent/hackathoninvite_delete.go new file mode 100644 index 00000000..e5a4c812 --- /dev/null +++ b/components/backend/ent/hackathoninvite_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/predicate" +) + +// HackathonInviteDelete is the builder for deleting a HackathonInvite entity. +type HackathonInviteDelete struct { + config + hooks []Hook + mutation *HackathonInviteMutation +} + +// Where appends a list predicates to the HackathonInviteDelete builder. +func (_d *HackathonInviteDelete) Where(ps ...predicate.HackathonInvite) *HackathonInviteDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *HackathonInviteDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *HackathonInviteDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *HackathonInviteDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(hackathoninvite.Table, sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID)) + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// HackathonInviteDeleteOne is the builder for deleting a single HackathonInvite entity. +type HackathonInviteDeleteOne struct { + _d *HackathonInviteDelete +} + +// Where appends a list predicates to the HackathonInviteDelete builder. +func (_d *HackathonInviteDeleteOne) Where(ps ...predicate.HackathonInvite) *HackathonInviteDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *HackathonInviteDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{hackathoninvite.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *HackathonInviteDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/components/backend/ent/hackathoninvite_query.go b/components/backend/ent/hackathoninvite_query.go new file mode 100644 index 00000000..82360d12 --- /dev/null +++ b/components/backend/ent/hackathoninvite_query.go @@ -0,0 +1,690 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/google/uuid" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/predicate" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/user" +) + +// HackathonInviteQuery is the builder for querying HackathonInvite entities. +type HackathonInviteQuery struct { + config + ctx *QueryContext + order []hackathoninvite.OrderOption + inters []Interceptor + predicates []predicate.HackathonInvite + withHackathon *HackathonQuery + withCreator *UserQuery + withFKs bool + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the HackathonInviteQuery builder. +func (_q *HackathonInviteQuery) Where(ps ...predicate.HackathonInvite) *HackathonInviteQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *HackathonInviteQuery) Limit(limit int) *HackathonInviteQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *HackathonInviteQuery) Offset(offset int) *HackathonInviteQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *HackathonInviteQuery) Unique(unique bool) *HackathonInviteQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *HackathonInviteQuery) Order(o ...hackathoninvite.OrderOption) *HackathonInviteQuery { + _q.order = append(_q.order, o...) + return _q +} + +// QueryHackathon chains the current query on the "hackathon" edge. +func (_q *HackathonInviteQuery) QueryHackathon() *HackathonQuery { + query := (&HackathonClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(hackathoninvite.Table, hackathoninvite.FieldID, selector), + sqlgraph.To(hackathon.Table, hackathon.FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, hackathoninvite.HackathonTable, hackathoninvite.HackathonColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryCreator chains the current query on the "creator" edge. +func (_q *HackathonInviteQuery) QueryCreator() *UserQuery { + query := (&UserClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(hackathoninvite.Table, hackathoninvite.FieldID, selector), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, hackathoninvite.CreatorTable, hackathoninvite.CreatorColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first HackathonInvite entity from the query. +// Returns a *NotFoundError when no HackathonInvite was found. +func (_q *HackathonInviteQuery) First(ctx context.Context) (*HackathonInvite, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{hackathoninvite.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *HackathonInviteQuery) FirstX(ctx context.Context) *HackathonInvite { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first HackathonInvite ID from the query. +// Returns a *NotFoundError when no HackathonInvite ID was found. +func (_q *HackathonInviteQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{hackathoninvite.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *HackathonInviteQuery) FirstIDX(ctx context.Context) uuid.UUID { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single HackathonInvite entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one HackathonInvite entity is found. +// Returns a *NotFoundError when no HackathonInvite entities are found. +func (_q *HackathonInviteQuery) Only(ctx context.Context) (*HackathonInvite, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{hackathoninvite.Label} + default: + return nil, &NotSingularError{hackathoninvite.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *HackathonInviteQuery) OnlyX(ctx context.Context) *HackathonInvite { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only HackathonInvite ID in the query. +// Returns a *NotSingularError when more than one HackathonInvite ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *HackathonInviteQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) { + var ids []uuid.UUID + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{hackathoninvite.Label} + default: + err = &NotSingularError{hackathoninvite.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *HackathonInviteQuery) OnlyIDX(ctx context.Context) uuid.UUID { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of HackathonInvites. +func (_q *HackathonInviteQuery) All(ctx context.Context) ([]*HackathonInvite, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*HackathonInvite, *HackathonInviteQuery]() + return withInterceptors[[]*HackathonInvite](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *HackathonInviteQuery) AllX(ctx context.Context) []*HackathonInvite { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of HackathonInvite IDs. +func (_q *HackathonInviteQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(hackathoninvite.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *HackathonInviteQuery) IDsX(ctx context.Context) []uuid.UUID { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *HackathonInviteQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*HackathonInviteQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *HackathonInviteQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *HackathonInviteQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *HackathonInviteQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the HackathonInviteQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *HackathonInviteQuery) Clone() *HackathonInviteQuery { + if _q == nil { + return nil + } + return &HackathonInviteQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]hackathoninvite.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.HackathonInvite{}, _q.predicates...), + withHackathon: _q.withHackathon.Clone(), + withCreator: _q.withCreator.Clone(), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// WithHackathon tells the query-builder to eager-load the nodes that are connected to +// the "hackathon" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *HackathonInviteQuery) WithHackathon(opts ...func(*HackathonQuery)) *HackathonInviteQuery { + query := (&HackathonClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withHackathon = query + return _q +} + +// WithCreator tells the query-builder to eager-load the nodes that are connected to +// the "creator" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *HackathonInviteQuery) WithCreator(opts ...func(*UserQuery)) *HackathonInviteQuery { + query := (&UserClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withCreator = query + return _q +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// CreatedAt time.Time `json:"created_at,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.HackathonInvite.Query(). +// GroupBy(hackathoninvite.FieldCreatedAt). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (_q *HackathonInviteQuery) GroupBy(field string, fields ...string) *HackathonInviteGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &HackathonInviteGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = hackathoninvite.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// CreatedAt time.Time `json:"created_at,omitempty"` +// } +// +// client.HackathonInvite.Query(). +// Select(hackathoninvite.FieldCreatedAt). +// Scan(ctx, &v) +func (_q *HackathonInviteQuery) Select(fields ...string) *HackathonInviteSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &HackathonInviteSelect{HackathonInviteQuery: _q} + sbuild.label = hackathoninvite.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a HackathonInviteSelect configured with the given aggregations. +func (_q *HackathonInviteQuery) Aggregate(fns ...AggregateFunc) *HackathonInviteSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *HackathonInviteQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !hackathoninvite.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *HackathonInviteQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*HackathonInvite, error) { + var ( + nodes = []*HackathonInvite{} + withFKs = _q.withFKs + _spec = _q.querySpec() + loadedTypes = [2]bool{ + _q.withHackathon != nil, + _q.withCreator != nil, + } + ) + if _q.withHackathon != nil || _q.withCreator != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, hackathoninvite.ForeignKeys...) + } + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*HackathonInvite).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &HackathonInvite{config: _q.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := _q.withHackathon; query != nil { + if err := _q.loadHackathon(ctx, query, nodes, nil, + func(n *HackathonInvite, e *Hackathon) { n.Edges.Hackathon = e }); err != nil { + return nil, err + } + } + if query := _q.withCreator; query != nil { + if err := _q.loadCreator(ctx, query, nodes, nil, + func(n *HackathonInvite, e *User) { n.Edges.Creator = e }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (_q *HackathonInviteQuery) loadHackathon(ctx context.Context, query *HackathonQuery, nodes []*HackathonInvite, init func(*HackathonInvite), assign func(*HackathonInvite, *Hackathon)) error { + ids := make([]uuid.UUID, 0, len(nodes)) + nodeids := make(map[uuid.UUID][]*HackathonInvite) + for i := range nodes { + if nodes[i].hackathon_invite_hackathon == nil { + continue + } + fk := *nodes[i].hackathon_invite_hackathon + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(hackathon.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "hackathon_invite_hackathon" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} +func (_q *HackathonInviteQuery) loadCreator(ctx context.Context, query *UserQuery, nodes []*HackathonInvite, init func(*HackathonInvite), assign func(*HackathonInvite, *User)) error { + ids := make([]uuid.UUID, 0, len(nodes)) + nodeids := make(map[uuid.UUID][]*HackathonInvite) + for i := range nodes { + if nodes[i].user_created_hackathon_invites == nil { + continue + } + fk := *nodes[i].user_created_hackathon_invites + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(user.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "user_created_hackathon_invites" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} + +func (_q *HackathonInviteQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *HackathonInviteQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(hackathoninvite.Table, hackathoninvite.Columns, sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, hackathoninvite.FieldID) + for i := range fields { + if fields[i] != hackathoninvite.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *HackathonInviteQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(hackathoninvite.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = hackathoninvite.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// HackathonInviteGroupBy is the group-by builder for HackathonInvite entities. +type HackathonInviteGroupBy struct { + selector + build *HackathonInviteQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *HackathonInviteGroupBy) Aggregate(fns ...AggregateFunc) *HackathonInviteGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *HackathonInviteGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*HackathonInviteQuery, *HackathonInviteGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *HackathonInviteGroupBy) sqlScan(ctx context.Context, root *HackathonInviteQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// HackathonInviteSelect is the builder for selecting fields of HackathonInvite entities. +type HackathonInviteSelect struct { + *HackathonInviteQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *HackathonInviteSelect) Aggregate(fns ...AggregateFunc) *HackathonInviteSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *HackathonInviteSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*HackathonInviteQuery, *HackathonInviteSelect](ctx, _s.HackathonInviteQuery, _s, _s.inters, v) +} + +func (_s *HackathonInviteSelect) sqlScan(ctx context.Context, root *HackathonInviteQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/components/backend/ent/hackathoninvite_update.go b/components/backend/ent/hackathoninvite_update.go new file mode 100644 index 00000000..ab48d139 --- /dev/null +++ b/components/backend/ent/hackathoninvite_update.go @@ -0,0 +1,405 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/google/uuid" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/predicate" +) + +// HackathonInviteUpdate is the builder for updating HackathonInvite entities. +type HackathonInviteUpdate struct { + config + hooks []Hook + mutation *HackathonInviteMutation +} + +// Where appends a list predicates to the HackathonInviteUpdate builder. +func (_u *HackathonInviteUpdate) Where(ps ...predicate.HackathonInvite) *HackathonInviteUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetRevokedAt sets the "revoked_at" field. +func (_u *HackathonInviteUpdate) SetRevokedAt(v time.Time) *HackathonInviteUpdate { + _u.mutation.SetRevokedAt(v) + return _u +} + +// SetNillableRevokedAt sets the "revoked_at" field if the given value is not nil. +func (_u *HackathonInviteUpdate) SetNillableRevokedAt(v *time.Time) *HackathonInviteUpdate { + if v != nil { + _u.SetRevokedAt(*v) + } + return _u +} + +// ClearRevokedAt clears the value of the "revoked_at" field. +func (_u *HackathonInviteUpdate) ClearRevokedAt() *HackathonInviteUpdate { + _u.mutation.ClearRevokedAt() + return _u +} + +// SetToken sets the "token" field. +func (_u *HackathonInviteUpdate) SetToken(v uuid.UUID) *HackathonInviteUpdate { + _u.mutation.SetToken(v) + return _u +} + +// SetNillableToken sets the "token" field if the given value is not nil. +func (_u *HackathonInviteUpdate) SetNillableToken(v *uuid.UUID) *HackathonInviteUpdate { + if v != nil { + _u.SetToken(*v) + } + return _u +} + +// SetNote sets the "note" field. +func (_u *HackathonInviteUpdate) SetNote(v string) *HackathonInviteUpdate { + _u.mutation.SetNote(v) + return _u +} + +// SetNillableNote sets the "note" field if the given value is not nil. +func (_u *HackathonInviteUpdate) SetNillableNote(v *string) *HackathonInviteUpdate { + if v != nil { + _u.SetNote(*v) + } + return _u +} + +// ClearNote clears the value of the "note" field. +func (_u *HackathonInviteUpdate) ClearNote() *HackathonInviteUpdate { + _u.mutation.ClearNote() + return _u +} + +// SetExpiresAt sets the "expires_at" field. +func (_u *HackathonInviteUpdate) SetExpiresAt(v time.Time) *HackathonInviteUpdate { + _u.mutation.SetExpiresAt(v) + return _u +} + +// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil. +func (_u *HackathonInviteUpdate) SetNillableExpiresAt(v *time.Time) *HackathonInviteUpdate { + if v != nil { + _u.SetExpiresAt(*v) + } + return _u +} + +// ClearExpiresAt clears the value of the "expires_at" field. +func (_u *HackathonInviteUpdate) ClearExpiresAt() *HackathonInviteUpdate { + _u.mutation.ClearExpiresAt() + return _u +} + +// Mutation returns the HackathonInviteMutation object of the builder. +func (_u *HackathonInviteUpdate) Mutation() *HackathonInviteMutation { + return _u.mutation +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *HackathonInviteUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *HackathonInviteUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *HackathonInviteUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *HackathonInviteUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *HackathonInviteUpdate) check() error { + if v, ok := _u.mutation.Note(); ok { + if err := hackathoninvite.NoteValidator(v); err != nil { + return &ValidationError{Name: "note", err: fmt.Errorf(`ent: validator failed for field "HackathonInvite.note": %w`, err)} + } + } + if _u.mutation.HackathonCleared() && len(_u.mutation.HackathonIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "HackathonInvite.hackathon"`) + } + if _u.mutation.CreatorCleared() && len(_u.mutation.CreatorIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "HackathonInvite.creator"`) + } + return nil +} + +func (_u *HackathonInviteUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(hackathoninvite.Table, hackathoninvite.Columns, sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.RevokedAt(); ok { + _spec.SetField(hackathoninvite.FieldRevokedAt, field.TypeTime, value) + } + if _u.mutation.RevokedAtCleared() { + _spec.ClearField(hackathoninvite.FieldRevokedAt, field.TypeTime) + } + if value, ok := _u.mutation.Token(); ok { + _spec.SetField(hackathoninvite.FieldToken, field.TypeUUID, value) + } + if value, ok := _u.mutation.Note(); ok { + _spec.SetField(hackathoninvite.FieldNote, field.TypeString, value) + } + if _u.mutation.NoteCleared() { + _spec.ClearField(hackathoninvite.FieldNote, field.TypeString) + } + if value, ok := _u.mutation.ExpiresAt(); ok { + _spec.SetField(hackathoninvite.FieldExpiresAt, field.TypeTime, value) + } + if _u.mutation.ExpiresAtCleared() { + _spec.ClearField(hackathoninvite.FieldExpiresAt, field.TypeTime) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{hackathoninvite.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// HackathonInviteUpdateOne is the builder for updating a single HackathonInvite entity. +type HackathonInviteUpdateOne struct { + config + fields []string + hooks []Hook + mutation *HackathonInviteMutation +} + +// SetRevokedAt sets the "revoked_at" field. +func (_u *HackathonInviteUpdateOne) SetRevokedAt(v time.Time) *HackathonInviteUpdateOne { + _u.mutation.SetRevokedAt(v) + return _u +} + +// SetNillableRevokedAt sets the "revoked_at" field if the given value is not nil. +func (_u *HackathonInviteUpdateOne) SetNillableRevokedAt(v *time.Time) *HackathonInviteUpdateOne { + if v != nil { + _u.SetRevokedAt(*v) + } + return _u +} + +// ClearRevokedAt clears the value of the "revoked_at" field. +func (_u *HackathonInviteUpdateOne) ClearRevokedAt() *HackathonInviteUpdateOne { + _u.mutation.ClearRevokedAt() + return _u +} + +// SetToken sets the "token" field. +func (_u *HackathonInviteUpdateOne) SetToken(v uuid.UUID) *HackathonInviteUpdateOne { + _u.mutation.SetToken(v) + return _u +} + +// SetNillableToken sets the "token" field if the given value is not nil. +func (_u *HackathonInviteUpdateOne) SetNillableToken(v *uuid.UUID) *HackathonInviteUpdateOne { + if v != nil { + _u.SetToken(*v) + } + return _u +} + +// SetNote sets the "note" field. +func (_u *HackathonInviteUpdateOne) SetNote(v string) *HackathonInviteUpdateOne { + _u.mutation.SetNote(v) + return _u +} + +// SetNillableNote sets the "note" field if the given value is not nil. +func (_u *HackathonInviteUpdateOne) SetNillableNote(v *string) *HackathonInviteUpdateOne { + if v != nil { + _u.SetNote(*v) + } + return _u +} + +// ClearNote clears the value of the "note" field. +func (_u *HackathonInviteUpdateOne) ClearNote() *HackathonInviteUpdateOne { + _u.mutation.ClearNote() + return _u +} + +// SetExpiresAt sets the "expires_at" field. +func (_u *HackathonInviteUpdateOne) SetExpiresAt(v time.Time) *HackathonInviteUpdateOne { + _u.mutation.SetExpiresAt(v) + return _u +} + +// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil. +func (_u *HackathonInviteUpdateOne) SetNillableExpiresAt(v *time.Time) *HackathonInviteUpdateOne { + if v != nil { + _u.SetExpiresAt(*v) + } + return _u +} + +// ClearExpiresAt clears the value of the "expires_at" field. +func (_u *HackathonInviteUpdateOne) ClearExpiresAt() *HackathonInviteUpdateOne { + _u.mutation.ClearExpiresAt() + return _u +} + +// Mutation returns the HackathonInviteMutation object of the builder. +func (_u *HackathonInviteUpdateOne) Mutation() *HackathonInviteMutation { + return _u.mutation +} + +// Where appends a list predicates to the HackathonInviteUpdate builder. +func (_u *HackathonInviteUpdateOne) Where(ps ...predicate.HackathonInvite) *HackathonInviteUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *HackathonInviteUpdateOne) Select(field string, fields ...string) *HackathonInviteUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated HackathonInvite entity. +func (_u *HackathonInviteUpdateOne) Save(ctx context.Context) (*HackathonInvite, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *HackathonInviteUpdateOne) SaveX(ctx context.Context) *HackathonInvite { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *HackathonInviteUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *HackathonInviteUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *HackathonInviteUpdateOne) check() error { + if v, ok := _u.mutation.Note(); ok { + if err := hackathoninvite.NoteValidator(v); err != nil { + return &ValidationError{Name: "note", err: fmt.Errorf(`ent: validator failed for field "HackathonInvite.note": %w`, err)} + } + } + if _u.mutation.HackathonCleared() && len(_u.mutation.HackathonIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "HackathonInvite.hackathon"`) + } + if _u.mutation.CreatorCleared() && len(_u.mutation.CreatorIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "HackathonInvite.creator"`) + } + return nil +} + +func (_u *HackathonInviteUpdateOne) sqlSave(ctx context.Context) (_node *HackathonInvite, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(hackathoninvite.Table, hackathoninvite.Columns, sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "HackathonInvite.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, hackathoninvite.FieldID) + for _, f := range fields { + if !hackathoninvite.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != hackathoninvite.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.RevokedAt(); ok { + _spec.SetField(hackathoninvite.FieldRevokedAt, field.TypeTime, value) + } + if _u.mutation.RevokedAtCleared() { + _spec.ClearField(hackathoninvite.FieldRevokedAt, field.TypeTime) + } + if value, ok := _u.mutation.Token(); ok { + _spec.SetField(hackathoninvite.FieldToken, field.TypeUUID, value) + } + if value, ok := _u.mutation.Note(); ok { + _spec.SetField(hackathoninvite.FieldNote, field.TypeString, value) + } + if _u.mutation.NoteCleared() { + _spec.ClearField(hackathoninvite.FieldNote, field.TypeString) + } + if value, ok := _u.mutation.ExpiresAt(); ok { + _spec.SetField(hackathoninvite.FieldExpiresAt, field.TypeTime, value) + } + if _u.mutation.ExpiresAtCleared() { + _spec.ClearField(hackathoninvite.FieldExpiresAt, field.TypeTime) + } + _node = &HackathonInvite{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{hackathoninvite.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/components/backend/ent/hook/hook.go b/components/backend/ent/hook/hook.go index f49147b4..392297c1 100644 --- a/components/backend/ent/hook/hook.go +++ b/components/backend/ent/hook/hook.go @@ -33,6 +33,18 @@ func (f HackathonFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, e return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.HackathonMutation", m) } +// The HackathonInviteFunc type is an adapter to allow the use of ordinary +// function as HackathonInvite mutator. +type HackathonInviteFunc func(context.Context, *ent.HackathonInviteMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f HackathonInviteFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.HackathonInviteMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.HackathonInviteMutation", m) +} + // The HackathonStateFunc type is an adapter to allow the use of ordinary // function as HackathonState mutator. type HackathonStateFunc func(context.Context, *ent.HackathonStateMutation) (ent.Value, error) diff --git a/components/backend/ent/migrate/schema.go b/components/backend/ent/migrate/schema.go index 248a9afe..bd8a91a2 100644 --- a/components/backend/ent/migrate/schema.go +++ b/components/backend/ent/migrate/schema.go @@ -107,6 +107,37 @@ var ( }, }, } + // HackathonInvitesColumns holds the columns for the "hackathon_invites" table. + HackathonInvitesColumns = []*schema.Column{ + {Name: "id", Type: field.TypeUUID}, + {Name: "created_at", Type: field.TypeTime}, + {Name: "revoked_at", Type: field.TypeTime, Nullable: true}, + {Name: "token", Type: field.TypeUUID, Unique: true}, + {Name: "note", Type: field.TypeString, Nullable: true, Size: 500}, + {Name: "expires_at", Type: field.TypeTime, Nullable: true}, + {Name: "hackathon_invite_hackathon", Type: field.TypeUUID}, + {Name: "user_created_hackathon_invites", Type: field.TypeUUID}, + } + // HackathonInvitesTable holds the schema information for the "hackathon_invites" table. + HackathonInvitesTable = &schema.Table{ + Name: "hackathon_invites", + Columns: HackathonInvitesColumns, + PrimaryKey: []*schema.Column{HackathonInvitesColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "hackathon_invites_hackathons_hackathon", + Columns: []*schema.Column{HackathonInvitesColumns[6]}, + RefColumns: []*schema.Column{HackathonsColumns[0]}, + OnDelete: schema.NoAction, + }, + { + Symbol: "hackathon_invites_users_created_hackathon_invites", + Columns: []*schema.Column{HackathonInvitesColumns[7]}, + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.Restrict, + }, + }, + } // HackathonStatesColumns holds the columns for the "hackathon_states" table. HackathonStatesColumns = []*schema.Column{ {Name: "id", Type: field.TypeUUID}, @@ -762,6 +793,7 @@ var ( Tables = []*schema.Table{ AnswersTable, HackathonsTable, + HackathonInvitesTable, HackathonStatesTable, PagesTable, ParticipantsTable, @@ -788,6 +820,8 @@ func init() { HackathonsTable.ForeignKeys[0].RefTable = PhasesTable HackathonsTable.ForeignKeys[1].RefTable = UsersTable HackathonsTable.ForeignKeys[2].RefTable = UsersTable + HackathonInvitesTable.ForeignKeys[0].RefTable = HackathonsTable + HackathonInvitesTable.ForeignKeys[1].RefTable = UsersTable HackathonStatesTable.ForeignKeys[0].RefTable = HackathonsTable HackathonStatesTable.ForeignKeys[1].RefTable = PhasesTable HackathonStatesTable.ForeignKeys[2].RefTable = UsersTable diff --git a/components/backend/ent/mutation.go b/components/backend/ent/mutation.go index fc64dd40..36db0ef6 100644 --- a/components/backend/ent/mutation.go +++ b/components/backend/ent/mutation.go @@ -14,6 +14,7 @@ import ( "github.com/google/uuid" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/answer" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathonstate" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/page" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/participant" @@ -42,6 +43,7 @@ const ( // Node types. TypeAnswer = "Answer" TypeHackathon = "Hackathon" + TypeHackathonInvite = "HackathonInvite" TypeHackathonState = "HackathonState" TypePage = "Page" TypeParticipant = "Participant" @@ -2346,6 +2348,740 @@ func (m *HackathonMutation) ResetEdge(name string) error { return fmt.Errorf("unknown Hackathon edge %s", name) } +// HackathonInviteMutation represents an operation that mutates the HackathonInvite nodes in the graph. +type HackathonInviteMutation struct { + config + op Op + typ string + id *uuid.UUID + created_at *time.Time + revoked_at *time.Time + token *uuid.UUID + note *string + expires_at *time.Time + clearedFields map[string]struct{} + hackathon *uuid.UUID + clearedhackathon bool + creator *uuid.UUID + clearedcreator bool + done bool + oldValue func(context.Context) (*HackathonInvite, error) + predicates []predicate.HackathonInvite +} + +var _ ent.Mutation = (*HackathonInviteMutation)(nil) + +// hackathoninviteOption allows management of the mutation configuration using functional options. +type hackathoninviteOption func(*HackathonInviteMutation) + +// newHackathonInviteMutation creates new mutation for the HackathonInvite entity. +func newHackathonInviteMutation(c config, op Op, opts ...hackathoninviteOption) *HackathonInviteMutation { + m := &HackathonInviteMutation{ + config: c, + op: op, + typ: TypeHackathonInvite, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withHackathonInviteID sets the ID field of the mutation. +func withHackathonInviteID(id uuid.UUID) hackathoninviteOption { + return func(m *HackathonInviteMutation) { + var ( + err error + once sync.Once + value *HackathonInvite + ) + m.oldValue = func(ctx context.Context) (*HackathonInvite, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().HackathonInvite.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withHackathonInvite sets the old HackathonInvite of the mutation. +func withHackathonInvite(node *HackathonInvite) hackathoninviteOption { + return func(m *HackathonInviteMutation) { + m.oldValue = func(context.Context) (*HackathonInvite, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m HackathonInviteMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m HackathonInviteMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of HackathonInvite entities. +func (m *HackathonInviteMutation) SetID(id uuid.UUID) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *HackathonInviteMutation) ID() (id uuid.UUID, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *HackathonInviteMutation) IDs(ctx context.Context) ([]uuid.UUID, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []uuid.UUID{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().HackathonInvite.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetCreatedAt sets the "created_at" field. +func (m *HackathonInviteMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *HackathonInviteMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_at" field's value of the HackathonInvite entity. +// If the HackathonInvite 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 *HackathonInviteMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *HackathonInviteMutation) ResetCreatedAt() { + m.created_at = nil +} + +// SetRevokedAt sets the "revoked_at" field. +func (m *HackathonInviteMutation) SetRevokedAt(t time.Time) { + m.revoked_at = &t +} + +// RevokedAt returns the value of the "revoked_at" field in the mutation. +func (m *HackathonInviteMutation) RevokedAt() (r time.Time, exists bool) { + v := m.revoked_at + if v == nil { + return + } + return *v, true +} + +// OldRevokedAt returns the old "revoked_at" field's value of the HackathonInvite entity. +// If the HackathonInvite 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 *HackathonInviteMutation) OldRevokedAt(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRevokedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRevokedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRevokedAt: %w", err) + } + return oldValue.RevokedAt, nil +} + +// ClearRevokedAt clears the value of the "revoked_at" field. +func (m *HackathonInviteMutation) ClearRevokedAt() { + m.revoked_at = nil + m.clearedFields[hackathoninvite.FieldRevokedAt] = struct{}{} +} + +// RevokedAtCleared returns if the "revoked_at" field was cleared in this mutation. +func (m *HackathonInviteMutation) RevokedAtCleared() bool { + _, ok := m.clearedFields[hackathoninvite.FieldRevokedAt] + return ok +} + +// ResetRevokedAt resets all changes to the "revoked_at" field. +func (m *HackathonInviteMutation) ResetRevokedAt() { + m.revoked_at = nil + delete(m.clearedFields, hackathoninvite.FieldRevokedAt) +} + +// SetToken sets the "token" field. +func (m *HackathonInviteMutation) SetToken(u uuid.UUID) { + m.token = &u +} + +// Token returns the value of the "token" field in the mutation. +func (m *HackathonInviteMutation) Token() (r uuid.UUID, exists bool) { + v := m.token + if v == nil { + return + } + return *v, true +} + +// OldToken returns the old "token" field's value of the HackathonInvite entity. +// If the HackathonInvite 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 *HackathonInviteMutation) OldToken(ctx context.Context) (v uuid.UUID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldToken is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldToken requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldToken: %w", err) + } + return oldValue.Token, nil +} + +// ResetToken resets all changes to the "token" field. +func (m *HackathonInviteMutation) ResetToken() { + m.token = nil +} + +// SetNote sets the "note" field. +func (m *HackathonInviteMutation) SetNote(s string) { + m.note = &s +} + +// Note returns the value of the "note" field in the mutation. +func (m *HackathonInviteMutation) Note() (r string, exists bool) { + v := m.note + if v == nil { + return + } + return *v, true +} + +// OldNote returns the old "note" field's value of the HackathonInvite entity. +// If the HackathonInvite 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 *HackathonInviteMutation) OldNote(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldNote is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldNote requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldNote: %w", err) + } + return oldValue.Note, nil +} + +// ClearNote clears the value of the "note" field. +func (m *HackathonInviteMutation) ClearNote() { + m.note = nil + m.clearedFields[hackathoninvite.FieldNote] = struct{}{} +} + +// NoteCleared returns if the "note" field was cleared in this mutation. +func (m *HackathonInviteMutation) NoteCleared() bool { + _, ok := m.clearedFields[hackathoninvite.FieldNote] + return ok +} + +// ResetNote resets all changes to the "note" field. +func (m *HackathonInviteMutation) ResetNote() { + m.note = nil + delete(m.clearedFields, hackathoninvite.FieldNote) +} + +// SetExpiresAt sets the "expires_at" field. +func (m *HackathonInviteMutation) SetExpiresAt(t time.Time) { + m.expires_at = &t +} + +// ExpiresAt returns the value of the "expires_at" field in the mutation. +func (m *HackathonInviteMutation) ExpiresAt() (r time.Time, exists bool) { + v := m.expires_at + if v == nil { + return + } + return *v, true +} + +// OldExpiresAt returns the old "expires_at" field's value of the HackathonInvite entity. +// If the HackathonInvite 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 *HackathonInviteMutation) OldExpiresAt(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldExpiresAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldExpiresAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldExpiresAt: %w", err) + } + return oldValue.ExpiresAt, nil +} + +// ClearExpiresAt clears the value of the "expires_at" field. +func (m *HackathonInviteMutation) ClearExpiresAt() { + m.expires_at = nil + m.clearedFields[hackathoninvite.FieldExpiresAt] = struct{}{} +} + +// ExpiresAtCleared returns if the "expires_at" field was cleared in this mutation. +func (m *HackathonInviteMutation) ExpiresAtCleared() bool { + _, ok := m.clearedFields[hackathoninvite.FieldExpiresAt] + return ok +} + +// ResetExpiresAt resets all changes to the "expires_at" field. +func (m *HackathonInviteMutation) ResetExpiresAt() { + m.expires_at = nil + delete(m.clearedFields, hackathoninvite.FieldExpiresAt) +} + +// SetHackathonID sets the "hackathon" edge to the Hackathon entity by id. +func (m *HackathonInviteMutation) SetHackathonID(id uuid.UUID) { + m.hackathon = &id +} + +// ClearHackathon clears the "hackathon" edge to the Hackathon entity. +func (m *HackathonInviteMutation) ClearHackathon() { + m.clearedhackathon = true +} + +// HackathonCleared reports if the "hackathon" edge to the Hackathon entity was cleared. +func (m *HackathonInviteMutation) HackathonCleared() bool { + return m.clearedhackathon +} + +// HackathonID returns the "hackathon" edge ID in the mutation. +func (m *HackathonInviteMutation) HackathonID() (id uuid.UUID, exists bool) { + if m.hackathon != nil { + return *m.hackathon, true + } + return +} + +// HackathonIDs returns the "hackathon" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// HackathonID instead. It exists only for internal usage by the builders. +func (m *HackathonInviteMutation) HackathonIDs() (ids []uuid.UUID) { + if id := m.hackathon; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetHackathon resets all changes to the "hackathon" edge. +func (m *HackathonInviteMutation) ResetHackathon() { + m.hackathon = nil + m.clearedhackathon = false +} + +// SetCreatorID sets the "creator" edge to the User entity by id. +func (m *HackathonInviteMutation) SetCreatorID(id uuid.UUID) { + m.creator = &id +} + +// ClearCreator clears the "creator" edge to the User entity. +func (m *HackathonInviteMutation) ClearCreator() { + m.clearedcreator = true +} + +// CreatorCleared reports if the "creator" edge to the User entity was cleared. +func (m *HackathonInviteMutation) CreatorCleared() bool { + return m.clearedcreator +} + +// CreatorID returns the "creator" edge ID in the mutation. +func (m *HackathonInviteMutation) CreatorID() (id uuid.UUID, exists bool) { + if m.creator != nil { + return *m.creator, true + } + return +} + +// CreatorIDs returns the "creator" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// CreatorID instead. It exists only for internal usage by the builders. +func (m *HackathonInviteMutation) CreatorIDs() (ids []uuid.UUID) { + if id := m.creator; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetCreator resets all changes to the "creator" edge. +func (m *HackathonInviteMutation) ResetCreator() { + m.creator = nil + m.clearedcreator = false +} + +// Where appends a list predicates to the HackathonInviteMutation builder. +func (m *HackathonInviteMutation) Where(ps ...predicate.HackathonInvite) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the HackathonInviteMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *HackathonInviteMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.HackathonInvite, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *HackathonInviteMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *HackathonInviteMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (HackathonInvite). +func (m *HackathonInviteMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *HackathonInviteMutation) Fields() []string { + fields := make([]string, 0, 5) + if m.created_at != nil { + fields = append(fields, hackathoninvite.FieldCreatedAt) + } + if m.revoked_at != nil { + fields = append(fields, hackathoninvite.FieldRevokedAt) + } + if m.token != nil { + fields = append(fields, hackathoninvite.FieldToken) + } + if m.note != nil { + fields = append(fields, hackathoninvite.FieldNote) + } + if m.expires_at != nil { + fields = append(fields, hackathoninvite.FieldExpiresAt) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *HackathonInviteMutation) Field(name string) (ent.Value, bool) { + switch name { + case hackathoninvite.FieldCreatedAt: + return m.CreatedAt() + case hackathoninvite.FieldRevokedAt: + return m.RevokedAt() + case hackathoninvite.FieldToken: + return m.Token() + case hackathoninvite.FieldNote: + return m.Note() + case hackathoninvite.FieldExpiresAt: + return m.ExpiresAt() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *HackathonInviteMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case hackathoninvite.FieldCreatedAt: + return m.OldCreatedAt(ctx) + case hackathoninvite.FieldRevokedAt: + return m.OldRevokedAt(ctx) + case hackathoninvite.FieldToken: + return m.OldToken(ctx) + case hackathoninvite.FieldNote: + return m.OldNote(ctx) + case hackathoninvite.FieldExpiresAt: + return m.OldExpiresAt(ctx) + } + return nil, fmt.Errorf("unknown HackathonInvite field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *HackathonInviteMutation) SetField(name string, value ent.Value) error { + switch name { + case hackathoninvite.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + case hackathoninvite.FieldRevokedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRevokedAt(v) + return nil + case hackathoninvite.FieldToken: + v, ok := value.(uuid.UUID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetToken(v) + return nil + case hackathoninvite.FieldNote: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNote(v) + return nil + case hackathoninvite.FieldExpiresAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetExpiresAt(v) + return nil + } + return fmt.Errorf("unknown HackathonInvite field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *HackathonInviteMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *HackathonInviteMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *HackathonInviteMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown HackathonInvite numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *HackathonInviteMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(hackathoninvite.FieldRevokedAt) { + fields = append(fields, hackathoninvite.FieldRevokedAt) + } + if m.FieldCleared(hackathoninvite.FieldNote) { + fields = append(fields, hackathoninvite.FieldNote) + } + if m.FieldCleared(hackathoninvite.FieldExpiresAt) { + fields = append(fields, hackathoninvite.FieldExpiresAt) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *HackathonInviteMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *HackathonInviteMutation) ClearField(name string) error { + switch name { + case hackathoninvite.FieldRevokedAt: + m.ClearRevokedAt() + return nil + case hackathoninvite.FieldNote: + m.ClearNote() + return nil + case hackathoninvite.FieldExpiresAt: + m.ClearExpiresAt() + return nil + } + return fmt.Errorf("unknown HackathonInvite nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *HackathonInviteMutation) ResetField(name string) error { + switch name { + case hackathoninvite.FieldCreatedAt: + m.ResetCreatedAt() + return nil + case hackathoninvite.FieldRevokedAt: + m.ResetRevokedAt() + return nil + case hackathoninvite.FieldToken: + m.ResetToken() + return nil + case hackathoninvite.FieldNote: + m.ResetNote() + return nil + case hackathoninvite.FieldExpiresAt: + m.ResetExpiresAt() + return nil + } + return fmt.Errorf("unknown HackathonInvite field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *HackathonInviteMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.hackathon != nil { + edges = append(edges, hackathoninvite.EdgeHackathon) + } + if m.creator != nil { + edges = append(edges, hackathoninvite.EdgeCreator) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *HackathonInviteMutation) AddedIDs(name string) []ent.Value { + switch name { + case hackathoninvite.EdgeHackathon: + if id := m.hackathon; id != nil { + return []ent.Value{*id} + } + case hackathoninvite.EdgeCreator: + if id := m.creator; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *HackathonInviteMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *HackathonInviteMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *HackathonInviteMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedhackathon { + edges = append(edges, hackathoninvite.EdgeHackathon) + } + if m.clearedcreator { + edges = append(edges, hackathoninvite.EdgeCreator) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *HackathonInviteMutation) EdgeCleared(name string) bool { + switch name { + case hackathoninvite.EdgeHackathon: + return m.clearedhackathon + case hackathoninvite.EdgeCreator: + return m.clearedcreator + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *HackathonInviteMutation) ClearEdge(name string) error { + switch name { + case hackathoninvite.EdgeHackathon: + m.ClearHackathon() + return nil + case hackathoninvite.EdgeCreator: + m.ClearCreator() + return nil + } + return fmt.Errorf("unknown HackathonInvite unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *HackathonInviteMutation) ResetEdge(name string) error { + switch name { + case hackathoninvite.EdgeHackathon: + m.ResetHackathon() + return nil + case hackathoninvite.EdgeCreator: + m.ResetCreator() + return nil + } + return fmt.Errorf("unknown HackathonInvite edge %s", name) +} + // HackathonStateMutation represents an operation that mutates the HackathonState nodes in the graph. type HackathonStateMutation struct { config @@ -11048,6 +11784,9 @@ type UserMutation struct { created_hackathons map[uuid.UUID]struct{} removedcreated_hackathons map[uuid.UUID]struct{} clearedcreated_hackathons bool + created_hackathon_invites map[uuid.UUID]struct{} + removedcreated_hackathon_invites map[uuid.UUID]struct{} + clearedcreated_hackathon_invites bool modified_hackathons map[uuid.UUID]struct{} removedmodified_hackathons map[uuid.UUID]struct{} clearedmodified_hackathons bool @@ -11522,6 +12261,60 @@ func (m *UserMutation) ResetCreatedHackathons() { m.removedcreated_hackathons = nil } +// AddCreatedHackathonInviteIDs adds the "created_hackathon_invites" edge to the HackathonInvite entity by ids. +func (m *UserMutation) AddCreatedHackathonInviteIDs(ids ...uuid.UUID) { + if m.created_hackathon_invites == nil { + m.created_hackathon_invites = make(map[uuid.UUID]struct{}) + } + for i := range ids { + m.created_hackathon_invites[ids[i]] = struct{}{} + } +} + +// ClearCreatedHackathonInvites clears the "created_hackathon_invites" edge to the HackathonInvite entity. +func (m *UserMutation) ClearCreatedHackathonInvites() { + m.clearedcreated_hackathon_invites = true +} + +// CreatedHackathonInvitesCleared reports if the "created_hackathon_invites" edge to the HackathonInvite entity was cleared. +func (m *UserMutation) CreatedHackathonInvitesCleared() bool { + return m.clearedcreated_hackathon_invites +} + +// RemoveCreatedHackathonInviteIDs removes the "created_hackathon_invites" edge to the HackathonInvite entity by IDs. +func (m *UserMutation) RemoveCreatedHackathonInviteIDs(ids ...uuid.UUID) { + if m.removedcreated_hackathon_invites == nil { + m.removedcreated_hackathon_invites = make(map[uuid.UUID]struct{}) + } + for i := range ids { + delete(m.created_hackathon_invites, ids[i]) + m.removedcreated_hackathon_invites[ids[i]] = struct{}{} + } +} + +// RemovedCreatedHackathonInvites returns the removed IDs of the "created_hackathon_invites" edge to the HackathonInvite entity. +func (m *UserMutation) RemovedCreatedHackathonInvitesIDs() (ids []uuid.UUID) { + for id := range m.removedcreated_hackathon_invites { + ids = append(ids, id) + } + return +} + +// CreatedHackathonInvitesIDs returns the "created_hackathon_invites" edge IDs in the mutation. +func (m *UserMutation) CreatedHackathonInvitesIDs() (ids []uuid.UUID) { + for id := range m.created_hackathon_invites { + ids = append(ids, id) + } + return +} + +// ResetCreatedHackathonInvites resets all changes to the "created_hackathon_invites" edge. +func (m *UserMutation) ResetCreatedHackathonInvites() { + m.created_hackathon_invites = nil + m.clearedcreated_hackathon_invites = false + m.removedcreated_hackathon_invites = nil +} + // AddModifiedHackathonIDs adds the "modified_hackathons" edge to the Hackathon entity by ids. func (m *UserMutation) AddModifiedHackathonIDs(ids ...uuid.UUID) { if m.modified_hackathons == nil { @@ -12997,10 +13790,13 @@ func (m *UserMutation) ResetField(name string) error { // AddedEdges returns all edge names that were set/added in this mutation. func (m *UserMutation) AddedEdges() []string { - edges := make([]string, 0, 24) + edges := make([]string, 0, 25) if m.created_hackathons != nil { edges = append(edges, user.EdgeCreatedHackathons) } + if m.created_hackathon_invites != nil { + edges = append(edges, user.EdgeCreatedHackathonInvites) + } if m.modified_hackathons != nil { edges = append(edges, user.EdgeModifiedHackathons) } @@ -13083,6 +13879,12 @@ func (m *UserMutation) AddedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case user.EdgeCreatedHackathonInvites: + ids := make([]ent.Value, 0, len(m.created_hackathon_invites)) + for id := range m.created_hackathon_invites { + ids = append(ids, id) + } + return ids case user.EdgeModifiedHackathons: ids := make([]ent.Value, 0, len(m.modified_hackathons)) for id := range m.modified_hackathons { @@ -13227,10 +14029,13 @@ func (m *UserMutation) AddedIDs(name string) []ent.Value { // RemovedEdges returns all edge names that were removed in this mutation. func (m *UserMutation) RemovedEdges() []string { - edges := make([]string, 0, 24) + edges := make([]string, 0, 25) if m.removedcreated_hackathons != nil { edges = append(edges, user.EdgeCreatedHackathons) } + if m.removedcreated_hackathon_invites != nil { + edges = append(edges, user.EdgeCreatedHackathonInvites) + } if m.removedmodified_hackathons != nil { edges = append(edges, user.EdgeModifiedHackathons) } @@ -13313,6 +14118,12 @@ func (m *UserMutation) RemovedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case user.EdgeCreatedHackathonInvites: + ids := make([]ent.Value, 0, len(m.removedcreated_hackathon_invites)) + for id := range m.removedcreated_hackathon_invites { + ids = append(ids, id) + } + return ids case user.EdgeModifiedHackathons: ids := make([]ent.Value, 0, len(m.removedmodified_hackathons)) for id := range m.removedmodified_hackathons { @@ -13457,10 +14268,13 @@ func (m *UserMutation) RemovedIDs(name string) []ent.Value { // ClearedEdges returns all edge names that were cleared in this mutation. func (m *UserMutation) ClearedEdges() []string { - edges := make([]string, 0, 24) + edges := make([]string, 0, 25) if m.clearedcreated_hackathons { edges = append(edges, user.EdgeCreatedHackathons) } + if m.clearedcreated_hackathon_invites { + edges = append(edges, user.EdgeCreatedHackathonInvites) + } if m.clearedmodified_hackathons { edges = append(edges, user.EdgeModifiedHackathons) } @@ -13539,6 +14353,8 @@ func (m *UserMutation) EdgeCleared(name string) bool { switch name { case user.EdgeCreatedHackathons: return m.clearedcreated_hackathons + case user.EdgeCreatedHackathonInvites: + return m.clearedcreated_hackathon_invites case user.EdgeModifiedHackathons: return m.clearedmodified_hackathons case user.EdgeCreatedProjects: @@ -13604,6 +14420,9 @@ func (m *UserMutation) ResetEdge(name string) error { case user.EdgeCreatedHackathons: m.ResetCreatedHackathons() return nil + case user.EdgeCreatedHackathonInvites: + m.ResetCreatedHackathonInvites() + return nil case user.EdgeModifiedHackathons: m.ResetModifiedHackathons() return nil diff --git a/components/backend/ent/predicate/predicate.go b/components/backend/ent/predicate/predicate.go index bfcb0033..a76e4431 100644 --- a/components/backend/ent/predicate/predicate.go +++ b/components/backend/ent/predicate/predicate.go @@ -12,6 +12,9 @@ type Answer func(*sql.Selector) // Hackathon is the predicate function for hackathon builders. type Hackathon func(*sql.Selector) +// HackathonInvite is the predicate function for hackathoninvite builders. +type HackathonInvite func(*sql.Selector) + // HackathonState is the predicate function for hackathonstate builders. type HackathonState func(*sql.Selector) diff --git a/components/backend/ent/runtime/runtime.go b/components/backend/ent/runtime/runtime.go index 32fd7884..5e8bc93c 100644 --- a/components/backend/ent/runtime/runtime.go +++ b/components/backend/ent/runtime/runtime.go @@ -9,6 +9,7 @@ import ( "github.com/swissdatasciencecenter/hackagon/components/backend/db/schema" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/answer" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathonstate" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/page" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/participant" @@ -71,6 +72,27 @@ func init() { hackathonDescID := hackathonMixinFields0[0].Descriptor() // hackathon.DefaultID holds the default value on creation for the id field. hackathon.DefaultID = hackathonDescID.Default.(func() uuid.UUID) + hackathoninviteMixin := schema.HackathonInvite{}.Mixin() + hackathoninviteMixinFields0 := hackathoninviteMixin[0].Fields() + _ = hackathoninviteMixinFields0 + hackathoninviteFields := schema.HackathonInvite{}.Fields() + _ = hackathoninviteFields + // hackathoninviteDescCreatedAt is the schema descriptor for created_at field. + hackathoninviteDescCreatedAt := hackathoninviteFields[0].Descriptor() + // hackathoninvite.DefaultCreatedAt holds the default value on creation for the created_at field. + hackathoninvite.DefaultCreatedAt = hackathoninviteDescCreatedAt.Default.(func() time.Time) + // hackathoninviteDescToken is the schema descriptor for token field. + hackathoninviteDescToken := hackathoninviteFields[2].Descriptor() + // hackathoninvite.DefaultToken holds the default value on creation for the token field. + hackathoninvite.DefaultToken = hackathoninviteDescToken.Default.(func() uuid.UUID) + // hackathoninviteDescNote is the schema descriptor for note field. + hackathoninviteDescNote := hackathoninviteFields[3].Descriptor() + // hackathoninvite.NoteValidator is a validator for the "note" field. It is called by the builders before save. + hackathoninvite.NoteValidator = hackathoninviteDescNote.Validators[0].(func(string) error) + // hackathoninviteDescID is the schema descriptor for id field. + hackathoninviteDescID := hackathoninviteMixinFields0[0].Descriptor() + // hackathoninvite.DefaultID holds the default value on creation for the id field. + hackathoninvite.DefaultID = hackathoninviteDescID.Default.(func() uuid.UUID) hackathonstateMixin := schema.HackathonState{}.Mixin() hackathonstateMixinFields0 := hackathonstateMixin[0].Fields() _ = hackathonstateMixinFields0 diff --git a/components/backend/ent/tx.go b/components/backend/ent/tx.go index 5be9666c..ec93f548 100644 --- a/components/backend/ent/tx.go +++ b/components/backend/ent/tx.go @@ -16,6 +16,8 @@ type Tx struct { Answer *AnswerClient // Hackathon is the client for interacting with the Hackathon builders. Hackathon *HackathonClient + // HackathonInvite is the client for interacting with the HackathonInvite builders. + HackathonInvite *HackathonInviteClient // HackathonState is the client for interacting with the HackathonState builders. HackathonState *HackathonStateClient // Page is the client for interacting with the Page builders. @@ -177,6 +179,7 @@ func (tx *Tx) Client() *Client { func (tx *Tx) init() { tx.Answer = NewAnswerClient(tx.config) tx.Hackathon = NewHackathonClient(tx.config) + tx.HackathonInvite = NewHackathonInviteClient(tx.config) tx.HackathonState = NewHackathonStateClient(tx.config) tx.Page = NewPageClient(tx.config) tx.Participant = NewParticipantClient(tx.config) diff --git a/components/backend/ent/user.go b/components/backend/ent/user.go index 5629cd78..d739fabe 100644 --- a/components/backend/ent/user.go +++ b/components/backend/ent/user.go @@ -40,6 +40,8 @@ type User struct { type UserEdges struct { // Hackathons this user created. CreatedHackathons []*Hackathon `json:"created_hackathons,omitempty"` + // Invites this user created. + CreatedHackathonInvites []*HackathonInvite `json:"created_hackathon_invites,omitempty"` // Hackathons this user last modified. ModifiedHackathons []*Hackathon `json:"modified_hackathons,omitempty"` // Projects this user created. @@ -92,7 +94,7 @@ type UserEdges struct { TeamParticipations []*TeamParticipant `json:"team_participations,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. - loadedTypes [26]bool + loadedTypes [27]bool } // CreatedHackathonsOrErr returns the CreatedHackathons value or an error if the edge @@ -104,10 +106,19 @@ func (e UserEdges) CreatedHackathonsOrErr() ([]*Hackathon, error) { return nil, &NotLoadedError{edge: "created_hackathons"} } +// CreatedHackathonInvitesOrErr returns the CreatedHackathonInvites value or an error if the edge +// was not loaded in eager-loading. +func (e UserEdges) CreatedHackathonInvitesOrErr() ([]*HackathonInvite, error) { + if e.loadedTypes[1] { + return e.CreatedHackathonInvites, nil + } + return nil, &NotLoadedError{edge: "created_hackathon_invites"} +} + // ModifiedHackathonsOrErr returns the ModifiedHackathons value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ModifiedHackathonsOrErr() ([]*Hackathon, error) { - if e.loadedTypes[1] { + if e.loadedTypes[2] { return e.ModifiedHackathons, nil } return nil, &NotLoadedError{edge: "modified_hackathons"} @@ -116,7 +127,7 @@ func (e UserEdges) ModifiedHackathonsOrErr() ([]*Hackathon, error) { // CreatedProjectsOrErr returns the CreatedProjects value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) CreatedProjectsOrErr() ([]*Project, error) { - if e.loadedTypes[2] { + if e.loadedTypes[3] { return e.CreatedProjects, nil } return nil, &NotLoadedError{edge: "created_projects"} @@ -125,7 +136,7 @@ func (e UserEdges) CreatedProjectsOrErr() ([]*Project, error) { // ModifiedProjectsOrErr returns the ModifiedProjects value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ModifiedProjectsOrErr() ([]*Project, error) { - if e.loadedTypes[3] { + if e.loadedTypes[4] { return e.ModifiedProjects, nil } return nil, &NotLoadedError{edge: "modified_projects"} @@ -134,7 +145,7 @@ func (e UserEdges) ModifiedProjectsOrErr() ([]*Project, error) { // ParticipatesInHackathonsOrErr returns the ParticipatesInHackathons value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ParticipatesInHackathonsOrErr() ([]*Hackathon, error) { - if e.loadedTypes[4] { + if e.loadedTypes[5] { return e.ParticipatesInHackathons, nil } return nil, &NotLoadedError{edge: "participates_in_hackathons"} @@ -143,7 +154,7 @@ func (e UserEdges) ParticipatesInHackathonsOrErr() ([]*Hackathon, error) { // ParticipatesInTeamsOrErr returns the ParticipatesInTeams value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ParticipatesInTeamsOrErr() ([]*Team, error) { - if e.loadedTypes[5] { + if e.loadedTypes[6] { return e.ParticipatesInTeams, nil } return nil, &NotLoadedError{edge: "participates_in_teams"} @@ -152,7 +163,7 @@ func (e UserEdges) ParticipatesInTeamsOrErr() ([]*Team, error) { // CreatedTeamsOrErr returns the CreatedTeams value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) CreatedTeamsOrErr() ([]*Team, error) { - if e.loadedTypes[6] { + if e.loadedTypes[7] { return e.CreatedTeams, nil } return nil, &NotLoadedError{edge: "created_teams"} @@ -161,7 +172,7 @@ func (e UserEdges) CreatedTeamsOrErr() ([]*Team, error) { // ModifiedTeamsOrErr returns the ModifiedTeams value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ModifiedTeamsOrErr() ([]*Team, error) { - if e.loadedTypes[7] { + if e.loadedTypes[8] { return e.ModifiedTeams, nil } return nil, &NotLoadedError{edge: "modified_teams"} @@ -170,7 +181,7 @@ func (e UserEdges) ModifiedTeamsOrErr() ([]*Team, error) { // CreatedPagesOrErr returns the CreatedPages value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) CreatedPagesOrErr() ([]*Page, error) { - if e.loadedTypes[8] { + if e.loadedTypes[9] { return e.CreatedPages, nil } return nil, &NotLoadedError{edge: "created_pages"} @@ -179,7 +190,7 @@ func (e UserEdges) CreatedPagesOrErr() ([]*Page, error) { // ModifiedPagesOrErr returns the ModifiedPages value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ModifiedPagesOrErr() ([]*Page, error) { - if e.loadedTypes[9] { + if e.loadedTypes[10] { return e.ModifiedPages, nil } return nil, &NotLoadedError{edge: "modified_pages"} @@ -188,7 +199,7 @@ func (e UserEdges) ModifiedPagesOrErr() ([]*Page, error) { // CreatedPhasesOrErr returns the CreatedPhases value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) CreatedPhasesOrErr() ([]*Phase, error) { - if e.loadedTypes[10] { + if e.loadedTypes[11] { return e.CreatedPhases, nil } return nil, &NotLoadedError{edge: "created_phases"} @@ -197,7 +208,7 @@ func (e UserEdges) CreatedPhasesOrErr() ([]*Phase, error) { // ModifiedPhasesOrErr returns the ModifiedPhases value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ModifiedPhasesOrErr() ([]*Phase, error) { - if e.loadedTypes[11] { + if e.loadedTypes[12] { return e.ModifiedPhases, nil } return nil, &NotLoadedError{edge: "modified_phases"} @@ -206,7 +217,7 @@ func (e UserEdges) ModifiedPhasesOrErr() ([]*Phase, error) { // CreatedSubmissionsOrErr returns the CreatedSubmissions value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) CreatedSubmissionsOrErr() ([]*Submission, error) { - if e.loadedTypes[12] { + if e.loadedTypes[13] { return e.CreatedSubmissions, nil } return nil, &NotLoadedError{edge: "created_submissions"} @@ -215,7 +226,7 @@ func (e UserEdges) CreatedSubmissionsOrErr() ([]*Submission, error) { // ModifiedSubmissionsOrErr returns the ModifiedSubmissions value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ModifiedSubmissionsOrErr() ([]*Submission, error) { - if e.loadedTypes[13] { + if e.loadedTypes[14] { return e.ModifiedSubmissions, nil } return nil, &NotLoadedError{edge: "modified_submissions"} @@ -224,7 +235,7 @@ func (e UserEdges) ModifiedSubmissionsOrErr() ([]*Submission, error) { // CreatedTracksOrErr returns the CreatedTracks value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) CreatedTracksOrErr() ([]*Track, error) { - if e.loadedTypes[14] { + if e.loadedTypes[15] { return e.CreatedTracks, nil } return nil, &NotLoadedError{edge: "created_tracks"} @@ -233,7 +244,7 @@ func (e UserEdges) CreatedTracksOrErr() ([]*Track, error) { // ModifiedTracksOrErr returns the ModifiedTracks value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ModifiedTracksOrErr() ([]*Track, error) { - if e.loadedTypes[15] { + if e.loadedTypes[16] { return e.ModifiedTracks, nil } return nil, &NotLoadedError{edge: "modified_tracks"} @@ -242,7 +253,7 @@ func (e UserEdges) ModifiedTracksOrErr() ([]*Track, error) { // CreatedQuestionsOrErr returns the CreatedQuestions value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) CreatedQuestionsOrErr() ([]*Question, error) { - if e.loadedTypes[16] { + if e.loadedTypes[17] { return e.CreatedQuestions, nil } return nil, &NotLoadedError{edge: "created_questions"} @@ -251,7 +262,7 @@ func (e UserEdges) CreatedQuestionsOrErr() ([]*Question, error) { // ModifiedQuestionsOrErr returns the ModifiedQuestions value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ModifiedQuestionsOrErr() ([]*Question, error) { - if e.loadedTypes[17] { + if e.loadedTypes[18] { return e.ModifiedQuestions, nil } return nil, &NotLoadedError{edge: "modified_questions"} @@ -260,7 +271,7 @@ func (e UserEdges) ModifiedQuestionsOrErr() ([]*Question, error) { // RegistrationAnswersOrErr returns the RegistrationAnswers value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) RegistrationAnswersOrErr() ([]*Answer, error) { - if e.loadedTypes[18] { + if e.loadedTypes[19] { return e.RegistrationAnswers, nil } return nil, &NotLoadedError{edge: "registration_answers"} @@ -269,7 +280,7 @@ func (e UserEdges) RegistrationAnswersOrErr() ([]*Answer, error) { // ModifiedStatesOrErr returns the ModifiedStates value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ModifiedStatesOrErr() ([]*HackathonState, error) { - if e.loadedTypes[19] { + if e.loadedTypes[20] { return e.ModifiedStates, nil } return nil, &NotLoadedError{edge: "modified_states"} @@ -278,7 +289,7 @@ func (e UserEdges) ModifiedStatesOrErr() ([]*HackathonState, error) { // PreferredProjectsOrErr returns the PreferredProjects value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) PreferredProjectsOrErr() ([]*Project, error) { - if e.loadedTypes[20] { + if e.loadedTypes[21] { return e.PreferredProjects, nil } return nil, &NotLoadedError{edge: "preferred_projects"} @@ -287,7 +298,7 @@ func (e UserEdges) PreferredProjectsOrErr() ([]*Project, error) { // VotesOrErr returns the Votes value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) VotesOrErr() ([]*Vote, error) { - if e.loadedTypes[21] { + if e.loadedTypes[22] { return e.Votes, nil } return nil, &NotLoadedError{edge: "votes"} @@ -296,7 +307,7 @@ func (e UserEdges) VotesOrErr() ([]*Vote, error) { // JuryCategoriesOrErr returns the JuryCategories value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) JuryCategoriesOrErr() ([]*VoteCategory, error) { - if e.loadedTypes[22] { + if e.loadedTypes[23] { return e.JuryCategories, nil } return nil, &NotLoadedError{edge: "jury_categories"} @@ -305,7 +316,7 @@ func (e UserEdges) JuryCategoriesOrErr() ([]*VoteCategory, error) { // OwnsOrErr returns the Owns value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) OwnsOrErr() ([]*Hackathon, error) { - if e.loadedTypes[23] { + if e.loadedTypes[24] { return e.Owns, nil } return nil, &NotLoadedError{edge: "owns"} @@ -314,7 +325,7 @@ func (e UserEdges) OwnsOrErr() ([]*Hackathon, error) { // ParticipationsOrErr returns the Participations value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) ParticipationsOrErr() ([]*Participant, error) { - if e.loadedTypes[24] { + if e.loadedTypes[25] { return e.Participations, nil } return nil, &NotLoadedError{edge: "participations"} @@ -323,7 +334,7 @@ func (e UserEdges) ParticipationsOrErr() ([]*Participant, error) { // TeamParticipationsOrErr returns the TeamParticipations value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) TeamParticipationsOrErr() ([]*TeamParticipant, error) { - if e.loadedTypes[25] { + if e.loadedTypes[26] { return e.TeamParticipations, nil } return nil, &NotLoadedError{edge: "team_participations"} @@ -415,6 +426,11 @@ func (_m *User) QueryCreatedHackathons() *HackathonQuery { return NewUserClient(_m.config).QueryCreatedHackathons(_m) } +// QueryCreatedHackathonInvites queries the "created_hackathon_invites" edge of the User entity. +func (_m *User) QueryCreatedHackathonInvites() *HackathonInviteQuery { + return NewUserClient(_m.config).QueryCreatedHackathonInvites(_m) +} + // QueryModifiedHackathons queries the "modified_hackathons" edge of the User entity. func (_m *User) QueryModifiedHackathons() *HackathonQuery { return NewUserClient(_m.config).QueryModifiedHackathons(_m) diff --git a/components/backend/ent/user/user.go b/components/backend/ent/user/user.go index bb93e9c4..0d3fdd0c 100644 --- a/components/backend/ent/user/user.go +++ b/components/backend/ent/user/user.go @@ -29,6 +29,8 @@ const ( FieldModifiedAt = "modified_at" // EdgeCreatedHackathons holds the string denoting the created_hackathons edge name in mutations. EdgeCreatedHackathons = "created_hackathons" + // EdgeCreatedHackathonInvites holds the string denoting the created_hackathon_invites edge name in mutations. + EdgeCreatedHackathonInvites = "created_hackathon_invites" // EdgeModifiedHackathons holds the string denoting the modified_hackathons edge name in mutations. EdgeModifiedHackathons = "modified_hackathons" // EdgeCreatedProjects holds the string denoting the created_projects edge name in mutations. @@ -88,6 +90,13 @@ const ( CreatedHackathonsInverseTable = "hackathons" // CreatedHackathonsColumn is the table column denoting the created_hackathons relation/edge. CreatedHackathonsColumn = "user_created_hackathons" + // CreatedHackathonInvitesTable is the table that holds the created_hackathon_invites relation/edge. + CreatedHackathonInvitesTable = "hackathon_invites" + // CreatedHackathonInvitesInverseTable is the table name for the HackathonInvite entity. + // It exists in this package in order to avoid circular dependency with the "hackathoninvite" package. + CreatedHackathonInvitesInverseTable = "hackathon_invites" + // CreatedHackathonInvitesColumn is the table column denoting the created_hackathon_invites relation/edge. + CreatedHackathonInvitesColumn = "user_created_hackathon_invites" // ModifiedHackathonsTable is the table that holds the modified_hackathons relation/edge. ModifiedHackathonsTable = "hackathons" // ModifiedHackathonsInverseTable is the table name for the Hackathon entity. @@ -363,6 +372,20 @@ func ByCreatedHackathons(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption } } +// ByCreatedHackathonInvitesCount orders the results by created_hackathon_invites count. +func ByCreatedHackathonInvitesCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newCreatedHackathonInvitesStep(), opts...) + } +} + +// ByCreatedHackathonInvites orders the results by created_hackathon_invites terms. +func ByCreatedHackathonInvites(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newCreatedHackathonInvitesStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + // ByModifiedHackathonsCount orders the results by modified_hackathons count. func ByModifiedHackathonsCount(opts ...sql.OrderTermOption) OrderOption { return func(s *sql.Selector) { @@ -719,6 +742,13 @@ func newCreatedHackathonsStep() *sqlgraph.Step { sqlgraph.Edge(sqlgraph.O2M, false, CreatedHackathonsTable, CreatedHackathonsColumn), ) } +func newCreatedHackathonInvitesStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(CreatedHackathonInvitesInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, CreatedHackathonInvitesTable, CreatedHackathonInvitesColumn), + ) +} func newModifiedHackathonsStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), diff --git a/components/backend/ent/user/where.go b/components/backend/ent/user/where.go index f2db17fa..a4449ba4 100644 --- a/components/backend/ent/user/where.go +++ b/components/backend/ent/user/where.go @@ -469,6 +469,29 @@ func HasCreatedHackathonsWith(preds ...predicate.Hackathon) predicate.User { }) } +// HasCreatedHackathonInvites applies the HasEdge predicate on the "created_hackathon_invites" edge. +func HasCreatedHackathonInvites() predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, CreatedHackathonInvitesTable, CreatedHackathonInvitesColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasCreatedHackathonInvitesWith applies the HasEdge predicate on the "created_hackathon_invites" edge with a given conditions (other predicates). +func HasCreatedHackathonInvitesWith(preds ...predicate.HackathonInvite) predicate.User { + return predicate.User(func(s *sql.Selector) { + step := newCreatedHackathonInvitesStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + // HasModifiedHackathons applies the HasEdge predicate on the "modified_hackathons" edge. func HasModifiedHackathons() predicate.User { return predicate.User(func(s *sql.Selector) { diff --git a/components/backend/ent/user_create.go b/components/backend/ent/user_create.go index 053f2e3d..cd3ca1c3 100644 --- a/components/backend/ent/user_create.go +++ b/components/backend/ent/user_create.go @@ -15,6 +15,7 @@ import ( "github.com/google/uuid" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/answer" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathonstate" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/page" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/phase" @@ -133,6 +134,21 @@ func (_c *UserCreate) AddCreatedHackathons(v ...*Hackathon) *UserCreate { return _c.AddCreatedHackathonIDs(ids...) } +// AddCreatedHackathonInviteIDs adds the "created_hackathon_invites" edge to the HackathonInvite entity by IDs. +func (_c *UserCreate) AddCreatedHackathonInviteIDs(ids ...uuid.UUID) *UserCreate { + _c.mutation.AddCreatedHackathonInviteIDs(ids...) + return _c +} + +// AddCreatedHackathonInvites adds the "created_hackathon_invites" edges to the HackathonInvite entity. +func (_c *UserCreate) AddCreatedHackathonInvites(v ...*HackathonInvite) *UserCreate { + ids := make([]uuid.UUID, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _c.AddCreatedHackathonInviteIDs(ids...) +} + // AddModifiedHackathonIDs adds the "modified_hackathons" edge to the Hackathon entity by IDs. func (_c *UserCreate) AddModifiedHackathonIDs(ids ...uuid.UUID) *UserCreate { _c.mutation.AddModifiedHackathonIDs(ids...) @@ -630,6 +646,22 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { } _spec.Edges = append(_spec.Edges, edge) } + if nodes := _c.mutation.CreatedHackathonInvitesIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CreatedHackathonInvitesTable, + Columns: []string{user.CreatedHackathonInvitesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } if nodes := _c.mutation.ModifiedHackathonsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, diff --git a/components/backend/ent/user_query.go b/components/backend/ent/user_query.go index 4fabea9d..dd4b6f15 100644 --- a/components/backend/ent/user_query.go +++ b/components/backend/ent/user_query.go @@ -15,6 +15,7 @@ import ( "github.com/google/uuid" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/answer" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathonstate" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/page" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/participant" @@ -39,6 +40,7 @@ type UserQuery struct { inters []Interceptor predicates []predicate.User withCreatedHackathons *HackathonQuery + withCreatedHackathonInvites *HackathonInviteQuery withModifiedHackathons *HackathonQuery withCreatedProjects *ProjectQuery withModifiedProjects *ProjectQuery @@ -122,6 +124,28 @@ func (_q *UserQuery) QueryCreatedHackathons() *HackathonQuery { return query } +// QueryCreatedHackathonInvites chains the current query on the "created_hackathon_invites" edge. +func (_q *UserQuery) QueryCreatedHackathonInvites() *HackathonInviteQuery { + query := (&HackathonInviteClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, selector), + sqlgraph.To(hackathoninvite.Table, hackathoninvite.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.CreatedHackathonInvitesTable, user.CreatedHackathonInvitesColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + // QueryModifiedHackathons chains the current query on the "modified_hackathons" edge. func (_q *UserQuery) QueryModifiedHackathons() *HackathonQuery { query := (&HackathonClient{config: _q.config}).Query() @@ -865,6 +889,7 @@ func (_q *UserQuery) Clone() *UserQuery { inters: append([]Interceptor{}, _q.inters...), predicates: append([]predicate.User{}, _q.predicates...), withCreatedHackathons: _q.withCreatedHackathons.Clone(), + withCreatedHackathonInvites: _q.withCreatedHackathonInvites.Clone(), withModifiedHackathons: _q.withModifiedHackathons.Clone(), withCreatedProjects: _q.withCreatedProjects.Clone(), withModifiedProjects: _q.withModifiedProjects.Clone(), @@ -907,6 +932,17 @@ func (_q *UserQuery) WithCreatedHackathons(opts ...func(*HackathonQuery)) *UserQ return _q } +// WithCreatedHackathonInvites tells the query-builder to eager-load the nodes that are connected to +// the "created_hackathon_invites" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *UserQuery) WithCreatedHackathonInvites(opts ...func(*HackathonInviteQuery)) *UserQuery { + query := (&HackathonInviteClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withCreatedHackathonInvites = query + return _q +} + // WithModifiedHackathons tells the query-builder to eager-load the nodes that are connected to // the "modified_hackathons" edge. The optional arguments are used to configure the query builder of the edge. func (_q *UserQuery) WithModifiedHackathons(opts ...func(*HackathonQuery)) *UserQuery { @@ -1260,8 +1296,9 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e var ( nodes = []*User{} _spec = _q.querySpec() - loadedTypes = [26]bool{ + loadedTypes = [27]bool{ _q.withCreatedHackathons != nil, + _q.withCreatedHackathonInvites != nil, _q.withModifiedHackathons != nil, _q.withCreatedProjects != nil, _q.withModifiedProjects != nil, @@ -1314,6 +1351,15 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e return nil, err } } + if query := _q.withCreatedHackathonInvites; query != nil { + if err := _q.loadCreatedHackathonInvites(ctx, query, nodes, + func(n *User) { n.Edges.CreatedHackathonInvites = []*HackathonInvite{} }, + func(n *User, e *HackathonInvite) { + n.Edges.CreatedHackathonInvites = append(n.Edges.CreatedHackathonInvites, e) + }); err != nil { + return nil, err + } + } if query := _q.withModifiedHackathons; query != nil { if err := _q.loadModifiedHackathons(ctx, query, nodes, func(n *User) { n.Edges.ModifiedHackathons = []*Hackathon{} }, @@ -1525,6 +1571,37 @@ func (_q *UserQuery) loadCreatedHackathons(ctx context.Context, query *Hackathon } return nil } +func (_q *UserQuery) loadCreatedHackathonInvites(ctx context.Context, query *HackathonInviteQuery, nodes []*User, init func(*User), assign func(*User, *HackathonInvite)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[uuid.UUID]*User) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + query.withFKs = true + query.Where(predicate.HackathonInvite(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(user.CreatedHackathonInvitesColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.user_created_hackathon_invites + if fk == nil { + return fmt.Errorf(`foreign-key "user_created_hackathon_invites" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "user_created_hackathon_invites" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} func (_q *UserQuery) loadModifiedHackathons(ctx context.Context, query *HackathonQuery, nodes []*User, init func(*User), assign func(*User, *Hackathon)) error { fks := make([]driver.Value, 0, len(nodes)) nodeids := make(map[uuid.UUID]*User) diff --git a/components/backend/ent/user_update.go b/components/backend/ent/user_update.go index 632b5c15..3398dc1d 100644 --- a/components/backend/ent/user_update.go +++ b/components/backend/ent/user_update.go @@ -14,6 +14,7 @@ import ( "github.com/google/uuid" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/answer" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" + "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathonstate" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/page" "github.com/swissdatasciencecenter/hackagon/components/backend/ent/phase" @@ -130,6 +131,21 @@ func (_u *UserUpdate) AddCreatedHackathons(v ...*Hackathon) *UserUpdate { return _u.AddCreatedHackathonIDs(ids...) } +// AddCreatedHackathonInviteIDs adds the "created_hackathon_invites" edge to the HackathonInvite entity by IDs. +func (_u *UserUpdate) AddCreatedHackathonInviteIDs(ids ...uuid.UUID) *UserUpdate { + _u.mutation.AddCreatedHackathonInviteIDs(ids...) + return _u +} + +// AddCreatedHackathonInvites adds the "created_hackathon_invites" edges to the HackathonInvite entity. +func (_u *UserUpdate) AddCreatedHackathonInvites(v ...*HackathonInvite) *UserUpdate { + ids := make([]uuid.UUID, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddCreatedHackathonInviteIDs(ids...) +} + // AddModifiedHackathonIDs adds the "modified_hackathons" edge to the Hackathon entity by IDs. func (_u *UserUpdate) AddModifiedHackathonIDs(ids ...uuid.UUID) *UserUpdate { _u.mutation.AddModifiedHackathonIDs(ids...) @@ -501,6 +517,27 @@ func (_u *UserUpdate) RemoveCreatedHackathons(v ...*Hackathon) *UserUpdate { return _u.RemoveCreatedHackathonIDs(ids...) } +// ClearCreatedHackathonInvites clears all "created_hackathon_invites" edges to the HackathonInvite entity. +func (_u *UserUpdate) ClearCreatedHackathonInvites() *UserUpdate { + _u.mutation.ClearCreatedHackathonInvites() + return _u +} + +// RemoveCreatedHackathonInviteIDs removes the "created_hackathon_invites" edge to HackathonInvite entities by IDs. +func (_u *UserUpdate) RemoveCreatedHackathonInviteIDs(ids ...uuid.UUID) *UserUpdate { + _u.mutation.RemoveCreatedHackathonInviteIDs(ids...) + return _u +} + +// RemoveCreatedHackathonInvites removes "created_hackathon_invites" edges to HackathonInvite entities. +func (_u *UserUpdate) RemoveCreatedHackathonInvites(v ...*HackathonInvite) *UserUpdate { + ids := make([]uuid.UUID, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemoveCreatedHackathonInviteIDs(ids...) +} + // ClearModifiedHackathons clears all "modified_hackathons" edges to the Hackathon entity. func (_u *UserUpdate) ClearModifiedHackathons() *UserUpdate { _u.mutation.ClearModifiedHackathons() @@ -1108,6 +1145,51 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if _u.mutation.CreatedHackathonInvitesCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CreatedHackathonInvitesTable, + Columns: []string{user.CreatedHackathonInvitesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedCreatedHackathonInvitesIDs(); len(nodes) > 0 && !_u.mutation.CreatedHackathonInvitesCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CreatedHackathonInvitesTable, + Columns: []string{user.CreatedHackathonInvitesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.CreatedHackathonInvitesIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CreatedHackathonInvitesTable, + Columns: []string{user.CreatedHackathonInvitesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if _u.mutation.ModifiedHackathonsCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, @@ -2276,6 +2358,21 @@ func (_u *UserUpdateOne) AddCreatedHackathons(v ...*Hackathon) *UserUpdateOne { return _u.AddCreatedHackathonIDs(ids...) } +// AddCreatedHackathonInviteIDs adds the "created_hackathon_invites" edge to the HackathonInvite entity by IDs. +func (_u *UserUpdateOne) AddCreatedHackathonInviteIDs(ids ...uuid.UUID) *UserUpdateOne { + _u.mutation.AddCreatedHackathonInviteIDs(ids...) + return _u +} + +// AddCreatedHackathonInvites adds the "created_hackathon_invites" edges to the HackathonInvite entity. +func (_u *UserUpdateOne) AddCreatedHackathonInvites(v ...*HackathonInvite) *UserUpdateOne { + ids := make([]uuid.UUID, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddCreatedHackathonInviteIDs(ids...) +} + // AddModifiedHackathonIDs adds the "modified_hackathons" edge to the Hackathon entity by IDs. func (_u *UserUpdateOne) AddModifiedHackathonIDs(ids ...uuid.UUID) *UserUpdateOne { _u.mutation.AddModifiedHackathonIDs(ids...) @@ -2647,6 +2744,27 @@ func (_u *UserUpdateOne) RemoveCreatedHackathons(v ...*Hackathon) *UserUpdateOne return _u.RemoveCreatedHackathonIDs(ids...) } +// ClearCreatedHackathonInvites clears all "created_hackathon_invites" edges to the HackathonInvite entity. +func (_u *UserUpdateOne) ClearCreatedHackathonInvites() *UserUpdateOne { + _u.mutation.ClearCreatedHackathonInvites() + return _u +} + +// RemoveCreatedHackathonInviteIDs removes the "created_hackathon_invites" edge to HackathonInvite entities by IDs. +func (_u *UserUpdateOne) RemoveCreatedHackathonInviteIDs(ids ...uuid.UUID) *UserUpdateOne { + _u.mutation.RemoveCreatedHackathonInviteIDs(ids...) + return _u +} + +// RemoveCreatedHackathonInvites removes "created_hackathon_invites" edges to HackathonInvite entities. +func (_u *UserUpdateOne) RemoveCreatedHackathonInvites(v ...*HackathonInvite) *UserUpdateOne { + ids := make([]uuid.UUID, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemoveCreatedHackathonInviteIDs(ids...) +} + // ClearModifiedHackathons clears all "modified_hackathons" edges to the Hackathon entity. func (_u *UserUpdateOne) ClearModifiedHackathons() *UserUpdateOne { _u.mutation.ClearModifiedHackathons() @@ -3284,6 +3402,51 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if _u.mutation.CreatedHackathonInvitesCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CreatedHackathonInvitesTable, + Columns: []string{user.CreatedHackathonInvitesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedCreatedHackathonInvitesIDs(); len(nodes) > 0 && !_u.mutation.CreatedHackathonInvitesCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CreatedHackathonInvitesTable, + Columns: []string{user.CreatedHackathonInvitesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.CreatedHackathonInvitesIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.CreatedHackathonInvitesTable, + Columns: []string{user.CreatedHackathonInvitesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(hackathoninvite.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if _u.mutation.ModifiedHackathonsCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, diff --git a/components/backend/go.sum b/components/backend/go.sum index 7c3dd192..93aeaf4b 100644 --- a/components/backend/go.sum +++ b/components/backend/go.sum @@ -45,6 +45,12 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo= +github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= +github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= +github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= +github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= +github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -52,6 +58,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= @@ -144,6 +152,12 @@ github.com/lib/pq v1.12.3 h1:tTWxr2YLKwIvK90ZXEw8GP7UFHtcbTtty8zsI+YjrfQ= github.com/lib/pq v1.12.3/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= +github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-sqlite3 v1.14.42 h1:MigqEP4ZmHw3aIdIT7T+9TLa90Z6smwcthx+Azv4Cgo= github.com/mattn/go-sqlite3 v1.14.42/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ= github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= @@ -154,6 +168,14 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc= +github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0= +github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM= +github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= +github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 h1:jrYnow5+hy3WRDCBypUFvVKNSPPCdqgSXIE9eJDD8LM= +github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew= +github.com/olekukonko/tablewriter v1.1.3 h1:VSHhghXxrP0JHl+0NnKid7WoEmd9/urKRJLysb70nnA= +github.com/olekukonko/tablewriter v1.1.3/go.mod h1:9VU0knjhmMkXjnMKrZ3+L2JhhtsQ/L38BbL3CRNE8tM= github.com/onsi/ginkgo/v2 v2.27.5 h1:ZeVgZMx2PDMdJm/+w5fE/OyG6ILo1Y3e+QX4zSR0zTE= github.com/onsi/ginkgo/v2 v2.27.5/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc= @@ -170,6 +192,10 @@ github.com/rodaine/protogofakeit v0.1.1/go.mod h1:pXn/AstBYMaSfc1/RqH3N82pBuxtWg github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= diff --git a/components/backend/internal/proto/hackathon/entities/hackathon_invite.pb.go b/components/backend/internal/proto/hackathon/entities/hackathon_invite.pb.go new file mode 100644 index 00000000..16588a24 --- /dev/null +++ b/components/backend/internal/proto/hackathon/entities/hackathon_invite.pb.go @@ -0,0 +1,179 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: hackathon/entities/hackathon_invite.proto + +package entities + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type HackathonInvite struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` + Note *string `protobuf:"bytes,3,opt,name=note,proto3,oneof" json:"note,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + RevokedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=revoked_at,json=revokedAt,proto3,oneof" json:"revoked_at,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *HackathonInvite) Reset() { + *x = HackathonInvite{} + mi := &file_hackathon_entities_hackathon_invite_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HackathonInvite) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HackathonInvite) ProtoMessage() {} + +func (x *HackathonInvite) ProtoReflect() protoreflect.Message { + mi := &file_hackathon_entities_hackathon_invite_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HackathonInvite.ProtoReflect.Descriptor instead. +func (*HackathonInvite) Descriptor() ([]byte, []int) { + return file_hackathon_entities_hackathon_invite_proto_rawDescGZIP(), []int{0} +} + +func (x *HackathonInvite) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *HackathonInvite) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *HackathonInvite) GetNote() string { + if x != nil && x.Note != nil { + return *x.Note + } + return "" +} + +func (x *HackathonInvite) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *HackathonInvite) GetRevokedAt() *timestamppb.Timestamp { + if x != nil { + return x.RevokedAt + } + return nil +} + +func (x *HackathonInvite) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +var File_hackathon_entities_hackathon_invite_proto protoreflect.FileDescriptor + +const file_hackathon_entities_hackathon_invite_proto_rawDesc = "" + + "\n" + + ")hackathon/entities/hackathon_invite.proto\x12\x12hackathon.entities\x1a\x1fgoogle/protobuf/timestamp.proto\"\xb2\x02\n" + + "\x0fHackathonInvite\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x14\n" + + "\x05token\x18\x02 \x01(\tR\x05token\x12\x17\n" + + "\x04note\x18\x03 \x01(\tH\x00R\x04note\x88\x01\x01\x129\n" + + "\n" + + "created_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x12>\n" + + "\n" + + "revoked_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampH\x01R\trevokedAt\x88\x01\x01\x12>\n" + + "\n" + + "expires_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampH\x02R\texpiresAt\x88\x01\x01B\a\n" + + "\x05_noteB\r\n" + + "\v_revoked_atB\r\n" + + "\v_expires_atBaZ_github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/entitiesb\x06proto3" + +var ( + file_hackathon_entities_hackathon_invite_proto_rawDescOnce sync.Once + file_hackathon_entities_hackathon_invite_proto_rawDescData []byte +) + +func file_hackathon_entities_hackathon_invite_proto_rawDescGZIP() []byte { + file_hackathon_entities_hackathon_invite_proto_rawDescOnce.Do(func() { + file_hackathon_entities_hackathon_invite_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_hackathon_entities_hackathon_invite_proto_rawDesc), len(file_hackathon_entities_hackathon_invite_proto_rawDesc))) + }) + return file_hackathon_entities_hackathon_invite_proto_rawDescData +} + +var file_hackathon_entities_hackathon_invite_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_hackathon_entities_hackathon_invite_proto_goTypes = []any{ + (*HackathonInvite)(nil), // 0: hackathon.entities.HackathonInvite + (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp +} +var file_hackathon_entities_hackathon_invite_proto_depIdxs = []int32{ + 1, // 0: hackathon.entities.HackathonInvite.created_at:type_name -> google.protobuf.Timestamp + 1, // 1: hackathon.entities.HackathonInvite.revoked_at:type_name -> google.protobuf.Timestamp + 1, // 2: hackathon.entities.HackathonInvite.expires_at:type_name -> google.protobuf.Timestamp + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_hackathon_entities_hackathon_invite_proto_init() } +func file_hackathon_entities_hackathon_invite_proto_init() { + if File_hackathon_entities_hackathon_invite_proto != nil { + return + } + file_hackathon_entities_hackathon_invite_proto_msgTypes[0].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_hackathon_entities_hackathon_invite_proto_rawDesc), len(file_hackathon_entities_hackathon_invite_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_hackathon_entities_hackathon_invite_proto_goTypes, + DependencyIndexes: file_hackathon_entities_hackathon_invite_proto_depIdxs, + MessageInfos: file_hackathon_entities_hackathon_invite_proto_msgTypes, + }.Build() + File_hackathon_entities_hackathon_invite_proto = out.File + file_hackathon_entities_hackathon_invite_proto_goTypes = nil + file_hackathon_entities_hackathon_invite_proto_depIdxs = nil +} diff --git a/components/backend/internal/proto/hackathon/hackathon_service.pb.go b/components/backend/internal/proto/hackathon/hackathon_service.pb.go index fae78db6..80b92886 100644 --- a/components/backend/internal/proto/hackathon/hackathon_service.pb.go +++ b/components/backend/internal/proto/hackathon/hackathon_service.pb.go @@ -25,14 +25,18 @@ var File_hackathon_hackathon_service_proto protoreflect.FileDescriptor const file_hackathon_hackathon_service_proto_rawDesc = "" + "\n" + - "!hackathon/hackathon_service.proto\x12\thackathon\x1a8hackathon/messages/hackathon_svc/add_owner_request.proto\x1a9hackathon/messages/hackathon_svc/add_owner_response.proto\x1aBhackathon/messages/hackathon_svc/approve_participant_request.proto\x1aChackathon/messages/hackathon_svc/approve_participant_response.proto\x1a>hackathon/messages/hackathon_svc/create_question_request.proto\x1a?hackathon/messages/hackathon_svc/create_question_response.proto\x1a5hackathon/messages/hackathon_svc/create_request.proto\x1a6hackathon/messages/hackathon_svc/create_response.proto\x1ahackathon/messages/hackathon_svc/list_questions_response.proto\x1a3hackathon/messages/hackathon_svc/list_request.proto\x1a4hackathon/messages/hackathon_svc/list_response.proto\x1a;hackathon/messages/hackathon_svc/remove_owner_request.proto\x1ahackathon/messages/hackathon_svc/remove_question_request.proto\x1a?hackathon/messages/hackathon_svc/remove_question_response.proto\x1a?hackathon/messages/hackathon_svc/set_capabilities_request.proto\x1a@hackathon/messages/hackathon_svc/set_capabilities_response.proto\x1a@hackathon/messages/hackathon_svc/set_current_phase_request.proto\x1aAhackathon/messages/hackathon_svc/set_current_phase_response.proto\x1a=hackathon/messages/hackathon_svc/submit_answers_request.proto\x1a>hackathon/messages/hackathon_svc/submit_answers_response.proto2\xe9\x10\n" + + "!hackathon/hackathon_service.proto\x12\thackathon\x1a8hackathon/messages/hackathon_svc/add_owner_request.proto\x1a9hackathon/messages/hackathon_svc/add_owner_response.proto\x1aBhackathon/messages/hackathon_svc/approve_participant_request.proto\x1aChackathon/messages/hackathon_svc/approve_participant_response.proto\x1a>hackathon/messages/hackathon_svc/create_question_request.proto\x1a?hackathon/messages/hackathon_svc/create_question_response.proto\x1a5hackathon/messages/hackathon_svc/create_request.proto\x1a6hackathon/messages/hackathon_svc/create_response.proto\x1ahackathon/messages/hackathon_svc/preview_invite_response.proto\x1ahackathon/messages/hackathon_svc/list_questions_response.proto\x1a3hackathon/messages/hackathon_svc/list_request.proto\x1a4hackathon/messages/hackathon_svc/list_response.proto\x1a;hackathon/messages/hackathon_svc/remove_owner_request.proto\x1ahackathon/messages/hackathon_svc/remove_question_request.proto\x1a?hackathon/messages/hackathon_svc/remove_question_response.proto\x1a?hackathon/messages/hackathon_svc/set_capabilities_request.proto\x1a@hackathon/messages/hackathon_svc/set_capabilities_response.proto\x1a@hackathon/messages/hackathon_svc/set_current_phase_request.proto\x1aAhackathon/messages/hackathon_svc/set_current_phase_response.proto\x1a=hackathon/messages/hackathon_svc/submit_answers_request.proto\x1a>hackathon/messages/hackathon_svc/submit_answers_response.proto2\xe6\x14\n" + "\x10HackathonService\x12e\n" + "\x04List\x12-.hackathon.messages.hackathon_svc.ListRequest\x1a..hackathon.messages.hackathon_svc.ListResponse\x12b\n" + "\x03Get\x12,.hackathon.messages.hackathon_svc.GetRequest\x1a-.hackathon.messages.hackathon_svc.GetResponse\x12k\n" + "\x06Create\x12/.hackathon.messages.hackathon_svc.CreateRequest\x1a0.hackathon.messages.hackathon_svc.CreateResponse\x12e\n" + "\x04Edit\x12-.hackathon.messages.hackathon_svc.EditRequest\x1a..hackathon.messages.hackathon_svc.EditResponse\x12\x86\x01\n" + "\x0fSetCapabilities\x128.hackathon.messages.hackathon_svc.SetCapabilitiesRequest\x1a9.hackathon.messages.hackathon_svc.SetCapabilitiesResponse\x12\x86\x01\n" + - "\x0fSetCurrentPhase\x128.hackathon.messages.hackathon_svc.SetCurrentPhaseRequest\x1a9.hackathon.messages.hackathon_svc.SetCurrentPhaseResponse\x12e\n" + + "\x0fSetCurrentPhase\x128.hackathon.messages.hackathon_svc.SetCurrentPhaseRequest\x1a9.hackathon.messages.hackathon_svc.SetCurrentPhaseResponse\x12}\n" + + "\fCreateInvite\x125.hackathon.messages.hackathon_svc.CreateInviteRequest\x1a6.hackathon.messages.hackathon_svc.CreateInviteResponse\x12z\n" + + "\vListInvites\x124.hackathon.messages.hackathon_svc.ListInvitesRequest\x1a5.hackathon.messages.hackathon_svc.ListInvitesResponse\x12}\n" + + "\fRevokeInvite\x125.hackathon.messages.hackathon_svc.RevokeInviteRequest\x1a6.hackathon.messages.hackathon_svc.RevokeInviteResponse\x12\x80\x01\n" + + "\rPreviewInvite\x126.hackathon.messages.hackathon_svc.PreviewInviteRequest\x1a7.hackathon.messages.hackathon_svc.PreviewInviteResponse\x12e\n" + "\x04Join\x12-.hackathon.messages.hackathon_svc.JoinRequest\x1a..hackathon.messages.hackathon_svc.JoinResponse\x12\x8f\x01\n" + "\x12ApproveParticipant\x12;.hackathon.messages.hackathon_svc.ApproveParticipantRequest\x1a<.hackathon.messages.hackathon_svc.ApproveParticipantResponse\x12\x8c\x01\n" + "\x11RemoveParticipant\x12:.hackathon.messages.hackathon_svc.RemoveParticipantRequest\x1a;.hackathon.messages.hackathon_svc.RemoveParticipantResponse\x12q\n" + @@ -52,34 +56,42 @@ var file_hackathon_hackathon_service_proto_goTypes = []any{ (*hackathon_svc.EditRequest)(nil), // 3: hackathon.messages.hackathon_svc.EditRequest (*hackathon_svc.SetCapabilitiesRequest)(nil), // 4: hackathon.messages.hackathon_svc.SetCapabilitiesRequest (*hackathon_svc.SetCurrentPhaseRequest)(nil), // 5: hackathon.messages.hackathon_svc.SetCurrentPhaseRequest - (*hackathon_svc.JoinRequest)(nil), // 6: hackathon.messages.hackathon_svc.JoinRequest - (*hackathon_svc.ApproveParticipantRequest)(nil), // 7: hackathon.messages.hackathon_svc.ApproveParticipantRequest - (*hackathon_svc.RemoveParticipantRequest)(nil), // 8: hackathon.messages.hackathon_svc.RemoveParticipantRequest - (*hackathon_svc.AddOwnerRequest)(nil), // 9: hackathon.messages.hackathon_svc.AddOwnerRequest - (*hackathon_svc.RemoveOwnerRequest)(nil), // 10: hackathon.messages.hackathon_svc.RemoveOwnerRequest - (*hackathon_svc.CreateQuestionRequest)(nil), // 11: hackathon.messages.hackathon_svc.CreateQuestionRequest - (*hackathon_svc.EditQuestionRequest)(nil), // 12: hackathon.messages.hackathon_svc.EditQuestionRequest - (*hackathon_svc.RemoveQuestionRequest)(nil), // 13: hackathon.messages.hackathon_svc.RemoveQuestionRequest - (*hackathon_svc.ListQuestionsRequest)(nil), // 14: hackathon.messages.hackathon_svc.ListQuestionsRequest - (*hackathon_svc.SubmitAnswersRequest)(nil), // 15: hackathon.messages.hackathon_svc.SubmitAnswersRequest - (*hackathon_svc.ListParticipantAnswersRequest)(nil), // 16: hackathon.messages.hackathon_svc.ListParticipantAnswersRequest - (*hackathon_svc.ListResponse)(nil), // 17: hackathon.messages.hackathon_svc.ListResponse - (*hackathon_svc.GetResponse)(nil), // 18: hackathon.messages.hackathon_svc.GetResponse - (*hackathon_svc.CreateResponse)(nil), // 19: hackathon.messages.hackathon_svc.CreateResponse - (*hackathon_svc.EditResponse)(nil), // 20: hackathon.messages.hackathon_svc.EditResponse - (*hackathon_svc.SetCapabilitiesResponse)(nil), // 21: hackathon.messages.hackathon_svc.SetCapabilitiesResponse - (*hackathon_svc.SetCurrentPhaseResponse)(nil), // 22: hackathon.messages.hackathon_svc.SetCurrentPhaseResponse - (*hackathon_svc.JoinResponse)(nil), // 23: hackathon.messages.hackathon_svc.JoinResponse - (*hackathon_svc.ApproveParticipantResponse)(nil), // 24: hackathon.messages.hackathon_svc.ApproveParticipantResponse - (*hackathon_svc.RemoveParticipantResponse)(nil), // 25: hackathon.messages.hackathon_svc.RemoveParticipantResponse - (*hackathon_svc.AddOwnerResponse)(nil), // 26: hackathon.messages.hackathon_svc.AddOwnerResponse - (*hackathon_svc.RemoveOwnerResponse)(nil), // 27: hackathon.messages.hackathon_svc.RemoveOwnerResponse - (*hackathon_svc.CreateQuestionResponse)(nil), // 28: hackathon.messages.hackathon_svc.CreateQuestionResponse - (*hackathon_svc.EditQuestionResponse)(nil), // 29: hackathon.messages.hackathon_svc.EditQuestionResponse - (*hackathon_svc.RemoveQuestionResponse)(nil), // 30: hackathon.messages.hackathon_svc.RemoveQuestionResponse - (*hackathon_svc.ListQuestionsResponse)(nil), // 31: hackathon.messages.hackathon_svc.ListQuestionsResponse - (*hackathon_svc.SubmitAnswersResponse)(nil), // 32: hackathon.messages.hackathon_svc.SubmitAnswersResponse - (*hackathon_svc.ListParticipantAnswersResponse)(nil), // 33: hackathon.messages.hackathon_svc.ListParticipantAnswersResponse + (*hackathon_svc.CreateInviteRequest)(nil), // 6: hackathon.messages.hackathon_svc.CreateInviteRequest + (*hackathon_svc.ListInvitesRequest)(nil), // 7: hackathon.messages.hackathon_svc.ListInvitesRequest + (*hackathon_svc.RevokeInviteRequest)(nil), // 8: hackathon.messages.hackathon_svc.RevokeInviteRequest + (*hackathon_svc.PreviewInviteRequest)(nil), // 9: hackathon.messages.hackathon_svc.PreviewInviteRequest + (*hackathon_svc.JoinRequest)(nil), // 10: hackathon.messages.hackathon_svc.JoinRequest + (*hackathon_svc.ApproveParticipantRequest)(nil), // 11: hackathon.messages.hackathon_svc.ApproveParticipantRequest + (*hackathon_svc.RemoveParticipantRequest)(nil), // 12: hackathon.messages.hackathon_svc.RemoveParticipantRequest + (*hackathon_svc.AddOwnerRequest)(nil), // 13: hackathon.messages.hackathon_svc.AddOwnerRequest + (*hackathon_svc.RemoveOwnerRequest)(nil), // 14: hackathon.messages.hackathon_svc.RemoveOwnerRequest + (*hackathon_svc.CreateQuestionRequest)(nil), // 15: hackathon.messages.hackathon_svc.CreateQuestionRequest + (*hackathon_svc.EditQuestionRequest)(nil), // 16: hackathon.messages.hackathon_svc.EditQuestionRequest + (*hackathon_svc.RemoveQuestionRequest)(nil), // 17: hackathon.messages.hackathon_svc.RemoveQuestionRequest + (*hackathon_svc.ListQuestionsRequest)(nil), // 18: hackathon.messages.hackathon_svc.ListQuestionsRequest + (*hackathon_svc.SubmitAnswersRequest)(nil), // 19: hackathon.messages.hackathon_svc.SubmitAnswersRequest + (*hackathon_svc.ListParticipantAnswersRequest)(nil), // 20: hackathon.messages.hackathon_svc.ListParticipantAnswersRequest + (*hackathon_svc.ListResponse)(nil), // 21: hackathon.messages.hackathon_svc.ListResponse + (*hackathon_svc.GetResponse)(nil), // 22: hackathon.messages.hackathon_svc.GetResponse + (*hackathon_svc.CreateResponse)(nil), // 23: hackathon.messages.hackathon_svc.CreateResponse + (*hackathon_svc.EditResponse)(nil), // 24: hackathon.messages.hackathon_svc.EditResponse + (*hackathon_svc.SetCapabilitiesResponse)(nil), // 25: hackathon.messages.hackathon_svc.SetCapabilitiesResponse + (*hackathon_svc.SetCurrentPhaseResponse)(nil), // 26: hackathon.messages.hackathon_svc.SetCurrentPhaseResponse + (*hackathon_svc.CreateInviteResponse)(nil), // 27: hackathon.messages.hackathon_svc.CreateInviteResponse + (*hackathon_svc.ListInvitesResponse)(nil), // 28: hackathon.messages.hackathon_svc.ListInvitesResponse + (*hackathon_svc.RevokeInviteResponse)(nil), // 29: hackathon.messages.hackathon_svc.RevokeInviteResponse + (*hackathon_svc.PreviewInviteResponse)(nil), // 30: hackathon.messages.hackathon_svc.PreviewInviteResponse + (*hackathon_svc.JoinResponse)(nil), // 31: hackathon.messages.hackathon_svc.JoinResponse + (*hackathon_svc.ApproveParticipantResponse)(nil), // 32: hackathon.messages.hackathon_svc.ApproveParticipantResponse + (*hackathon_svc.RemoveParticipantResponse)(nil), // 33: hackathon.messages.hackathon_svc.RemoveParticipantResponse + (*hackathon_svc.AddOwnerResponse)(nil), // 34: hackathon.messages.hackathon_svc.AddOwnerResponse + (*hackathon_svc.RemoveOwnerResponse)(nil), // 35: hackathon.messages.hackathon_svc.RemoveOwnerResponse + (*hackathon_svc.CreateQuestionResponse)(nil), // 36: hackathon.messages.hackathon_svc.CreateQuestionResponse + (*hackathon_svc.EditQuestionResponse)(nil), // 37: hackathon.messages.hackathon_svc.EditQuestionResponse + (*hackathon_svc.RemoveQuestionResponse)(nil), // 38: hackathon.messages.hackathon_svc.RemoveQuestionResponse + (*hackathon_svc.ListQuestionsResponse)(nil), // 39: hackathon.messages.hackathon_svc.ListQuestionsResponse + (*hackathon_svc.SubmitAnswersResponse)(nil), // 40: hackathon.messages.hackathon_svc.SubmitAnswersResponse + (*hackathon_svc.ListParticipantAnswersResponse)(nil), // 41: hackathon.messages.hackathon_svc.ListParticipantAnswersResponse } var file_hackathon_hackathon_service_proto_depIdxs = []int32{ 0, // 0: hackathon.HackathonService.List:input_type -> hackathon.messages.hackathon_svc.ListRequest @@ -88,36 +100,44 @@ var file_hackathon_hackathon_service_proto_depIdxs = []int32{ 3, // 3: hackathon.HackathonService.Edit:input_type -> hackathon.messages.hackathon_svc.EditRequest 4, // 4: hackathon.HackathonService.SetCapabilities:input_type -> hackathon.messages.hackathon_svc.SetCapabilitiesRequest 5, // 5: hackathon.HackathonService.SetCurrentPhase:input_type -> hackathon.messages.hackathon_svc.SetCurrentPhaseRequest - 6, // 6: hackathon.HackathonService.Join:input_type -> hackathon.messages.hackathon_svc.JoinRequest - 7, // 7: hackathon.HackathonService.ApproveParticipant:input_type -> hackathon.messages.hackathon_svc.ApproveParticipantRequest - 8, // 8: hackathon.HackathonService.RemoveParticipant:input_type -> hackathon.messages.hackathon_svc.RemoveParticipantRequest - 9, // 9: hackathon.HackathonService.AddOwner:input_type -> hackathon.messages.hackathon_svc.AddOwnerRequest - 10, // 10: hackathon.HackathonService.RemoveOwner:input_type -> hackathon.messages.hackathon_svc.RemoveOwnerRequest - 11, // 11: hackathon.HackathonService.CreateQuestion:input_type -> hackathon.messages.hackathon_svc.CreateQuestionRequest - 12, // 12: hackathon.HackathonService.EditQuestion:input_type -> hackathon.messages.hackathon_svc.EditQuestionRequest - 13, // 13: hackathon.HackathonService.RemoveQuestion:input_type -> hackathon.messages.hackathon_svc.RemoveQuestionRequest - 14, // 14: hackathon.HackathonService.ListQuestions:input_type -> hackathon.messages.hackathon_svc.ListQuestionsRequest - 15, // 15: hackathon.HackathonService.SubmitAnswers:input_type -> hackathon.messages.hackathon_svc.SubmitAnswersRequest - 16, // 16: hackathon.HackathonService.ListParticipantAnswers:input_type -> hackathon.messages.hackathon_svc.ListParticipantAnswersRequest - 17, // 17: hackathon.HackathonService.List:output_type -> hackathon.messages.hackathon_svc.ListResponse - 18, // 18: hackathon.HackathonService.Get:output_type -> hackathon.messages.hackathon_svc.GetResponse - 19, // 19: hackathon.HackathonService.Create:output_type -> hackathon.messages.hackathon_svc.CreateResponse - 20, // 20: hackathon.HackathonService.Edit:output_type -> hackathon.messages.hackathon_svc.EditResponse - 21, // 21: hackathon.HackathonService.SetCapabilities:output_type -> hackathon.messages.hackathon_svc.SetCapabilitiesResponse - 22, // 22: hackathon.HackathonService.SetCurrentPhase:output_type -> hackathon.messages.hackathon_svc.SetCurrentPhaseResponse - 23, // 23: hackathon.HackathonService.Join:output_type -> hackathon.messages.hackathon_svc.JoinResponse - 24, // 24: hackathon.HackathonService.ApproveParticipant:output_type -> hackathon.messages.hackathon_svc.ApproveParticipantResponse - 25, // 25: hackathon.HackathonService.RemoveParticipant:output_type -> hackathon.messages.hackathon_svc.RemoveParticipantResponse - 26, // 26: hackathon.HackathonService.AddOwner:output_type -> hackathon.messages.hackathon_svc.AddOwnerResponse - 27, // 27: hackathon.HackathonService.RemoveOwner:output_type -> hackathon.messages.hackathon_svc.RemoveOwnerResponse - 28, // 28: hackathon.HackathonService.CreateQuestion:output_type -> hackathon.messages.hackathon_svc.CreateQuestionResponse - 29, // 29: hackathon.HackathonService.EditQuestion:output_type -> hackathon.messages.hackathon_svc.EditQuestionResponse - 30, // 30: hackathon.HackathonService.RemoveQuestion:output_type -> hackathon.messages.hackathon_svc.RemoveQuestionResponse - 31, // 31: hackathon.HackathonService.ListQuestions:output_type -> hackathon.messages.hackathon_svc.ListQuestionsResponse - 32, // 32: hackathon.HackathonService.SubmitAnswers:output_type -> hackathon.messages.hackathon_svc.SubmitAnswersResponse - 33, // 33: hackathon.HackathonService.ListParticipantAnswers:output_type -> hackathon.messages.hackathon_svc.ListParticipantAnswersResponse - 17, // [17:34] is the sub-list for method output_type - 0, // [0:17] is the sub-list for method input_type + 6, // 6: hackathon.HackathonService.CreateInvite:input_type -> hackathon.messages.hackathon_svc.CreateInviteRequest + 7, // 7: hackathon.HackathonService.ListInvites:input_type -> hackathon.messages.hackathon_svc.ListInvitesRequest + 8, // 8: hackathon.HackathonService.RevokeInvite:input_type -> hackathon.messages.hackathon_svc.RevokeInviteRequest + 9, // 9: hackathon.HackathonService.PreviewInvite:input_type -> hackathon.messages.hackathon_svc.PreviewInviteRequest + 10, // 10: hackathon.HackathonService.Join:input_type -> hackathon.messages.hackathon_svc.JoinRequest + 11, // 11: hackathon.HackathonService.ApproveParticipant:input_type -> hackathon.messages.hackathon_svc.ApproveParticipantRequest + 12, // 12: hackathon.HackathonService.RemoveParticipant:input_type -> hackathon.messages.hackathon_svc.RemoveParticipantRequest + 13, // 13: hackathon.HackathonService.AddOwner:input_type -> hackathon.messages.hackathon_svc.AddOwnerRequest + 14, // 14: hackathon.HackathonService.RemoveOwner:input_type -> hackathon.messages.hackathon_svc.RemoveOwnerRequest + 15, // 15: hackathon.HackathonService.CreateQuestion:input_type -> hackathon.messages.hackathon_svc.CreateQuestionRequest + 16, // 16: hackathon.HackathonService.EditQuestion:input_type -> hackathon.messages.hackathon_svc.EditQuestionRequest + 17, // 17: hackathon.HackathonService.RemoveQuestion:input_type -> hackathon.messages.hackathon_svc.RemoveQuestionRequest + 18, // 18: hackathon.HackathonService.ListQuestions:input_type -> hackathon.messages.hackathon_svc.ListQuestionsRequest + 19, // 19: hackathon.HackathonService.SubmitAnswers:input_type -> hackathon.messages.hackathon_svc.SubmitAnswersRequest + 20, // 20: hackathon.HackathonService.ListParticipantAnswers:input_type -> hackathon.messages.hackathon_svc.ListParticipantAnswersRequest + 21, // 21: hackathon.HackathonService.List:output_type -> hackathon.messages.hackathon_svc.ListResponse + 22, // 22: hackathon.HackathonService.Get:output_type -> hackathon.messages.hackathon_svc.GetResponse + 23, // 23: hackathon.HackathonService.Create:output_type -> hackathon.messages.hackathon_svc.CreateResponse + 24, // 24: hackathon.HackathonService.Edit:output_type -> hackathon.messages.hackathon_svc.EditResponse + 25, // 25: hackathon.HackathonService.SetCapabilities:output_type -> hackathon.messages.hackathon_svc.SetCapabilitiesResponse + 26, // 26: hackathon.HackathonService.SetCurrentPhase:output_type -> hackathon.messages.hackathon_svc.SetCurrentPhaseResponse + 27, // 27: hackathon.HackathonService.CreateInvite:output_type -> hackathon.messages.hackathon_svc.CreateInviteResponse + 28, // 28: hackathon.HackathonService.ListInvites:output_type -> hackathon.messages.hackathon_svc.ListInvitesResponse + 29, // 29: hackathon.HackathonService.RevokeInvite:output_type -> hackathon.messages.hackathon_svc.RevokeInviteResponse + 30, // 30: hackathon.HackathonService.PreviewInvite:output_type -> hackathon.messages.hackathon_svc.PreviewInviteResponse + 31, // 31: hackathon.HackathonService.Join:output_type -> hackathon.messages.hackathon_svc.JoinResponse + 32, // 32: hackathon.HackathonService.ApproveParticipant:output_type -> hackathon.messages.hackathon_svc.ApproveParticipantResponse + 33, // 33: hackathon.HackathonService.RemoveParticipant:output_type -> hackathon.messages.hackathon_svc.RemoveParticipantResponse + 34, // 34: hackathon.HackathonService.AddOwner:output_type -> hackathon.messages.hackathon_svc.AddOwnerResponse + 35, // 35: hackathon.HackathonService.RemoveOwner:output_type -> hackathon.messages.hackathon_svc.RemoveOwnerResponse + 36, // 36: hackathon.HackathonService.CreateQuestion:output_type -> hackathon.messages.hackathon_svc.CreateQuestionResponse + 37, // 37: hackathon.HackathonService.EditQuestion:output_type -> hackathon.messages.hackathon_svc.EditQuestionResponse + 38, // 38: hackathon.HackathonService.RemoveQuestion:output_type -> hackathon.messages.hackathon_svc.RemoveQuestionResponse + 39, // 39: hackathon.HackathonService.ListQuestions:output_type -> hackathon.messages.hackathon_svc.ListQuestionsResponse + 40, // 40: hackathon.HackathonService.SubmitAnswers:output_type -> hackathon.messages.hackathon_svc.SubmitAnswersResponse + 41, // 41: hackathon.HackathonService.ListParticipantAnswers:output_type -> hackathon.messages.hackathon_svc.ListParticipantAnswersResponse + 21, // [21:42] is the sub-list for method output_type + 0, // [0:21] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/components/backend/internal/proto/hackathon/hackathon_service_grpc.pb.go b/components/backend/internal/proto/hackathon/hackathon_service_grpc.pb.go index de7e6c67..465e8b63 100644 --- a/components/backend/internal/proto/hackathon/hackathon_service_grpc.pb.go +++ b/components/backend/internal/proto/hackathon/hackathon_service_grpc.pb.go @@ -26,6 +26,10 @@ const ( HackathonService_Edit_FullMethodName = "/hackathon.HackathonService/Edit" HackathonService_SetCapabilities_FullMethodName = "/hackathon.HackathonService/SetCapabilities" HackathonService_SetCurrentPhase_FullMethodName = "/hackathon.HackathonService/SetCurrentPhase" + HackathonService_CreateInvite_FullMethodName = "/hackathon.HackathonService/CreateInvite" + HackathonService_ListInvites_FullMethodName = "/hackathon.HackathonService/ListInvites" + HackathonService_RevokeInvite_FullMethodName = "/hackathon.HackathonService/RevokeInvite" + HackathonService_PreviewInvite_FullMethodName = "/hackathon.HackathonService/PreviewInvite" HackathonService_Join_FullMethodName = "/hackathon.HackathonService/Join" HackathonService_ApproveParticipant_FullMethodName = "/hackathon.HackathonService/ApproveParticipant" HackathonService_RemoveParticipant_FullMethodName = "/hackathon.HackathonService/RemoveParticipant" @@ -49,6 +53,10 @@ type HackathonServiceClient interface { Edit(ctx context.Context, in *hackathon_svc.EditRequest, opts ...grpc.CallOption) (*hackathon_svc.EditResponse, error) SetCapabilities(ctx context.Context, in *hackathon_svc.SetCapabilitiesRequest, opts ...grpc.CallOption) (*hackathon_svc.SetCapabilitiesResponse, error) SetCurrentPhase(ctx context.Context, in *hackathon_svc.SetCurrentPhaseRequest, opts ...grpc.CallOption) (*hackathon_svc.SetCurrentPhaseResponse, error) + CreateInvite(ctx context.Context, in *hackathon_svc.CreateInviteRequest, opts ...grpc.CallOption) (*hackathon_svc.CreateInviteResponse, error) + ListInvites(ctx context.Context, in *hackathon_svc.ListInvitesRequest, opts ...grpc.CallOption) (*hackathon_svc.ListInvitesResponse, error) + RevokeInvite(ctx context.Context, in *hackathon_svc.RevokeInviteRequest, opts ...grpc.CallOption) (*hackathon_svc.RevokeInviteResponse, error) + PreviewInvite(ctx context.Context, in *hackathon_svc.PreviewInviteRequest, opts ...grpc.CallOption) (*hackathon_svc.PreviewInviteResponse, error) Join(ctx context.Context, in *hackathon_svc.JoinRequest, opts ...grpc.CallOption) (*hackathon_svc.JoinResponse, error) ApproveParticipant(ctx context.Context, in *hackathon_svc.ApproveParticipantRequest, opts ...grpc.CallOption) (*hackathon_svc.ApproveParticipantResponse, error) RemoveParticipant(ctx context.Context, in *hackathon_svc.RemoveParticipantRequest, opts ...grpc.CallOption) (*hackathon_svc.RemoveParticipantResponse, error) @@ -131,6 +139,46 @@ func (c *hackathonServiceClient) SetCurrentPhase(ctx context.Context, in *hackat return out, nil } +func (c *hackathonServiceClient) CreateInvite(ctx context.Context, in *hackathon_svc.CreateInviteRequest, opts ...grpc.CallOption) (*hackathon_svc.CreateInviteResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(hackathon_svc.CreateInviteResponse) + err := c.cc.Invoke(ctx, HackathonService_CreateInvite_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hackathonServiceClient) ListInvites(ctx context.Context, in *hackathon_svc.ListInvitesRequest, opts ...grpc.CallOption) (*hackathon_svc.ListInvitesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(hackathon_svc.ListInvitesResponse) + err := c.cc.Invoke(ctx, HackathonService_ListInvites_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hackathonServiceClient) RevokeInvite(ctx context.Context, in *hackathon_svc.RevokeInviteRequest, opts ...grpc.CallOption) (*hackathon_svc.RevokeInviteResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(hackathon_svc.RevokeInviteResponse) + err := c.cc.Invoke(ctx, HackathonService_RevokeInvite_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hackathonServiceClient) PreviewInvite(ctx context.Context, in *hackathon_svc.PreviewInviteRequest, opts ...grpc.CallOption) (*hackathon_svc.PreviewInviteResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(hackathon_svc.PreviewInviteResponse) + err := c.cc.Invoke(ctx, HackathonService_PreviewInvite_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *hackathonServiceClient) Join(ctx context.Context, in *hackathon_svc.JoinRequest, opts ...grpc.CallOption) (*hackathon_svc.JoinResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(hackathon_svc.JoinResponse) @@ -251,6 +299,10 @@ type HackathonServiceServer interface { Edit(context.Context, *hackathon_svc.EditRequest) (*hackathon_svc.EditResponse, error) SetCapabilities(context.Context, *hackathon_svc.SetCapabilitiesRequest) (*hackathon_svc.SetCapabilitiesResponse, error) SetCurrentPhase(context.Context, *hackathon_svc.SetCurrentPhaseRequest) (*hackathon_svc.SetCurrentPhaseResponse, error) + CreateInvite(context.Context, *hackathon_svc.CreateInviteRequest) (*hackathon_svc.CreateInviteResponse, error) + ListInvites(context.Context, *hackathon_svc.ListInvitesRequest) (*hackathon_svc.ListInvitesResponse, error) + RevokeInvite(context.Context, *hackathon_svc.RevokeInviteRequest) (*hackathon_svc.RevokeInviteResponse, error) + PreviewInvite(context.Context, *hackathon_svc.PreviewInviteRequest) (*hackathon_svc.PreviewInviteResponse, error) Join(context.Context, *hackathon_svc.JoinRequest) (*hackathon_svc.JoinResponse, error) ApproveParticipant(context.Context, *hackathon_svc.ApproveParticipantRequest) (*hackathon_svc.ApproveParticipantResponse, error) RemoveParticipant(context.Context, *hackathon_svc.RemoveParticipantRequest) (*hackathon_svc.RemoveParticipantResponse, error) @@ -291,6 +343,18 @@ func (UnimplementedHackathonServiceServer) SetCapabilities(context.Context, *hac func (UnimplementedHackathonServiceServer) SetCurrentPhase(context.Context, *hackathon_svc.SetCurrentPhaseRequest) (*hackathon_svc.SetCurrentPhaseResponse, error) { return nil, status.Error(codes.Unimplemented, "method SetCurrentPhase not implemented") } +func (UnimplementedHackathonServiceServer) CreateInvite(context.Context, *hackathon_svc.CreateInviteRequest) (*hackathon_svc.CreateInviteResponse, error) { + return nil, status.Error(codes.Unimplemented, "method CreateInvite not implemented") +} +func (UnimplementedHackathonServiceServer) ListInvites(context.Context, *hackathon_svc.ListInvitesRequest) (*hackathon_svc.ListInvitesResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListInvites not implemented") +} +func (UnimplementedHackathonServiceServer) RevokeInvite(context.Context, *hackathon_svc.RevokeInviteRequest) (*hackathon_svc.RevokeInviteResponse, error) { + return nil, status.Error(codes.Unimplemented, "method RevokeInvite not implemented") +} +func (UnimplementedHackathonServiceServer) PreviewInvite(context.Context, *hackathon_svc.PreviewInviteRequest) (*hackathon_svc.PreviewInviteResponse, error) { + return nil, status.Error(codes.Unimplemented, "method PreviewInvite not implemented") +} func (UnimplementedHackathonServiceServer) Join(context.Context, *hackathon_svc.JoinRequest) (*hackathon_svc.JoinResponse, error) { return nil, status.Error(codes.Unimplemented, "method Join not implemented") } @@ -453,6 +517,78 @@ func _HackathonService_SetCurrentPhase_Handler(srv interface{}, ctx context.Cont return interceptor(ctx, in, info, handler) } +func _HackathonService_CreateInvite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(hackathon_svc.CreateInviteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HackathonServiceServer).CreateInvite(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HackathonService_CreateInvite_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HackathonServiceServer).CreateInvite(ctx, req.(*hackathon_svc.CreateInviteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HackathonService_ListInvites_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(hackathon_svc.ListInvitesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HackathonServiceServer).ListInvites(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HackathonService_ListInvites_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HackathonServiceServer).ListInvites(ctx, req.(*hackathon_svc.ListInvitesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HackathonService_RevokeInvite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(hackathon_svc.RevokeInviteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HackathonServiceServer).RevokeInvite(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HackathonService_RevokeInvite_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HackathonServiceServer).RevokeInvite(ctx, req.(*hackathon_svc.RevokeInviteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HackathonService_PreviewInvite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(hackathon_svc.PreviewInviteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HackathonServiceServer).PreviewInvite(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HackathonService_PreviewInvite_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HackathonServiceServer).PreviewInvite(ctx, req.(*hackathon_svc.PreviewInviteRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _HackathonService_Join_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(hackathon_svc.JoinRequest) if err := dec(in); err != nil { @@ -682,6 +818,22 @@ var HackathonService_ServiceDesc = grpc.ServiceDesc{ MethodName: "SetCurrentPhase", Handler: _HackathonService_SetCurrentPhase_Handler, }, + { + MethodName: "CreateInvite", + Handler: _HackathonService_CreateInvite_Handler, + }, + { + MethodName: "ListInvites", + Handler: _HackathonService_ListInvites_Handler, + }, + { + MethodName: "RevokeInvite", + Handler: _HackathonService_RevokeInvite_Handler, + }, + { + MethodName: "PreviewInvite", + Handler: _HackathonService_PreviewInvite_Handler, + }, { MethodName: "Join", Handler: _HackathonService_Join_Handler, diff --git a/components/backend/internal/proto/hackathon/messages/hackathon_svc/create_invite_request.pb.go b/components/backend/internal/proto/hackathon/messages/hackathon_svc/create_invite_request.pb.go new file mode 100644 index 00000000..76f1ba7e --- /dev/null +++ b/components/backend/internal/proto/hackathon/messages/hackathon_svc/create_invite_request.pb.go @@ -0,0 +1,148 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: hackathon/messages/hackathon_svc/create_invite_request.proto + +package hackathon_svc + +import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type CreateInviteRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + HackathonId string `protobuf:"bytes,1,opt,name=hackathon_id,json=hackathonId,proto3" json:"hackathon_id,omitempty"` + Note *string `protobuf:"bytes,2,opt,name=note,proto3,oneof" json:"note,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateInviteRequest) Reset() { + *x = CreateInviteRequest{} + mi := &file_hackathon_messages_hackathon_svc_create_invite_request_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateInviteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateInviteRequest) ProtoMessage() {} + +func (x *CreateInviteRequest) ProtoReflect() protoreflect.Message { + mi := &file_hackathon_messages_hackathon_svc_create_invite_request_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateInviteRequest.ProtoReflect.Descriptor instead. +func (*CreateInviteRequest) Descriptor() ([]byte, []int) { + return file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateInviteRequest) GetHackathonId() string { + if x != nil { + return x.HackathonId + } + return "" +} + +func (x *CreateInviteRequest) GetNote() string { + if x != nil && x.Note != nil { + return *x.Note + } + return "" +} + +func (x *CreateInviteRequest) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +var File_hackathon_messages_hackathon_svc_create_invite_request_proto protoreflect.FileDescriptor + +const file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDesc = "" + + "\n" + + "\n" + + "\n" + + "expires_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampH\x01R\texpiresAt\x88\x01\x01B\a\n" + + "\x05_noteB\r\n" + + "\v_expires_atBoZmgithub.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svcb\x06proto3" + +var ( + file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDescOnce sync.Once + file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDescData []byte +) + +func file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDescGZIP() []byte { + file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDescOnce.Do(func() { + file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDesc), len(file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDesc))) + }) + return file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDescData +} + +var file_hackathon_messages_hackathon_svc_create_invite_request_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_hackathon_messages_hackathon_svc_create_invite_request_proto_goTypes = []any{ + (*CreateInviteRequest)(nil), // 0: hackathon.messages.hackathon_svc.CreateInviteRequest + (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp +} +var file_hackathon_messages_hackathon_svc_create_invite_request_proto_depIdxs = []int32{ + 1, // 0: hackathon.messages.hackathon_svc.CreateInviteRequest.expires_at:type_name -> google.protobuf.Timestamp + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_hackathon_messages_hackathon_svc_create_invite_request_proto_init() } +func file_hackathon_messages_hackathon_svc_create_invite_request_proto_init() { + if File_hackathon_messages_hackathon_svc_create_invite_request_proto != nil { + return + } + file_hackathon_messages_hackathon_svc_create_invite_request_proto_msgTypes[0].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDesc), len(file_hackathon_messages_hackathon_svc_create_invite_request_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_hackathon_messages_hackathon_svc_create_invite_request_proto_goTypes, + DependencyIndexes: file_hackathon_messages_hackathon_svc_create_invite_request_proto_depIdxs, + MessageInfos: file_hackathon_messages_hackathon_svc_create_invite_request_proto_msgTypes, + }.Build() + File_hackathon_messages_hackathon_svc_create_invite_request_proto = out.File + file_hackathon_messages_hackathon_svc_create_invite_request_proto_goTypes = nil + file_hackathon_messages_hackathon_svc_create_invite_request_proto_depIdxs = nil +} diff --git a/components/backend/internal/proto/hackathon/messages/hackathon_svc/create_invite_response.pb.go b/components/backend/internal/proto/hackathon/messages/hackathon_svc/create_invite_response.pb.go new file mode 100644 index 00000000..a282bbe1 --- /dev/null +++ b/components/backend/internal/proto/hackathon/messages/hackathon_svc/create_invite_response.pb.go @@ -0,0 +1,125 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: hackathon/messages/hackathon_svc/create_invite_response.proto + +package hackathon_svc + +import ( + entities "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/entities" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type CreateInviteResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Invite *entities.HackathonInvite `protobuf:"bytes,1,opt,name=invite,proto3" json:"invite,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateInviteResponse) Reset() { + *x = CreateInviteResponse{} + mi := &file_hackathon_messages_hackathon_svc_create_invite_response_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateInviteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateInviteResponse) ProtoMessage() {} + +func (x *CreateInviteResponse) ProtoReflect() protoreflect.Message { + mi := &file_hackathon_messages_hackathon_svc_create_invite_response_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateInviteResponse.ProtoReflect.Descriptor instead. +func (*CreateInviteResponse) Descriptor() ([]byte, []int) { + return file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateInviteResponse) GetInvite() *entities.HackathonInvite { + if x != nil { + return x.Invite + } + return nil +} + +var File_hackathon_messages_hackathon_svc_create_invite_response_proto protoreflect.FileDescriptor + +const file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDesc = "" + + "\n" + + "=hackathon/messages/hackathon_svc/create_invite_response.proto\x12 hackathon.messages.hackathon_svc\x1a)hackathon/entities/hackathon_invite.proto\"S\n" + + "\x14CreateInviteResponse\x12;\n" + + "\x06invite\x18\x01 \x01(\v2#.hackathon.entities.HackathonInviteR\x06inviteBoZmgithub.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svcb\x06proto3" + +var ( + file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDescOnce sync.Once + file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDescData []byte +) + +func file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDescGZIP() []byte { + file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDescOnce.Do(func() { + file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDesc), len(file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDesc))) + }) + return file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDescData +} + +var file_hackathon_messages_hackathon_svc_create_invite_response_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_hackathon_messages_hackathon_svc_create_invite_response_proto_goTypes = []any{ + (*CreateInviteResponse)(nil), // 0: hackathon.messages.hackathon_svc.CreateInviteResponse + (*entities.HackathonInvite)(nil), // 1: hackathon.entities.HackathonInvite +} +var file_hackathon_messages_hackathon_svc_create_invite_response_proto_depIdxs = []int32{ + 1, // 0: hackathon.messages.hackathon_svc.CreateInviteResponse.invite:type_name -> hackathon.entities.HackathonInvite + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_hackathon_messages_hackathon_svc_create_invite_response_proto_init() } +func file_hackathon_messages_hackathon_svc_create_invite_response_proto_init() { + if File_hackathon_messages_hackathon_svc_create_invite_response_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDesc), len(file_hackathon_messages_hackathon_svc_create_invite_response_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_hackathon_messages_hackathon_svc_create_invite_response_proto_goTypes, + DependencyIndexes: file_hackathon_messages_hackathon_svc_create_invite_response_proto_depIdxs, + MessageInfos: file_hackathon_messages_hackathon_svc_create_invite_response_proto_msgTypes, + }.Build() + File_hackathon_messages_hackathon_svc_create_invite_response_proto = out.File + file_hackathon_messages_hackathon_svc_create_invite_response_proto_goTypes = nil + file_hackathon_messages_hackathon_svc_create_invite_response_proto_depIdxs = nil +} diff --git a/components/backend/internal/proto/hackathon/messages/hackathon_svc/join_request.pb.go b/components/backend/internal/proto/hackathon/messages/hackathon_svc/join_request.pb.go index 93466d81..e748627f 100644 --- a/components/backend/internal/proto/hackathon/messages/hackathon_svc/join_request.pb.go +++ b/components/backend/internal/proto/hackathon/messages/hackathon_svc/join_request.pb.go @@ -27,6 +27,7 @@ type JoinRequest struct { state protoimpl.MessageState `protogen:"open.v1"` HackathonId string `protobuf:"bytes,1,opt,name=hackathon_id,json=hackathonId,proto3" json:"hackathon_id,omitempty"` Answers []*entities.Answer `protobuf:"bytes,2,rep,name=answers,proto3" json:"answers,omitempty"` + InviteToken *string `protobuf:"bytes,3,opt,name=invite_token,json=inviteToken,proto3,oneof" json:"invite_token,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -75,14 +76,23 @@ func (x *JoinRequest) GetAnswers() []*entities.Answer { return nil } +func (x *JoinRequest) GetInviteToken() string { + if x != nil && x.InviteToken != nil { + return *x.InviteToken + } + return "" +} + var File_hackathon_messages_hackathon_svc_join_request_proto protoreflect.FileDescriptor const file_hackathon_messages_hackathon_svc_join_request_proto_rawDesc = "" + "\n" + - "3hackathon/messages/hackathon_svc/join_request.proto\x12 hackathon.messages.hackathon_svc\x1a\x1bbuf/validate/validate.proto\x1a\x1fhackathon/entities/answer.proto\"p\n" + + "3hackathon/messages/hackathon_svc/join_request.proto\x12 hackathon.messages.hackathon_svc\x1a\x1bbuf/validate/validate.proto\x1a\x1fhackathon/entities/answer.proto\"\xa9\x01\n" + "\vJoinRequest\x12+\n" + "\fhackathon_id\x18\x01 \x01(\tB\b\xbaH\x05r\x03\xb0\x01\x01R\vhackathonId\x124\n" + - "\aanswers\x18\x02 \x03(\v2\x1a.hackathon.entities.AnswerR\aanswersBoZmgithub.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svcb\x06proto3" + "\aanswers\x18\x02 \x03(\v2\x1a.hackathon.entities.AnswerR\aanswers\x12&\n" + + "\finvite_token\x18\x03 \x01(\tH\x00R\vinviteToken\x88\x01\x01B\x0f\n" + + "\r_invite_tokenBoZmgithub.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svcb\x06proto3" var ( file_hackathon_messages_hackathon_svc_join_request_proto_rawDescOnce sync.Once @@ -115,6 +125,7 @@ func file_hackathon_messages_hackathon_svc_join_request_proto_init() { if File_hackathon_messages_hackathon_svc_join_request_proto != nil { return } + file_hackathon_messages_hackathon_svc_join_request_proto_msgTypes[0].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/components/backend/internal/proto/hackathon/messages/hackathon_svc/list_invites_request.pb.go b/components/backend/internal/proto/hackathon/messages/hackathon_svc/list_invites_request.pb.go new file mode 100644 index 00000000..a3a87472 --- /dev/null +++ b/components/backend/internal/proto/hackathon/messages/hackathon_svc/list_invites_request.pb.go @@ -0,0 +1,123 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: hackathon/messages/hackathon_svc/list_invites_request.proto + +package hackathon_svc + +import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ListInvitesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + HackathonId string `protobuf:"bytes,1,opt,name=hackathon_id,json=hackathonId,proto3" json:"hackathon_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListInvitesRequest) Reset() { + *x = ListInvitesRequest{} + mi := &file_hackathon_messages_hackathon_svc_list_invites_request_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListInvitesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInvitesRequest) ProtoMessage() {} + +func (x *ListInvitesRequest) ProtoReflect() protoreflect.Message { + mi := &file_hackathon_messages_hackathon_svc_list_invites_request_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInvitesRequest.ProtoReflect.Descriptor instead. +func (*ListInvitesRequest) Descriptor() ([]byte, []int) { + return file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDescGZIP(), []int{0} +} + +func (x *ListInvitesRequest) GetHackathonId() string { + if x != nil { + return x.HackathonId + } + return "" +} + +var File_hackathon_messages_hackathon_svc_list_invites_request_proto protoreflect.FileDescriptor + +const file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDesc = "" + + "\n" + + ";hackathon/messages/hackathon_svc/list_invites_request.proto\x12 hackathon.messages.hackathon_svc\x1a\x1bbuf/validate/validate.proto\"A\n" + + "\x12ListInvitesRequest\x12+\n" + + "\fhackathon_id\x18\x01 \x01(\tB\b\xbaH\x05r\x03\xb0\x01\x01R\vhackathonIdBoZmgithub.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svcb\x06proto3" + +var ( + file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDescOnce sync.Once + file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDescData []byte +) + +func file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDescGZIP() []byte { + file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDescOnce.Do(func() { + file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDesc), len(file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDesc))) + }) + return file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDescData +} + +var file_hackathon_messages_hackathon_svc_list_invites_request_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_hackathon_messages_hackathon_svc_list_invites_request_proto_goTypes = []any{ + (*ListInvitesRequest)(nil), // 0: hackathon.messages.hackathon_svc.ListInvitesRequest +} +var file_hackathon_messages_hackathon_svc_list_invites_request_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_hackathon_messages_hackathon_svc_list_invites_request_proto_init() } +func file_hackathon_messages_hackathon_svc_list_invites_request_proto_init() { + if File_hackathon_messages_hackathon_svc_list_invites_request_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDesc), len(file_hackathon_messages_hackathon_svc_list_invites_request_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_hackathon_messages_hackathon_svc_list_invites_request_proto_goTypes, + DependencyIndexes: file_hackathon_messages_hackathon_svc_list_invites_request_proto_depIdxs, + MessageInfos: file_hackathon_messages_hackathon_svc_list_invites_request_proto_msgTypes, + }.Build() + File_hackathon_messages_hackathon_svc_list_invites_request_proto = out.File + file_hackathon_messages_hackathon_svc_list_invites_request_proto_goTypes = nil + file_hackathon_messages_hackathon_svc_list_invites_request_proto_depIdxs = nil +} diff --git a/components/backend/internal/proto/hackathon/messages/hackathon_svc/list_invites_response.pb.go b/components/backend/internal/proto/hackathon/messages/hackathon_svc/list_invites_response.pb.go new file mode 100644 index 00000000..ee16f27a --- /dev/null +++ b/components/backend/internal/proto/hackathon/messages/hackathon_svc/list_invites_response.pb.go @@ -0,0 +1,125 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: hackathon/messages/hackathon_svc/list_invites_response.proto + +package hackathon_svc + +import ( + entities "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/entities" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ListInvitesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Invites []*entities.HackathonInvite `protobuf:"bytes,1,rep,name=invites,proto3" json:"invites,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListInvitesResponse) Reset() { + *x = ListInvitesResponse{} + mi := &file_hackathon_messages_hackathon_svc_list_invites_response_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListInvitesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInvitesResponse) ProtoMessage() {} + +func (x *ListInvitesResponse) ProtoReflect() protoreflect.Message { + mi := &file_hackathon_messages_hackathon_svc_list_invites_response_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInvitesResponse.ProtoReflect.Descriptor instead. +func (*ListInvitesResponse) Descriptor() ([]byte, []int) { + return file_hackathon_messages_hackathon_svc_list_invites_response_proto_rawDescGZIP(), []int{0} +} + +func (x *ListInvitesResponse) GetInvites() []*entities.HackathonInvite { + if x != nil { + return x.Invites + } + return nil +} + +var File_hackathon_messages_hackathon_svc_list_invites_response_proto protoreflect.FileDescriptor + +const file_hackathon_messages_hackathon_svc_list_invites_response_proto_rawDesc = "" + + "\n" + + " hackathon.entities.HackathonInvite + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_hackathon_messages_hackathon_svc_list_invites_response_proto_init() } +func file_hackathon_messages_hackathon_svc_list_invites_response_proto_init() { + if File_hackathon_messages_hackathon_svc_list_invites_response_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_hackathon_messages_hackathon_svc_list_invites_response_proto_rawDesc), len(file_hackathon_messages_hackathon_svc_list_invites_response_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_hackathon_messages_hackathon_svc_list_invites_response_proto_goTypes, + DependencyIndexes: file_hackathon_messages_hackathon_svc_list_invites_response_proto_depIdxs, + MessageInfos: file_hackathon_messages_hackathon_svc_list_invites_response_proto_msgTypes, + }.Build() + File_hackathon_messages_hackathon_svc_list_invites_response_proto = out.File + file_hackathon_messages_hackathon_svc_list_invites_response_proto_goTypes = nil + file_hackathon_messages_hackathon_svc_list_invites_response_proto_depIdxs = nil +} diff --git a/components/backend/internal/proto/hackathon/messages/hackathon_svc/preview_invite_request.pb.go b/components/backend/internal/proto/hackathon/messages/hackathon_svc/preview_invite_request.pb.go new file mode 100644 index 00000000..b4b23793 --- /dev/null +++ b/components/backend/internal/proto/hackathon/messages/hackathon_svc/preview_invite_request.pb.go @@ -0,0 +1,124 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: hackathon/messages/hackathon_svc/preview_invite_request.proto + +package hackathon_svc + +import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PreviewInviteRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The invite token — the only credential. No hackathon_id to prevent probing. + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PreviewInviteRequest) Reset() { + *x = PreviewInviteRequest{} + mi := &file_hackathon_messages_hackathon_svc_preview_invite_request_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PreviewInviteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PreviewInviteRequest) ProtoMessage() {} + +func (x *PreviewInviteRequest) ProtoReflect() protoreflect.Message { + mi := &file_hackathon_messages_hackathon_svc_preview_invite_request_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PreviewInviteRequest.ProtoReflect.Descriptor instead. +func (*PreviewInviteRequest) Descriptor() ([]byte, []int) { + return file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDescGZIP(), []int{0} +} + +func (x *PreviewInviteRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +var File_hackathon_messages_hackathon_svc_preview_invite_request_proto protoreflect.FileDescriptor + +const file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDesc = "" + + "\n" + + "=hackathon/messages/hackathon_svc/preview_invite_request.proto\x12 hackathon.messages.hackathon_svc\x1a\x1bbuf/validate/validate.proto\"6\n" + + "\x14PreviewInviteRequest\x12\x1e\n" + + "\x05token\x18\x01 \x01(\tB\b\xbaH\x05r\x03\xb0\x01\x01R\x05tokenBoZmgithub.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svcb\x06proto3" + +var ( + file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDescOnce sync.Once + file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDescData []byte +) + +func file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDescGZIP() []byte { + file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDescOnce.Do(func() { + file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDesc), len(file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDesc))) + }) + return file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDescData +} + +var file_hackathon_messages_hackathon_svc_preview_invite_request_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_hackathon_messages_hackathon_svc_preview_invite_request_proto_goTypes = []any{ + (*PreviewInviteRequest)(nil), // 0: hackathon.messages.hackathon_svc.PreviewInviteRequest +} +var file_hackathon_messages_hackathon_svc_preview_invite_request_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_hackathon_messages_hackathon_svc_preview_invite_request_proto_init() } +func file_hackathon_messages_hackathon_svc_preview_invite_request_proto_init() { + if File_hackathon_messages_hackathon_svc_preview_invite_request_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDesc), len(file_hackathon_messages_hackathon_svc_preview_invite_request_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_hackathon_messages_hackathon_svc_preview_invite_request_proto_goTypes, + DependencyIndexes: file_hackathon_messages_hackathon_svc_preview_invite_request_proto_depIdxs, + MessageInfos: file_hackathon_messages_hackathon_svc_preview_invite_request_proto_msgTypes, + }.Build() + File_hackathon_messages_hackathon_svc_preview_invite_request_proto = out.File + file_hackathon_messages_hackathon_svc_preview_invite_request_proto_goTypes = nil + file_hackathon_messages_hackathon_svc_preview_invite_request_proto_depIdxs = nil +} diff --git a/components/backend/internal/proto/hackathon/messages/hackathon_svc/preview_invite_response.pb.go b/components/backend/internal/proto/hackathon/messages/hackathon_svc/preview_invite_response.pb.go new file mode 100644 index 00000000..fae043bd --- /dev/null +++ b/components/backend/internal/proto/hackathon/messages/hackathon_svc/preview_invite_response.pb.go @@ -0,0 +1,145 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: hackathon/messages/hackathon_svc/preview_invite_response.proto + +package hackathon_svc + +import ( + entities "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/entities" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PreviewInviteResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Hackathon *entities.Hackathon `protobuf:"bytes,1,opt,name=hackathon,proto3" json:"hackathon,omitempty"` + Questions []*entities.Question `protobuf:"bytes,2,rep,name=questions,proto3" json:"questions,omitempty"` + AlreadyParticipant bool `protobuf:"varint,3,opt,name=already_participant,json=alreadyParticipant,proto3" json:"already_participant,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PreviewInviteResponse) Reset() { + *x = PreviewInviteResponse{} + mi := &file_hackathon_messages_hackathon_svc_preview_invite_response_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PreviewInviteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PreviewInviteResponse) ProtoMessage() {} + +func (x *PreviewInviteResponse) ProtoReflect() protoreflect.Message { + mi := &file_hackathon_messages_hackathon_svc_preview_invite_response_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PreviewInviteResponse.ProtoReflect.Descriptor instead. +func (*PreviewInviteResponse) Descriptor() ([]byte, []int) { + return file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDescGZIP(), []int{0} +} + +func (x *PreviewInviteResponse) GetHackathon() *entities.Hackathon { + if x != nil { + return x.Hackathon + } + return nil +} + +func (x *PreviewInviteResponse) GetQuestions() []*entities.Question { + if x != nil { + return x.Questions + } + return nil +} + +func (x *PreviewInviteResponse) GetAlreadyParticipant() bool { + if x != nil { + return x.AlreadyParticipant + } + return false +} + +var File_hackathon_messages_hackathon_svc_preview_invite_response_proto protoreflect.FileDescriptor + +const file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDesc = "" + + "\n" + + ">hackathon/messages/hackathon_svc/preview_invite_response.proto\x12 hackathon.messages.hackathon_svc\x1a\"hackathon/entities/hackathon.proto\x1a!hackathon/entities/question.proto\"\xc1\x01\n" + + "\x15PreviewInviteResponse\x12;\n" + + "\thackathon\x18\x01 \x01(\v2\x1d.hackathon.entities.HackathonR\thackathon\x12:\n" + + "\tquestions\x18\x02 \x03(\v2\x1c.hackathon.entities.QuestionR\tquestions\x12/\n" + + "\x13already_participant\x18\x03 \x01(\bR\x12alreadyParticipantBoZmgithub.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svcb\x06proto3" + +var ( + file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDescOnce sync.Once + file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDescData []byte +) + +func file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDescGZIP() []byte { + file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDescOnce.Do(func() { + file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDesc), len(file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDesc))) + }) + return file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDescData +} + +var file_hackathon_messages_hackathon_svc_preview_invite_response_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_hackathon_messages_hackathon_svc_preview_invite_response_proto_goTypes = []any{ + (*PreviewInviteResponse)(nil), // 0: hackathon.messages.hackathon_svc.PreviewInviteResponse + (*entities.Hackathon)(nil), // 1: hackathon.entities.Hackathon + (*entities.Question)(nil), // 2: hackathon.entities.Question +} +var file_hackathon_messages_hackathon_svc_preview_invite_response_proto_depIdxs = []int32{ + 1, // 0: hackathon.messages.hackathon_svc.PreviewInviteResponse.hackathon:type_name -> hackathon.entities.Hackathon + 2, // 1: hackathon.messages.hackathon_svc.PreviewInviteResponse.questions:type_name -> hackathon.entities.Question + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_hackathon_messages_hackathon_svc_preview_invite_response_proto_init() } +func file_hackathon_messages_hackathon_svc_preview_invite_response_proto_init() { + if File_hackathon_messages_hackathon_svc_preview_invite_response_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDesc), len(file_hackathon_messages_hackathon_svc_preview_invite_response_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_hackathon_messages_hackathon_svc_preview_invite_response_proto_goTypes, + DependencyIndexes: file_hackathon_messages_hackathon_svc_preview_invite_response_proto_depIdxs, + MessageInfos: file_hackathon_messages_hackathon_svc_preview_invite_response_proto_msgTypes, + }.Build() + File_hackathon_messages_hackathon_svc_preview_invite_response_proto = out.File + file_hackathon_messages_hackathon_svc_preview_invite_response_proto_goTypes = nil + file_hackathon_messages_hackathon_svc_preview_invite_response_proto_depIdxs = nil +} diff --git a/components/backend/internal/proto/hackathon/messages/hackathon_svc/revoke_invite_request.pb.go b/components/backend/internal/proto/hackathon/messages/hackathon_svc/revoke_invite_request.pb.go new file mode 100644 index 00000000..f22b6996 --- /dev/null +++ b/components/backend/internal/proto/hackathon/messages/hackathon_svc/revoke_invite_request.pb.go @@ -0,0 +1,123 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: hackathon/messages/hackathon_svc/revoke_invite_request.proto + +package hackathon_svc + +import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type RevokeInviteRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + InviteId string `protobuf:"bytes,1,opt,name=invite_id,json=inviteId,proto3" json:"invite_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RevokeInviteRequest) Reset() { + *x = RevokeInviteRequest{} + mi := &file_hackathon_messages_hackathon_svc_revoke_invite_request_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RevokeInviteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RevokeInviteRequest) ProtoMessage() {} + +func (x *RevokeInviteRequest) ProtoReflect() protoreflect.Message { + mi := &file_hackathon_messages_hackathon_svc_revoke_invite_request_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RevokeInviteRequest.ProtoReflect.Descriptor instead. +func (*RevokeInviteRequest) Descriptor() ([]byte, []int) { + return file_hackathon_messages_hackathon_svc_revoke_invite_request_proto_rawDescGZIP(), []int{0} +} + +func (x *RevokeInviteRequest) GetInviteId() string { + if x != nil { + return x.InviteId + } + return "" +} + +var File_hackathon_messages_hackathon_svc_revoke_invite_request_proto protoreflect.FileDescriptor + +const file_hackathon_messages_hackathon_svc_revoke_invite_request_proto_rawDesc = "" + + "\n" + + " = { + encode(message: HackathonInvite, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.token !== "") { + writer.uint32(18).string(message.token); + } + if (message.note !== undefined) { + writer.uint32(26).string(message.note); + } + if (message.createdAt !== undefined) { + Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(34).fork()).join(); + } + if (message.revokedAt !== undefined) { + Timestamp.encode(toTimestamp(message.revokedAt), writer.uint32(42).fork()).join(); + } + if (message.expiresAt !== undefined) { + Timestamp.encode(toTimestamp(message.expiresAt), writer.uint32(50).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HackathonInvite { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHackathonInvite(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.token = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.note = reader.string(); + continue; + } + case 4: { + if (tag !== 34) { + break; + } + + message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + } + case 5: { + if (tag !== 42) { + break; + } + + message.revokedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + } + case 6: { + if (tag !== 50) { + break; + } + + message.expiresAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HackathonInvite { + return { + id: isSet(object.id) ? globalThis.String(object.id) : "", + token: isSet(object.token) ? globalThis.String(object.token) : "", + note: isSet(object.note) ? globalThis.String(object.note) : undefined, + createdAt: isSet(object.createdAt) + ? fromJsonTimestamp(object.createdAt) + : isSet(object.created_at) + ? fromJsonTimestamp(object.created_at) + : undefined, + revokedAt: isSet(object.revokedAt) + ? fromJsonTimestamp(object.revokedAt) + : isSet(object.revoked_at) + ? fromJsonTimestamp(object.revoked_at) + : undefined, + expiresAt: isSet(object.expiresAt) + ? fromJsonTimestamp(object.expiresAt) + : isSet(object.expires_at) + ? fromJsonTimestamp(object.expires_at) + : undefined, + }; + }, + + toJSON(message: HackathonInvite): unknown { + const obj: any = {}; + if (message.id !== "") { + obj.id = message.id; + } + if (message.token !== "") { + obj.token = message.token; + } + if (message.note !== undefined) { + obj.note = message.note; + } + if (message.createdAt !== undefined) { + obj.createdAt = message.createdAt.toISOString(); + } + if (message.revokedAt !== undefined) { + obj.revokedAt = message.revokedAt.toISOString(); + } + if (message.expiresAt !== undefined) { + obj.expiresAt = message.expiresAt.toISOString(); + } + return obj; + }, + + create(base?: DeepPartial): HackathonInvite { + return HackathonInvite.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HackathonInvite { + const message = createBaseHackathonInvite(); + message.id = object.id ?? ""; + message.token = object.token ?? ""; + message.note = object.note ?? undefined; + message.createdAt = object.createdAt ?? undefined; + message.revokedAt = object.revokedAt ?? undefined; + message.expiresAt = object.expiresAt ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +function toTimestamp(date: Date): Timestamp { + const seconds = Math.trunc(date.getTime() / 1_000); + const nanos = (date.getTime() % 1_000) * 1_000_000; + return { seconds, nanos }; +} + +function fromTimestamp(t: Timestamp): Date { + let millis = (t.seconds || 0) * 1_000; + millis += (t.nanos || 0) / 1_000_000; + return new globalThis.Date(millis); +} + +function fromJsonTimestamp(o: any): Date { + if (o instanceof globalThis.Date) { + return o; + } else if (typeof o === "string") { + return new globalThis.Date(o); + } else { + return fromTimestamp(Timestamp.fromJSON(o)); + } +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create(base?: DeepPartial): T; + fromPartial(object: DeepPartial): T; +} diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/hackathon_service.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/hackathon_service.ts index 8ebd25c1..c4db7f8d 100644 --- a/components/frontend/src/lib/server/grpc/generated/hackathon/hackathon_service.ts +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/hackathon_service.ts @@ -10,6 +10,8 @@ import { AddOwnerRequest } from "./messages/hackathon_svc/add_owner_request"; import { AddOwnerResponse } from "./messages/hackathon_svc/add_owner_response"; import { ApproveParticipantRequest } from "./messages/hackathon_svc/approve_participant_request"; import { ApproveParticipantResponse } from "./messages/hackathon_svc/approve_participant_response"; +import { CreateInviteRequest } from "./messages/hackathon_svc/create_invite_request"; +import { CreateInviteResponse } from "./messages/hackathon_svc/create_invite_response"; import { CreateQuestionRequest } from "./messages/hackathon_svc/create_question_request"; import { CreateQuestionResponse } from "./messages/hackathon_svc/create_question_response"; import { CreateRequest } from "./messages/hackathon_svc/create_request"; @@ -22,18 +24,24 @@ import { GetRequest } from "./messages/hackathon_svc/get_request"; import { GetResponse } from "./messages/hackathon_svc/get_response"; import { JoinRequest } from "./messages/hackathon_svc/join_request"; import { JoinResponse } from "./messages/hackathon_svc/join_response"; +import { ListInvitesRequest } from "./messages/hackathon_svc/list_invites_request"; +import { ListInvitesResponse } from "./messages/hackathon_svc/list_invites_response"; import { ListParticipantAnswersRequest } from "./messages/hackathon_svc/list_participant_answers_request"; import { ListParticipantAnswersResponse } from "./messages/hackathon_svc/list_participant_answers_response"; import { ListQuestionsRequest } from "./messages/hackathon_svc/list_questions_request"; import { ListQuestionsResponse } from "./messages/hackathon_svc/list_questions_response"; import { ListRequest } from "./messages/hackathon_svc/list_request"; import { ListResponse } from "./messages/hackathon_svc/list_response"; +import { PreviewInviteRequest } from "./messages/hackathon_svc/preview_invite_request"; +import { PreviewInviteResponse } from "./messages/hackathon_svc/preview_invite_response"; import { RemoveOwnerRequest } from "./messages/hackathon_svc/remove_owner_request"; import { RemoveOwnerResponse } from "./messages/hackathon_svc/remove_owner_response"; import { RemoveParticipantRequest } from "./messages/hackathon_svc/remove_participant_request"; import { RemoveParticipantResponse } from "./messages/hackathon_svc/remove_participant_response"; import { RemoveQuestionRequest } from "./messages/hackathon_svc/remove_question_request"; import { RemoveQuestionResponse } from "./messages/hackathon_svc/remove_question_response"; +import { RevokeInviteRequest } from "./messages/hackathon_svc/revoke_invite_request"; +import { RevokeInviteResponse } from "./messages/hackathon_svc/revoke_invite_response"; import { SetCapabilitiesRequest } from "./messages/hackathon_svc/set_capabilities_request"; import { SetCapabilitiesResponse } from "./messages/hackathon_svc/set_capabilities_response"; import { SetCurrentPhaseRequest } from "./messages/hackathon_svc/set_current_phase_request"; @@ -96,6 +104,38 @@ export const HackathonServiceDefinition = { responseStream: false, options: {}, }, + createInvite: { + name: "CreateInvite", + requestType: CreateInviteRequest as typeof CreateInviteRequest, + requestStream: false, + responseType: CreateInviteResponse as typeof CreateInviteResponse, + responseStream: false, + options: {}, + }, + listInvites: { + name: "ListInvites", + requestType: ListInvitesRequest as typeof ListInvitesRequest, + requestStream: false, + responseType: ListInvitesResponse as typeof ListInvitesResponse, + responseStream: false, + options: {}, + }, + revokeInvite: { + name: "RevokeInvite", + requestType: RevokeInviteRequest as typeof RevokeInviteRequest, + requestStream: false, + responseType: RevokeInviteResponse as typeof RevokeInviteResponse, + responseStream: false, + options: {}, + }, + previewInvite: { + name: "PreviewInvite", + requestType: PreviewInviteRequest as typeof PreviewInviteRequest, + requestStream: false, + responseType: PreviewInviteResponse as typeof PreviewInviteResponse, + responseStream: false, + options: {}, + }, join: { name: "Join", requestType: JoinRequest as typeof JoinRequest, @@ -201,6 +241,22 @@ export interface HackathonServiceImplementation { request: SetCurrentPhaseRequest, context: CallContext & CallContextExt, ): Promise>; + createInvite( + request: CreateInviteRequest, + context: CallContext & CallContextExt, + ): Promise>; + listInvites( + request: ListInvitesRequest, + context: CallContext & CallContextExt, + ): Promise>; + revokeInvite( + request: RevokeInviteRequest, + context: CallContext & CallContextExt, + ): Promise>; + previewInvite( + request: PreviewInviteRequest, + context: CallContext & CallContextExt, + ): Promise>; join(request: JoinRequest, context: CallContext & CallContextExt): Promise>; approveParticipant( request: ApproveParticipantRequest, @@ -255,6 +311,22 @@ export interface HackathonServiceClient { request: DeepPartial, options?: CallOptions & CallOptionsExt, ): Promise; + createInvite( + request: DeepPartial, + options?: CallOptions & CallOptionsExt, + ): Promise; + listInvites( + request: DeepPartial, + options?: CallOptions & CallOptionsExt, + ): Promise; + revokeInvite( + request: DeepPartial, + options?: CallOptions & CallOptionsExt, + ): Promise; + previewInvite( + request: DeepPartial, + options?: CallOptions & CallOptionsExt, + ): Promise; join(request: DeepPartial, options?: CallOptions & CallOptionsExt): Promise; approveParticipant( request: DeepPartial, diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/create_invite_request.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/create_invite_request.ts new file mode 100644 index 00000000..b47c0de0 --- /dev/null +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/create_invite_request.ts @@ -0,0 +1,160 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.11.6 +// protoc unknown +// source: hackathon/messages/hackathon_svc/create_invite_request.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { Timestamp } from "../../../google/protobuf/timestamp"; + +export const protobufPackage = "hackathon.messages.hackathon_svc"; + +export interface CreateInviteRequest { + hackathonId: string; + note?: string | undefined; + expiresAt?: Date | undefined; +} + +function createBaseCreateInviteRequest(): CreateInviteRequest { + return { hackathonId: "", note: undefined, expiresAt: undefined }; +} + +export const CreateInviteRequest: MessageFns = { + encode(message: CreateInviteRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.hackathonId !== "") { + writer.uint32(10).string(message.hackathonId); + } + if (message.note !== undefined) { + writer.uint32(18).string(message.note); + } + if (message.expiresAt !== undefined) { + Timestamp.encode(toTimestamp(message.expiresAt), writer.uint32(26).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): CreateInviteRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCreateInviteRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.hackathonId = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.note = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.expiresAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): CreateInviteRequest { + return { + hackathonId: isSet(object.hackathonId) + ? globalThis.String(object.hackathonId) + : isSet(object.hackathon_id) + ? globalThis.String(object.hackathon_id) + : "", + note: isSet(object.note) ? globalThis.String(object.note) : undefined, + expiresAt: isSet(object.expiresAt) + ? fromJsonTimestamp(object.expiresAt) + : isSet(object.expires_at) + ? fromJsonTimestamp(object.expires_at) + : undefined, + }; + }, + + toJSON(message: CreateInviteRequest): unknown { + const obj: any = {}; + if (message.hackathonId !== "") { + obj.hackathonId = message.hackathonId; + } + if (message.note !== undefined) { + obj.note = message.note; + } + if (message.expiresAt !== undefined) { + obj.expiresAt = message.expiresAt.toISOString(); + } + return obj; + }, + + create(base?: DeepPartial): CreateInviteRequest { + return CreateInviteRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): CreateInviteRequest { + const message = createBaseCreateInviteRequest(); + message.hackathonId = object.hackathonId ?? ""; + message.note = object.note ?? undefined; + message.expiresAt = object.expiresAt ?? undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +function toTimestamp(date: Date): Timestamp { + const seconds = Math.trunc(date.getTime() / 1_000); + const nanos = (date.getTime() % 1_000) * 1_000_000; + return { seconds, nanos }; +} + +function fromTimestamp(t: Timestamp): Date { + let millis = (t.seconds || 0) * 1_000; + millis += (t.nanos || 0) / 1_000_000; + return new globalThis.Date(millis); +} + +function fromJsonTimestamp(o: any): Date { + if (o instanceof globalThis.Date) { + return o; + } else if (typeof o === "string") { + return new globalThis.Date(o); + } else { + return fromTimestamp(Timestamp.fromJSON(o)); + } +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create(base?: DeepPartial): T; + fromPartial(object: DeepPartial): T; +} diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/create_invite_response.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/create_invite_response.ts new file mode 100644 index 00000000..326c949b --- /dev/null +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/create_invite_response.ts @@ -0,0 +1,96 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.11.6 +// protoc unknown +// source: hackathon/messages/hackathon_svc/create_invite_response.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { HackathonInvite } from "../../entities/hackathon_invite"; + +export const protobufPackage = "hackathon.messages.hackathon_svc"; + +export interface CreateInviteResponse { + invite: HackathonInvite | undefined; +} + +function createBaseCreateInviteResponse(): CreateInviteResponse { + return { invite: undefined }; +} + +export const CreateInviteResponse: MessageFns = { + encode(message: CreateInviteResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.invite !== undefined) { + HackathonInvite.encode(message.invite, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): CreateInviteResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCreateInviteResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.invite = HackathonInvite.decode(reader, reader.uint32()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): CreateInviteResponse { + return { invite: isSet(object.invite) ? HackathonInvite.fromJSON(object.invite) : undefined }; + }, + + toJSON(message: CreateInviteResponse): unknown { + const obj: any = {}; + if (message.invite !== undefined) { + obj.invite = HackathonInvite.toJSON(message.invite); + } + return obj; + }, + + create(base?: DeepPartial): CreateInviteResponse { + return CreateInviteResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): CreateInviteResponse { + const message = createBaseCreateInviteResponse(); + message.invite = (object.invite !== undefined && object.invite !== null) + ? HackathonInvite.fromPartial(object.invite) + : undefined; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create(base?: DeepPartial): T; + fromPartial(object: DeepPartial): T; +} diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/join_request.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/join_request.ts index f061e376..d8462b01 100644 --- a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/join_request.ts +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/join_request.ts @@ -13,10 +13,11 @@ export const protobufPackage = "hackathon.messages.hackathon_svc"; export interface JoinRequest { hackathonId: string; answers: Answer[]; + inviteToken?: string | undefined; } function createBaseJoinRequest(): JoinRequest { - return { hackathonId: "", answers: [] }; + return { hackathonId: "", answers: [], inviteToken: undefined }; } export const JoinRequest: MessageFns = { @@ -27,6 +28,9 @@ export const JoinRequest: MessageFns = { for (const v of message.answers) { Answer.encode(v!, writer.uint32(18).fork()).join(); } + if (message.inviteToken !== undefined) { + writer.uint32(26).string(message.inviteToken); + } return writer; }, @@ -53,6 +57,14 @@ export const JoinRequest: MessageFns = { message.answers.push(Answer.decode(reader, reader.uint32())); continue; } + case 3: { + if (tag !== 26) { + break; + } + + message.inviteToken = reader.string(); + continue; + } } if ((tag & 7) === 4 || tag === 0) { break; @@ -70,6 +82,11 @@ export const JoinRequest: MessageFns = { ? globalThis.String(object.hackathon_id) : "", answers: globalThis.Array.isArray(object?.answers) ? object.answers.map((e: any) => Answer.fromJSON(e)) : [], + inviteToken: isSet(object.inviteToken) + ? globalThis.String(object.inviteToken) + : isSet(object.invite_token) + ? globalThis.String(object.invite_token) + : undefined, }; }, @@ -81,6 +98,9 @@ export const JoinRequest: MessageFns = { if (message.answers?.length) { obj.answers = message.answers.map((e) => Answer.toJSON(e)); } + if (message.inviteToken !== undefined) { + obj.inviteToken = message.inviteToken; + } return obj; }, @@ -91,6 +111,7 @@ export const JoinRequest: MessageFns = { const message = createBaseJoinRequest(); message.hackathonId = object.hackathonId ?? ""; message.answers = object.answers?.map((e) => Answer.fromPartial(e)) || []; + message.inviteToken = object.inviteToken ?? undefined; return message; }, }; diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/list_invites_request.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/list_invites_request.ts new file mode 100644 index 00000000..325afea2 --- /dev/null +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/list_invites_request.ts @@ -0,0 +1,99 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.11.6 +// protoc unknown +// source: hackathon/messages/hackathon_svc/list_invites_request.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; + +export const protobufPackage = "hackathon.messages.hackathon_svc"; + +export interface ListInvitesRequest { + hackathonId: string; +} + +function createBaseListInvitesRequest(): ListInvitesRequest { + return { hackathonId: "" }; +} + +export const ListInvitesRequest: MessageFns = { + encode(message: ListInvitesRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.hackathonId !== "") { + writer.uint32(10).string(message.hackathonId); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ListInvitesRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseListInvitesRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.hackathonId = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ListInvitesRequest { + return { + hackathonId: isSet(object.hackathonId) + ? globalThis.String(object.hackathonId) + : isSet(object.hackathon_id) + ? globalThis.String(object.hackathon_id) + : "", + }; + }, + + toJSON(message: ListInvitesRequest): unknown { + const obj: any = {}; + if (message.hackathonId !== "") { + obj.hackathonId = message.hackathonId; + } + return obj; + }, + + create(base?: DeepPartial): ListInvitesRequest { + return ListInvitesRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ListInvitesRequest { + const message = createBaseListInvitesRequest(); + message.hackathonId = object.hackathonId ?? ""; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create(base?: DeepPartial): T; + fromPartial(object: DeepPartial): T; +} diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/list_invites_response.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/list_invites_response.ts new file mode 100644 index 00000000..f3895057 --- /dev/null +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/list_invites_response.ts @@ -0,0 +1,94 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.11.6 +// protoc unknown +// source: hackathon/messages/hackathon_svc/list_invites_response.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { HackathonInvite } from "../../entities/hackathon_invite"; + +export const protobufPackage = "hackathon.messages.hackathon_svc"; + +export interface ListInvitesResponse { + invites: HackathonInvite[]; +} + +function createBaseListInvitesResponse(): ListInvitesResponse { + return { invites: [] }; +} + +export const ListInvitesResponse: MessageFns = { + encode(message: ListInvitesResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.invites) { + HackathonInvite.encode(v!, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ListInvitesResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseListInvitesResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.invites.push(HackathonInvite.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ListInvitesResponse { + return { + invites: globalThis.Array.isArray(object?.invites) + ? object.invites.map((e: any) => HackathonInvite.fromJSON(e)) + : [], + }; + }, + + toJSON(message: ListInvitesResponse): unknown { + const obj: any = {}; + if (message.invites?.length) { + obj.invites = message.invites.map((e) => HackathonInvite.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): ListInvitesResponse { + return ListInvitesResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ListInvitesResponse { + const message = createBaseListInvitesResponse(); + message.invites = object.invites?.map((e) => HackathonInvite.fromPartial(e)) || []; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create(base?: DeepPartial): T; + fromPartial(object: DeepPartial): T; +} diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/preview_invite_request.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/preview_invite_request.ts new file mode 100644 index 00000000..7170b077 --- /dev/null +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/preview_invite_request.ts @@ -0,0 +1,94 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.11.6 +// protoc unknown +// source: hackathon/messages/hackathon_svc/preview_invite_request.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; + +export const protobufPackage = "hackathon.messages.hackathon_svc"; + +export interface PreviewInviteRequest { + /** The invite token — the only credential. No hackathon_id to prevent probing. */ + token: string; +} + +function createBasePreviewInviteRequest(): PreviewInviteRequest { + return { token: "" }; +} + +export const PreviewInviteRequest: MessageFns = { + encode(message: PreviewInviteRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.token !== "") { + writer.uint32(10).string(message.token); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PreviewInviteRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePreviewInviteRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.token = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PreviewInviteRequest { + return { token: isSet(object.token) ? globalThis.String(object.token) : "" }; + }, + + toJSON(message: PreviewInviteRequest): unknown { + const obj: any = {}; + if (message.token !== "") { + obj.token = message.token; + } + return obj; + }, + + create(base?: DeepPartial): PreviewInviteRequest { + return PreviewInviteRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): PreviewInviteRequest { + const message = createBasePreviewInviteRequest(); + message.token = object.token ?? ""; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create(base?: DeepPartial): T; + fromPartial(object: DeepPartial): T; +} diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/preview_invite_response.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/preview_invite_response.ts new file mode 100644 index 00000000..d10a481c --- /dev/null +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/preview_invite_response.ts @@ -0,0 +1,139 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.11.6 +// protoc unknown +// source: hackathon/messages/hackathon_svc/preview_invite_response.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { Hackathon } from "../../entities/hackathon"; +import { Question } from "../../entities/question"; + +export const protobufPackage = "hackathon.messages.hackathon_svc"; + +export interface PreviewInviteResponse { + hackathon: Hackathon | undefined; + questions: Question[]; + alreadyParticipant: boolean; +} + +function createBasePreviewInviteResponse(): PreviewInviteResponse { + return { hackathon: undefined, questions: [], alreadyParticipant: false }; +} + +export const PreviewInviteResponse: MessageFns = { + encode(message: PreviewInviteResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.hackathon !== undefined) { + Hackathon.encode(message.hackathon, writer.uint32(10).fork()).join(); + } + for (const v of message.questions) { + Question.encode(v!, writer.uint32(18).fork()).join(); + } + if (message.alreadyParticipant !== false) { + writer.uint32(24).bool(message.alreadyParticipant); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PreviewInviteResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePreviewInviteResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.hackathon = Hackathon.decode(reader, reader.uint32()); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.questions.push(Question.decode(reader, reader.uint32())); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.alreadyParticipant = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PreviewInviteResponse { + return { + hackathon: isSet(object.hackathon) ? Hackathon.fromJSON(object.hackathon) : undefined, + questions: globalThis.Array.isArray(object?.questions) + ? object.questions.map((e: any) => Question.fromJSON(e)) + : [], + alreadyParticipant: isSet(object.alreadyParticipant) + ? globalThis.Boolean(object.alreadyParticipant) + : isSet(object.already_participant) + ? globalThis.Boolean(object.already_participant) + : false, + }; + }, + + toJSON(message: PreviewInviteResponse): unknown { + const obj: any = {}; + if (message.hackathon !== undefined) { + obj.hackathon = Hackathon.toJSON(message.hackathon); + } + if (message.questions?.length) { + obj.questions = message.questions.map((e) => Question.toJSON(e)); + } + if (message.alreadyParticipant !== false) { + obj.alreadyParticipant = message.alreadyParticipant; + } + return obj; + }, + + create(base?: DeepPartial): PreviewInviteResponse { + return PreviewInviteResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): PreviewInviteResponse { + const message = createBasePreviewInviteResponse(); + message.hackathon = (object.hackathon !== undefined && object.hackathon !== null) + ? Hackathon.fromPartial(object.hackathon) + : undefined; + message.questions = object.questions?.map((e) => Question.fromPartial(e)) || []; + message.alreadyParticipant = object.alreadyParticipant ?? false; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create(base?: DeepPartial): T; + fromPartial(object: DeepPartial): T; +} diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/revoke_invite_request.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/revoke_invite_request.ts new file mode 100644 index 00000000..5c245aa2 --- /dev/null +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/revoke_invite_request.ts @@ -0,0 +1,99 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.11.6 +// protoc unknown +// source: hackathon/messages/hackathon_svc/revoke_invite_request.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; + +export const protobufPackage = "hackathon.messages.hackathon_svc"; + +export interface RevokeInviteRequest { + inviteId: string; +} + +function createBaseRevokeInviteRequest(): RevokeInviteRequest { + return { inviteId: "" }; +} + +export const RevokeInviteRequest: MessageFns = { + encode(message: RevokeInviteRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.inviteId !== "") { + writer.uint32(10).string(message.inviteId); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): RevokeInviteRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRevokeInviteRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.inviteId = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): RevokeInviteRequest { + return { + inviteId: isSet(object.inviteId) + ? globalThis.String(object.inviteId) + : isSet(object.invite_id) + ? globalThis.String(object.invite_id) + : "", + }; + }, + + toJSON(message: RevokeInviteRequest): unknown { + const obj: any = {}; + if (message.inviteId !== "") { + obj.inviteId = message.inviteId; + } + return obj; + }, + + create(base?: DeepPartial): RevokeInviteRequest { + return RevokeInviteRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): RevokeInviteRequest { + const message = createBaseRevokeInviteRequest(); + message.inviteId = object.inviteId ?? ""; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create(base?: DeepPartial): T; + fromPartial(object: DeepPartial): T; +} diff --git a/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/revoke_invite_response.ts b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/revoke_invite_response.ts new file mode 100644 index 00000000..879eac34 --- /dev/null +++ b/components/frontend/src/lib/server/grpc/generated/hackathon/messages/hackathon_svc/revoke_invite_response.ts @@ -0,0 +1,73 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.11.6 +// protoc unknown +// source: hackathon/messages/hackathon_svc/revoke_invite_response.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; + +export const protobufPackage = "hackathon.messages.hackathon_svc"; + +export interface RevokeInviteResponse { +} + +function createBaseRevokeInviteResponse(): RevokeInviteResponse { + return {}; +} + +export const RevokeInviteResponse: MessageFns = { + encode(_: RevokeInviteResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): RevokeInviteResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRevokeInviteResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): RevokeInviteResponse { + return {}; + }, + + toJSON(_: RevokeInviteResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): RevokeInviteResponse { + return RevokeInviteResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): RevokeInviteResponse { + const message = createBaseRevokeInviteResponse(); + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create(base?: DeepPartial): T; + fromPartial(object: DeepPartial): T; +} From 46fbab241607fee39aa8d58ba0fd702b71833a5c Mon Sep 17 00:00:00 2001 From: Ralf Grubenmann Date: Mon, 24 Aug 2026 16:15:05 +0200 Subject: [PATCH 3/3] fix tests --- api/proto/API.md | 322 +++++++++--------- .../hackathon/entities/hackathon_invite.proto | 2 +- api/proto/hackathon/hackathon_service.proto | 12 +- .../hackathon_svc/create_invite_request.proto | 2 +- .../create_invite_response.proto | 2 +- .../hackathon_svc/list_invites_request.proto | 2 +- .../hackathon_svc/list_invites_response.proto | 2 +- .../preview_invite_request.proto | 2 +- .../preview_invite_response.proto | 2 +- .../hackathon_svc/revoke_invite_request.proto | 2 +- .../revoke_invite_response.proto | 2 +- .../backend/db/schema/hackathoninvite.go | 3 +- .../ent/hackathoninvite/hackathoninvite.go | 2 - .../backend/ent/hackathoninvite_create.go | 5 - .../backend/ent/hackathoninvite_update.go | 10 - components/backend/ent/migrate/schema.go | 2 +- components/backend/ent/runtime/runtime.go | 4 - components/backend/go.sum | 26 -- .../proto/hackathon/hackathon_service.pb.go | 2 +- .../internal/service/hackathon_service.go | 105 ++++-- .../service/hackathon_service_test.go | 51 +-- .../backend/internal/service/mappers.go | 9 +- 22 files changed, 289 insertions(+), 282 deletions(-) diff --git a/api/proto/API.md b/api/proto/API.md index b29c553d..6dc2049a 100644 --- a/api/proto/API.md +++ b/api/proto/API.md @@ -81,6 +81,12 @@ - [hackathon/messages/hackathon_svc/approve_participant_response.proto](#hackathon_messages_hackathon_svc_approve_participant_response-proto) - [ApproveParticipantResponse](#hackathon-messages-hackathon_svc-ApproveParticipantResponse) +- [hackathon/messages/hackathon_svc/create_invite_request.proto](#hackathon_messages_hackathon_svc_create_invite_request-proto) + - [CreateInviteRequest](#hackathon-messages-hackathon_svc-CreateInviteRequest) + +- [hackathon/messages/hackathon_svc/create_invite_response.proto](#hackathon_messages_hackathon_svc_create_invite_response-proto) + - [CreateInviteResponse](#hackathon-messages-hackathon_svc-CreateInviteResponse) + - [hackathon/messages/hackathon_svc/create_question_request.proto](#hackathon_messages_hackathon_svc_create_question_request-proto) - [CreateQuestionRequest](#hackathon-messages-hackathon_svc-CreateQuestionRequest) @@ -111,12 +117,6 @@ - [hackathon/messages/hackathon_svc/get_response.proto](#hackathon_messages_hackathon_svc_get_response-proto) - [GetResponse](#hackathon-messages-hackathon_svc-GetResponse) -- [hackathon/messages/hackathon_svc/create_invite_request.proto](#hackathon_messages_hackathon_svc_create_invite_request-proto) - - [CreateInviteRequest](#hackathon-messages-hackathon_svc-CreateInviteRequest) - -- [hackathon/messages/hackathon_svc/create_invite_response.proto](#hackathon_messages_hackathon_svc_create_invite_response-proto) - - [CreateInviteResponse](#hackathon-messages-hackathon_svc-CreateInviteResponse) - - [hackathon/messages/hackathon_svc/join_request.proto](#hackathon_messages_hackathon_svc_join_request-proto) - [JoinRequest](#hackathon-messages-hackathon_svc-JoinRequest) @@ -132,18 +132,6 @@ - [hackathon/messages/hackathon_svc/list_participant_answers_request.proto](#hackathon_messages_hackathon_svc_list_participant_answers_request-proto) - [ListParticipantAnswersRequest](#hackathon-messages-hackathon_svc-ListParticipantAnswersRequest) -- [hackathon/messages/hackathon_svc/preview_invite_request.proto](#hackathon_messages_hackathon_svc_preview_invite_request-proto) - - [PreviewInviteRequest](#hackathon-messages-hackathon_svc-PreviewInviteRequest) - -- [hackathon/messages/hackathon_svc/preview_invite_response.proto](#hackathon_messages_hackathon_svc_preview_invite_response-proto) - - [PreviewInviteResponse](#hackathon-messages-hackathon_svc-PreviewInviteResponse) - -- [hackathon/messages/hackathon_svc/revoke_invite_request.proto](#hackathon_messages_hackathon_svc_revoke_invite_request-proto) - - [RevokeInviteRequest](#hackathon-messages-hackathon_svc-RevokeInviteRequest) - -- [hackathon/messages/hackathon_svc/revoke_invite_response.proto](#hackathon_messages_hackathon_svc_revoke_invite_response-proto) - - [RevokeInviteResponse](#hackathon-messages-hackathon_svc-RevokeInviteResponse) - - [hackathon/messages/hackathon_svc/list_participant_answers_response.proto](#hackathon_messages_hackathon_svc_list_participant_answers_response-proto) - [ListParticipantAnswersResponse](#hackathon-messages-hackathon_svc-ListParticipantAnswersResponse) @@ -159,6 +147,12 @@ - [hackathon/messages/hackathon_svc/list_response.proto](#hackathon_messages_hackathon_svc_list_response-proto) - [ListResponse](#hackathon-messages-hackathon_svc-ListResponse) +- [hackathon/messages/hackathon_svc/preview_invite_request.proto](#hackathon_messages_hackathon_svc_preview_invite_request-proto) + - [PreviewInviteRequest](#hackathon-messages-hackathon_svc-PreviewInviteRequest) + +- [hackathon/messages/hackathon_svc/preview_invite_response.proto](#hackathon_messages_hackathon_svc_preview_invite_response-proto) + - [PreviewInviteResponse](#hackathon-messages-hackathon_svc-PreviewInviteResponse) + - [hackathon/messages/hackathon_svc/remove_owner_request.proto](#hackathon_messages_hackathon_svc_remove_owner_request-proto) - [RemoveOwnerRequest](#hackathon-messages-hackathon_svc-RemoveOwnerRequest) @@ -177,6 +171,12 @@ - [hackathon/messages/hackathon_svc/remove_question_response.proto](#hackathon_messages_hackathon_svc_remove_question_response-proto) - [RemoveQuestionResponse](#hackathon-messages-hackathon_svc-RemoveQuestionResponse) +- [hackathon/messages/hackathon_svc/revoke_invite_request.proto](#hackathon_messages_hackathon_svc_revoke_invite_request-proto) + - [RevokeInviteRequest](#hackathon-messages-hackathon_svc-RevokeInviteRequest) + +- [hackathon/messages/hackathon_svc/revoke_invite_response.proto](#hackathon_messages_hackathon_svc_revoke_invite_response-proto) + - [RevokeInviteResponse](#hackathon-messages-hackathon_svc-RevokeInviteResponse) + - [hackathon/messages/hackathon_svc/set_capabilities_request.proto](#hackathon_messages_hackathon_svc_set_capabilities_request-proto) - [CapabilityState](#hackathon-messages-hackathon_svc-CapabilityState) - [SetCapabilitiesRequest](#hackathon-messages-hackathon_svc-SetCapabilitiesRequest) @@ -1518,6 +1518,70 @@ casbin role for this hackathon; `is_waiting` is false once approved. + +

Top

+ +## hackathon/messages/hackathon_svc/create_invite_request.proto + + + + + +### CreateInviteRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| hackathon_id | [string](#string) | | | +| note | [string](#string) | optional | | +| expires_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | optional | | + + + + + + + + + + + + + + + + +

Top

+ +## hackathon/messages/hackathon_svc/create_invite_response.proto + + + + + +### CreateInviteResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| invite | [hackathon.entities.HackathonInvite](#hackathon-entities-HackathonInvite) | | | + + + + + + + + + + + + + + +

Top

@@ -1846,70 +1910,6 @@ casbin role for this hackathon; `is_waiting` is false once approved. - -

Top

- -## hackathon/messages/hackathon_svc/create_invite_request.proto - - - - - -### CreateInviteRequest - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| hackathon_id | [string](#string) | | | -| note | [string](#string) | optional | | -| expires_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | optional | | - - - - - - - - - - - - - - - - -

Top

- -## hackathon/messages/hackathon_svc/create_invite_response.proto - - - - - -### CreateInviteResponse - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| invite | [hackathon.entities.HackathonInvite](#hackathon-entities-HackathonInvite) | | | - - - - - - - - - - - - - - -

Top

@@ -2068,22 +2068,22 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/preview_invite_request.proto +## hackathon/messages/hackathon_svc/list_participant_answers_response.proto - + -### PreviewInviteRequest +### ListParticipantAnswersResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| token | [string](#string) | | The invite token — the only credential. No hackathon_id to prevent probing. | +| answers | [hackathon.entities.Answer](#hackathon-entities-Answer) | repeated | | @@ -2099,24 +2099,22 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/preview_invite_response.proto +## hackathon/messages/hackathon_svc/list_questions_request.proto - + -### PreviewInviteResponse +### ListQuestionsRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| hackathon | [hackathon.entities.Hackathon](#hackathon-entities-Hackathon) | | | -| questions | [hackathon.entities.Question](#hackathon-entities-Question) | repeated | | -| already_participant | [bool](#bool) | | | +| hackathon_id | [string](#string) | | | @@ -2132,22 +2130,22 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/revoke_invite_request.proto +## hackathon/messages/hackathon_svc/list_questions_response.proto - + -### RevokeInviteRequest +### ListQuestionsResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| invite_id | [string](#string) | | | +| questions | [hackathon.entities.Question](#hackathon-entities-Question) | repeated | | @@ -2163,18 +2161,26 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/revoke_invite_response.proto +## hackathon/messages/hackathon_svc/list_request.proto - + + +### ListRequest -### RevokeInviteResponse +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| status_filter | [hackathon.entities.HackathonStatus](#hackathon-entities-HackathonStatus) | repeated | | +| owner_id | [string](#string) | optional | | +| participant_id | [string](#string) | optional | | +| visibility_filter | [hackathon.entities.Visibility](#hackathon-entities-Visibility) | optional | | + @@ -2189,22 +2195,22 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/list_participant_answers_response.proto +## hackathon/messages/hackathon_svc/list_response.proto - + -### ListParticipantAnswersResponse +### ListResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| answers | [hackathon.entities.Answer](#hackathon-entities-Answer) | repeated | | +| hackathons | [hackathon.entities.Hackathon](#hackathon-entities-Hackathon) | repeated | | @@ -2220,22 +2226,22 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/list_questions_request.proto +## hackathon/messages/hackathon_svc/preview_invite_request.proto - + -### ListQuestionsRequest +### PreviewInviteRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| hackathon_id | [string](#string) | | | +| token | [string](#string) | | The invite token — the only credential. No hackathon_id to prevent probing. | @@ -2251,22 +2257,24 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/list_questions_response.proto +## hackathon/messages/hackathon_svc/preview_invite_response.proto - + -### ListQuestionsResponse +### PreviewInviteResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | +| hackathon | [hackathon.entities.Hackathon](#hackathon-entities-Hackathon) | | | | questions | [hackathon.entities.Question](#hackathon-entities-Question) | repeated | | +| already_participant | [bool](#bool) | | | @@ -2282,25 +2290,23 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/list_request.proto +## hackathon/messages/hackathon_svc/remove_owner_request.proto - + -### ListRequest +### RemoveOwnerRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| status_filter | [hackathon.entities.HackathonStatus](#hackathon-entities-HackathonStatus) | repeated | | -| owner_id | [string](#string) | optional | | -| participant_id | [string](#string) | optional | | -| visibility_filter | [hackathon.entities.Visibility](#hackathon-entities-Visibility) | optional | | +| hackathon_id | [string](#string) | | | +| user_id | [string](#string) | | | @@ -2316,22 +2322,17 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/list_response.proto - - +## hackathon/messages/hackathon_svc/remove_owner_response.proto - -### ListResponse + +### RemoveOwnerResponse -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| hackathons | [hackathon.entities.Hackathon](#hackathon-entities-Hackathon) | repeated | | @@ -2347,16 +2348,16 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/remove_owner_request.proto +## hackathon/messages/hackathon_svc/remove_participant_request.proto - + -### RemoveOwnerRequest +### RemoveParticipantRequest @@ -2379,16 +2380,16 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/remove_owner_response.proto +## hackathon/messages/hackathon_svc/remove_participant_response.proto - + -### RemoveOwnerResponse +### RemoveParticipantResponse @@ -2405,23 +2406,23 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/remove_participant_request.proto +## hackathon/messages/hackathon_svc/remove_question_request.proto - + -### RemoveParticipantRequest +### RemoveQuestionRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | hackathon_id | [string](#string) | | | -| user_id | [string](#string) | | | +| question_id | [string](#string) | | | @@ -2437,16 +2438,16 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/remove_participant_response.proto +## hackathon/messages/hackathon_svc/remove_question_response.proto - + -### RemoveParticipantResponse +### RemoveQuestionResponse @@ -2463,23 +2464,22 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/remove_question_request.proto +## hackathon/messages/hackathon_svc/revoke_invite_request.proto - + -### RemoveQuestionRequest +### RevokeInviteRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| hackathon_id | [string](#string) | | | -| question_id | [string](#string) | | | +| invite_id | [string](#string) | | | @@ -2495,16 +2495,16 @@ casbin role for this hackathon; `is_waiting` is false once approved. - +

Top

-## hackathon/messages/hackathon_svc/remove_question_response.proto +## hackathon/messages/hackathon_svc/revoke_invite_response.proto - + -### RemoveQuestionResponse +### RevokeInviteResponse diff --git a/api/proto/hackathon/entities/hackathon_invite.proto b/api/proto/hackathon/entities/hackathon_invite.proto index 02b0e7a4..b68e4a7a 100644 --- a/api/proto/hackathon/entities/hackathon_invite.proto +++ b/api/proto/hackathon/entities/hackathon_invite.proto @@ -13,4 +13,4 @@ message HackathonInvite { google.protobuf.Timestamp created_at = 4; optional google.protobuf.Timestamp revoked_at = 5; optional google.protobuf.Timestamp expires_at = 6; -} \ No newline at end of file +} diff --git a/api/proto/hackathon/hackathon_service.proto b/api/proto/hackathon/hackathon_service.proto index 769112d0..6f4db8d1 100644 --- a/api/proto/hackathon/hackathon_service.proto +++ b/api/proto/hackathon/hackathon_service.proto @@ -6,6 +6,8 @@ import "hackathon/messages/hackathon_svc/add_owner_request.proto"; import "hackathon/messages/hackathon_svc/add_owner_response.proto"; import "hackathon/messages/hackathon_svc/approve_participant_request.proto"; import "hackathon/messages/hackathon_svc/approve_participant_response.proto"; +import "hackathon/messages/hackathon_svc/create_invite_request.proto"; +import "hackathon/messages/hackathon_svc/create_invite_response.proto"; import "hackathon/messages/hackathon_svc/create_question_request.proto"; import "hackathon/messages/hackathon_svc/create_question_response.proto"; import "hackathon/messages/hackathon_svc/create_request.proto"; @@ -16,28 +18,26 @@ import "hackathon/messages/hackathon_svc/edit_request.proto"; import "hackathon/messages/hackathon_svc/edit_response.proto"; import "hackathon/messages/hackathon_svc/get_request.proto"; import "hackathon/messages/hackathon_svc/get_response.proto"; -import "hackathon/messages/hackathon_svc/create_invite_request.proto"; -import "hackathon/messages/hackathon_svc/create_invite_response.proto"; import "hackathon/messages/hackathon_svc/join_request.proto"; import "hackathon/messages/hackathon_svc/join_response.proto"; import "hackathon/messages/hackathon_svc/list_invites_request.proto"; import "hackathon/messages/hackathon_svc/list_invites_response.proto"; import "hackathon/messages/hackathon_svc/list_participant_answers_request.proto"; -import "hackathon/messages/hackathon_svc/preview_invite_request.proto"; -import "hackathon/messages/hackathon_svc/preview_invite_response.proto"; -import "hackathon/messages/hackathon_svc/revoke_invite_request.proto"; -import "hackathon/messages/hackathon_svc/revoke_invite_response.proto"; import "hackathon/messages/hackathon_svc/list_participant_answers_response.proto"; import "hackathon/messages/hackathon_svc/list_questions_request.proto"; import "hackathon/messages/hackathon_svc/list_questions_response.proto"; import "hackathon/messages/hackathon_svc/list_request.proto"; import "hackathon/messages/hackathon_svc/list_response.proto"; +import "hackathon/messages/hackathon_svc/preview_invite_request.proto"; +import "hackathon/messages/hackathon_svc/preview_invite_response.proto"; import "hackathon/messages/hackathon_svc/remove_owner_request.proto"; import "hackathon/messages/hackathon_svc/remove_owner_response.proto"; import "hackathon/messages/hackathon_svc/remove_participant_request.proto"; import "hackathon/messages/hackathon_svc/remove_participant_response.proto"; import "hackathon/messages/hackathon_svc/remove_question_request.proto"; import "hackathon/messages/hackathon_svc/remove_question_response.proto"; +import "hackathon/messages/hackathon_svc/revoke_invite_request.proto"; +import "hackathon/messages/hackathon_svc/revoke_invite_response.proto"; import "hackathon/messages/hackathon_svc/set_capabilities_request.proto"; import "hackathon/messages/hackathon_svc/set_capabilities_response.proto"; import "hackathon/messages/hackathon_svc/set_current_phase_request.proto"; diff --git a/api/proto/hackathon/messages/hackathon_svc/create_invite_request.proto b/api/proto/hackathon/messages/hackathon_svc/create_invite_request.proto index 193dc695..4fded2b5 100644 --- a/api/proto/hackathon/messages/hackathon_svc/create_invite_request.proto +++ b/api/proto/hackathon/messages/hackathon_svc/create_invite_request.proto @@ -11,4 +11,4 @@ message CreateInviteRequest { string hackathon_id = 1 [(buf.validate.field).string.uuid = true]; optional string note = 2 [(buf.validate.field).string.max_len = 500]; optional google.protobuf.Timestamp expires_at = 3; -} \ No newline at end of file +} diff --git a/api/proto/hackathon/messages/hackathon_svc/create_invite_response.proto b/api/proto/hackathon/messages/hackathon_svc/create_invite_response.proto index c7f2b5ae..5a83d36c 100644 --- a/api/proto/hackathon/messages/hackathon_svc/create_invite_response.proto +++ b/api/proto/hackathon/messages/hackathon_svc/create_invite_response.proto @@ -8,4 +8,4 @@ option go_package = "github.com/swissdatasciencecenter/hackagon/components/backe message CreateInviteResponse { hackathon.entities.HackathonInvite invite = 1; -} \ No newline at end of file +} diff --git a/api/proto/hackathon/messages/hackathon_svc/list_invites_request.proto b/api/proto/hackathon/messages/hackathon_svc/list_invites_request.proto index 7ab8551f..d0524418 100644 --- a/api/proto/hackathon/messages/hackathon_svc/list_invites_request.proto +++ b/api/proto/hackathon/messages/hackathon_svc/list_invites_request.proto @@ -8,4 +8,4 @@ option go_package = "github.com/swissdatasciencecenter/hackagon/components/backe message ListInvitesRequest { string hackathon_id = 1 [(buf.validate.field).string.uuid = true]; -} \ No newline at end of file +} diff --git a/api/proto/hackathon/messages/hackathon_svc/list_invites_response.proto b/api/proto/hackathon/messages/hackathon_svc/list_invites_response.proto index 63b78959..66017015 100644 --- a/api/proto/hackathon/messages/hackathon_svc/list_invites_response.proto +++ b/api/proto/hackathon/messages/hackathon_svc/list_invites_response.proto @@ -8,4 +8,4 @@ option go_package = "github.com/swissdatasciencecenter/hackagon/components/backe message ListInvitesResponse { repeated hackathon.entities.HackathonInvite invites = 1; -} \ No newline at end of file +} diff --git a/api/proto/hackathon/messages/hackathon_svc/preview_invite_request.proto b/api/proto/hackathon/messages/hackathon_svc/preview_invite_request.proto index 8f881340..63f6db6b 100644 --- a/api/proto/hackathon/messages/hackathon_svc/preview_invite_request.proto +++ b/api/proto/hackathon/messages/hackathon_svc/preview_invite_request.proto @@ -9,4 +9,4 @@ option go_package = "github.com/swissdatasciencecenter/hackagon/components/backe message PreviewInviteRequest { // The invite token — the only credential. No hackathon_id to prevent probing. string token = 1 [(buf.validate.field).string.uuid = true]; -} \ No newline at end of file +} diff --git a/api/proto/hackathon/messages/hackathon_svc/preview_invite_response.proto b/api/proto/hackathon/messages/hackathon_svc/preview_invite_response.proto index 584b852e..14561d76 100644 --- a/api/proto/hackathon/messages/hackathon_svc/preview_invite_response.proto +++ b/api/proto/hackathon/messages/hackathon_svc/preview_invite_response.proto @@ -11,4 +11,4 @@ message PreviewInviteResponse { hackathon.entities.Hackathon hackathon = 1; repeated hackathon.entities.Question questions = 2; bool already_participant = 3; -} \ No newline at end of file +} diff --git a/api/proto/hackathon/messages/hackathon_svc/revoke_invite_request.proto b/api/proto/hackathon/messages/hackathon_svc/revoke_invite_request.proto index f7d247ed..aa5271f8 100644 --- a/api/proto/hackathon/messages/hackathon_svc/revoke_invite_request.proto +++ b/api/proto/hackathon/messages/hackathon_svc/revoke_invite_request.proto @@ -8,4 +8,4 @@ option go_package = "github.com/swissdatasciencecenter/hackagon/components/backe message RevokeInviteRequest { string invite_id = 1 [(buf.validate.field).string.uuid = true]; -} \ No newline at end of file +} diff --git a/api/proto/hackathon/messages/hackathon_svc/revoke_invite_response.proto b/api/proto/hackathon/messages/hackathon_svc/revoke_invite_response.proto index 39149384..2ceae174 100644 --- a/api/proto/hackathon/messages/hackathon_svc/revoke_invite_response.proto +++ b/api/proto/hackathon/messages/hackathon_svc/revoke_invite_response.proto @@ -4,4 +4,4 @@ package hackathon.messages.hackathon_svc; option go_package = "github.com/swissdatasciencecenter/hackagon/components/backend/internal/proto/hackathon/messages/hackathon_svc"; -message RevokeInviteResponse {} \ No newline at end of file +message RevokeInviteResponse {} diff --git a/components/backend/db/schema/hackathoninvite.go b/components/backend/db/schema/hackathoninvite.go index 1d996619..35113f5b 100644 --- a/components/backend/db/schema/hackathoninvite.go +++ b/components/backend/db/schema/hackathoninvite.go @@ -40,8 +40,7 @@ func (HackathonInvite) Fields() []ent.Field { return id }), field.String("note"). - Optional(). - MaxLen(500), + Optional(), field.Time("expires_at"). Optional(). Nillable(), diff --git a/components/backend/ent/hackathoninvite/hackathoninvite.go b/components/backend/ent/hackathoninvite/hackathoninvite.go index 0be3a692..18572104 100644 --- a/components/backend/ent/hackathoninvite/hackathoninvite.go +++ b/components/backend/ent/hackathoninvite/hackathoninvite.go @@ -84,8 +84,6 @@ var ( DefaultCreatedAt func() time.Time // DefaultToken holds the default value on creation for the "token" field. DefaultToken func() uuid.UUID - // NoteValidator is a validator for the "note" field. It is called by the builders before save. - NoteValidator func(string) error // DefaultID holds the default value on creation for the "id" field. DefaultID func() uuid.UUID ) diff --git a/components/backend/ent/hackathoninvite_create.go b/components/backend/ent/hackathoninvite_create.go index 2c0eac21..0c0c30ab 100644 --- a/components/backend/ent/hackathoninvite_create.go +++ b/components/backend/ent/hackathoninvite_create.go @@ -189,11 +189,6 @@ func (_c *HackathonInviteCreate) check() error { if _, ok := _c.mutation.Token(); !ok { return &ValidationError{Name: "token", err: errors.New(`ent: missing required field "HackathonInvite.token"`)} } - if v, ok := _c.mutation.Note(); ok { - if err := hackathoninvite.NoteValidator(v); err != nil { - return &ValidationError{Name: "note", err: fmt.Errorf(`ent: validator failed for field "HackathonInvite.note": %w`, err)} - } - } if len(_c.mutation.HackathonIDs()) == 0 { return &ValidationError{Name: "hackathon", err: errors.New(`ent: missing required edge "HackathonInvite.hackathon"`)} } diff --git a/components/backend/ent/hackathoninvite_update.go b/components/backend/ent/hackathoninvite_update.go index ab48d139..ff439c37 100644 --- a/components/backend/ent/hackathoninvite_update.go +++ b/components/backend/ent/hackathoninvite_update.go @@ -137,11 +137,6 @@ func (_u *HackathonInviteUpdate) ExecX(ctx context.Context) { // check runs all checks and user-defined validators on the builder. func (_u *HackathonInviteUpdate) check() error { - if v, ok := _u.mutation.Note(); ok { - if err := hackathoninvite.NoteValidator(v); err != nil { - return &ValidationError{Name: "note", err: fmt.Errorf(`ent: validator failed for field "HackathonInvite.note": %w`, err)} - } - } if _u.mutation.HackathonCleared() && len(_u.mutation.HackathonIDs()) > 0 { return errors.New(`ent: clearing a required unique edge "HackathonInvite.hackathon"`) } @@ -325,11 +320,6 @@ func (_u *HackathonInviteUpdateOne) ExecX(ctx context.Context) { // check runs all checks and user-defined validators on the builder. func (_u *HackathonInviteUpdateOne) check() error { - if v, ok := _u.mutation.Note(); ok { - if err := hackathoninvite.NoteValidator(v); err != nil { - return &ValidationError{Name: "note", err: fmt.Errorf(`ent: validator failed for field "HackathonInvite.note": %w`, err)} - } - } if _u.mutation.HackathonCleared() && len(_u.mutation.HackathonIDs()) > 0 { return errors.New(`ent: clearing a required unique edge "HackathonInvite.hackathon"`) } diff --git a/components/backend/ent/migrate/schema.go b/components/backend/ent/migrate/schema.go index bd8a91a2..c6c5b474 100644 --- a/components/backend/ent/migrate/schema.go +++ b/components/backend/ent/migrate/schema.go @@ -113,7 +113,7 @@ var ( {Name: "created_at", Type: field.TypeTime}, {Name: "revoked_at", Type: field.TypeTime, Nullable: true}, {Name: "token", Type: field.TypeUUID, Unique: true}, - {Name: "note", Type: field.TypeString, Nullable: true, Size: 500}, + {Name: "note", Type: field.TypeString, Nullable: true}, {Name: "expires_at", Type: field.TypeTime, Nullable: true}, {Name: "hackathon_invite_hackathon", Type: field.TypeUUID}, {Name: "user_created_hackathon_invites", Type: field.TypeUUID}, diff --git a/components/backend/ent/runtime/runtime.go b/components/backend/ent/runtime/runtime.go index 5e8bc93c..904453ca 100644 --- a/components/backend/ent/runtime/runtime.go +++ b/components/backend/ent/runtime/runtime.go @@ -85,10 +85,6 @@ func init() { hackathoninviteDescToken := hackathoninviteFields[2].Descriptor() // hackathoninvite.DefaultToken holds the default value on creation for the token field. hackathoninvite.DefaultToken = hackathoninviteDescToken.Default.(func() uuid.UUID) - // hackathoninviteDescNote is the schema descriptor for note field. - hackathoninviteDescNote := hackathoninviteFields[3].Descriptor() - // hackathoninvite.NoteValidator is a validator for the "note" field. It is called by the builders before save. - hackathoninvite.NoteValidator = hackathoninviteDescNote.Validators[0].(func(string) error) // hackathoninviteDescID is the schema descriptor for id field. hackathoninviteDescID := hackathoninviteMixinFields0[0].Descriptor() // hackathoninvite.DefaultID holds the default value on creation for the id field. diff --git a/components/backend/go.sum b/components/backend/go.sum index 93aeaf4b..7c3dd192 100644 --- a/components/backend/go.sum +++ b/components/backend/go.sum @@ -45,12 +45,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo= -github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= -github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= -github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= -github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= -github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -58,8 +52,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= @@ -152,12 +144,6 @@ github.com/lib/pq v1.12.3 h1:tTWxr2YLKwIvK90ZXEw8GP7UFHtcbTtty8zsI+YjrfQ= github.com/lib/pq v1.12.3/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= -github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-sqlite3 v1.14.42 h1:MigqEP4ZmHw3aIdIT7T+9TLa90Z6smwcthx+Azv4Cgo= github.com/mattn/go-sqlite3 v1.14.42/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ= github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= @@ -168,14 +154,6 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc= -github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0= -github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM= -github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= -github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 h1:jrYnow5+hy3WRDCBypUFvVKNSPPCdqgSXIE9eJDD8LM= -github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew= -github.com/olekukonko/tablewriter v1.1.3 h1:VSHhghXxrP0JHl+0NnKid7WoEmd9/urKRJLysb70nnA= -github.com/olekukonko/tablewriter v1.1.3/go.mod h1:9VU0knjhmMkXjnMKrZ3+L2JhhtsQ/L38BbL3CRNE8tM= github.com/onsi/ginkgo/v2 v2.27.5 h1:ZeVgZMx2PDMdJm/+w5fE/OyG6ILo1Y3e+QX4zSR0zTE= github.com/onsi/ginkgo/v2 v2.27.5/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc= @@ -192,10 +170,6 @@ github.com/rodaine/protogofakeit v0.1.1/go.mod h1:pXn/AstBYMaSfc1/RqH3N82pBuxtWg github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= diff --git a/components/backend/internal/proto/hackathon/hackathon_service.pb.go b/components/backend/internal/proto/hackathon/hackathon_service.pb.go index 80b92886..33596e81 100644 --- a/components/backend/internal/proto/hackathon/hackathon_service.pb.go +++ b/components/backend/internal/proto/hackathon/hackathon_service.pb.go @@ -25,7 +25,7 @@ var File_hackathon_hackathon_service_proto protoreflect.FileDescriptor const file_hackathon_hackathon_service_proto_rawDesc = "" + "\n" + - "!hackathon/hackathon_service.proto\x12\thackathon\x1a8hackathon/messages/hackathon_svc/add_owner_request.proto\x1a9hackathon/messages/hackathon_svc/add_owner_response.proto\x1aBhackathon/messages/hackathon_svc/approve_participant_request.proto\x1aChackathon/messages/hackathon_svc/approve_participant_response.proto\x1a>hackathon/messages/hackathon_svc/create_question_request.proto\x1a?hackathon/messages/hackathon_svc/create_question_response.proto\x1a5hackathon/messages/hackathon_svc/create_request.proto\x1a6hackathon/messages/hackathon_svc/create_response.proto\x1ahackathon/messages/hackathon_svc/preview_invite_response.proto\x1ahackathon/messages/hackathon_svc/list_questions_response.proto\x1a3hackathon/messages/hackathon_svc/list_request.proto\x1a4hackathon/messages/hackathon_svc/list_response.proto\x1a;hackathon/messages/hackathon_svc/remove_owner_request.proto\x1ahackathon/messages/hackathon_svc/remove_question_request.proto\x1a?hackathon/messages/hackathon_svc/remove_question_response.proto\x1a?hackathon/messages/hackathon_svc/set_capabilities_request.proto\x1a@hackathon/messages/hackathon_svc/set_capabilities_response.proto\x1a@hackathon/messages/hackathon_svc/set_current_phase_request.proto\x1aAhackathon/messages/hackathon_svc/set_current_phase_response.proto\x1a=hackathon/messages/hackathon_svc/submit_answers_request.proto\x1a>hackathon/messages/hackathon_svc/submit_answers_response.proto2\xe6\x14\n" + + "!hackathon/hackathon_service.proto\x12\thackathon\x1a8hackathon/messages/hackathon_svc/add_owner_request.proto\x1a9hackathon/messages/hackathon_svc/add_owner_response.proto\x1aBhackathon/messages/hackathon_svc/approve_participant_request.proto\x1aChackathon/messages/hackathon_svc/approve_participant_response.proto\x1ahackathon/messages/hackathon_svc/create_question_request.proto\x1a?hackathon/messages/hackathon_svc/create_question_response.proto\x1a5hackathon/messages/hackathon_svc/create_request.proto\x1a6hackathon/messages/hackathon_svc/create_response.proto\x1ahackathon/messages/hackathon_svc/list_questions_response.proto\x1a3hackathon/messages/hackathon_svc/list_request.proto\x1a4hackathon/messages/hackathon_svc/list_response.proto\x1a=hackathon/messages/hackathon_svc/preview_invite_request.proto\x1a>hackathon/messages/hackathon_svc/preview_invite_response.proto\x1a;hackathon/messages/hackathon_svc/remove_owner_request.proto\x1ahackathon/messages/hackathon_svc/remove_question_request.proto\x1a?hackathon/messages/hackathon_svc/remove_question_response.proto\x1ahackathon/messages/hackathon_svc/submit_answers_response.proto2\xe6\x14\n" + "\x10HackathonService\x12e\n" + "\x04List\x12-.hackathon.messages.hackathon_svc.ListRequest\x1a..hackathon.messages.hackathon_svc.ListResponse\x12b\n" + "\x03Get\x12,.hackathon.messages.hackathon_svc.GetRequest\x1a-.hackathon.messages.hackathon_svc.GetResponse\x12k\n" + diff --git a/components/backend/internal/service/hackathon_service.go b/components/backend/internal/service/hackathon_service.go index 6944e66e..a619212a 100644 --- a/components/backend/internal/service/hackathon_service.go +++ b/components/backend/internal/service/hackathon_service.go @@ -9,8 +9,8 @@ import ( "github.com/swissdatasciencecenter/hackagon/components/backend/ent" entanswer "github.com/swissdatasciencecenter/hackagon/components/backend/ent/answer" enthackathon "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" - enthackathonstate "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathonstate" enthackathoninvite "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" + enthackathonstate "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathonstate" entparticipant "github.com/swissdatasciencecenter/hackagon/components/backend/ent/participant" entphase "github.com/swissdatasciencecenter/hackagon/components/backend/ent/phase" entquestion "github.com/swissdatasciencecenter/hackagon/components/backend/ent/question" @@ -224,7 +224,6 @@ func (s *HackathonService) Get( return &msgs.GetResponse{Hackathon: entry}, nil } - // --- Invite RPCs --- func (s *HackathonService) CreateInvite( @@ -248,7 +247,11 @@ func (s *HackathonService) CreateInvite( h, err := s.dbClient.Hackathon.Query().Where(enthackathon.IDEQ(id)).Only(ctx) if err != nil { if ent.IsNotFound(err) { - return nil, status.Errorf(codes.NotFound, "hackathon %s not found", req.GetHackathonId()) + return nil, status.Errorf( + codes.NotFound, + "hackathon %s not found", + req.GetHackathonId(), + ) } slog.Error("query hackathon", "err", err) return nil, status.Error(codes.Internal, "couldn't query database") @@ -273,8 +276,10 @@ func (s *HackathonService) CreateInvite( createQ = createQ.SetNote(note) } - // Default expires_at to hackathon.ends_at when nil - if req.GetExpiresAt() == nil && h.EndsAt != nil { + // Set expires_at: use explicit value if provided, otherwise default to hackathon.ends_at + if req.GetExpiresAt() != nil { + createQ = createQ.SetExpiresAt(req.GetExpiresAt().AsTime()) + } else if h.EndsAt != nil { createQ = createQ.SetExpiresAt(*h.EndsAt) } @@ -291,7 +296,7 @@ func (s *HackathonService) ListInvites( ctx context.Context, req *msgs.ListInvitesRequest, ) (*msgs.ListInvitesResponse, error) { - uid, _, err := mw.RequireSubject(ctx) + _, _, err := mw.RequireSubject(ctx) if err != nil { return nil, err } @@ -304,15 +309,29 @@ func (s *HackathonService) ListInvites( return nil, err } + // Verify hackathon exists + _, err = s.dbClient.Hackathon.Query().Where(enthackathon.IDEQ(id)).Only(ctx) + if err != nil { + if ent.IsNotFound(err) { + return nil, status.Errorf( + codes.NotFound, + "hackathon %s not found", + req.GetHackathonId(), + ) + } + slog.Error("query hackathon", "err", err) + return nil, status.Error(codes.Internal, "couldn't query database") + } + invites, err := s.dbClient.HackathonInvite.Query(). - Where(enthackathoninvite.HackathonIDEQ(id)). + Where(enthackathoninvite.HasHackathonWith(enthackathon.IDEQ(id))). All(ctx) if err != nil { slog.Error("query invites", "err", err) return nil, status.Error(codes.Internal, "couldn't query invites") } - entries := make([]*hackEnts.HackathonInvite, 0, len(invites)) + entries := make([]*ents.HackathonInvite, 0, len(invites)) for _, i := range invites { entries = append(entries, hackathonInviteEntryFromEnt(i)) } @@ -324,7 +343,7 @@ func (s *HackathonService) RevokeInvite( ctx context.Context, req *msgs.RevokeInviteRequest, ) (*msgs.RevokeInviteResponse, error) { - uid, _, err := mw.RequireSubject(ctx) + _, _, err := mw.RequireSubject(ctx) if err != nil { return nil, err } @@ -336,6 +355,7 @@ func (s *HackathonService) RevokeInvite( invite, err := s.dbClient.HackathonInvite.Query(). Where(enthackathoninvite.IDEQ(inviteID)). + WithHackathon(). Only(ctx) if err != nil { if ent.IsNotFound(err) { @@ -346,7 +366,7 @@ func (s *HackathonService) RevokeInvite( } // Check write permission on the invite's hackathon - hackID := invite.HackathonID + hackID := invite.Edges.Hackathon.ID if err := s.enforcer.RequirePermission(ctx, hackID.String(), mw.Hackathon, mw.Write); err != nil { return nil, err } @@ -378,7 +398,8 @@ func (s *HackathonService) PreviewInvite( } invite, err := s.dbClient.HackathonInvite.Query(). - Where(enthackathoninvite.Token(tokenID.String())). + Where(enthackathoninvite.Token(tokenID)). + WithHackathon(). Only(ctx) if err != nil { if ent.IsNotFound(err) { @@ -398,7 +419,7 @@ func (s *HackathonService) PreviewInvite( return nil, status.Error(codes.NotFound, "invalid or expired invitation") } - hackID := invite.HackathonID + hackID := invite.Edges.Hackathon.ID // Get shallow hackathon h, err := s.dbClient.Hackathon.Query(). @@ -423,7 +444,7 @@ func (s *HackathonService) PreviewInvite( return nil, status.Error(codes.Internal, "couldn't query questions") } - qEntries := make([]*hackEnts.Question, 0, len(questions)) + qEntries := make([]*ents.Question, 0, len(questions)) for _, q := range questions { qEntries = append(qEntries, questionEntryFromEnt(q)) } @@ -452,6 +473,7 @@ func (s *HackathonService) PreviewInvite( }, nil } +//nolint:gocognit // Joining is pretty complex, no way around that. func (s *HackathonService) Join( ctx context.Context, req *msgs.JoinRequest, @@ -485,39 +507,60 @@ func (s *HackathonService) Join( return nil, status.Error(codes.Internal, "couldn't query database") } - // Permission check: invite token OR casbin role. If either passes, allow. - // For private hackathons the invite is the admission ticket — without it - // the user has no casbin role and casbin would reject anyway. For public - // hackathons casbin handles everything. We check both and allow if either - // succeeds. inviteValid := false + //nolint:nestif // Complexity is ok here. if h.Visibility == enthackathon.VisibilityPrivate { inviteToken := req.GetInviteToken() if inviteToken != "" { inviteID, parseErr := uuid.Parse(inviteToken) - if parseErr == nil { - invite, err := s.dbClient.HackathonInvite.Query(). - Where( - enthackathoninvite.Token(inviteID.String()), - enthackathoninvite.HackathonIDEQ(id), - ).Only(ctx) - if err == nil && invite.RevokedAt == nil && (invite.ExpiresAt == nil || !invite.ExpiresAt.Before(time.Now())) { - inviteValid = true + if parseErr != nil { + return nil, status.Error(codes.InvalidArgument, "invalid invite token") + } + invite, err := s.dbClient.HackathonInvite.Query(). + Where( + enthackathoninvite.Token(inviteID), + enthackathoninvite.HasHackathonWith(enthackathon.IDEQ(id)), + ).Only(ctx) + if err != nil { + if ent.IsNotFound(err) { + return nil, status.Errorf( + codes.NotFound, + "invite not found", + ) } + slog.Error("query hackathon", "err", err) + + return nil, status.Error(codes.Internal, "couldn't query database") + } + if invite.RevokedAt != nil { + return nil, status.Errorf( + codes.FailedPrecondition, + "this invite is not valid anymore", + ) + } + if invite.ExpiresAt != nil && invite.ExpiresAt.Before(time.Now()) { + return nil, status.Errorf( + codes.FailedPrecondition, + "this invite expired", + ) } + inviteValid = true } - } else { - // Public hackathons: no invite needed, rely on casbin - inviteValid = true + } + // a hackathon need to have join permission enabled(== registration phase open), and + // the user needs to either have read on the hackathon (can see the hackathon) or have + // a valid invite to join + if err = s.enforcer.RequirePermission(ctx, id.String(), mw.Hackathon, mw.Join); err != nil { + return nil, err } - casbinOk, err := s.enforcer.CheckPermission(uid, id.String(), mw.Hackathon, mw.Join) + hasRead, err := s.enforcer.CheckPermission(uid, id.String(), mw.Hackathon, mw.Read) if err != nil { slog.Error("check permission", "err", err) return nil, status.Error(codes.Internal, "authorization error") } - if !inviteValid && !casbinOk { + if !inviteValid && !hasRead { return nil, status.Error(codes.PermissionDenied, "invalid or expired invitation") } diff --git a/components/backend/internal/service/hackathon_service_test.go b/components/backend/internal/service/hackathon_service_test.go index 9152093c..29b25c17 100644 --- a/components/backend/internal/service/hackathon_service_test.go +++ b/components/backend/internal/service/hackathon_service_test.go @@ -20,7 +20,7 @@ import ( ent "github.com/swissdatasciencecenter/hackagon/components/backend/ent" entanswer "github.com/swissdatasciencecenter/hackagon/components/backend/ent/answer" enthackathon "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" -enthackathoninvite "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" + enthackathoninvite "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" enthackathonstate "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathonstate" entparticipant "github.com/swissdatasciencecenter/hackagon/components/backend/ent/participant" entquestion "github.com/swissdatasciencecenter/hackagon/components/backend/ent/question" @@ -3763,6 +3763,7 @@ var _ = Describe("HackathonService", func() { }) }) }) + Describe("Invite Tests", func() { var ( privateHackathonID string publicHackathonID string @@ -3821,11 +3822,12 @@ var _ = Describe("HackathonService", func() { // Verify in database invite, err := dbClient.HackathonInvite.Query(). Where(enthackathoninvite.IDEQ(uuid.MustParse(resp.GetInvite().GetId()))). + WithHackathon(). Only(context.Background()) Expect(err).NotTo(HaveOccurred()) - Expect(invite.Token).To(Equal(resp.GetInvite().GetToken())) + Expect(invite.Token.String()).To(Equal(resp.GetInvite().GetToken())) Expect(invite.Note).To(Equal(note)) - Expect(invite.HackathonID.String()).To(Equal(privateHackathonID)) + Expect(invite.Edges.Hackathon.ID.String()).To(Equal(privateHackathonID)) }) It("defaults expires_at to hackathon.ends_at", func() { @@ -3844,6 +3846,7 @@ var _ = Describe("HackathonService", func() { // Verify in database invite, err := dbClient.HackathonInvite.Query(). Where(enthackathoninvite.IDEQ(uuid.MustParse(resp.GetInvite().GetId()))). + WithHackathon(). Only(context.Background()) Expect(err).NotTo(HaveOccurred()) Expect(invite.ExpiresAt).NotTo(BeNil()) @@ -4106,6 +4109,7 @@ var _ = Describe("HackathonService", func() { Describe("PreviewInvite", func() { var inviteToken string + var inviteId string BeforeEach(func() { token := testutils.CreateTestJWTToken(testAdmin) @@ -4118,6 +4122,7 @@ var _ = Describe("HackathonService", func() { HackathonId: privateHackathonID, }) Expect(err).NotTo(HaveOccurred()) + inviteId = resp.GetInvite().GetId() inviteToken = resp.GetInvite().GetToken() }) @@ -4129,7 +4134,9 @@ var _ = Describe("HackathonService", func() { Expect(resp.GetHackathon()).NotTo(BeNil()) Expect(resp.GetHackathon().GetId()).To(Equal(privateHackathonID)) Expect(resp.GetHackathon().GetName()).To(Equal("Private Test Hackathon")) - Expect(resp.GetHackathon().GetVisibility()).To(Equal(entities.Visibility_VISIBILITY_PRIVATE)) + Expect( + resp.GetHackathon().GetVisibility(), + ).To(Equal(entities.Visibility_VISIBILITY_PRIVATE)) Expect(resp.GetAlreadyParticipant()).To(BeFalse()) }) @@ -4187,13 +4194,13 @@ var _ = Describe("HackathonService", func() { Expect(resp.GetAlreadyParticipant()).To(BeTrue()) }) - It("returns NOT_FOUND for invalid token format", func() { + It("returns INVALID_ARGUMENT for invalid token format", func() { _, err := client.PreviewInvite(context.Background(), &msgs.PreviewInviteRequest{ Token: "not-a-uuid", }) Expect(err).To(HaveOccurred()) st := status.Convert(err) - Expect(st.Code()).To(Equal(codes.NotFound)) + Expect(st.Code()).To(Equal(codes.InvalidArgument)) }) It("returns NOT_FOUND for non-existent token", func() { @@ -4212,17 +4219,9 @@ var _ = Describe("HackathonService", func() { context.Background(), metadata.Pairs("authorization", "Bearer "+token), ) + _, err := client.RevokeInvite(ctx, &msgs.RevokeInviteRequest{ - InviteId: "invalid", - }) - Expect(err).To(HaveOccurred()) - // Actually revoke it properly - invite, err := dbClient.HackathonInvite.Query(). - Where(enthackathoninvite.HackathonIDEQ(uuid.MustParse(privateHackathonID))). - First(context.Background()) - Expect(err).NotTo(HaveOccurred()) - _, err = client.RevokeInvite(ctx, &msgs.RevokeInviteRequest{ - InviteId: invite.ID.String(), + InviteId: inviteId, }) Expect(err).NotTo(HaveOccurred()) @@ -4276,6 +4275,19 @@ var _ = Describe("HackathonService", func() { context.Background(), metadata.Pairs("authorization", "Bearer "+token), ) + _, err := client.SetCapabilities(ctx, &msgs.SetCapabilitiesRequest{ + HackathonId: publicHackathonID, + Capabilities: []*msgs.CapabilityState{ + {Capability: entities.Capability_CAPABILITY_REGISTER, Enabled: true}, + }, + }) + + _, err = client.SetCapabilities(ctx, &msgs.SetCapabilitiesRequest{ + HackathonId: privateHackathonID, + Capabilities: []*msgs.CapabilityState{ + {Capability: entities.Capability_CAPABILITY_REGISTER, Enabled: true}, + }, + }) resp, err := client.CreateInvite(ctx, &msgs.CreateInviteRequest{ HackathonId: privateHackathonID, @@ -4293,7 +4305,7 @@ var _ = Describe("HackathonService", func() { ) // Ensure user exists - _, err := dbClient.User.Create(). + user, err := dbClient.User.Create(). SetKeycloakID(nonAdminKeycloakID). SetUsername("invite-join-user-username"). Save(context.Background()) @@ -4311,7 +4323,7 @@ var _ = Describe("HackathonService", func() { participant, err := dbClient.Participant.Query(). Where( entparticipant.HackathonIDEQ(uuid.MustParse(privateHackathonID)), - entparticipant.UserIDEQ(nonAdminKeycloakID), + entparticipant.UserID(user.ID), ). WithUser(). Only(context.Background()) @@ -4363,7 +4375,7 @@ var _ = Describe("HackathonService", func() { _, err = client.Join(ctx, joinReq) Expect(err).To(HaveOccurred()) st := status.Convert(err) - Expect(st.Code()).To(Equal(codes.PermissionDenied)) + Expect(st.Code()).To(Equal(codes.NotFound)) }) It("allows join on public hackathon without invite token", func() { @@ -4389,3 +4401,4 @@ var _ = Describe("HackathonService", func() { }) }) }) +}) diff --git a/components/backend/internal/service/mappers.go b/components/backend/internal/service/mappers.go index b8798ce1..90c42e77 100644 --- a/components/backend/internal/service/mappers.go +++ b/components/backend/internal/service/mappers.go @@ -6,7 +6,6 @@ import ( "github.com/google/uuid" "github.com/swissdatasciencecenter/hackagon/components/backend/ent" enthackathon "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathon" - enthackathoninvite "github.com/swissdatasciencecenter/hackagon/components/backend/ent/hackathoninvite" entquestion "github.com/swissdatasciencecenter/hackagon/components/backend/ent/question" entvote "github.com/swissdatasciencecenter/hackagon/components/backend/ent/vote" entvotecategory "github.com/swissdatasciencecenter/hackagon/components/backend/ent/votecategory" @@ -530,11 +529,11 @@ func questionEntryFromEnt(q *ent.Question) *hackEnts.Question { } } -func hackathonInviteEntryFromEnt(i *enthackathoninvite.HackathonInvite) *hackEnts.HackathonInvite { +func hackathonInviteEntryFromEnt(i *ent.HackathonInvite) *hackEnts.HackathonInvite { e := &hackEnts.HackathonInvite{ - Id: i.ID.String(), - Token: i.Token, - CreatedAt: timestamppb.New(i.CreatedAt), + Id: i.ID.String(), + Token: i.Token.String(), + CreatedAt: timestamppb.New(i.CreatedAt), } if i.Note != "" { e.Note = &i.Note