- positive cases with create repo for a project;

This commit is contained in:
naudachu 2023-11-06 16:46:56 +05:00
parent ecad950f54
commit f8bccf0135
21 changed files with 307 additions and 306 deletions

View File

@ -8,15 +8,14 @@ import (
"os/signal" "os/signal"
"syscall" "syscall"
"ticket-pimp/internal/controller"
"ticket-pimp/internal/domain" "ticket-pimp/internal/domain"
"ticket-pimp/internal/services" "ticket-pimp/internal/services"
"ticket-pimp/discord" "ticket-pimp/discord"
"ticket-pimp/telegram" "ticket-pimp/telegram"
ticketDB "ticket-pimp/internal/storage/db/tickets" "github.com/jackc/pgx/v5/pgxpool"
"github.com/jackc/pgx/v5"
) )
func main() { func main() {
@ -26,37 +25,12 @@ func main() {
// test(config) // test(config)
} }
// func test(conf domain.Config) {
// ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill, syscall.SIGTERM)
// defer cancel()
// conn, err := pgxpool.New(ctx, fmt.Sprintf(
// "postgresql://%s:%s@%s:%s/%s",
// conf.DB.User,
// conf.DB.Pass,
// conf.DB.Host,
// conf.DB.Port,
// conf.DB.Name,
// ))
// if err != nil {
// log.Fatalf("DB connection failed: %v", err)
// }
// q := configDB.New(conn)
// appController := controller.NewAppConfig(q)
// ticketConfig, err := appController.NewKey(ctx)
// _ = ticketConfig
// }
func run(conf domain.Config) { func run(conf domain.Config) {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill, syscall.SIGTERM) ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill, syscall.SIGTERM)
defer cancel() defer cancel()
// -- DB connection init -- START // -- DB connection init -- START
conn, err := pgx.Connect( conn, err := pgxpool.New(
ctx, ctx,
fmt.Sprintf( fmt.Sprintf(
"postgresql://%s:%s@%s:%s/%s", "postgresql://%s:%s@%s:%s/%s",
@ -65,20 +39,23 @@ func run(conf domain.Config) {
if err != nil { if err != nil {
log.Fatalf("DB connection failed: %v", err) log.Fatalf("DB connection failed: %v", err)
} }
defer conn.Close(ctx)
// -- DB connection init -- END // -- DB connection init -- END
ticketsRepo := ticketDB.New(conn)
gitService := services.NewGit(conf.Git) gitService := services.NewGit(conf.Git)
cloudService := services.NewCloud(conf.Cloud) cloudService := services.NewCloud(conf.Cloud)
codeService := services.NewCodaClient(conf.Coda) codeService := services.NewCodaClient(conf.Coda)
// Инициализация контроллера:
controller := controller.NewWorkflowController(
gitService,
cloudService,
codeService,
conn,
)
go func() { go func() {
opts := discord.DiscordOptions{ opts := discord.DiscordOptions{
TicketsRepo: ticketsRepo, Controller: controller,
GitService: gitService,
CloudService: cloudService,
Coda: codeService,
AppConfig: &conf, AppConfig: &conf,
} }
if err := discord.Run(conf, opts); err != nil { if err := discord.Run(conf, opts); err != nil {
@ -88,7 +65,7 @@ func run(conf domain.Config) {
// go func() { // go func() {
opts := telegram.TelegramOptions{ opts := telegram.TelegramOptions{
TicketsRepo: ticketsRepo, // TicketsRepo: db,
GitService: gitService, GitService: gitService,
CloudService: cloudService, CloudService: cloudService,
Coda: codeService, Coda: codeService,

View File

@ -6,10 +6,8 @@ import (
"os" "os"
"os/signal" "os/signal"
"ticket-pimp/discord/handler" "ticket-pimp/discord/handler"
"ticket-pimp/internal/controller"
"ticket-pimp/internal/domain" "ticket-pimp/internal/domain"
"ticket-pimp/internal/services"
tickets "ticket-pimp/internal/storage/db/tickets"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
@ -23,11 +21,8 @@ func initBotWith(token string) (*discordgo.Session, error) {
} }
type DiscordOptions struct { type DiscordOptions struct {
TicketsRepo *tickets.Queries
GitService *services.Git
CloudService *services.Cloud
Coda *services.Coda
AppConfig *domain.Config AppConfig *domain.Config
Controller *controller.WorkflowController
} }
func Run(conf domain.Config, opts DiscordOptions) error { func Run(conf domain.Config, opts DiscordOptions) error {
@ -38,7 +33,7 @@ func Run(conf domain.Config, opts DiscordOptions) error {
return err return err
} }
router := handler.InitRouter(opts.GitService) router := handler.InitRouter(*opts.Controller)
commandHandlers := map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){} commandHandlers := map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){}
for _, handler := range router.Routes { for _, handler := range router.Routes {

View File

@ -1,29 +1,30 @@
package handler package handler
import ( import (
"context"
"fmt" "fmt"
"log" "log"
"ticket-pimp/internal/controller"
"ticket-pimp/internal/domain" "ticket-pimp/internal/domain"
"ticket-pimp/internal/services"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
type router struct { type router struct {
Routes []route Routes []route
controller controller.WorkflowController
git services.IGit
} }
// Подключение роутов к Discord боту // Подключение роутов к Discord боту
func InitRouter(gitService services.IGit) *router { func InitRouter(wc controller.WorkflowController) *router {
var r router var r router
r.Routes = append( r.Routes = append(
r.Routes, r.Routes,
r.CreateRepoHandler(3), r.CreateRepoHandler(3),
r.CreateTicketHandler(3), r.CreateTicketHandler(3),
) )
r.git = gitService r.controller = wc
return &r return &r
} }
@ -64,12 +65,13 @@ func (h *router) CreateRepoHandler(repoNameMinLength int) route {
Type: discordgo.ApplicationCommandOptionString, Type: discordgo.ApplicationCommandOptionString,
Name: "repo_name", Name: "repo_name",
Description: "Type the repository's name", Description: "Type the repository's name",
Required: true, Required: false,
MinLength: &repoNameMinLength, MinLength: &repoNameMinLength,
}, },
}, },
}, },
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) { Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
var result string
// Access options in the order provided by the user. // Access options in the order provided by the user.
options := i.ApplicationCommandData().Options options := i.ApplicationCommandData().Options
@ -81,27 +83,38 @@ func (h *router) CreateRepoHandler(repoNameMinLength int) route {
var str string = "" var str string = ""
if option, ok := optionMap["repo_name"]; ok { project, err := h.controller.GetProjectByChannelID(context.TODO(), i.ChannelID)
str = option.StringValue() if err != nil {
result = fmt.Sprintf("unable to retrieve project from db, error: %v", err)
} else {
var suffix string
if option, ok := optionMap["repo_type"]; ok { if option, ok := optionMap["repo_type"]; ok {
switch option.Value { switch option.Value {
case projectRepo: case projectRepo:
suffix = ""
case buildRepo: case buildRepo:
str += "-build" suffix = "-build"
} }
} }
if option, ok := optionMap["repo_name"]; ok {
str = option.StringValue()
} else {
str = project.ShortName
} }
str = str + suffix
var g *domain.Git var g *domain.Git
var result string
g, err := h.git.CreateRepo(str) g, err := h.controller.IGit.CreateRepo(str)
// g, err := h.git.CreateRepo(str)
if err != nil { if err != nil {
result = fmt.Sprintf("error while repo creation: %v", err) result = fmt.Sprintf("error while repo creation: %v", err)
} else { } else {
result = "🚀 " + g.HtmlUrl + " was created" result = "🚀 " + g.HtmlUrl + " was created"
} }
}
discerr := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ discerr := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
// Ignore type for now, they will be discussed in "responses" // Ignore type for now, they will be discussed in "responses"
@ -144,29 +157,33 @@ func (h *router) CreateTicketHandler(repoNameMinLength int) route {
if option, ok := optionMap["project_name"]; ok { if option, ok := optionMap["project_name"]; ok {
dchan, err := s.GuildChannelCreate(i.GuildID, option.StringValue(), discordgo.ChannelTypeGuildText) dchan, err := s.GuildChannelCreate(i.GuildID, option.StringValue(), discordgo.ChannelTypeGuildText)
if err != nil { if err != nil {
log.Printf("chan creation problem: %v\n", err) result = fmt.Sprintf("chan creation problem: %v\n", err)
} } else {
p, err := h.controller.ProjectCreate(context.TODO(), domain.Project{
// permissions := discordgo.PermissionOverwrite{ ChannelID: dchan.ID,
// ID: i.User.ID, })
// Type: 1, if err != nil {
// //Deny: 0, result = fmt.Sprintf("unable to create project: %v\n", err)
// Allow: 1, } else {
// }
edit := discordgo.ChannelEdit{ edit := discordgo.ChannelEdit{
// PermissionOverwrites: []*discordgo.PermissionOverwrite{&permissions}, // [ ] Как сделать приватный канал то??? Name: p.ShortName,
ParentID: "1150719794853716028", ParentID: "1150719794853716028",
} }
dchan, err = s.ChannelEdit(dchan.ID, &edit) dchan, err = s.ChannelEdit(dchan.ID, &edit)
if err != nil { if err != nil {
log.Printf("chan editing problem: %v\n", err) result = fmt.Sprintf("channel created, but unable to edit: %v\n", err)
}
} else {
_, err = s.ChannelMessageSend(dchan.ID, "Hello!") _, err = s.ChannelMessageSend(dchan.ID, "Hello!")
if err != nil { if err != nil {
log.Printf("message send problem: %v\n", err) log.Printf("message send problem: %v\n", err)
} }
result = dchan.ID result = dchan.ID
} }
}
}
}
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
// Ignore type for now, they will be discussed in "responses" // Ignore type for now, they will be discussed in "responses"

View File

@ -8,38 +8,36 @@ import (
"sync" "sync"
"ticket-pimp/internal/domain" "ticket-pimp/internal/domain"
"ticket-pimp/internal/services" "ticket-pimp/internal/services"
db "ticket-pimp/internal/storage/db/tickets" "ticket-pimp/internal/storage/db"
"time"
"github.com/jackc/pgx/v5/pgtype" "github.com/jackc/pgx/v5/pgtype"
"github.com/jackc/pgx/v5/pgxpool"
) )
type WorkflowController struct { type WorkflowController struct {
iGit services.IGit IGit services.IGit
iCloud services.ICloud ICloud services.ICloud
iCoda services.ICoda ICoda services.ICoda
db *db.Queries pool *pgxpool.Pool
q *db.Queries
} }
func NewWorkflowController( func NewWorkflowController(
git services.IGit, git services.IGit,
cloud services.ICloud, cloud services.ICloud,
coda services.ICoda, coda services.ICoda,
db *db.Queries, pool *pgxpool.Pool,
) *WorkflowController { ) *WorkflowController {
return &WorkflowController{ return &WorkflowController{
iGit: git, IGit: git,
iCloud: cloud, ICloud: cloud,
iCoda: coda, ICoda: coda,
db: db, pool: pool,
q: db.New(pool),
} }
} }
type IWorkflowController interface { func (wc *WorkflowController) FullProjectInit(name, key, id string) (string, error) {
Workflow(name, key, id string) (string, error)
}
func (wc *WorkflowController) Workflow(name, key, id string) (string, error) {
appKey := fmt.Sprintf("%s-%s", key, id) appKey := fmt.Sprintf("%s-%s", key, id)
@ -53,17 +51,17 @@ func (wc *WorkflowController) Workflow(name, key, id string) (string, error) {
go func(ref **domain.Git) { go func(ref **domain.Git) {
defer wg.Done() defer wg.Done()
*ref, _ = wc.iGit.CreateRepo(appKey) *ref, _ = wc.IGit.CreateRepo(appKey)
}(&git) }(&git)
go func(ref **domain.Git) { go func(ref **domain.Git) {
defer wg.Done() defer wg.Done()
*ref, _ = wc.iGit.CreateRepo(appKey + "-build") *ref, _ = wc.IGit.CreateRepo(appKey + "-build")
}(&gitBuild) }(&gitBuild)
go func(ref **domain.Folder) { go func(ref **domain.Folder) {
defer wg.Done() defer wg.Done()
*ref, _ = wc.iCloud.CreateFolder(appKey) *ref, _ = wc.ICloud.CreateFolder(appKey)
}(&cloud) }(&cloud)
wg.Wait() wg.Wait()
@ -89,19 +87,16 @@ func (wc *WorkflowController) Workflow(name, key, id string) (string, error) {
} }
ctx := context.TODO() ctx := context.TODO()
insertedTicket, err := wc.db.CreateTicket(ctx, db.CreateTicketParams{ insertedTicket, err := wc.q.CreateTicket(ctx, db.CreateTicketParams{
Key: pgtype.Text{String: appKey, Valid: true}, Key: pgtype.Text{String: appKey, Valid: true},
ProjectGit: pgtype.Text{String: gitResult, Valid: true}, Channelid: pgtype.Text{},
BuildGit: pgtype.Text{String: gitBuildResult, Valid: true},
Folder: pgtype.Text{String: cloudResult, Valid: true},
CreatedAt: pgtype.Timestamptz{Time: time.Now(), InfinityModifier: 0, Valid: true},
}) })
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
log.Print(insertedTicket) log.Print(insertedTicket)
wc.iCoda.CreateApp(domain.CodaApplication{ wc.ICoda.CreateApp(domain.CodaApplication{
ID: appKey, ID: appKey,
Summary: strings.TrimSpace(name), Summary: strings.TrimSpace(name),
Git: gitResult, Git: gitResult,

View File

@ -0,0 +1,84 @@
package controller
import (
"context"
"fmt"
"ticket-pimp/internal/domain"
"ticket-pimp/internal/storage/db"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgtype"
)
func (wc *WorkflowController) Get(ctx context.Context) (*domain.ApplicationConfig, error) {
c, err := wc.q.GetConfig(ctx)
return &domain.ApplicationConfig{
Key: c.TicketKey.String,
ID: int(c.TicketID.Int32),
}, err
}
func (wc *WorkflowController) NewKey(ctx context.Context) (*domain.ApplicationConfig, error) {
c, err := wc.q.SetNewConfig(ctx)
return &domain.ApplicationConfig{
Key: c.TicketKey.String,
ID: int(c.TicketID.Int32),
}, err
}
func (wc *WorkflowController) ProjectCreate(ctx context.Context, project domain.Project) (*domain.Project, error) {
tx, err := wc.pool.Begin(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback(ctx)
qtx := wc.q.WithTx(tx)
appconfig, err := qtx.SetNewConfig(ctx)
if err != nil {
return nil, err
}
project.ShortName = fmt.Sprintf(
"%s-%d",
appconfig.TicketKey.String,
appconfig.TicketID.Int32,
)
project.ID = string(appconfig.TicketID.Int32)
projectRow, err := qtx.CreateTicket(ctx, db.CreateTicketParams{
Key: pgtype.Text{String: project.ShortName, Valid: true},
Channelid: pgtype.Text{String: project.ChannelID, Valid: true},
})
if err != nil {
tx.Rollback(ctx)
return nil, err
} else {
tx.Commit(ctx)
fmt.Println(projectRow)
}
return &project, nil
}
func (wc *WorkflowController) GetProjectByChannelID(ctx context.Context, id string) (*domain.Project, error) {
var proj domain.Project
dbTicket, err := wc.q.GetTicketByChannelID(ctx, pgtype.Text{String: id, Valid: true})
if err != nil {
if err == pgx.ErrNoRows {
return nil, nil
}
return nil, err
} else {
proj = domain.Project{
ID: string(dbTicket.ID),
ShortName: dbTicket.Key.String,
Name: dbTicket.Key.String,
ChannelID: dbTicket.Channelid.String,
}
}
return &proj, nil
}

View File

@ -3,7 +3,7 @@ package controller
import ( import (
"context" "context"
"ticket-pimp/internal/domain" "ticket-pimp/internal/domain"
db "ticket-pimp/internal/storage/db/config" db "ticket-pimp/internal/storage/db"
) )
type IConfigController interface { type IConfigController interface {
@ -20,19 +20,3 @@ func NewAppConfig(db *db.Queries) AppConfig {
db: db, db: db,
} }
} }
func (ac *AppConfig) Get(ctx context.Context) (*domain.ApplicationConfig, error) {
c, err := ac.db.GetConfig(ctx)
return &domain.ApplicationConfig{
Key: c.TicketKey.String,
ID: int(c.TicketID.Int32),
}, err
}
func (ac *AppConfig) NewKey(ctx context.Context) (*domain.ApplicationConfig, error) {
c, err := ac.db.SetNewConfig(ctx)
return &domain.ApplicationConfig{
Key: c.TicketKey.String,
ID: int(c.TicketID.Int32),
}, err
}

View File

@ -86,6 +86,7 @@ type Project struct {
ID string `json:"id"` ID string `json:"id"`
ShortName string `json:"shortName"` ShortName string `json:"shortName"`
Name string `json:"name"` Name string `json:"name"`
ChannelID string `json:"channel_id"`
} }
type ProjectID struct { type ProjectID struct {

View File

@ -1,35 +0,0 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.23.0
// source: config.sql
package db
import (
"context"
)
const getConfig = `-- name: GetConfig :one
SELECT ticket_key, ticket_id
FROM appconfig
`
func (q *Queries) GetConfig(ctx context.Context) (Appconfig, error) {
row := q.db.QueryRow(ctx, getConfig)
var i Appconfig
err := row.Scan(&i.TicketKey, &i.TicketID)
return i, err
}
const setNewConfig = `-- name: SetNewConfig :one
UPDATE appconfig
SET ticket_id = ticket_id + 1
RETURNING ticket_key, ticket_id
`
func (q *Queries) SetNewConfig(ctx context.Context) (Appconfig, error) {
row := q.db.QueryRow(ctx, setNewConfig)
var i Appconfig
err := row.Scan(&i.TicketKey, &i.TicketID)
return i, err
}

View File

@ -1,14 +0,0 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.23.0
package db
import (
"github.com/jackc/pgx/v5/pgtype"
)
type Appconfig struct {
TicketKey pgtype.Text
TicketID pgtype.Int4
}

View File

@ -8,9 +8,15 @@ import (
"github.com/jackc/pgx/v5/pgtype" "github.com/jackc/pgx/v5/pgtype"
) )
type Appconfig struct {
TicketKey pgtype.Text
TicketID pgtype.Int4
}
type Ticket struct { type Ticket struct {
ID int32 ID int32
Key pgtype.Text Key pgtype.Text
Channelid pgtype.Text
ProjectGit pgtype.Text ProjectGit pgtype.Text
BuildGit pgtype.Text BuildGit pgtype.Text
Folder pgtype.Text Folder pgtype.Text

View File

@ -1,7 +1,7 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.23.0 // sqlc v1.23.0
// source: tickets.sql // source: queries.sql
package db package db
@ -13,33 +13,25 @@ import (
const createTicket = `-- name: CreateTicket :one const createTicket = `-- name: CreateTicket :one
INSERT INTO tickets ( INSERT INTO tickets (
key, project_git, build_git, folder, created_at key, channelID
) VALUES ( ) VALUES (
$1, $2, $3, $4, $5 $1, $2
) )
RETURNING id, key, project_git, build_git, folder, created_at, deleted_at, updated_at RETURNING id, key, channelid, project_git, build_git, folder, created_at, deleted_at, updated_at
` `
type CreateTicketParams struct { type CreateTicketParams struct {
Key pgtype.Text Key pgtype.Text
ProjectGit pgtype.Text Channelid pgtype.Text
BuildGit pgtype.Text
Folder pgtype.Text
CreatedAt pgtype.Timestamptz
} }
func (q *Queries) CreateTicket(ctx context.Context, arg CreateTicketParams) (Ticket, error) { func (q *Queries) CreateTicket(ctx context.Context, arg CreateTicketParams) (Ticket, error) {
row := q.db.QueryRow(ctx, createTicket, row := q.db.QueryRow(ctx, createTicket, arg.Key, arg.Channelid)
arg.Key,
arg.ProjectGit,
arg.BuildGit,
arg.Folder,
arg.CreatedAt,
)
var i Ticket var i Ticket
err := row.Scan( err := row.Scan(
&i.ID, &i.ID,
&i.Key, &i.Key,
&i.Channelid,
&i.ProjectGit, &i.ProjectGit,
&i.BuildGit, &i.BuildGit,
&i.Folder, &i.Folder,
@ -68,8 +60,41 @@ func (q *Queries) DeleteTicketByKey(ctx context.Context, key pgtype.Text) error
return err return err
} }
const getConfig = `-- name: GetConfig :one
SELECT ticket_key, ticket_id
FROM appconfig
`
func (q *Queries) GetConfig(ctx context.Context) (Appconfig, error) {
row := q.db.QueryRow(ctx, getConfig)
var i Appconfig
err := row.Scan(&i.TicketKey, &i.TicketID)
return i, err
}
const getTicketByChannelID = `-- name: GetTicketByChannelID :one
SELECT id, key, channelid, project_git, build_git, folder, created_at, deleted_at, updated_at FROM tickets WHERE channelID = $1
`
func (q *Queries) GetTicketByChannelID(ctx context.Context, channelid pgtype.Text) (Ticket, error) {
row := q.db.QueryRow(ctx, getTicketByChannelID, channelid)
var i Ticket
err := row.Scan(
&i.ID,
&i.Key,
&i.Channelid,
&i.ProjectGit,
&i.BuildGit,
&i.Folder,
&i.CreatedAt,
&i.DeletedAt,
&i.UpdatedAt,
)
return i, err
}
const getTicketByID = `-- name: GetTicketByID :one const getTicketByID = `-- name: GetTicketByID :one
SELECT id, key, project_git, build_git, folder, created_at, deleted_at, updated_at FROM tickets WHERE id = $1 SELECT id, key, channelid, project_git, build_git, folder, created_at, deleted_at, updated_at FROM tickets WHERE id = $1
` `
func (q *Queries) GetTicketByID(ctx context.Context, id int32) (Ticket, error) { func (q *Queries) GetTicketByID(ctx context.Context, id int32) (Ticket, error) {
@ -78,6 +103,7 @@ func (q *Queries) GetTicketByID(ctx context.Context, id int32) (Ticket, error) {
err := row.Scan( err := row.Scan(
&i.ID, &i.ID,
&i.Key, &i.Key,
&i.Channelid,
&i.ProjectGit, &i.ProjectGit,
&i.BuildGit, &i.BuildGit,
&i.Folder, &i.Folder,
@ -89,7 +115,7 @@ func (q *Queries) GetTicketByID(ctx context.Context, id int32) (Ticket, error) {
} }
const listTickets = `-- name: ListTickets :many const listTickets = `-- name: ListTickets :many
SELECT id, key, project_git, build_git, folder, created_at, deleted_at, updated_at FROM tickets WHERE deleted_at IS NULL SELECT id, key, channelid, project_git, build_git, folder, created_at, deleted_at, updated_at FROM tickets WHERE deleted_at IS NULL
` `
func (q *Queries) ListTickets(ctx context.Context) ([]Ticket, error) { func (q *Queries) ListTickets(ctx context.Context) ([]Ticket, error) {
@ -104,6 +130,7 @@ func (q *Queries) ListTickets(ctx context.Context) ([]Ticket, error) {
if err := rows.Scan( if err := rows.Scan(
&i.ID, &i.ID,
&i.Key, &i.Key,
&i.Channelid,
&i.ProjectGit, &i.ProjectGit,
&i.BuildGit, &i.BuildGit,
&i.Folder, &i.Folder,
@ -122,7 +149,7 @@ func (q *Queries) ListTickets(ctx context.Context) ([]Ticket, error) {
} }
const listTicketsWithDeleted = `-- name: ListTicketsWithDeleted :many const listTicketsWithDeleted = `-- name: ListTicketsWithDeleted :many
SELECT id, key, project_git, build_git, folder, created_at, deleted_at, updated_at FROM tickets SELECT id, key, channelid, project_git, build_git, folder, created_at, deleted_at, updated_at FROM tickets
` `
func (q *Queries) ListTicketsWithDeleted(ctx context.Context) ([]Ticket, error) { func (q *Queries) ListTicketsWithDeleted(ctx context.Context) ([]Ticket, error) {
@ -137,6 +164,7 @@ func (q *Queries) ListTicketsWithDeleted(ctx context.Context) ([]Ticket, error)
if err := rows.Scan( if err := rows.Scan(
&i.ID, &i.ID,
&i.Key, &i.Key,
&i.Channelid,
&i.ProjectGit, &i.ProjectGit,
&i.BuildGit, &i.BuildGit,
&i.Folder, &i.Folder,
@ -154,6 +182,19 @@ func (q *Queries) ListTicketsWithDeleted(ctx context.Context) ([]Ticket, error)
return items, nil return items, nil
} }
const setNewConfig = `-- name: SetNewConfig :one
UPDATE appconfig
SET ticket_id = ticket_id + 1
RETURNING ticket_key, ticket_id
`
func (q *Queries) SetNewConfig(ctx context.Context) (Appconfig, error) {
row := q.db.QueryRow(ctx, setNewConfig)
var i Appconfig
err := row.Scan(&i.TicketKey, &i.TicketID)
return i, err
}
const updateTicketByID = `-- name: UpdateTicketByID :exec const updateTicketByID = `-- name: UpdateTicketByID :exec
UPDATE tickets SET project_git = $1, build_git = $2, folder = $3 WHERE id = $4 UPDATE tickets SET project_git = $1, build_git = $2, folder = $3 WHERE id = $4
` `

View File

@ -1,32 +0,0 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.23.0
package db
import (
"context"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
)
type DBTX interface {
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row
}
func New(db DBTX) *Queries {
return &Queries{db: db}
}
type Queries struct {
db DBTX
}
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
return &Queries{
db: tx,
}
}

View File

@ -2,6 +2,7 @@
CREATE TABLE tickets ( CREATE TABLE tickets (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
key VARCHAR(10), key VARCHAR(10),
channelID VARCHAR(255),
project_git VARCHAR(255), project_git VARCHAR(255),
build_git VARCHAR(255), build_git VARCHAR(255),
folder VARCHAR(255), folder VARCHAR(255),

View File

@ -4,5 +4,8 @@ CREATE TABLE appconfig (
ticket_id INT ticket_id INT
); );
-- +migrate Up
INSERT INTO appconfig (ticket_key, ticket_id) VALUES ('DAP', 100);
-- +migrate Down -- +migrate Down
DROP TABLE appconfig; DROP TABLE appconfig;

View File

@ -1,18 +1,10 @@
version: "2" version: "2"
sql: sql:
- engine: "postgresql" - engine: "postgresql"
queries: "sqlc/tickets.sql" queries: "sqlc/queries.sql"
schema: "migrate/0001_init_tickets.sql" schema: "migrate"
gen: gen:
go: go:
package: "db" package: "db"
sql_package: "pgx/v5" sql_package: "pgx/v5"
out: "db/tickets" out: "db"
- engine: "postgresql"
queries: "sqlc/config.sql"
schema: "migrate/0002_init_config.sql"
gen:
go:
package: "db"
sql_package: "pgx/v5"
out: "db/config"

View File

@ -1,8 +0,0 @@
-- name: GetConfig :one
SELECT ticket_key, ticket_id
FROM appconfig;
-- name: SetNewConfig :one
UPDATE appconfig
SET ticket_id = ticket_id + 1
RETURNING *;

View File

@ -1,8 +1,17 @@
-- name: GetConfig :one
SELECT ticket_key, ticket_id
FROM appconfig;
-- name: SetNewConfig :one
UPDATE appconfig
SET ticket_id = ticket_id + 1
RETURNING *;
-- name: CreateTicket :one -- name: CreateTicket :one
INSERT INTO tickets ( INSERT INTO tickets (
key, project_git, build_git, folder, created_at key, channelID
) VALUES ( ) VALUES (
$1, $2, $3, $4, $5 $1, $2
) )
RETURNING *; RETURNING *;
@ -15,6 +24,9 @@ SELECT * FROM tickets;
-- name: GetTicketByID :one -- name: GetTicketByID :one
SELECT * FROM tickets WHERE id = $1; SELECT * FROM tickets WHERE id = $1;
-- name: GetTicketByChannelID :one
SELECT * FROM tickets WHERE channelID = $1;
-- name: UpdateTicketByID :exec -- name: UpdateTicketByID :exec
UPDATE tickets SET project_git = $1, build_git = $2, folder = $3 WHERE id = $4; UPDATE tickets SET project_git = $1, build_git = $2, folder = $3 WHERE id = $4;

View File

@ -1,48 +1,38 @@
package handler package handler
import ( // func (h *Handler) DevelopmentTaskHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
"context"
"errors"
"strconv"
"strings"
"github.com/mr-linch/go-tg" // str := strings.Replace(mu.Text, "/new", "", 1)
"github.com/mr-linch/go-tg/tgb"
)
func (h *Handler) DevelopmentTaskHandler(ctx context.Context, mu *tgb.MessageUpdate) error { // if str == "" {
// return errors.New("empty command provided")
// }
str := strings.Replace(mu.Text, "/new", "", 1) // issueKeyStr, err := h.workflow.Workflow(str, h.key, h.id)
if str == "" { // if err != nil {
return errors.New("empty command provided") // answer := errorAnswer(err.Error())
} // h.LogMessage(ctx, mu, answer)
// return mu.Answer(answer).ParseMode(tg.HTML).DoVoid(ctx)
// }
issueKeyStr, err := h.workflow.Workflow(str, h.key, h.id) // i, err := strconv.Atoi(h.id)
// if err != nil {
// return errors.New("problem with conversion id to int")
// }
// h.id = strconv.Itoa(i + 1)
if err != nil { // answer := newTicketAnswer(issueKeyStr)
answer := errorAnswer(err.Error()) // h.LogMessage(ctx, mu, answer)
h.LogMessage(ctx, mu, answer) // return mu.Answer(answer).ParseMode(tg.HTML).DoVoid(ctx)
return mu.Answer(answer).ParseMode(tg.HTML).DoVoid(ctx) // }
}
i, err := strconv.Atoi(h.id) // func newTicketAnswer(name string) string {
if err != nil { // return tg.HTML.Text(
return errors.New("problem with conversion id to int") // tg.HTML.Line(
} // "🤘 Ticket ",
h.id = strconv.Itoa(i + 1) // name,
// " has been created!",
answer := newTicketAnswer(issueKeyStr) // ),
h.LogMessage(ctx, mu, answer) // )
return mu.Answer(answer).ParseMode(tg.HTML).DoVoid(ctx) // }
}
func newTicketAnswer(name string) string {
return tg.HTML.Text(
tg.HTML.Line(
"🤘 Ticket ",
name,
" has been created!",
),
)
}

View File

@ -1,33 +1,26 @@
package handler package handler
import ( import (
"ticket-pimp/internal/controller"
"ticket-pimp/internal/services" "ticket-pimp/internal/services"
tickets "ticket-pimp/internal/storage/db/tickets"
) )
type Handler struct { type Handler struct {
workflow controller.IWorkflowController
git services.IGit git services.IGit
cloud services.ICloud cloud services.ICloud
coda services.ICoda coda services.ICoda
key string key string
id string id string
db *tickets.Queries
} }
func NewHandler( func NewHandler(
git services.IGit, git services.IGit,
cloud services.ICloud, cloud services.ICloud,
coda services.ICoda, coda services.ICoda,
db *tickets.Queries,
) *Handler { ) *Handler {
return &Handler{ return &Handler{
workflow: controller.NewWorkflowController(git, cloud, coda, db),
git: git, git: git,
cloud: cloud, cloud: cloud,
coda: coda, coda: coda,
db: db,
} }
} }

View File

@ -10,7 +10,7 @@ import (
"github.com/mr-linch/go-tg" "github.com/mr-linch/go-tg"
"github.com/mr-linch/go-tg/tgb" "github.com/mr-linch/go-tg/tgb"
tickets "ticket-pimp/internal/storage/db/tickets" tickets "ticket-pimp/internal/storage/db"
) )
type TelegramOptions struct { type TelegramOptions struct {
@ -35,13 +35,12 @@ func Run(ctx context.Context, opts TelegramOptions) error {
opts.GitService, opts.GitService,
opts.CloudService, opts.CloudService,
opts.Coda, opts.Coda,
opts.TicketsRepo,
) )
router := tgb.NewRouter(). router := tgb.NewRouter().
Message(h.Init, tgb.Command("init")). Message(h.Init, tgb.Command("init")).
Message(h.PingHandler, tgb.Command("ping")). Message(h.PingHandler, tgb.Command("ping")).
Message(h.DevelopmentTaskHandler, tgb.TextHasPrefix("/new")). // Message(h.DevelopmentTaskHandler, tgb.TextHasPrefix("/new")).
Message(h.NewRepoHandler, tgb.TextHasPrefix("/repo")). Message(h.NewRepoHandler, tgb.TextHasPrefix("/repo")).
Message(h.NewFolderHandler, tgb.TextHasPrefix("/folder")). Message(h.NewFolderHandler, tgb.TextHasPrefix("/folder")).
Message(h.FarmTaskHandler, tgb.TextHasPrefix("/task")) Message(h.FarmTaskHandler, tgb.TextHasPrefix("/task"))