prototyped svg reports
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
Tests / Go tests (push) Failing after 20s

This commit is contained in:
2026-08-20 00:35:13 -06:00
parent 4748eda41e
commit 50adc8e2de
106 changed files with 5450 additions and 46 deletions
+227
View File
@@ -2,9 +2,14 @@ package reports
import (
"context"
"fmt"
"slices"
"time"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
"ruben/inventory2/consts"
"ruben/inventory2/domains/accounts"
"ruben/inventory2/logging"
)
@@ -30,3 +35,225 @@ func NewStore(logger *logging.Logger, db *pgxpool.Pool, accts *accounts.Store) *
func (db *Store) WithContext(ctx context.Context) *StoreWithContext {
return NewStoreWithContext(ctx, db)
}
// TODO: prefix all these names with 'mock' since they're all mock stuff
type (
ListingCountsOverTimeReport struct {
AccountID int64
Platform accounts.Platform
ShopID string
ListingID string
Counts []ListingCountAtTime
}
ListingCountAtTime struct {
EventTimestamp *time.Time
Count int64
}
)
func (r ListingCountsOverTimeReport) MaxCount() ListingCountAtTime {
if len(r.Counts) == 0 {
return ListingCountAtTime{}
}
return slices.MaxFunc(r.Counts, func(a, b ListingCountAtTime) int {
return int(a.Count - b.Count)
})
}
func (r ListingCountsOverTimeReport) MinCount() ListingCountAtTime {
if len(r.Counts) == 0 {
return ListingCountAtTime{}
}
return slices.MinFunc(r.Counts, func(a, b ListingCountAtTime) int {
return int(a.Count - b.Count)
})
}
func (db *Store) GetListingCountsReport(ctx context.Context, acctID int64, platform accounts.Platform, shopID, listingID string) (*ListingCountsOverTimeReport, error) {
counts, err := db.GetListingCountsOverTime(ctx, acctID, platform, shopID, listingID)
if err != nil {
return nil, err
}
return &ListingCountsOverTimeReport{
AccountID: acctID,
Platform: platform,
ShopID: shopID,
ListingID: listingID,
Counts: counts,
}, nil
}
func (db *Store) GetListingCountsOverTime(ctx context.Context, acctID int64, platform accounts.Platform, shopID, listingID string) ([]ListingCountAtTime, error) {
info, ok := getMockShopSchemaInfo(platform)
if !ok {
return nil, consts.ErrNotFound
}
var counts []ListingCountAtTime
err := pgx.BeginTxFunc(ctx, db.db, pgx.TxOptions{
AccessMode: pgx.ReadOnly,
}, func(tx pgx.Tx) error {
rows, err := tx.Query(
ctx,
fmt.Sprintf(
`
SELECT
1
FROM
%s
WHERE
shop_id = @shop_id
AND listing_id = @listing_id
`,
info.listingsTable,
),
pgx.NamedArgs{
"shop_id": shopID,
"listing_id": listingID,
},
)
if err != nil {
return fmt.Errorf("failed to perform query to check the existing of the listing: %w", err)
}
if _, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[int]); err != nil {
return fmt.Errorf("listing not found: %w", consts.ErrNotFound)
}
rows, err = tx.Query(
ctx,
fmt.Sprintf(
`
SELECT
event_timestamp AS eventTimestamp,
"count"
FROM
%s
WHERE
shop_id = @shop_id
AND listing_id = @listing_id
`,
info.listingCountsView,
),
pgx.NamedArgs{
"shop_id": shopID,
"listing_id": listingID,
},
)
if err != nil {
return fmt.Errorf("failed to perform query: %w", err)
}
if counts, err = pgx.CollectRows(rows, pgx.RowToStructByNameLax[ListingCountAtTime]); err != nil {
return fmt.Errorf("failed to scan rows: %w", err)
}
return nil
})
return counts, err
}
type mockShopSchemaInfo struct {
platform accounts.Platform
shopTable string
listingsTable string
listingCountsView string
}
func getMockShopSchemaInfo(platform accounts.Platform) (mockShopSchemaInfo, bool) {
for _, in := range getAllMockShopSchemaInfos() {
if in.platform == platform {
return in, true
}
}
return mockShopSchemaInfo{}, false
}
func getAllMockShopSchemaInfos() []mockShopSchemaInfo {
return []mockShopSchemaInfo{
{
platform: accounts.Amazon,
shopTable: "mock.shop_amazon",
listingsTable: "mock.shop_amazon_listings",
listingCountsView: "mock.shop_amazon_listing_counts",
},
{
platform: accounts.BigCartel,
shopTable: "mock.shop_big_cartel",
listingsTable: "mock.shop_big_cartel_listings",
listingCountsView: "mock.shop_big_cartel_listing_counts",
},
{
platform: accounts.Ebay,
shopTable: "mock.shop_ebay",
listingsTable: "mock.shop_ebay_listings",
listingCountsView: "mock.shop_ebay_listing_counts",
},
{
platform: accounts.Ecwid,
shopTable: "mock.shop_ecwid",
listingsTable: "mock.shop_ecwid_listings",
listingCountsView: "mock.shop_ecwid_listing_counts",
},
{
platform: accounts.Etsy,
shopTable: "mock.shop_etsy",
listingsTable: "mock.shop_etsy_listings",
listingCountsView: "mock.shop_etsy_listing_counts",
},
{
platform: accounts.Shopify,
shopTable: "mock.shop_shopify",
listingsTable: "mock.shop_shopify_listings",
listingCountsView: "mock.shop_shopify_listing_counts",
},
{
platform: accounts.SquareOnline,
shopTable: "mock.shop_square_online",
listingsTable: "mock.shop_square_online_listings",
listingCountsView: "mock.shop_square_online_listing_counts",
},
{
platform: accounts.Squarespace,
shopTable: "mock.shop_squarespace",
listingsTable: "mock.shop_squarespace_listings",
listingCountsView: "mock.shop_squarespace_listing_counts",
},
{
platform: accounts.Tiktok,
shopTable: "mock.shop_tiktok",
listingsTable: "mock.shop_tiktok_listings",
listingCountsView: "mock.shop_tiktok_listing_counts",
},
{
platform: accounts.WalmartMarketplace,
shopTable: "mock.shop_walmart_marketplace",
listingsTable: "mock.shop_walmart_marketplace_listings",
listingCountsView: "mock.shop_walmart_marketplace_listing_counts",
},
{
platform: accounts.Wix,
shopTable: "mock.shop_wix",
listingsTable: "mock.shop_wix_listings",
listingCountsView: "mock.shop_wix_listing_counts",
},
{
platform: accounts.WooCommerce,
shopTable: "mock.shop_woo_commerce",
listingsTable: "mock.shop_woo_commerce_listings",
listingCountsView: "mock.shop_woo_commerce_listing_counts",
},
{
platform: accounts.Zoho,
shopTable: "mock.shop_zoho",
listingsTable: "mock.shop_zoho_listings",
listingCountsView: "mock.shop_zoho_listing_counts",
},
}
}
+8
View File
@@ -23,3 +23,11 @@ func NewStoreWithContext(ctx context.Context, v *Store) *StoreWithContext {
func (v_ctx *StoreWithContext) GetRawShopEvents(acctID int64, platform accounts.Platform, shopID string) ([]RawShopEvent, error) {
return v_ctx.Store.GetRawShopEvents(v_ctx.ctx, acctID, platform, shopID)
}
func (v_ctx *StoreWithContext) GetListingCountsReport(acctID int64, platform accounts.Platform, shopID string, listingID string) (*ListingCountsOverTimeReport, error) {
return v_ctx.Store.GetListingCountsReport(v_ctx.ctx, acctID, platform, shopID, listingID)
}
func (v_ctx *StoreWithContext) GetListingCountsOverTime(acctID int64, platform accounts.Platform, shopID string, listingID string) ([]ListingCountAtTime, error) {
return v_ctx.Store.GetListingCountsOverTime(v_ctx.ctx, acctID, platform, shopID, listingID)
}