saved mock listing
This commit is contained in:
@@ -0,0 +1,34 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE mock.shop_etsy_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_ebay_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_walmart_marketplace_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_amazon_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_big_cartel_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_ecwid_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_zoho_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_square_online_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_squarespace_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_wix_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_woo_commerce_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_shopify_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
ALTER TABLE mock.shop_tiktok_listings
|
||||||
|
DROP COLUMN "count";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE mock.shop_tiktok_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_shopify_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_woo_commerce_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_wix_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_squarespace_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_square_online_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_zoho_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_ecwid_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_big_cartel_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_amazon_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_walmart_marketplace_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_ebay_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_etsy_listings
|
||||||
|
ADD COLUMN "count" INTEGER NOT NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE mock.shop_etsy_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_ebay_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_walmart_marketplace_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_amazon_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_big_cartel_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_ecwid_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_zoho_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_square_online_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_squarespace_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_wix_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_woo_commerce_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_shopify_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
ALTER TABLE mock.shop_tiktok_listings
|
||||||
|
DROP COLUMN sku,
|
||||||
|
DROP COLUMN description;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE mock.shop_tiktok_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_shopify_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_woo_commerce_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_wix_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_squarespace_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_square_online_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_zoho_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_ecwid_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_big_cartel_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_amazon_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_walmart_marketplace_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_ebay_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
ALTER TABLE mock.shop_etsy_listings
|
||||||
|
ADD COLUMN sku TEXT NOT NULL,
|
||||||
|
ADD COLUMN description TEXT NOT NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 225 KiB After Width: | Height: | Size: 245 KiB |
@@ -23,6 +23,9 @@ entity "**shop_amazon_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_amazon_sync_group_listings**" {
|
entity "**shop_amazon_sync_group_listings**" {
|
||||||
@@ -48,6 +51,9 @@ entity "**shop_big_cartel_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_big_cartel_sync_group_listings**" {
|
entity "**shop_big_cartel_sync_group_listings**" {
|
||||||
@@ -73,6 +79,9 @@ entity "**shop_ebay_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_ebay_sync_group_listings**" {
|
entity "**shop_ebay_sync_group_listings**" {
|
||||||
@@ -98,6 +107,9 @@ entity "**shop_ecwid_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_ecwid_sync_group_listings**" {
|
entity "**shop_ecwid_sync_group_listings**" {
|
||||||
@@ -123,6 +135,9 @@ entity "**shop_etsy_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_etsy_sync_group_listings**" {
|
entity "**shop_etsy_sync_group_listings**" {
|
||||||
@@ -148,6 +163,9 @@ entity "**shop_shopify_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_shopify_sync_group_listings**" {
|
entity "**shop_shopify_sync_group_listings**" {
|
||||||
@@ -173,6 +191,9 @@ entity "**shop_square_online_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_square_online_sync_group_listings**" {
|
entity "**shop_square_online_sync_group_listings**" {
|
||||||
@@ -198,6 +219,9 @@ entity "**shop_squarespace_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_squarespace_sync_group_listings**" {
|
entity "**shop_squarespace_sync_group_listings**" {
|
||||||
@@ -223,6 +247,9 @@ entity "**shop_tiktok_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_tiktok_sync_group_listings**" {
|
entity "**shop_tiktok_sync_group_listings**" {
|
||||||
@@ -248,6 +275,9 @@ entity "**shop_walmart_marketplace_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_walmart_marketplace_sync_group_listings**" {
|
entity "**shop_walmart_marketplace_sync_group_listings**" {
|
||||||
@@ -273,6 +303,9 @@ entity "**shop_wix_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_wix_sync_group_listings**" {
|
entity "**shop_wix_sync_group_listings**" {
|
||||||
@@ -298,6 +331,9 @@ entity "**shop_woo_commerce_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_woo_commerce_sync_group_listings**" {
|
entity "**shop_woo_commerce_sync_group_listings**" {
|
||||||
@@ -323,6 +359,9 @@ entity "**shop_zoho_listings**" {
|
|||||||
--
|
--
|
||||||
*""account_id"": //integer [FK]//
|
*""account_id"": //integer [FK]//
|
||||||
*""name"": //text //
|
*""name"": //text //
|
||||||
|
*""count"": //integer //
|
||||||
|
*""sku"": //text //
|
||||||
|
*""description"": //text //
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "**shop_zoho_sync_group_listings**" {
|
entity "**shop_zoho_sync_group_listings**" {
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"ruben/inventory2/internal/consts"
|
"ruben/inventory2/internal/consts"
|
||||||
"ruben/inventory2/internal/logging"
|
"ruben/inventory2/internal/logging"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
)
|
)
|
||||||
@@ -43,28 +42,6 @@ type (
|
|||||||
Description string
|
Description string
|
||||||
Count int64
|
Count int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// ids
|
|
||||||
|
|
||||||
AccountIDs struct {
|
|
||||||
AccountID int64
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountShopIDs struct {
|
|
||||||
AccountIDs
|
|
||||||
Platform Platform
|
|
||||||
ShopID string
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountShopListingIDs struct {
|
|
||||||
AccountShopIDs
|
|
||||||
ListingID string
|
|
||||||
}
|
|
||||||
|
|
||||||
MockShop struct {
|
|
||||||
AccountShopIDs
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewStore(logger *logging.Logger, db *pgxpool.Pool) *Store {
|
func NewStore(logger *logging.Logger, db *pgxpool.Pool) *Store {
|
||||||
@@ -315,258 +292,6 @@ func (db *Store) GetListingsForShop(ctx context.Context, acctID int64, platform
|
|||||||
return vs, nil
|
return vs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Store) CreateMockShop(ctx context.Context, acctID int64, platform Platform, name string) (shopID uuid.UUID, err error) {
|
|
||||||
shopTableName, err := getMockShopTableName(platform)
|
|
||||||
if err != nil {
|
|
||||||
return uuid.Nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
tx, err := db.db.Begin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return uuid.Nil, fmt.Errorf("failed to being transaction: %w", err)
|
|
||||||
}
|
|
||||||
defer tx.Rollback(ctx)
|
|
||||||
|
|
||||||
// TODO: are we really going to just copy the id between accounts and mock.accounts?
|
|
||||||
|
|
||||||
// upsert mock account
|
|
||||||
|
|
||||||
rows, err := tx.Query(
|
|
||||||
ctx,
|
|
||||||
`
|
|
||||||
WITH existing_account(account_id, user_id) AS (
|
|
||||||
SELECT
|
|
||||||
account_id,
|
|
||||||
user_id
|
|
||||||
FROM
|
|
||||||
accounts
|
|
||||||
WHERE
|
|
||||||
account_id = @account_id
|
|
||||||
), existing_mock_account AS (
|
|
||||||
SELECT
|
|
||||||
user_id
|
|
||||||
FROM
|
|
||||||
accounts
|
|
||||||
WHERE
|
|
||||||
account_id = @account_id
|
|
||||||
), inserted_mock_account AS (
|
|
||||||
INSERT INTO
|
|
||||||
mock.accounts (
|
|
||||||
account_id,
|
|
||||||
user_id
|
|
||||||
)
|
|
||||||
SELECT
|
|
||||||
account_id,
|
|
||||||
user_id
|
|
||||||
FROM
|
|
||||||
existing_account
|
|
||||||
ON CONFLICT
|
|
||||||
DO NOTHING
|
|
||||||
RETURNING
|
|
||||||
user_id
|
|
||||||
)
|
|
||||||
SELECT
|
|
||||||
COALESCE(ia.user_id, ea.user_id)
|
|
||||||
FROM
|
|
||||||
inserted_mock_account ia
|
|
||||||
FULL OUTER JOIN
|
|
||||||
existing_mock_account ea
|
|
||||||
USING
|
|
||||||
(user_id)
|
|
||||||
`,
|
|
||||||
pgx.NamedArgs{
|
|
||||||
"account_id": acctID,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return uuid.Nil, fmt.Errorf("test query failed: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
userID, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[string])
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, pgx.ErrNoRows) {
|
|
||||||
return uuid.Nil, fmt.Errorf("%w: account not found", consts.ErrNotFound)
|
|
||||||
}
|
|
||||||
return uuid.Nil, fmt.Errorf("failed to scan rows: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the mock shop
|
|
||||||
|
|
||||||
shopID = uuid.New()
|
|
||||||
|
|
||||||
_, err = tx.Exec(
|
|
||||||
ctx,
|
|
||||||
fmt.Sprintf(
|
|
||||||
`
|
|
||||||
INSERT INTO
|
|
||||||
%s (
|
|
||||||
user_id,
|
|
||||||
account_id,
|
|
||||||
shop_id,
|
|
||||||
name
|
|
||||||
)
|
|
||||||
VALUES (
|
|
||||||
@user_id,
|
|
||||||
@account_id,
|
|
||||||
@shop_id,
|
|
||||||
@name
|
|
||||||
)
|
|
||||||
`,
|
|
||||||
shopTableName,
|
|
||||||
),
|
|
||||||
pgx.NamedArgs{
|
|
||||||
"account_id": acctID,
|
|
||||||
"user_id": userID,
|
|
||||||
"shop_id": shopID,
|
|
||||||
"name": name,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return uuid.Nil, fmt.Errorf("failed to perform query to create mock shop: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := tx.Commit(ctx); err != nil {
|
|
||||||
return uuid.Nil, fmt.Errorf("failed to commit transaction: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return shopID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *Store) ListMockShopsForPlatform(ctx context.Context, acctID int64, platform Platform) ([]MockShop, error) {
|
|
||||||
shopTableName, err := getMockShopTableName(platform)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, err := db.db.Query(
|
|
||||||
ctx,
|
|
||||||
fmt.Sprintf(
|
|
||||||
`
|
|
||||||
SELECT
|
|
||||||
shop_id,
|
|
||||||
name
|
|
||||||
FROM
|
|
||||||
%s
|
|
||||||
WHERE
|
|
||||||
account_id = @account_id
|
|
||||||
`,
|
|
||||||
shopTableName,
|
|
||||||
),
|
|
||||||
pgx.NamedArgs{
|
|
||||||
"account_id": acctID,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to perform query: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
vs, err := pgx.CollectRows(rows, pgx.RowToStructByNameLax[struct {
|
|
||||||
Shop_id uuid.UUID
|
|
||||||
Name string
|
|
||||||
}])
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to scan rows: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
shops := make([]MockShop, len(vs))
|
|
||||||
for i, v := range vs {
|
|
||||||
shops[i] = MockShop{
|
|
||||||
AccountShopIDs: AccountShopIDs{
|
|
||||||
AccountIDs: AccountIDs{
|
|
||||||
AccountID: acctID,
|
|
||||||
},
|
|
||||||
Platform: platform,
|
|
||||||
ShopID: v.Shop_id.String(),
|
|
||||||
},
|
|
||||||
Name: v.Name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return shops, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *Store) GetMockShop(ctx context.Context, acctID int64, platform Platform, shopID string) (*MockShop, error) {
|
|
||||||
shopTableName, err := getMockShopTableName(platform)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, err := db.db.Query(
|
|
||||||
ctx,
|
|
||||||
fmt.Sprintf(
|
|
||||||
`
|
|
||||||
SELECT
|
|
||||||
name
|
|
||||||
FROM
|
|
||||||
%s
|
|
||||||
WHERE
|
|
||||||
account_id = @account_id
|
|
||||||
AND shop_id = @shop_id
|
|
||||||
`,
|
|
||||||
shopTableName,
|
|
||||||
),
|
|
||||||
pgx.NamedArgs{
|
|
||||||
"account_id": acctID,
|
|
||||||
"shop_id": shopID,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to perform query: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
name, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[string])
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, pgx.ErrNoRows) {
|
|
||||||
return nil, consts.ErrNotFound
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("failed to scan rows: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &MockShop{
|
|
||||||
AccountShopIDs: AccountShopIDs{
|
|
||||||
AccountIDs: AccountIDs{
|
|
||||||
AccountID: acctID,
|
|
||||||
},
|
|
||||||
Platform: platform,
|
|
||||||
ShopID: shopID,
|
|
||||||
},
|
|
||||||
Name: name,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMockShopTableName(platform Platform) (string, error) {
|
|
||||||
switch platform {
|
|
||||||
case Amazon:
|
|
||||||
return "mock.shop_amazon", nil
|
|
||||||
case BigCartel:
|
|
||||||
return "mock.shop_big_cartel", nil
|
|
||||||
case Ebay:
|
|
||||||
return "mock.shop_ebay", nil
|
|
||||||
case Ecwid:
|
|
||||||
return "mock.shop_ecwid", nil
|
|
||||||
case Etsy:
|
|
||||||
return "mock.shop_etsy", nil
|
|
||||||
case Shopify:
|
|
||||||
return "mock.shop_shopify", nil
|
|
||||||
case SquareOnline:
|
|
||||||
return "mock.shop_square_online", nil
|
|
||||||
case Squarespace:
|
|
||||||
return "mock.shop_squarespace", nil
|
|
||||||
case Tiktok:
|
|
||||||
return "mock.shop_tiktok", nil
|
|
||||||
case WalmartMarketplace:
|
|
||||||
return "mock.shop_walmart_marketplace", nil
|
|
||||||
case Wix:
|
|
||||||
return "mock.shop_wix", nil
|
|
||||||
case WooCommerce:
|
|
||||||
return "mock.shop_woo_commerce", nil
|
|
||||||
case Zoho:
|
|
||||||
return "mock.shop_zoho", nil
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("%w: unrecognized platform", consts.ErrBadRequest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// additional context
|
// additional context
|
||||||
|
|
||||||
func (db *Store) GetAccountPointerByUserID(ctx context.Context, userID string) (*Account, error) {
|
func (db *Store) GetAccountPointerByUserID(ctx context.Context, userID string) (*Account, error) {
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package accounts
|
||||||
|
|
||||||
|
type (
|
||||||
|
AccountIDs struct {
|
||||||
|
AccountID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountShopIDs struct {
|
||||||
|
AccountIDs
|
||||||
|
Platform Platform
|
||||||
|
ShopID string
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountShopListingIDs struct {
|
||||||
|
AccountShopIDs
|
||||||
|
ListingID string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewAccountIDs(acctID int64) AccountIDs {
|
||||||
|
return AccountIDs{
|
||||||
|
AccountID: acctID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ids AccountIDs) ShopID(p Platform, id string) AccountShopIDs {
|
||||||
|
return AccountShopIDs{
|
||||||
|
AccountIDs: ids,
|
||||||
|
Platform: p,
|
||||||
|
ShopID: id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ids AccountShopIDs) ListingID(id string) AccountShopListingIDs {
|
||||||
|
return AccountShopListingIDs{
|
||||||
|
AccountShopIDs: ids,
|
||||||
|
ListingID: id,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,457 @@
|
|||||||
|
package accounts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"ruben/inventory2/internal/consts"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
MockShop struct {
|
||||||
|
AccountShopIDs
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
MockListing struct {
|
||||||
|
AccountShopListingIDs
|
||||||
|
SKU string
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
Count int64
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (db *Store) CreateMockShop(ctx context.Context, acctID int64, platform Platform, name string) (shopID uuid.UUID, err error) {
|
||||||
|
shopTableName, err := getMockShopTableName(platform)
|
||||||
|
if err != nil {
|
||||||
|
return uuid.Nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tx, err := db.db.Begin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return uuid.Nil, fmt.Errorf("failed to being transaction: %w", err)
|
||||||
|
}
|
||||||
|
defer tx.Rollback(ctx)
|
||||||
|
|
||||||
|
// TODO: are we really going to just copy the id between accounts and mock.accounts?
|
||||||
|
|
||||||
|
// upsert mock account
|
||||||
|
|
||||||
|
rows, err := tx.Query(
|
||||||
|
ctx,
|
||||||
|
`
|
||||||
|
WITH existing_account(account_id, user_id) AS (
|
||||||
|
SELECT
|
||||||
|
account_id,
|
||||||
|
user_id
|
||||||
|
FROM
|
||||||
|
accounts
|
||||||
|
WHERE
|
||||||
|
account_id = @account_id
|
||||||
|
), existing_mock_account AS (
|
||||||
|
SELECT
|
||||||
|
user_id
|
||||||
|
FROM
|
||||||
|
accounts
|
||||||
|
WHERE
|
||||||
|
account_id = @account_id
|
||||||
|
), inserted_mock_account AS (
|
||||||
|
INSERT INTO
|
||||||
|
mock.accounts (
|
||||||
|
account_id,
|
||||||
|
user_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
account_id,
|
||||||
|
user_id
|
||||||
|
FROM
|
||||||
|
existing_account
|
||||||
|
ON CONFLICT
|
||||||
|
DO NOTHING
|
||||||
|
RETURNING
|
||||||
|
user_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
COALESCE(ia.user_id, ea.user_id)
|
||||||
|
FROM
|
||||||
|
inserted_mock_account ia
|
||||||
|
FULL OUTER JOIN
|
||||||
|
existing_mock_account ea
|
||||||
|
USING
|
||||||
|
(user_id)
|
||||||
|
`,
|
||||||
|
pgx.NamedArgs{
|
||||||
|
"account_id": acctID,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return uuid.Nil, fmt.Errorf("failed to perform query: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
userID, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[string])
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, pgx.ErrNoRows) {
|
||||||
|
return uuid.Nil, fmt.Errorf("%w: account not found", consts.ErrNotFound)
|
||||||
|
}
|
||||||
|
return uuid.Nil, fmt.Errorf("failed to scan rows: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the mock shop
|
||||||
|
|
||||||
|
shopID = uuid.New()
|
||||||
|
|
||||||
|
_, err = tx.Exec(
|
||||||
|
ctx,
|
||||||
|
fmt.Sprintf(
|
||||||
|
`
|
||||||
|
INSERT INTO
|
||||||
|
%s (
|
||||||
|
user_id,
|
||||||
|
account_id,
|
||||||
|
shop_id,
|
||||||
|
name
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
@user_id,
|
||||||
|
@account_id,
|
||||||
|
@shop_id,
|
||||||
|
@name
|
||||||
|
)
|
||||||
|
`,
|
||||||
|
shopTableName,
|
||||||
|
),
|
||||||
|
pgx.NamedArgs{
|
||||||
|
"account_id": acctID,
|
||||||
|
"user_id": userID,
|
||||||
|
"shop_id": shopID,
|
||||||
|
"name": name,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return uuid.Nil, fmt.Errorf("failed to perform query to create mock shop: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.Commit(ctx); err != nil {
|
||||||
|
return uuid.Nil, fmt.Errorf("failed to commit transaction: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return shopID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Store) ListMockShopsForPlatform(ctx context.Context, acctID int64, platform Platform) ([]MockShop, error) {
|
||||||
|
shopTableName, err := getMockShopTableName(platform)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := db.db.Query(
|
||||||
|
ctx,
|
||||||
|
fmt.Sprintf(
|
||||||
|
`
|
||||||
|
SELECT
|
||||||
|
shop_id,
|
||||||
|
name
|
||||||
|
FROM
|
||||||
|
%s
|
||||||
|
WHERE
|
||||||
|
account_id = @account_id
|
||||||
|
`,
|
||||||
|
shopTableName,
|
||||||
|
),
|
||||||
|
pgx.NamedArgs{
|
||||||
|
"account_id": acctID,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to perform query: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
vs, err := pgx.CollectRows(rows, pgx.RowToStructByNameLax[struct {
|
||||||
|
Shop_id uuid.UUID
|
||||||
|
Name string
|
||||||
|
}])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to scan rows: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
shops := make([]MockShop, len(vs))
|
||||||
|
for i, v := range vs {
|
||||||
|
shops[i] = MockShop{
|
||||||
|
AccountShopIDs: AccountShopIDs{
|
||||||
|
AccountIDs: AccountIDs{
|
||||||
|
AccountID: acctID,
|
||||||
|
},
|
||||||
|
Platform: platform,
|
||||||
|
ShopID: v.Shop_id.String(),
|
||||||
|
},
|
||||||
|
Name: v.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return shops, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Store) GetMockShop(ctx context.Context, acctID int64, platform Platform, shopID string) (*MockShop, error) {
|
||||||
|
shopTableName, err := getMockShopTableName(platform)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := db.db.Query(
|
||||||
|
ctx,
|
||||||
|
fmt.Sprintf(
|
||||||
|
`
|
||||||
|
SELECT
|
||||||
|
name
|
||||||
|
FROM
|
||||||
|
%s
|
||||||
|
WHERE
|
||||||
|
account_id = @account_id
|
||||||
|
AND shop_id = @shop_id
|
||||||
|
`,
|
||||||
|
shopTableName,
|
||||||
|
),
|
||||||
|
pgx.NamedArgs{
|
||||||
|
"account_id": acctID,
|
||||||
|
"shop_id": shopID,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to perform query: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
name, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[string])
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, pgx.ErrNoRows) {
|
||||||
|
return nil, consts.ErrNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("failed to scan rows: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &MockShop{
|
||||||
|
AccountShopIDs: AccountShopIDs{
|
||||||
|
AccountIDs: AccountIDs{
|
||||||
|
AccountID: acctID,
|
||||||
|
},
|
||||||
|
Platform: platform,
|
||||||
|
ShopID: shopID,
|
||||||
|
},
|
||||||
|
Name: name,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Store) CreateMockListing(ctx context.Context, listing MockListing) (MockListing, error) {
|
||||||
|
shopTableName, listingTableName, err := getMockShopAndListingsTableNames(listing.Platform)
|
||||||
|
if err != nil {
|
||||||
|
return MockListing{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
listing.ListingID = uuid.New().String()
|
||||||
|
|
||||||
|
tag, err := db.db.Exec(
|
||||||
|
ctx,
|
||||||
|
fmt.Sprintf(
|
||||||
|
`
|
||||||
|
WITH existing_shop(account_id, shop_id) AS (
|
||||||
|
SELECT
|
||||||
|
account_id,
|
||||||
|
shop_id
|
||||||
|
FROM
|
||||||
|
%s
|
||||||
|
WHERE
|
||||||
|
account_id = @account_id
|
||||||
|
AND shop_id = @shop_id
|
||||||
|
), new_values(listing_id, sku, name, description, "count") AS (
|
||||||
|
SELECT
|
||||||
|
@listing_id::text,
|
||||||
|
@sku::text,
|
||||||
|
@name::text,
|
||||||
|
@description::text,
|
||||||
|
@count::integer
|
||||||
|
)
|
||||||
|
INSERT INTO
|
||||||
|
%s (
|
||||||
|
account_id,
|
||||||
|
shop_id,
|
||||||
|
listing_id,
|
||||||
|
sku,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
count
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
account_id,
|
||||||
|
shop_id,
|
||||||
|
listing_id,
|
||||||
|
sku,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
"count"
|
||||||
|
FROM
|
||||||
|
existing_shop
|
||||||
|
JOIN
|
||||||
|
new_values
|
||||||
|
ON
|
||||||
|
true
|
||||||
|
`,
|
||||||
|
shopTableName,
|
||||||
|
listingTableName,
|
||||||
|
),
|
||||||
|
pgx.NamedArgs{
|
||||||
|
"account_id": listing.AccountID,
|
||||||
|
"shop_id": listing.ShopID,
|
||||||
|
"listing_id": listing.ListingID,
|
||||||
|
"sku": listing.SKU,
|
||||||
|
"name": listing.Name,
|
||||||
|
"description": listing.Description,
|
||||||
|
"count": listing.Count + 5,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return MockListing{}, fmt.Errorf("failed to perform query: %w", err)
|
||||||
|
}
|
||||||
|
if tag.RowsAffected() == 0 {
|
||||||
|
return MockListing{}, fmt.Errorf("%w: shop not found", consts.ErrNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
return listing, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Store) ListMockListingsForShop(ctx context.Context, acctID int64, platform Platform, shopID string) ([]MockListing, error) {
|
||||||
|
shopTableName, listingsTableName, err := getMockShopAndListingsTableNames(platform)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := db.db.Query(
|
||||||
|
ctx,
|
||||||
|
fmt.Sprintf(
|
||||||
|
`
|
||||||
|
WITH shop_exists(shop_exists) AS (
|
||||||
|
SELECT
|
||||||
|
true
|
||||||
|
FROM
|
||||||
|
%s
|
||||||
|
WHERE
|
||||||
|
account_id = @account_id
|
||||||
|
AND shop_id = @shop_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
COALESCE(shop_exists, false) AS shop_exists,
|
||||||
|
listing_id,
|
||||||
|
sku,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
"count"
|
||||||
|
FROM
|
||||||
|
shop_exists
|
||||||
|
LEFT JOIN
|
||||||
|
%s
|
||||||
|
ON
|
||||||
|
TRUE
|
||||||
|
WHERE
|
||||||
|
account_id = @account_id
|
||||||
|
AND shop_id = @shop_id
|
||||||
|
`,
|
||||||
|
shopTableName,
|
||||||
|
listingsTableName,
|
||||||
|
),
|
||||||
|
pgx.NamedArgs{
|
||||||
|
"account_id": acctID,
|
||||||
|
"shop_id": shopID,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to perform query: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
vs, err := pgx.CollectRows(rows, pgx.RowToStructByNameLax[struct {
|
||||||
|
Shop_exists bool
|
||||||
|
Listing_id string
|
||||||
|
SKU string
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
Count int64
|
||||||
|
}])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to scan rows: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the shop exists, and confirm there were actually listings (LEFT JOIN)
|
||||||
|
|
||||||
|
if len(vs) == 0 || !vs[0].Shop_exists {
|
||||||
|
return nil, fmt.Errorf("%w: shop not found", consts.ErrNotFound)
|
||||||
|
}
|
||||||
|
if vs[0].SKU == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
listings := make([]MockListing, len(vs))
|
||||||
|
for i, v := range vs {
|
||||||
|
listings[i] = MockListing{
|
||||||
|
AccountShopListingIDs: AccountShopListingIDs{
|
||||||
|
AccountShopIDs: AccountShopIDs{
|
||||||
|
AccountIDs: AccountIDs{
|
||||||
|
AccountID: acctID,
|
||||||
|
},
|
||||||
|
Platform: platform,
|
||||||
|
ShopID: shopID,
|
||||||
|
},
|
||||||
|
ListingID: v.Listing_id,
|
||||||
|
},
|
||||||
|
SKU: v.SKU,
|
||||||
|
Name: v.Name,
|
||||||
|
Description: v.Description,
|
||||||
|
Count: v.Count,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return listings, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMockShopTableName(platform Platform) (string, error) {
|
||||||
|
switch platform {
|
||||||
|
case Amazon:
|
||||||
|
return "mock.shop_amazon", nil
|
||||||
|
case BigCartel:
|
||||||
|
return "mock.shop_big_cartel", nil
|
||||||
|
case Ebay:
|
||||||
|
return "mock.shop_ebay", nil
|
||||||
|
case Ecwid:
|
||||||
|
return "mock.shop_ecwid", nil
|
||||||
|
case Etsy:
|
||||||
|
return "mock.shop_etsy", nil
|
||||||
|
case Shopify:
|
||||||
|
return "mock.shop_shopify", nil
|
||||||
|
case SquareOnline:
|
||||||
|
return "mock.shop_square_online", nil
|
||||||
|
case Squarespace:
|
||||||
|
return "mock.shop_squarespace", nil
|
||||||
|
case Tiktok:
|
||||||
|
return "mock.shop_tiktok", nil
|
||||||
|
case WalmartMarketplace:
|
||||||
|
return "mock.shop_walmart_marketplace", nil
|
||||||
|
case Wix:
|
||||||
|
return "mock.shop_wix", nil
|
||||||
|
case WooCommerce:
|
||||||
|
return "mock.shop_woo_commerce", nil
|
||||||
|
case Zoho:
|
||||||
|
return "mock.shop_zoho", nil
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("%w: unrecognized platform", consts.ErrBadRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMockShopAndListingsTableNames(platform Platform) (shop string, listing string, err error) {
|
||||||
|
shop, err = getMockShopTableName(platform)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return shop, shop + "_listings", nil
|
||||||
|
|
||||||
|
}
|
||||||
@@ -48,6 +48,10 @@ func (v_ctx *StoreWithContext) GetListingsForShop(acctID int64, platform Platfor
|
|||||||
return v_ctx.Store.GetListingsForShop(v_ctx.ctx, acctID, platform, shopID)
|
return v_ctx.Store.GetListingsForShop(v_ctx.ctx, acctID, platform, shopID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v_ctx *StoreWithContext) GetAccountPointerByUserID(userID string) (*Account, error) {
|
||||||
|
return v_ctx.Store.GetAccountPointerByUserID(v_ctx.ctx, userID)
|
||||||
|
}
|
||||||
|
|
||||||
func (v_ctx *StoreWithContext) CreateMockShop(acctID int64, platform Platform, name string) (uuid.UUID, error) {
|
func (v_ctx *StoreWithContext) CreateMockShop(acctID int64, platform Platform, name string) (uuid.UUID, error) {
|
||||||
return v_ctx.Store.CreateMockShop(v_ctx.ctx, acctID, platform, name)
|
return v_ctx.Store.CreateMockShop(v_ctx.ctx, acctID, platform, name)
|
||||||
}
|
}
|
||||||
@@ -60,8 +64,12 @@ func (v_ctx *StoreWithContext) GetMockShop(acctID int64, platform Platform, shop
|
|||||||
return v_ctx.Store.GetMockShop(v_ctx.ctx, acctID, platform, shopID)
|
return v_ctx.Store.GetMockShop(v_ctx.ctx, acctID, platform, shopID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v_ctx *StoreWithContext) GetAccountPointerByUserID(userID string) (*Account, error) {
|
func (v_ctx *StoreWithContext) CreateMockListing(listing MockListing) (MockListing, error) {
|
||||||
return v_ctx.Store.GetAccountPointerByUserID(v_ctx.ctx, userID)
|
return v_ctx.Store.CreateMockListing(v_ctx.ctx, listing)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v_ctx *StoreWithContext) ListMockListingsForShop(acctID int64, platform Platform, shopID string) ([]MockListing, error) {
|
||||||
|
return v_ctx.Store.ListMockListingsForShop(v_ctx.ctx, acctID, platform, shopID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v_ctx *StoreWithContext) SetOrderOfPlatformOnAccountPage(acctID int64, platform Platform, orderIndex int) ([]Platform, int, error) {
|
func (v_ctx *StoreWithContext) SetOrderOfPlatformOnAccountPage(acctID int64, platform Platform, orderIndex int) ([]Platform, int, error) {
|
||||||
|
|||||||
@@ -269,6 +269,8 @@ func (s *accountSubrouter) createMockShop(c *gin.Context) (response.Response, er
|
|||||||
|
|
||||||
// POST /:acctID/platforms/:platform/shops/mocks/:shop-id/listings
|
// POST /:acctID/platforms/:platform/shops/mocks/:shop-id/listings
|
||||||
func (s *accountSubrouter) addMockListing(c *gin.Context) (response.Response, error) {
|
func (s *accountSubrouter) addMockListing(c *gin.Context) (response.Response, error) {
|
||||||
|
acctID := auth.GetIdentity(c).Account.AccountID
|
||||||
|
|
||||||
var (
|
var (
|
||||||
platform accounts.Platform
|
platform accounts.Platform
|
||||||
shopID string
|
shopID string
|
||||||
@@ -287,11 +289,20 @@ func (s *accountSubrouter) addMockListing(c *gin.Context) (response.Response, er
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.log.Debugf("platform: %v", platform)
|
_, err = s.accts.CreateMockListing(
|
||||||
s.log.Debugf("shopID: %v", shopID)
|
c,
|
||||||
s.log.Debugf("name: %v", name)
|
accounts.MockListing{
|
||||||
s.log.Debugf("sku: %v", sku)
|
AccountShopListingIDs: accounts.NewAccountIDs(acctID).
|
||||||
s.log.Debugf("description: %v", description)
|
ShopID(platform, shopID).
|
||||||
|
ListingID(""),
|
||||||
|
Name: name,
|
||||||
|
SKU: sku,
|
||||||
|
Description: description,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create new listing: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-72
@@ -15,8 +15,6 @@
|
|||||||
--text-lg--line-height: calc(1.75 / 1.125);
|
--text-lg--line-height: calc(1.75 / 1.125);
|
||||||
--text-xl: 1.25rem;
|
--text-xl: 1.25rem;
|
||||||
--text-xl--line-height: calc(1.75 / 1.25);
|
--text-xl--line-height: calc(1.75 / 1.25);
|
||||||
--text-2xl: 1.5rem;
|
|
||||||
--text-2xl--line-height: calc(2 / 1.5);
|
|
||||||
--text-3xl: 1.875rem;
|
--text-3xl: 1.875rem;
|
||||||
--text-6xl: 3.75rem;
|
--text-6xl: 3.75rem;
|
||||||
--font-weight-semibold: 600;
|
--font-weight-semibold: 600;
|
||||||
@@ -291,6 +289,18 @@
|
|||||||
.h-\[2rem\] {
|
.h-\[2rem\] {
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
}
|
}
|
||||||
|
.h-\[10em\] {
|
||||||
|
height: 10em;
|
||||||
|
}
|
||||||
|
.h-fit {
|
||||||
|
height: fit-content;
|
||||||
|
}
|
||||||
|
.max-h-\[10em\] {
|
||||||
|
max-height: 10em;
|
||||||
|
}
|
||||||
|
.max-h-\[50em\] {
|
||||||
|
max-height: 50em;
|
||||||
|
}
|
||||||
.max-h-full {
|
.max-h-full {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
@@ -333,12 +343,6 @@
|
|||||||
.basis-full {
|
.basis-full {
|
||||||
flex-basis: 100%;
|
flex-basis: 100%;
|
||||||
}
|
}
|
||||||
.border-collapse {
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
.transform {
|
|
||||||
transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
|
|
||||||
}
|
|
||||||
.animate-pulse {
|
.animate-pulse {
|
||||||
animation: var(--animate-pulse);
|
animation: var(--animate-pulse);
|
||||||
}
|
}
|
||||||
@@ -351,9 +355,6 @@
|
|||||||
.resize {
|
.resize {
|
||||||
resize: both;
|
resize: both;
|
||||||
}
|
}
|
||||||
.list-disc {
|
|
||||||
list-style-type: disc;
|
|
||||||
}
|
|
||||||
.list-none {
|
.list-none {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
@@ -372,9 +373,6 @@
|
|||||||
.grid-cols-\[max-content_max-content\] {
|
.grid-cols-\[max-content_max-content\] {
|
||||||
grid-template-columns: max-content max-content;
|
grid-template-columns: max-content max-content;
|
||||||
}
|
}
|
||||||
.grid-rows-\[auto\] {
|
|
||||||
grid-template-rows: auto;
|
|
||||||
}
|
|
||||||
.grid-rows-\[auto_auto_auto\] {
|
.grid-rows-\[auto_auto_auto\] {
|
||||||
grid-template-rows: auto auto auto;
|
grid-template-rows: auto auto auto;
|
||||||
}
|
}
|
||||||
@@ -417,9 +415,15 @@
|
|||||||
.overflow-x-hidden {
|
.overflow-x-hidden {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
.overflow-y-auto {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
.overflow-y-hidden {
|
.overflow-y-hidden {
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
.overflow-y-scroll {
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
.rounded {
|
.rounded {
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
@@ -435,10 +439,6 @@
|
|||||||
.rounded-sm {
|
.rounded-sm {
|
||||||
border-radius: calc(var(--radius) - 4px);
|
border-radius: calc(var(--radius) - 4px);
|
||||||
}
|
}
|
||||||
.border {
|
|
||||||
border-style: var(--tw-border-style);
|
|
||||||
border-width: 1px;
|
|
||||||
}
|
|
||||||
.border-\[1px\] {
|
.border-\[1px\] {
|
||||||
border-style: var(--tw-border-style);
|
border-style: var(--tw-border-style);
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@@ -455,9 +455,6 @@
|
|||||||
--tw-border-style: solid;
|
--tw-border-style: solid;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
}
|
}
|
||||||
.border-background {
|
|
||||||
border-color: var(--background);
|
|
||||||
}
|
|
||||||
.border-foreground {
|
.border-foreground {
|
||||||
border-color: var(--foreground);
|
border-color: var(--foreground);
|
||||||
}
|
}
|
||||||
@@ -467,9 +464,6 @@
|
|||||||
.border-sidebar-border {
|
.border-sidebar-border {
|
||||||
border-color: var(--sidebar-border);
|
border-color: var(--sidebar-border);
|
||||||
}
|
}
|
||||||
.border-white {
|
|
||||||
border-color: var(--color-white);
|
|
||||||
}
|
|
||||||
.bg-accent {
|
.bg-accent {
|
||||||
background-color: var(--accent);
|
background-color: var(--accent);
|
||||||
}
|
}
|
||||||
@@ -494,9 +488,6 @@
|
|||||||
.py-\[0\.5em\] {
|
.py-\[0\.5em\] {
|
||||||
padding-block: 0.5em;
|
padding-block: 0.5em;
|
||||||
}
|
}
|
||||||
.py-\[1em\] {
|
|
||||||
padding-block: 1em;
|
|
||||||
}
|
|
||||||
.pt-\[1em\] {
|
.pt-\[1em\] {
|
||||||
padding-top: 1em;
|
padding-top: 1em;
|
||||||
}
|
}
|
||||||
@@ -518,13 +509,6 @@
|
|||||||
.font-display {
|
.font-display {
|
||||||
font-family: var(--display-family);
|
font-family: var(--display-family);
|
||||||
}
|
}
|
||||||
.font-text {
|
|
||||||
font-family: var(--text-family);
|
|
||||||
}
|
|
||||||
.text-2xl {
|
|
||||||
font-size: var(--text-2xl);
|
|
||||||
line-height: var(--tw-leading, var(--text-2xl--line-height));
|
|
||||||
}
|
|
||||||
.text-lg {
|
.text-lg {
|
||||||
font-size: var(--text-lg);
|
font-size: var(--text-lg);
|
||||||
line-height: var(--tw-leading, var(--text-lg--line-height));
|
line-height: var(--tw-leading, var(--text-lg--line-height));
|
||||||
@@ -548,9 +532,6 @@
|
|||||||
.text-nowrap {
|
.text-nowrap {
|
||||||
text-wrap: nowrap;
|
text-wrap: nowrap;
|
||||||
}
|
}
|
||||||
.text-wrap {
|
|
||||||
text-wrap: wrap;
|
|
||||||
}
|
|
||||||
.capitalize {
|
.capitalize {
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
}
|
}
|
||||||
@@ -560,10 +541,6 @@
|
|||||||
.underline {
|
.underline {
|
||||||
text-decoration-line: underline;
|
text-decoration-line: underline;
|
||||||
}
|
}
|
||||||
.outline {
|
|
||||||
outline-style: var(--tw-outline-style);
|
|
||||||
outline-width: 1px;
|
|
||||||
}
|
|
||||||
.filter {
|
.filter {
|
||||||
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
||||||
}
|
}
|
||||||
@@ -1139,26 +1116,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@property --tw-rotate-x {
|
|
||||||
syntax: "*";
|
|
||||||
inherits: false;
|
|
||||||
}
|
|
||||||
@property --tw-rotate-y {
|
|
||||||
syntax: "*";
|
|
||||||
inherits: false;
|
|
||||||
}
|
|
||||||
@property --tw-rotate-z {
|
|
||||||
syntax: "*";
|
|
||||||
inherits: false;
|
|
||||||
}
|
|
||||||
@property --tw-skew-x {
|
|
||||||
syntax: "*";
|
|
||||||
inherits: false;
|
|
||||||
}
|
|
||||||
@property --tw-skew-y {
|
|
||||||
syntax: "*";
|
|
||||||
inherits: false;
|
|
||||||
}
|
|
||||||
@property --tw-border-style {
|
@property --tw-border-style {
|
||||||
syntax: "*";
|
syntax: "*";
|
||||||
inherits: false;
|
inherits: false;
|
||||||
@@ -1168,11 +1125,6 @@
|
|||||||
syntax: "*";
|
syntax: "*";
|
||||||
inherits: false;
|
inherits: false;
|
||||||
}
|
}
|
||||||
@property --tw-outline-style {
|
|
||||||
syntax: "*";
|
|
||||||
inherits: false;
|
|
||||||
initial-value: solid;
|
|
||||||
}
|
|
||||||
@property --tw-blur {
|
@property --tw-blur {
|
||||||
syntax: "*";
|
syntax: "*";
|
||||||
inherits: false;
|
inherits: false;
|
||||||
@@ -1241,6 +1193,26 @@
|
|||||||
inherits: false;
|
inherits: false;
|
||||||
initial-value: 1;
|
initial-value: 1;
|
||||||
}
|
}
|
||||||
|
@property --tw-rotate-x {
|
||||||
|
syntax: "*";
|
||||||
|
inherits: false;
|
||||||
|
}
|
||||||
|
@property --tw-rotate-y {
|
||||||
|
syntax: "*";
|
||||||
|
inherits: false;
|
||||||
|
}
|
||||||
|
@property --tw-rotate-z {
|
||||||
|
syntax: "*";
|
||||||
|
inherits: false;
|
||||||
|
}
|
||||||
|
@property --tw-skew-x {
|
||||||
|
syntax: "*";
|
||||||
|
inherits: false;
|
||||||
|
}
|
||||||
|
@property --tw-skew-y {
|
||||||
|
syntax: "*";
|
||||||
|
inherits: false;
|
||||||
|
}
|
||||||
@property --tw-content {
|
@property --tw-content {
|
||||||
syntax: "*";
|
syntax: "*";
|
||||||
initial-value: "";
|
initial-value: "";
|
||||||
@@ -1258,14 +1230,8 @@
|
|||||||
@layer properties {
|
@layer properties {
|
||||||
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
|
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
|
||||||
*, ::before, ::after, ::backdrop {
|
*, ::before, ::after, ::backdrop {
|
||||||
--tw-rotate-x: initial;
|
|
||||||
--tw-rotate-y: initial;
|
|
||||||
--tw-rotate-z: initial;
|
|
||||||
--tw-skew-x: initial;
|
|
||||||
--tw-skew-y: initial;
|
|
||||||
--tw-border-style: solid;
|
--tw-border-style: solid;
|
||||||
--tw-font-weight: initial;
|
--tw-font-weight: initial;
|
||||||
--tw-outline-style: solid;
|
|
||||||
--tw-blur: initial;
|
--tw-blur: initial;
|
||||||
--tw-brightness: initial;
|
--tw-brightness: initial;
|
||||||
--tw-contrast: initial;
|
--tw-contrast: initial;
|
||||||
@@ -1282,6 +1248,11 @@
|
|||||||
--tw-scale-x: 1;
|
--tw-scale-x: 1;
|
||||||
--tw-scale-y: 1;
|
--tw-scale-y: 1;
|
||||||
--tw-scale-z: 1;
|
--tw-scale-z: 1;
|
||||||
|
--tw-rotate-x: initial;
|
||||||
|
--tw-rotate-y: initial;
|
||||||
|
--tw-rotate-z: initial;
|
||||||
|
--tw-skew-x: initial;
|
||||||
|
--tw-skew-y: initial;
|
||||||
--tw-content: "";
|
--tw-content: "";
|
||||||
--tw-leading: initial;
|
--tw-leading: initial;
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-14
@@ -27,7 +27,7 @@
|
|||||||
</h3>
|
</h3>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="grid grid-cols-[1fr_1fr]">
|
<div class="grid grid-cols-[1fr_1fr] gap-[1em] p-[1em]">
|
||||||
<form
|
<form
|
||||||
id="new-listing-form"
|
id="new-listing-form"
|
||||||
hx-post={{ printf "/api/accounts/%d/platforms/amazon/shops/mocks/%s/listings" $acctID $shopID }}
|
hx-post={{ printf "/api/accounts/%d/platforms/amazon/shops/mocks/%s/listings" $acctID $shopID }}
|
||||||
@@ -37,7 +37,10 @@
|
|||||||
grid-cols-[max-content_1fr]
|
grid-cols-[max-content_1fr]
|
||||||
grid-rows-[auto_auto_auto]
|
grid-rows-[auto_auto_auto]
|
||||||
gap-[0.5em]
|
gap-[0.5em]
|
||||||
m-[0.5em]
|
p-[1em]
|
||||||
|
bg-card
|
||||||
|
h-fit
|
||||||
|
rounded-lg
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<label for="name">
|
<label for="name">
|
||||||
@@ -49,7 +52,7 @@
|
|||||||
required
|
required
|
||||||
minlength="5"
|
minlength="5"
|
||||||
placeholder="What's in a name..."
|
placeholder="What's in a name..."
|
||||||
class="bg-card p-[0.25em]"
|
class="bg-accent p-[0.25em] rounded-sm"
|
||||||
/>
|
/>
|
||||||
<label for="sku">
|
<label for="sku">
|
||||||
SKU:
|
SKU:
|
||||||
@@ -58,7 +61,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
name="sku"
|
name="sku"
|
||||||
required
|
required
|
||||||
class="bg-card p-[0.25em]"
|
class="bg-accent p-[0.25em] rounded-sm"
|
||||||
/>
|
/>
|
||||||
<label for="description">
|
<label for="description">
|
||||||
Description:
|
Description:
|
||||||
@@ -69,7 +72,7 @@
|
|||||||
required
|
required
|
||||||
minlength="10"
|
minlength="10"
|
||||||
placeholder="Anything will do..."
|
placeholder="Anything will do..."
|
||||||
class="bg-card p-[0.25em]"
|
class="bg-accent p-[0.25em] rounded-sm"
|
||||||
/>
|
/>
|
||||||
{{ component "button"
|
{{ component "button"
|
||||||
"Text" "Save Listing"
|
"Text" "Save Listing"
|
||||||
@@ -77,16 +80,24 @@
|
|||||||
}}
|
}}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
<ul class="max-h-[50em] overflow-y-auto flex flex-col gap-[1em]">
|
||||||
Listing 1
|
{{- range $listing := .Accounts.ListMockListingsForShop $acctID $platform $shopID }}
|
||||||
</li>
|
<li class="p-[1em] bg-card rounded-lg">
|
||||||
<li>
|
<div>
|
||||||
Listing 2
|
Name: {{ $listing.Name }}
|
||||||
</li>
|
</div>
|
||||||
<li>
|
<div>
|
||||||
Listing 3
|
SKU: {{ $listing.SKU }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Description: {{ $listing.Description }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Count: {{ $listing.Count }}
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
{{- end }}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user