final
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,187 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BlueLaminate.EFCore.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// cs.money's <c>pricing.default</c> is the post-discount sticker price, which understates
|
||||
/// what a copy actually costs to buy — so tradeup input costs (and cross-market price
|
||||
/// comparisons) read low and conjure phantom profit. Switch the csmoney arm of the
|
||||
/// cross-market view to <c>price_before_discount</c>, falling back to <c>price</c> when no
|
||||
/// discount was recorded. View-only change; the underlying table keeps both columns.
|
||||
/// </summary>
|
||||
public partial class UseCsMoneyPriceBeforeDiscountInMarketView : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql("""
|
||||
CREATE OR REPLACE VIEW skintracker.market_listings AS
|
||||
SELECT
|
||||
'csfloat'::text AS marketplace,
|
||||
l.cs_float_listing_id AS external_id,
|
||||
l.skin_id AS skin_id,
|
||||
l.condition_id AS condition_id,
|
||||
l.skin_instance_id AS skin_instance_id,
|
||||
l.market_hash_name AS market_hash_name,
|
||||
l.wear_name AS wear,
|
||||
l.float_value AS float_value,
|
||||
l.paint_seed AS paint_seed,
|
||||
l.is_stat_trak AS is_stat_trak,
|
||||
l.is_souvenir AS is_souvenir,
|
||||
l.sticker_count AS sticker_count,
|
||||
l.price AS price,
|
||||
l.currency AS currency,
|
||||
l.inspect_link AS inspect_link,
|
||||
l.asset_id AS asset_id,
|
||||
l.status AS status,
|
||||
l.first_seen_at AS first_seen_at,
|
||||
l.last_seen_at AS last_seen_at,
|
||||
l.removed_at AS removed_at
|
||||
FROM skintracker.listings l
|
||||
UNION ALL
|
||||
SELECT
|
||||
'csmoney'::text,
|
||||
c.sell_order_id::text,
|
||||
c.skin_id,
|
||||
c.condition_id,
|
||||
c.skin_instance_id,
|
||||
c.market_hash_name,
|
||||
CASE lower(c.quality)
|
||||
WHEN 'fn' THEN 'Factory New'
|
||||
WHEN 'mw' THEN 'Minimal Wear'
|
||||
WHEN 'ft' THEN 'Field-Tested'
|
||||
WHEN 'ww' THEN 'Well-Worn'
|
||||
WHEN 'bs' THEN 'Battle-Scarred'
|
||||
ELSE c.quality
|
||||
END,
|
||||
c.float_value,
|
||||
c.paint_seed,
|
||||
c.is_stat_trak,
|
||||
c.is_souvenir,
|
||||
c.sticker_count,
|
||||
-- Undiscounted price is the real cost to buy; fall back to price when no
|
||||
-- discount was recorded.
|
||||
COALESCE(c.price_before_discount, c.price),
|
||||
c.currency,
|
||||
c.inspect_link,
|
||||
c.asset_id,
|
||||
c.status,
|
||||
c.first_seen_at,
|
||||
c.last_seen_at,
|
||||
c.removed_at
|
||||
FROM skintracker.cs_money_listings c
|
||||
UNION ALL
|
||||
SELECT
|
||||
'skinland'::text,
|
||||
s.listing_id::text,
|
||||
s.skin_id,
|
||||
s.condition_id,
|
||||
NULL::integer,
|
||||
s.market_hash_name,
|
||||
sc.condition,
|
||||
s.float_value,
|
||||
NULL::integer,
|
||||
s.is_stat_trak,
|
||||
s.is_souvenir,
|
||||
s.sticker_count,
|
||||
s.price,
|
||||
s.currency,
|
||||
s.inspect_link,
|
||||
NULL::text,
|
||||
s.status,
|
||||
s.first_seen_at,
|
||||
s.last_seen_at,
|
||||
s.removed_at
|
||||
FROM skintracker.skin_land_listings s
|
||||
LEFT JOIN skintracker.skin_conditions sc ON sc.id = s.condition_id;
|
||||
""");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Restore the csmoney arm to the post-discount pricing.default price.
|
||||
migrationBuilder.Sql("""
|
||||
CREATE OR REPLACE VIEW skintracker.market_listings AS
|
||||
SELECT
|
||||
'csfloat'::text AS marketplace,
|
||||
l.cs_float_listing_id AS external_id,
|
||||
l.skin_id AS skin_id,
|
||||
l.condition_id AS condition_id,
|
||||
l.skin_instance_id AS skin_instance_id,
|
||||
l.market_hash_name AS market_hash_name,
|
||||
l.wear_name AS wear,
|
||||
l.float_value AS float_value,
|
||||
l.paint_seed AS paint_seed,
|
||||
l.is_stat_trak AS is_stat_trak,
|
||||
l.is_souvenir AS is_souvenir,
|
||||
l.sticker_count AS sticker_count,
|
||||
l.price AS price,
|
||||
l.currency AS currency,
|
||||
l.inspect_link AS inspect_link,
|
||||
l.asset_id AS asset_id,
|
||||
l.status AS status,
|
||||
l.first_seen_at AS first_seen_at,
|
||||
l.last_seen_at AS last_seen_at,
|
||||
l.removed_at AS removed_at
|
||||
FROM skintracker.listings l
|
||||
UNION ALL
|
||||
SELECT
|
||||
'csmoney'::text,
|
||||
c.sell_order_id::text,
|
||||
c.skin_id,
|
||||
c.condition_id,
|
||||
c.skin_instance_id,
|
||||
c.market_hash_name,
|
||||
CASE lower(c.quality)
|
||||
WHEN 'fn' THEN 'Factory New'
|
||||
WHEN 'mw' THEN 'Minimal Wear'
|
||||
WHEN 'ft' THEN 'Field-Tested'
|
||||
WHEN 'ww' THEN 'Well-Worn'
|
||||
WHEN 'bs' THEN 'Battle-Scarred'
|
||||
ELSE c.quality
|
||||
END,
|
||||
c.float_value,
|
||||
c.paint_seed,
|
||||
c.is_stat_trak,
|
||||
c.is_souvenir,
|
||||
c.sticker_count,
|
||||
c.price,
|
||||
c.currency,
|
||||
c.inspect_link,
|
||||
c.asset_id,
|
||||
c.status,
|
||||
c.first_seen_at,
|
||||
c.last_seen_at,
|
||||
c.removed_at
|
||||
FROM skintracker.cs_money_listings c
|
||||
UNION ALL
|
||||
SELECT
|
||||
'skinland'::text,
|
||||
s.listing_id::text,
|
||||
s.skin_id,
|
||||
s.condition_id,
|
||||
NULL::integer,
|
||||
s.market_hash_name,
|
||||
sc.condition,
|
||||
s.float_value,
|
||||
NULL::integer,
|
||||
s.is_stat_trak,
|
||||
s.is_souvenir,
|
||||
s.sticker_count,
|
||||
s.price,
|
||||
s.currency,
|
||||
s.inspect_link,
|
||||
NULL::text,
|
||||
s.status,
|
||||
s.first_seen_at,
|
||||
s.last_seen_at,
|
||||
s.removed_at
|
||||
FROM skintracker.skin_land_listings s
|
||||
LEFT JOIN skintracker.skin_conditions sc ON sc.id = s.condition_id;
|
||||
""");
|
||||
}
|
||||
}
|
||||
}
|
||||
1347
BlueLaminate/BlueLaminate.EFCore/Migrations/20260602034328_UseCsMoneyComputedPriceInMarketView.Designer.cs
generated
Normal file
1347
BlueLaminate/BlueLaminate.EFCore/Migrations/20260602034328_UseCsMoneyComputedPriceInMarketView.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,186 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BlueLaminate.EFCore.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Spot-checking tradeups against cs.money's live site showed <c>pricing.computed</c> (the
|
||||
/// reference/market price) — not the post-discount <c>price</c> nor <c>price_before_discount</c>
|
||||
/// — is the true value of a copy. Switch the csmoney arm of the cross-market view to
|
||||
/// <c>computed_price</c>, falling back to price_before_discount then price when it's null.
|
||||
/// View-only change; the underlying table keeps all three price columns.
|
||||
/// </summary>
|
||||
public partial class UseCsMoneyComputedPriceInMarketView : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql("""
|
||||
CREATE OR REPLACE VIEW skintracker.market_listings AS
|
||||
SELECT
|
||||
'csfloat'::text AS marketplace,
|
||||
l.cs_float_listing_id AS external_id,
|
||||
l.skin_id AS skin_id,
|
||||
l.condition_id AS condition_id,
|
||||
l.skin_instance_id AS skin_instance_id,
|
||||
l.market_hash_name AS market_hash_name,
|
||||
l.wear_name AS wear,
|
||||
l.float_value AS float_value,
|
||||
l.paint_seed AS paint_seed,
|
||||
l.is_stat_trak AS is_stat_trak,
|
||||
l.is_souvenir AS is_souvenir,
|
||||
l.sticker_count AS sticker_count,
|
||||
l.price AS price,
|
||||
l.currency AS currency,
|
||||
l.inspect_link AS inspect_link,
|
||||
l.asset_id AS asset_id,
|
||||
l.status AS status,
|
||||
l.first_seen_at AS first_seen_at,
|
||||
l.last_seen_at AS last_seen_at,
|
||||
l.removed_at AS removed_at
|
||||
FROM skintracker.listings l
|
||||
UNION ALL
|
||||
SELECT
|
||||
'csmoney'::text,
|
||||
c.sell_order_id::text,
|
||||
c.skin_id,
|
||||
c.condition_id,
|
||||
c.skin_instance_id,
|
||||
c.market_hash_name,
|
||||
CASE lower(c.quality)
|
||||
WHEN 'fn' THEN 'Factory New'
|
||||
WHEN 'mw' THEN 'Minimal Wear'
|
||||
WHEN 'ft' THEN 'Field-Tested'
|
||||
WHEN 'ww' THEN 'Well-Worn'
|
||||
WHEN 'bs' THEN 'Battle-Scarred'
|
||||
ELSE c.quality
|
||||
END,
|
||||
c.float_value,
|
||||
c.paint_seed,
|
||||
c.is_stat_trak,
|
||||
c.is_souvenir,
|
||||
c.sticker_count,
|
||||
-- computed_price is the true market value; fall back when it's missing.
|
||||
COALESCE(c.computed_price, c.price_before_discount, c.price),
|
||||
c.currency,
|
||||
c.inspect_link,
|
||||
c.asset_id,
|
||||
c.status,
|
||||
c.first_seen_at,
|
||||
c.last_seen_at,
|
||||
c.removed_at
|
||||
FROM skintracker.cs_money_listings c
|
||||
UNION ALL
|
||||
SELECT
|
||||
'skinland'::text,
|
||||
s.listing_id::text,
|
||||
s.skin_id,
|
||||
s.condition_id,
|
||||
NULL::integer,
|
||||
s.market_hash_name,
|
||||
sc.condition,
|
||||
s.float_value,
|
||||
NULL::integer,
|
||||
s.is_stat_trak,
|
||||
s.is_souvenir,
|
||||
s.sticker_count,
|
||||
s.price,
|
||||
s.currency,
|
||||
s.inspect_link,
|
||||
NULL::text,
|
||||
s.status,
|
||||
s.first_seen_at,
|
||||
s.last_seen_at,
|
||||
s.removed_at
|
||||
FROM skintracker.skin_land_listings s
|
||||
LEFT JOIN skintracker.skin_conditions sc ON sc.id = s.condition_id;
|
||||
""");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Restore the csmoney arm to price_before_discount (with price fallback).
|
||||
migrationBuilder.Sql("""
|
||||
CREATE OR REPLACE VIEW skintracker.market_listings AS
|
||||
SELECT
|
||||
'csfloat'::text AS marketplace,
|
||||
l.cs_float_listing_id AS external_id,
|
||||
l.skin_id AS skin_id,
|
||||
l.condition_id AS condition_id,
|
||||
l.skin_instance_id AS skin_instance_id,
|
||||
l.market_hash_name AS market_hash_name,
|
||||
l.wear_name AS wear,
|
||||
l.float_value AS float_value,
|
||||
l.paint_seed AS paint_seed,
|
||||
l.is_stat_trak AS is_stat_trak,
|
||||
l.is_souvenir AS is_souvenir,
|
||||
l.sticker_count AS sticker_count,
|
||||
l.price AS price,
|
||||
l.currency AS currency,
|
||||
l.inspect_link AS inspect_link,
|
||||
l.asset_id AS asset_id,
|
||||
l.status AS status,
|
||||
l.first_seen_at AS first_seen_at,
|
||||
l.last_seen_at AS last_seen_at,
|
||||
l.removed_at AS removed_at
|
||||
FROM skintracker.listings l
|
||||
UNION ALL
|
||||
SELECT
|
||||
'csmoney'::text,
|
||||
c.sell_order_id::text,
|
||||
c.skin_id,
|
||||
c.condition_id,
|
||||
c.skin_instance_id,
|
||||
c.market_hash_name,
|
||||
CASE lower(c.quality)
|
||||
WHEN 'fn' THEN 'Factory New'
|
||||
WHEN 'mw' THEN 'Minimal Wear'
|
||||
WHEN 'ft' THEN 'Field-Tested'
|
||||
WHEN 'ww' THEN 'Well-Worn'
|
||||
WHEN 'bs' THEN 'Battle-Scarred'
|
||||
ELSE c.quality
|
||||
END,
|
||||
c.float_value,
|
||||
c.paint_seed,
|
||||
c.is_stat_trak,
|
||||
c.is_souvenir,
|
||||
c.sticker_count,
|
||||
COALESCE(c.price_before_discount, c.price),
|
||||
c.currency,
|
||||
c.inspect_link,
|
||||
c.asset_id,
|
||||
c.status,
|
||||
c.first_seen_at,
|
||||
c.last_seen_at,
|
||||
c.removed_at
|
||||
FROM skintracker.cs_money_listings c
|
||||
UNION ALL
|
||||
SELECT
|
||||
'skinland'::text,
|
||||
s.listing_id::text,
|
||||
s.skin_id,
|
||||
s.condition_id,
|
||||
NULL::integer,
|
||||
s.market_hash_name,
|
||||
sc.condition,
|
||||
s.float_value,
|
||||
NULL::integer,
|
||||
s.is_stat_trak,
|
||||
s.is_souvenir,
|
||||
s.sticker_count,
|
||||
s.price,
|
||||
s.currency,
|
||||
s.inspect_link,
|
||||
NULL::text,
|
||||
s.status,
|
||||
s.first_seen_at,
|
||||
s.last_seen_at,
|
||||
s.removed_at
|
||||
FROM skintracker.skin_land_listings s
|
||||
LEFT JOIN skintracker.skin_conditions sc ON sc.id = s.condition_id;
|
||||
""");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user