Add job application quick reference for storing profile links and experience
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m34s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m34s
Auth-protected CRUD for personal info (LinkedIn, GitHub, etc.) and experience entries, stored in the database so nothing sensitive is in the public repo. Displayed as a categorized panel on the Job Applications page. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -69,3 +69,9 @@ models:
|
||||
fields:
|
||||
deletedAt:
|
||||
resolver: false
|
||||
JobAppReference:
|
||||
model:
|
||||
- adam-french.co.uk/backend/models.JobAppReference
|
||||
fields:
|
||||
deletedAt:
|
||||
resolver: false
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
22
backend/graph/job_app_reference.resolvers.go
Normal file
22
backend/graph/job_app_reference.resolvers.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package graph
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver
|
||||
// implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
// Code generated by github.com/99designs/gqlgen version v0.17.88
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"adam-french.co.uk/backend/models"
|
||||
)
|
||||
|
||||
// ID is the resolver for the id field.
|
||||
func (r *jobAppReferenceResolver) ID(ctx context.Context, obj *models.JobAppReference) (int, error) {
|
||||
return int(obj.ID), nil
|
||||
}
|
||||
|
||||
// JobAppReference returns JobAppReferenceResolver implementation.
|
||||
func (r *Resolver) JobAppReference() JobAppReferenceResolver { return &jobAppReferenceResolver{r} }
|
||||
|
||||
type jobAppReferenceResolver struct{ *Resolver }
|
||||
@@ -30,6 +30,13 @@ type CreateFavoriteInput struct {
|
||||
Link *string `json:"link,omitempty"`
|
||||
}
|
||||
|
||||
type CreateJobAppReferenceInput struct {
|
||||
Category string `json:"category"`
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
SortOrder *int `json:"sortOrder,omitempty"`
|
||||
}
|
||||
|
||||
type CreateJobApplicationInput struct {
|
||||
JobTitle string `json:"jobTitle"`
|
||||
Company string `json:"company"`
|
||||
@@ -112,6 +119,13 @@ type SteamStatus struct {
|
||||
RecentGames []*SteamGame `json:"recentGames"`
|
||||
}
|
||||
|
||||
type UpdateJobAppReferenceInput struct {
|
||||
Category *string `json:"category,omitempty"`
|
||||
Label *string `json:"label,omitempty"`
|
||||
Value *string `json:"value,omitempty"`
|
||||
SortOrder *int `json:"sortOrder,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateJobApplicationInput struct {
|
||||
JobTitle *string `json:"jobTitle,omitempty"`
|
||||
Company *string `json:"company,omitempty"`
|
||||
|
||||
@@ -387,6 +387,63 @@ func (r *mutationResolver) DeleteJobApplication(ctx context.Context, id int) (bo
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// CreateJobAppReference is the resolver for the createJobAppReference field.
|
||||
func (r *mutationResolver) CreateJobAppReference(ctx context.Context, input model.CreateJobAppReferenceInput) (*models.JobAppReference, error) {
|
||||
if !IsAdminFromCtx(ctx) {
|
||||
return nil, fmt.Errorf("admin access required")
|
||||
}
|
||||
ref := models.JobAppReference{
|
||||
Category: input.Category,
|
||||
Label: input.Label,
|
||||
Value: input.Value,
|
||||
}
|
||||
if input.SortOrder != nil {
|
||||
ref.SortOrder = *input.SortOrder
|
||||
}
|
||||
if err := r.Store.DB.Create(&ref).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ref, nil
|
||||
}
|
||||
|
||||
// UpdateJobAppReference is the resolver for the updateJobAppReference field.
|
||||
func (r *mutationResolver) UpdateJobAppReference(ctx context.Context, id int, input model.UpdateJobAppReferenceInput) (*models.JobAppReference, error) {
|
||||
if !IsAdminFromCtx(ctx) {
|
||||
return nil, fmt.Errorf("admin access required")
|
||||
}
|
||||
var ref models.JobAppReference
|
||||
if err := r.Store.DB.First(&ref, id).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if input.Category != nil {
|
||||
ref.Category = *input.Category
|
||||
}
|
||||
if input.Label != nil {
|
||||
ref.Label = *input.Label
|
||||
}
|
||||
if input.Value != nil {
|
||||
ref.Value = *input.Value
|
||||
}
|
||||
if input.SortOrder != nil {
|
||||
ref.SortOrder = *input.SortOrder
|
||||
}
|
||||
if err := r.Store.DB.Save(&ref).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ref, nil
|
||||
}
|
||||
|
||||
// DeleteJobAppReference is the resolver for the deleteJobAppReference field.
|
||||
func (r *mutationResolver) DeleteJobAppReference(ctx context.Context, id int) (bool, error) {
|
||||
if !IsAdminFromCtx(ctx) {
|
||||
return false, fmt.Errorf("admin access required")
|
||||
}
|
||||
if err := r.Store.DB.Delete(&models.JobAppReference{}, id).Error; err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Users is the resolver for the users field.
|
||||
func (r *queryResolver) Users(ctx context.Context) ([]*models.User, error) {
|
||||
var users []models.User
|
||||
@@ -635,6 +692,18 @@ func (r *queryResolver) JobApplication(ctx context.Context, id int) (*models.Job
|
||||
return &app, nil
|
||||
}
|
||||
|
||||
// JobAppReferences is the resolver for the jobAppReferences field.
|
||||
func (r *queryResolver) JobAppReferences(ctx context.Context) ([]*models.JobAppReference, error) {
|
||||
if !IsAdminFromCtx(ctx) {
|
||||
return nil, fmt.Errorf("admin access required")
|
||||
}
|
||||
var refs []*models.JobAppReference
|
||||
if err := r.Store.DB.Order("category ASC, sort_order ASC, created_at ASC").Find(&refs).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return refs, nil
|
||||
}
|
||||
|
||||
// Mutation returns MutationResolver implementation.
|
||||
func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} }
|
||||
|
||||
|
||||
23
backend/graph/schema/job_app_reference.graphql
Normal file
23
backend/graph/schema/job_app_reference.graphql
Normal file
@@ -0,0 +1,23 @@
|
||||
type JobAppReference {
|
||||
id: ID!
|
||||
createdAt: Time!
|
||||
updatedAt: Time!
|
||||
category: String!
|
||||
label: String!
|
||||
value: String!
|
||||
sortOrder: Int!
|
||||
}
|
||||
|
||||
input CreateJobAppReferenceInput {
|
||||
category: String!
|
||||
label: String!
|
||||
value: String!
|
||||
sortOrder: Int
|
||||
}
|
||||
|
||||
input UpdateJobAppReferenceInput {
|
||||
category: String
|
||||
label: String
|
||||
value: String
|
||||
sortOrder: Int
|
||||
}
|
||||
@@ -17,6 +17,7 @@ type Query {
|
||||
bookmarks: [Bookmark!]!
|
||||
jobApplications: [JobApplication!]!
|
||||
jobApplication(id: ID!): JobApplication
|
||||
jobAppReferences: [JobAppReference!]!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
@@ -36,4 +37,7 @@ type Mutation {
|
||||
createBookmark(input: CreateBookmarkInput!): Bookmark!
|
||||
deleteBookmark(id: ID!): Bookmark!
|
||||
deleteJobApplication(id: ID!): Boolean!
|
||||
createJobAppReference(input: CreateJobAppReferenceInput!): JobAppReference!
|
||||
updateJobAppReference(id: ID!, input: UpdateJobAppReferenceInput!): JobAppReference!
|
||||
deleteJobAppReference(id: ID!): Boolean!
|
||||
}
|
||||
|
||||
@@ -77,6 +77,17 @@ type Bookmark struct {
|
||||
Link string `gorm:"not null" json:"link"`
|
||||
}
|
||||
|
||||
type JobAppReference struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"deletedAt"`
|
||||
Category string `gorm:"not null" json:"category"`
|
||||
Label string `gorm:"not null" json:"label"`
|
||||
Value string `gorm:"not null" json:"value"`
|
||||
SortOrder int `gorm:"default:0" json:"sortOrder"`
|
||||
}
|
||||
|
||||
type JobApplication struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
|
||||
@@ -39,6 +39,7 @@ func migrateDatabase(db *gorm.DB) error {
|
||||
&models.Rowing{},
|
||||
&models.Message{},
|
||||
&models.JobApplication{},
|
||||
&models.JobAppReference{},
|
||||
&models.Bookmark{},
|
||||
)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user