refactor: Update ARR body parsing logic

This commit is contained in:
windyboy
2024-07-23 11:29:12 +08:00
parent 3202521f7b
commit 77a7c7eae0
14 changed files with 3348 additions and 50 deletions
+163
View File
@@ -0,0 +1,163 @@
// Code generated by github.com/Khan/genqlient, DO NOT EDIT.
package repository
import (
"context"
"encoding/json"
"time"
"github.com/Khan/genqlient/graphql"
"github.com/google/uuid"
)
// input type for inserting data into table "aviation.telegrams"
type Aviation_telegrams_insert_input struct {
Body_and_footer string `json:"body_and_footer"`
Body_data json.RawMessage `json:"body_data"`
Category string `json:"category"`
Date_time string `json:"date_time"`
Dispatched_at time.Time `json:"dispatched_at"`
Id int `json:"id"`
Message_id string `json:"message_id"`
Need_dispatch bool `json:"need_dispatch"`
Originator string `json:"originator"`
Originator_date_time string `json:"originator_date_time"`
Parsed_at time.Time `json:"parsed_at"`
Primary_address string `json:"primary_address"`
Priority_indicator string `json:"priority_indicator"`
Received_at time.Time `json:"received_at"`
Secondary_addresses json.RawMessage `json:"secondary_addresses"`
Uuid uuid.UUID `json:"uuid"`
}
// GetBody_and_footer returns Aviation_telegrams_insert_input.Body_and_footer, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetBody_and_footer() string { return v.Body_and_footer }
// GetBody_data returns Aviation_telegrams_insert_input.Body_data, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetBody_data() json.RawMessage { return v.Body_data }
// GetCategory returns Aviation_telegrams_insert_input.Category, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetCategory() string { return v.Category }
// GetDate_time returns Aviation_telegrams_insert_input.Date_time, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetDate_time() string { return v.Date_time }
// GetDispatched_at returns Aviation_telegrams_insert_input.Dispatched_at, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetDispatched_at() time.Time { return v.Dispatched_at }
// GetId returns Aviation_telegrams_insert_input.Id, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetId() int { return v.Id }
// GetMessage_id returns Aviation_telegrams_insert_input.Message_id, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetMessage_id() string { return v.Message_id }
// GetNeed_dispatch returns Aviation_telegrams_insert_input.Need_dispatch, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetNeed_dispatch() bool { return v.Need_dispatch }
// GetOriginator returns Aviation_telegrams_insert_input.Originator, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetOriginator() string { return v.Originator }
// GetOriginator_date_time returns Aviation_telegrams_insert_input.Originator_date_time, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetOriginator_date_time() string {
return v.Originator_date_time
}
// GetParsed_at returns Aviation_telegrams_insert_input.Parsed_at, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetParsed_at() time.Time { return v.Parsed_at }
// GetPrimary_address returns Aviation_telegrams_insert_input.Primary_address, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetPrimary_address() string { return v.Primary_address }
// GetPriority_indicator returns Aviation_telegrams_insert_input.Priority_indicator, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetPriority_indicator() string { return v.Priority_indicator }
// GetReceived_at returns Aviation_telegrams_insert_input.Received_at, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetReceived_at() time.Time { return v.Received_at }
// GetSecondary_addresses returns Aviation_telegrams_insert_input.Secondary_addresses, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetSecondary_addresses() json.RawMessage {
return v.Secondary_addresses
}
// GetUuid returns Aviation_telegrams_insert_input.Uuid, and is useful for accessing the field via an interface.
func (v *Aviation_telegrams_insert_input) GetUuid() uuid.UUID { return v.Uuid }
// __newMessageInput is used internally by genqlient
type __newMessageInput struct {
Object Aviation_telegrams_insert_input `json:"object"`
}
// GetObject returns __newMessageInput.Object, and is useful for accessing the field via an interface.
func (v *__newMessageInput) GetObject() Aviation_telegrams_insert_input { return v.Object }
// newMessageInsert_aviation_telegrams_oneAviation_telegrams includes the requested fields of the GraphQL type aviation_telegrams.
// The GraphQL type's documentation follows.
//
// columns and relationships of "aviation.telegrams"
type newMessageInsert_aviation_telegrams_oneAviation_telegrams struct {
Id int `json:"id"`
Message_id string `json:"message_id"`
Uuid uuid.UUID `json:"uuid"`
}
// GetId returns newMessageInsert_aviation_telegrams_oneAviation_telegrams.Id, and is useful for accessing the field via an interface.
func (v *newMessageInsert_aviation_telegrams_oneAviation_telegrams) GetId() int { return v.Id }
// GetMessage_id returns newMessageInsert_aviation_telegrams_oneAviation_telegrams.Message_id, and is useful for accessing the field via an interface.
func (v *newMessageInsert_aviation_telegrams_oneAviation_telegrams) GetMessage_id() string {
return v.Message_id
}
// GetUuid returns newMessageInsert_aviation_telegrams_oneAviation_telegrams.Uuid, and is useful for accessing the field via an interface.
func (v *newMessageInsert_aviation_telegrams_oneAviation_telegrams) GetUuid() uuid.UUID {
return v.Uuid
}
// newMessageResponse is returned by newMessage on success.
type newMessageResponse struct {
// insert a single row into the table: "aviation.telegrams"
Insert_aviation_telegrams_one newMessageInsert_aviation_telegrams_oneAviation_telegrams `json:"insert_aviation_telegrams_one"`
}
// GetInsert_aviation_telegrams_one returns newMessageResponse.Insert_aviation_telegrams_one, and is useful for accessing the field via an interface.
func (v *newMessageResponse) GetInsert_aviation_telegrams_one() newMessageInsert_aviation_telegrams_oneAviation_telegrams {
return v.Insert_aviation_telegrams_one
}
// The query or mutation executed by newMessage.
const newMessage_Operation = `
mutation newMessage ($object: aviation_telegrams_insert_input!) {
insert_aviation_telegrams_one(object: $object) {
id
message_id
uuid
}
}
`
func newMessage(
ctx_ context.Context,
client_ graphql.Client,
object Aviation_telegrams_insert_input,
) (*newMessageResponse, error) {
req_ := &graphql.Request{
OpName: "newMessage",
Query: newMessage_Operation,
Variables: &__newMessageInput{
Object: object,
},
}
var err_ error
var data_ newMessageResponse
resp_ := &graphql.Response{Data: &data_}
err_ = client_.MakeRequest(
ctx_,
req_,
resp_,
)
return &data_, err_
}
+7
View File
@@ -0,0 +1,7 @@
mutation newMessage($object: aviation_telegrams_insert_input!) {
insert_aviation_telegrams_one(object: $object) {
id
message_id
uuid
}
}
+13
View File
@@ -0,0 +1,13 @@
# Default genqlient config; for full documentation see:
# https://github.com/Khan/genqlient/blob/main/docs/genqlient.yaml
schema: schema.graphql
operations:
- genqlient.graphql
generated: generated.go
bindings:
jsonb:
type: encoding/json.RawMessage
timestamp:
type: time.Time
uuid:
type: github.com/google/uuid.UUID
+180
View File
@@ -0,0 +1,180 @@
[
{
"SuitePath": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository",
"SuiteDescription": "Repositories Suite",
"SuiteLabels": [],
"SuiteSucceeded": true,
"SuiteHasProgrammaticFocus": false,
"SpecialSuiteFailureReasons": null,
"PreRunStats": {
"TotalSpecs": 3,
"SpecsThatWillRun": 1
},
"StartTime": "2024-07-23T11:25:30.889407931+08:00",
"EndTime": "2024-07-23T11:25:30.892377154+08:00",
"RunTime": 2969222,
"SuiteConfig": {
"RandomSeed": 1721705130,
"RandomizeAllSpecs": false,
"FocusStrings": [
"Repositories Hasura Repository should mutate a parsed message"
],
"SkipStrings": null,
"FocusFiles": null,
"SkipFiles": null,
"LabelFilter": "",
"FailOnPending": false,
"FailOnEmpty": false,
"FailFast": false,
"FlakeAttempts": 0,
"MustPassRepeatedly": 0,
"DryRun": false,
"PollProgressAfter": 0,
"PollProgressInterval": 0,
"Timeout": 3599523895104,
"EmitSpecProgress": false,
"OutputInterceptorMode": "",
"SourceRoots": null,
"GracePeriod": 30000000000,
"ParallelProcess": 1,
"ParallelTotal": 1,
"ParallelHost": ""
},
"SpecReports": [
{
"ContainerHierarchyTexts": [
"Repositories",
"Just a simple test"
],
"ContainerHierarchyLocations": [
{
"FileName": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository/hasura_test.go",
"LineNumber": 19
},
{
"FileName": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository/hasura_test.go",
"LineNumber": 20
}
],
"ContainerHierarchyLabels": [
[],
[]
],
"LeafNodeType": "It",
"LeafNodeLocation": {
"FileName": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository/hasura_test.go",
"LineNumber": 56
},
"LeafNodeLabels": [],
"LeafNodeText": "should not error",
"State": "skipped",
"StartTime": "2024-07-23T11:25:30.889468443+08:00",
"EndTime": "0001-01-01T00:00:00Z",
"RunTime": 0,
"ParallelProcess": 1,
"NumAttempts": 0,
"MaxFlakeAttempts": 0,
"MaxMustPassRepeatedly": 0
},
{
"ContainerHierarchyTexts": [
"Repositories",
"Just a simple test"
],
"ContainerHierarchyLocations": [
{
"FileName": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository/hasura_test.go",
"LineNumber": 19
},
{
"FileName": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository/hasura_test.go",
"LineNumber": 20
}
],
"ContainerHierarchyLabels": [
[],
[]
],
"LeafNodeType": "It",
"LeafNodeLocation": {
"FileName": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository/hasura_test.go",
"LineNumber": 60
},
"LeafNodeLabels": [],
"LeafNodeText": "name should be new",
"State": "skipped",
"StartTime": "2024-07-23T11:25:30.889483979+08:00",
"EndTime": "0001-01-01T00:00:00Z",
"RunTime": 0,
"ParallelProcess": 1,
"NumAttempts": 0,
"MaxFlakeAttempts": 0,
"MaxMustPassRepeatedly": 0
},
{
"ContainerHierarchyTexts": [
"Repositories",
"Hasura Repository"
],
"ContainerHierarchyLocations": [
{
"FileName": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository/hasura_test.go",
"LineNumber": 19
},
{
"FileName": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository/hasura_test.go",
"LineNumber": 66
}
],
"ContainerHierarchyLabels": [
[],
[]
],
"LeafNodeType": "It",
"LeafNodeLocation": {
"FileName": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository/hasura_test.go",
"LineNumber": 72
},
"LeafNodeLabels": [],
"LeafNodeText": "should mutate a parsed message",
"State": "passed",
"StartTime": "2024-07-23T11:25:30.889488379+08:00",
"EndTime": "2024-07-23T11:25:30.89235263+08:00",
"RunTime": 2864253,
"ParallelProcess": 1,
"NumAttempts": 1,
"MaxFlakeAttempts": 0,
"MaxMustPassRepeatedly": 0,
"SpecEvents": [
{
"SpecEventType": "Node",
"CodeLocation": {
"FileName": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository/hasura_test.go",
"LineNumber": 72
},
"TimelineLocation": {
"Order": 1,
"Time": "2024-07-23T11:25:30.889491289+08:00"
},
"Message": "should mutate a parsed message",
"NodeType": "It"
},
{
"SpecEventType": "Node (End)",
"CodeLocation": {
"FileName": "/home/windy/project/airport/projects/new-telegram/caatsm/internal/repository/hasura_test.go",
"LineNumber": 72
},
"TimelineLocation": {
"Order": 3,
"Time": "2024-07-23T11:25:30.892349748+08:00"
},
"Message": "should mutate a parsed message",
"Duration": 2858459,
"NodeType": "It"
}
]
}
]
}
]
+15 -37
View File
@@ -2,67 +2,45 @@ package repository
import (
"context"
"fmt"
"os"
"time"
"caatsm/internal/domain"
"github.com/hasura/go-graphql-client"
"github.com/Khan/genqlient/graphql"
"github.com/google/uuid"
"golang.org/x/oauth2"
)
type HasuraRepository struct {
hasuraClient *graphql.Client
client graphql.Client
}
// NewHasuraClient creates a new HasuraClient
// NewHasuraRepo creates a new HasuraRepository
func NewHasuraRepo(endpoint, secret string) *HasuraRepository {
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GRAPHQL_TOKEN")},
)
httpClient := oauth2.NewClient(context.Background(), src)
return &HasuraRepository{
hasuraClient: graphql.NewClient(endpoint, httpClient),
client: graphql.NewClient(endpoint, httpClient),
}
}
// InsertParsedMessage inserts a new ParsedMessage into the Hasura GraphQL API
func (hr *HasuraRepository) InsertParsedMessage(pm *domain.ParsedMessage) error {
if hr.hasuraClient == nil {
return fmt.Errorf("hasuraClient is nil")
variables := Aviation_telegrams_insert_input{
// Id: 10,
Body_and_footer: pm.BodyAndFooter,
// Body_data: pm.BodyData.(json.RawMessage),
Category: pm.Category,
Date_time: pm.DateTime,
Dispatched_at: pm.DispatchedAt,
Uuid: uuid.New(),
}
var mutation struct {
InsertParsedMessages struct {
Returning []domain.ParsedMessage `json:"returning"`
} `graphql:"insert_messages_one(object: {message_id: $messageId, date_time: $dateTime, priority_indicator: $priorityIndicator, primary_address: $primaryAddress, secondary_addresses: $secondaryAddresses, originator: $originator, originator_date_time: $originatorDateTime, category: $category, body_and_footer: $bodyAndFooter, body_data: $bodyData, received_at: $receivedAt, parsed_at: $parsedAt, need_dispatch: $needDispatch})"`
}
// Define the variables with their types
variables := map[string]interface{}{
"messageId": graphql.String(pm.MessageID),
"dateTime": graphql.String(pm.DateTime),
"priorityIndicator": graphql.String(pm.PriorityIndicator),
"primaryAddress": graphql.String(pm.PrimaryAddress),
"secondaryAddresses": graphql.String("second"),
"originator": graphql.String(pm.Originator),
"originatorDateTime": graphql.String(pm.OriginatorDateTime),
"category": graphql.String(pm.Category),
"bodyAndFooter": graphql.String(pm.BodyAndFooter),
"bodyData": graphql.String("{}"),
"receivedAt": pm.ReceivedAt.Format(time.RFC3339),
"parsedAt": pm.ParsedAt.Format(time.RFC3339),
// "dispatchedAt": pm.DispatchedAt.Format(time.RFC3339),
"needDispatch": graphql.Boolean(false),
}
ctx := context.Background()
// Execute the mutation with the variables
err := hr.hasuraClient.Mutate(ctx, &mutation, variables)
_, err := newMessage(context.Background(), hr.client, variables)
if err != nil {
return err
}
// fmt.Printf("Inserted new message with ID: %v\n", resp)
return nil
}
+50 -2
View File
@@ -2,9 +2,11 @@ package repository
import (
"caatsm/internal/domain"
"context"
"testing"
"time"
"github.com/hasura/go-graphql-client"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
@@ -15,6 +17,52 @@ func TestConfig(t *testing.T) {
}
var _ = Describe("Repositories", func() {
Context("Just a simple test", func() {
// Define a struct for the mutation input to match the expected GraphQL input
// Define a struct for the mutation input to match the expected GraphQL input
type aviation_user_insert_input struct {
Name graphql.String `json:"name"`
Email graphql.String `json:"email"`
UpdateAt graphql.String `json:"update_at"` // Use string for timestamp
}
// Get the current time in RFC3339 format
currentTime := time.Now().Format(time.RFC3339)
input := aviation_user_insert_input{
Name: graphql.String("new"),
Email: graphql.String("2@2.com"),
UpdateAt: graphql.String(currentTime), // Use formatted string
}
// Define the mutation
var mutation struct {
InsertAviationUserOne struct {
ID int `json:"id"`
Name string
} `graphql:"insert_aviation_user_one(object: $object)"`
}
// Define the mutation variables
// Define the mutation variables
variables := map[string]interface{}{
"object": input,
}
// Define the mutation
client := graphql.NewClient("http://localhost:8080/v1/graphql", nil)
err := client.Mutate(context.Background(), &mutation, variables)
It("should not error", func() {
Expect(err).NotTo(HaveOccurred())
})
It("name should be new", func() {
Expect(mutation.InsertAviationUserOne.Name).To(Equal("new"))
})
})
Context("Hasura Repository", func() {
// var repository *HasuraRepository
var uuid = "uuid"
@@ -34,8 +82,8 @@ var _ = Describe("Repositories", func() {
OriginatorDateTime: "originator_date_time",
Category: "category",
BodyAndFooter: "body_and_footer",
BodyData: nil,
ReceivedAt: time.Now(),
// BodyData: &interface{},
ReceivedAt: time.Now(),
}
err := repository.InsertParsedMessage(parseMessage)
Expect(err).NotTo(HaveOccurred())
File diff suppressed because it is too large Load Diff